445 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			445 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
								 | 
							
								#include "TextureImpl.h"
							 | 
						||
| 
								 | 
							
								#include "ogl.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <Kore/Graphics1/Image.h>
							 | 
						||
| 
								 | 
							
								#include <Kore/Graphics3/Graphics.h>
							 | 
						||
| 
								 | 
							
								#include <Kore/Log.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								using namespace Kore;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef GL_TEXTURE_3D
							 | 
						||
| 
								 | 
							
								#define GL_TEXTURE_3D 0x806F
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace {
							 | 
						||
| 
								 | 
							
									int convertFormat(Graphics3::Image::Format format) {
							 | 
						||
| 
								 | 
							
										switch (format) {
							 | 
						||
| 
								 | 
							
										case Graphics3::Image::RGBA32:
							 | 
						||
| 
								 | 
							
										case Graphics3::Image::RGBA64:
							 | 
						||
| 
								 | 
							
										case Graphics3::Image::RGBA128:
							 | 
						||
| 
								 | 
							
										default:
							 | 
						||
| 
								 | 
							
											// #ifdef GL_BGRA
							 | 
						||
| 
								 | 
							
											// return GL_BGRA;
							 | 
						||
| 
								 | 
							
											// #else
							 | 
						||
| 
								 | 
							
											return GL_RGBA;
							 | 
						||
| 
								 | 
							
										// #endif
							 | 
						||
| 
								 | 
							
										case Graphics3::Image::RGB24:
							 | 
						||
| 
								 | 
							
											return GL_RGB;
							 | 
						||
| 
								 | 
							
										case Graphics3::Image::Grey8:
							 | 
						||
| 
								 | 
							
								#ifdef KINC_OPENGL_ES
							 | 
						||
| 
								 | 
							
											return GL_LUMINANCE;
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
											return GL_RED;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int convertInternalFormat(Graphics3::Image::Format format) {
							 | 
						||
| 
								 | 
							
										switch (format) {
							 | 
						||
| 
								 | 
							
										case Graphics3::Image::RGBA128:
							 | 
						||
| 
								 | 
							
											return GL_RGBA;
							 | 
						||
| 
								 | 
							
										case Graphics3::Image::RGBA32:
							 | 
						||
| 
								 | 
							
										case Graphics3::Image::RGBA64:
							 | 
						||
| 
								 | 
							
										default:
							 | 
						||
| 
								 | 
							
											// #ifdef GL_BGRA
							 | 
						||
| 
								 | 
							
											// return GL_BGRA;
							 | 
						||
| 
								 | 
							
											// #else
							 | 
						||
| 
								 | 
							
											return GL_RGBA;
							 | 
						||
| 
								 | 
							
										// #endif
							 | 
						||
| 
								 | 
							
										case Graphics3::Image::RGB24:
							 | 
						||
| 
								 | 
							
											return GL_RGB;
							 | 
						||
| 
								 | 
							
										case Graphics3::Image::Grey8:
							 | 
						||
| 
								 | 
							
								#ifdef KINC_OPENGL_ES
							 | 
						||
| 
								 | 
							
											return GL_LUMINANCE;
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
											return GL_RED;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int convertType(Graphics3::Image::Format format) {
							 | 
						||
| 
								 | 
							
										switch (format) {
							 | 
						||
| 
								 | 
							
										case Graphics3::Image::RGBA128:
							 | 
						||
| 
								 | 
							
										case Graphics3::Image::RGBA64:
							 | 
						||
| 
								 | 
							
											return GL_FLOAT;
							 | 
						||
| 
								 | 
							
										case Graphics3::Image::RGBA32:
							 | 
						||
| 
								 | 
							
										default:
							 | 
						||
| 
								 | 
							
											return GL_UNSIGNED_BYTE;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if 0
							 | 
						||
| 
								 | 
							
									int astcFormat(u8 blockX, u8 blockY) {
							 | 
						||
| 
								 | 
							
										switch (blockX) {
							 | 
						||
| 
								 | 
							
										case 4:
							 | 
						||
| 
								 | 
							
											switch (blockY) {
							 | 
						||
| 
								 | 
							
											case 4:
							 | 
						||
| 
								 | 
							
												return COMPRESSED_RGBA_ASTC_4x4_KHR;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										case 5:
							 | 
						||
| 
								 | 
							
											switch (blockY) {
							 | 
						||
| 
								 | 
							
											case 4:
							 | 
						||
| 
								 | 
							
												return COMPRESSED_RGBA_ASTC_5x4_KHR;
							 | 
						||
| 
								 | 
							
											case 5:
							 | 
						||
| 
								 | 
							
												return COMPRESSED_RGBA_ASTC_5x5_KHR;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										case 6:
							 | 
						||
| 
								 | 
							
											switch (blockY) {
							 | 
						||
| 
								 | 
							
											case 5:
							 | 
						||
| 
								 | 
							
												return COMPRESSED_RGBA_ASTC_6x5_KHR;
							 | 
						||
| 
								 | 
							
											case 6:
							 | 
						||
| 
								 | 
							
												return COMPRESSED_RGBA_ASTC_6x6_KHR;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										case 8:
							 | 
						||
| 
								 | 
							
											switch (blockY) {
							 | 
						||
| 
								 | 
							
											case 5:
							 | 
						||
| 
								 | 
							
												return COMPRESSED_RGBA_ASTC_8x5_KHR;
							 | 
						||
| 
								 | 
							
											case 6:
							 | 
						||
| 
								 | 
							
												return COMPRESSED_RGBA_ASTC_8x6_KHR;
							 | 
						||
| 
								 | 
							
											case 8:
							 | 
						||
| 
								 | 
							
												return COMPRESSED_RGBA_ASTC_8x8_KHR;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										case 10:
							 | 
						||
| 
								 | 
							
											switch (blockY) {
							 | 
						||
| 
								 | 
							
											case 5:
							 | 
						||
| 
								 | 
							
												return COMPRESSED_RGBA_ASTC_10x5_KHR;
							 | 
						||
| 
								 | 
							
											case 6:
							 | 
						||
| 
								 | 
							
												return COMPRESSED_RGBA_ASTC_10x6_KHR;
							 | 
						||
| 
								 | 
							
											case 8:
							 | 
						||
| 
								 | 
							
												return COMPRESSED_RGBA_ASTC_10x8_KHR;
							 | 
						||
| 
								 | 
							
											case 10:
							 | 
						||
| 
								 | 
							
												return COMPRESSED_RGBA_ASTC_10x10_KHR;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										case 12:
							 | 
						||
| 
								 | 
							
											switch (blockY) {
							 | 
						||
| 
								 | 
							
											case 10:
							 | 
						||
| 
								 | 
							
												return COMPRESSED_RGBA_ASTC_12x10_KHR;
							 | 
						||
| 
								 | 
							
											case 12:
							 | 
						||
| 
								 | 
							
												return COMPRESSED_RGBA_ASTC_12x12_KHR;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										return 0;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int pow(int pow) {
							 | 
						||
| 
								 | 
							
										int ret = 1;
							 | 
						||
| 
								 | 
							
										for (int i = 0; i < pow; ++i)
							 | 
						||
| 
								 | 
							
											ret *= 2;
							 | 
						||
| 
								 | 
							
										return ret;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int getPower2(int i) {
							 | 
						||
| 
								 | 
							
										for (int power = 0;; ++power)
							 | 
						||
| 
								 | 
							
											if (pow(power) >= i)
							 | 
						||
| 
								 | 
							
												return pow(power);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void convertImageToPow2(Graphics3::Image::Format format, u8 *from, int fw, int fh, u8 *to, int tw, int th) {
							 | 
						||
| 
								 | 
							
										switch (format) {
							 | 
						||
| 
								 | 
							
										case Graphics3::Image::RGBA32:
							 | 
						||
| 
								 | 
							
											for (int y = 0; y < th; ++y) {
							 | 
						||
| 
								 | 
							
												for (int x = 0; x < tw; ++x) {
							 | 
						||
| 
								 | 
							
													to[tw * 4 * y + x * 4 + 0] = 0;
							 | 
						||
| 
								 | 
							
													to[tw * 4 * y + x * 4 + 1] = 0;
							 | 
						||
| 
								 | 
							
													to[tw * 4 * y + x * 4 + 2] = 0;
							 | 
						||
| 
								 | 
							
													to[tw * 4 * y + x * 4 + 3] = 0;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											for (int y = 0; y < fh; ++y) {
							 | 
						||
| 
								 | 
							
												for (int x = 0; x < fw; ++x) {
							 | 
						||
| 
								 | 
							
													to[tw * 4 * y + x * 4 + 0] = from[y * fw * 4 + x * 4 + 0];
							 | 
						||
| 
								 | 
							
													to[tw * 4 * y + x * 4 + 1] = from[y * fw * 4 + x * 4 + 1];
							 | 
						||
| 
								 | 
							
													to[tw * 4 * y + x * 4 + 2] = from[y * fw * 4 + x * 4 + 2];
							 | 
						||
| 
								 | 
							
													to[tw * 4 * y + x * 4 + 3] = from[y * fw * 4 + x * 4 + 3];
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
										case Graphics3::Image::Grey8:
							 | 
						||
| 
								 | 
							
											for (int y = 0; y < th; ++y) {
							 | 
						||
| 
								 | 
							
												for (int x = 0; x < tw; ++x) {
							 | 
						||
| 
								 | 
							
													to[tw * y + x] = 0;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											for (int y = 0; y < fh; ++y) {
							 | 
						||
| 
								 | 
							
												for (int x = 0; x < fw; ++x) {
							 | 
						||
| 
								 | 
							
													to[tw * y + x] = from[y * fw + x];
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void Graphics3::Texture::init(const char *format, bool readable) {
							 | 
						||
| 
								 | 
							
									bool toPow2;
							 | 
						||
| 
								 | 
							
									if (Graphics3::nonPow2TexturesSupported()) {
							 | 
						||
| 
								 | 
							
										texWidth = width;
							 | 
						||
| 
								 | 
							
										texHeight = height;
							 | 
						||
| 
								 | 
							
										toPow2 = false;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else {
							 | 
						||
| 
								 | 
							
										texWidth = getPower2(width);
							 | 
						||
| 
								 | 
							
										texHeight = getPower2(height);
							 | 
						||
| 
								 | 
							
										toPow2 = !(texWidth == width && texHeight == height);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									u8 *conversionBuffer = nullptr;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (compressed) {
							 | 
						||
| 
								 | 
							
								#if defined(KINC_IOS)
							 | 
						||
| 
								 | 
							
										texWidth = Kore::max(texWidth, texHeight);
							 | 
						||
| 
								 | 
							
										texHeight = Kore::max(texWidth, texHeight);
							 | 
						||
| 
								 | 
							
										if (texWidth < 8)
							 | 
						||
| 
								 | 
							
											texWidth = 8;
							 | 
						||
| 
								 | 
							
										if (texHeight < 8)
							 | 
						||
| 
								 | 
							
											texHeight = 8;
							 | 
						||
| 
								 | 
							
								#elif defined(KINC_ANDROID)
							 | 
						||
| 
								 | 
							
										texWidth = width;
							 | 
						||
| 
								 | 
							
										texHeight = height;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else if (toPow2) {
							 | 
						||
| 
								 | 
							
										conversionBuffer = new u8[texWidth * texHeight * sizeOf(this->format)];
							 | 
						||
| 
								 | 
							
										convertImageToPow2(this->format, (u8 *)data, width, height, conversionBuffer, texWidth, texHeight);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef KINC_ANDROID
							 | 
						||
| 
								 | 
							
									external_oes = false;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
							 | 
						||
| 
								 | 
							
									glCheckErrors();
							 | 
						||
| 
								 | 
							
									glGenTextures(1, &texture);
							 | 
						||
| 
								 | 
							
									glCheckErrors();
							 | 
						||
| 
								 | 
							
									glBindTexture(GL_TEXTURE_2D, texture);
							 | 
						||
| 
								 | 
							
									glCheckErrors();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int convertedType = convertType(this->format);
							 | 
						||
| 
								 | 
							
									bool isHdr = convertedType == GL_FLOAT;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (compressed) {
							 | 
						||
| 
								 | 
							
								#ifdef KINC_IOS
							 | 
						||
| 
								 | 
							
										glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, texWidth, texHeight, 0, texWidth * texHeight / 2, data);
							 | 
						||
| 
								 | 
							
								// #elif defined(KINC_ANDROID)
							 | 
						||
| 
								 | 
							
								//		u8 blockX = internalFormat >> 8;
							 | 
						||
| 
								 | 
							
								//		u8 blockY = internalFormat & 0xff;
							 | 
						||
| 
								 | 
							
								//		glCompressedTexImage2D(GL_TEXTURE_2D, 0, astcFormat(blockX, blockY), texWidth, texHeight, 0, dataSize, data);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else {
							 | 
						||
| 
								 | 
							
										if (isHdr) {
							 | 
						||
| 
								 | 
							
											glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, convertedType, hdrData);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, convertedType, toPow2 ? conversionBuffer : data);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										glCheckErrors();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
							 | 
						||
| 
								 | 
							
									glCheckErrors();
							 | 
						||
| 
								 | 
							
									glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
							 | 
						||
| 
								 | 
							
									glCheckErrors();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (toPow2) {
							 | 
						||
| 
								 | 
							
										delete[] conversionBuffer;
							 | 
						||
| 
								 | 
							
										conversionBuffer = nullptr;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (!readable) {
							 | 
						||
| 
								 | 
							
										if (isHdr) {
							 | 
						||
| 
								 | 
							
											delete[] hdrData;
							 | 
						||
| 
								 | 
							
											hdrData = nullptr;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										else {
							 | 
						||
| 
								 | 
							
											delete[] data;
							 | 
						||
| 
								 | 
							
											data = nullptr;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (readable && compressed) {
							 | 
						||
| 
								 | 
							
										log(Kore::Warning, "Compressed images can not be readable.");
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Graphics3::Texture::Texture(int width, int height, Image::Format format, bool readable) : Image(width, height, format, readable) {
							 | 
						||
| 
								 | 
							
								#ifdef KINC_IOS
							 | 
						||
| 
								 | 
							
									texWidth = width;
							 | 
						||
| 
								 | 
							
									texHeight = height;
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
									if (Graphics3::nonPow2TexturesSupported()) {
							 | 
						||
| 
								 | 
							
										texWidth = width;
							 | 
						||
| 
								 | 
							
										texHeight = height;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else {
							 | 
						||
| 
								 | 
							
										texWidth = getPower2(width);
							 | 
						||
| 
								 | 
							
										texHeight = getPower2(height);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
									// conversionBuffer = new u8[texWidth * texHeight * 4];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef KINC_ANDROID
							 | 
						||
| 
								 | 
							
									external_oes = false;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
							 | 
						||
| 
								 | 
							
									glCheckErrors();
							 | 
						||
| 
								 | 
							
									glGenTextures(1, &texture);
							 | 
						||
| 
								 | 
							
									glCheckErrors();
							 | 
						||
| 
								 | 
							
									glBindTexture(GL_TEXTURE_2D, texture);
							 | 
						||
| 
								 | 
							
									glCheckErrors();
							 | 
						||
| 
								 | 
							
									glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
							 | 
						||
| 
								 | 
							
									glCheckErrors();
							 | 
						||
| 
								 | 
							
									glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
							 | 
						||
| 
								 | 
							
									glCheckErrors();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if (convertType(format) == GL_FLOAT) {
							 | 
						||
| 
								 | 
							
										glTexImage2D(GL_TEXTURE_2D, 0, convertInternalFormat(format), texWidth, texHeight, 0, convertFormat(format), GL_FLOAT, nullptr);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else {
							 | 
						||
| 
								 | 
							
										glTexImage2D(GL_TEXTURE_2D, 0, convertInternalFormat(format), texWidth, texHeight, 0, convertFormat(format), GL_UNSIGNED_BYTE, data);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									glCheckErrors();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/*if (!readable) {
							 | 
						||
| 
								 | 
							
									    delete[] data;
							 | 
						||
| 
								 | 
							
									    data = nullptr;
							 | 
						||
| 
								 | 
							
									}*/
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Graphics3::Texture::Texture(int width, int height, int depth, Graphics3::Image::Format format, bool readable) : Image(width, height, depth, format, readable) {
							 | 
						||
| 
								 | 
							
								#ifndef OPENGLES
							 | 
						||
| 
								 | 
							
									glGenTextures(1, &texture);
							 | 
						||
| 
								 | 
							
									glCheckErrors();
							 | 
						||
| 
								 | 
							
									glBindTexture(GL_TEXTURE_3D, texture);
							 | 
						||
| 
								 | 
							
									glCheckErrors();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
							 | 
						||
| 
								 | 
							
									glCheckErrors();
							 | 
						||
| 
								 | 
							
									glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
							 | 
						||
| 
								 | 
							
									glCheckErrors();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									glTexImage3D(GL_TEXTURE_3D, 0, convertFormat(format), width, height, depth, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
							 | 
						||
| 
								 | 
							
									glCheckErrors();
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef KINC_ANDROID
							 | 
						||
| 
								 | 
							
								Texture::Texture(unsigned texid) : Image(1023, 684, Image::RGBA32, false) {
							 | 
						||
| 
								 | 
							
									texture = texid;
							 | 
						||
| 
								 | 
							
									external_oes = true;
							 | 
						||
| 
								 | 
							
									texWidth = 1023;
							 | 
						||
| 
								 | 
							
									texHeight = 684;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								TextureImpl::~TextureImpl() {
							 | 
						||
| 
								 | 
							
									glDeleteTextures(1, &texture);
							 | 
						||
| 
								 | 
							
									glFlush();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void Graphics3::Texture::_set(TextureUnit unit) {
							 | 
						||
| 
								 | 
							
									GLenum target = depth > 1 ? GL_TEXTURE_3D : GL_TEXTURE_2D;
							 | 
						||
| 
								 | 
							
									glActiveTexture(GL_TEXTURE0 + unit.unit);
							 | 
						||
| 
								 | 
							
									glCheckErrors();
							 | 
						||
| 
								 | 
							
								#ifdef KINC_ANDROID
							 | 
						||
| 
								 | 
							
									if (external_oes) {
							 | 
						||
| 
								 | 
							
										glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture);
							 | 
						||
| 
								 | 
							
										glCheckErrors();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else {
							 | 
						||
| 
								 | 
							
										glBindTexture(target, texture);
							 | 
						||
| 
								 | 
							
										glCheckErrors();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
									glBindTexture(target, texture);
							 | 
						||
| 
								 | 
							
									glCheckErrors();
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int Graphics3::Texture::stride() {
							 | 
						||
| 
								 | 
							
									return width * sizeOf(format);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								u8 *Graphics3::Texture::lock() {
							 | 
						||
| 
								 | 
							
									return (u8 *)data;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*void Texture::unlock() {
							 | 
						||
| 
								 | 
							
								    if (conversionBuffer != nullptr) {
							 | 
						||
| 
								 | 
							
								        convertImageToPow2(format, (u8*)data, width, height, conversionBuffer, texWidth, texHeight);
							 | 
						||
| 
								 | 
							
								        glBindTexture(GL_TEXTURE_2D, texture);
							 | 
						||
| 
								 | 
							
								#ifndef GL_LUMINANCE
							 | 
						||
| 
								 | 
							
								#define GL_LUMINANCE GL_RED
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								        glTexImage2D(GL_TEXTURE_2D, 0, (format == Image::RGBA32) ? GL_RGBA : GL_LUMINANCE, texWidth, texHeight, 0, (format == Image::RGBA32) ? GL_RGBA :
							 | 
						||
| 
								 | 
							
								GL_LUMINANCE, GL_UNSIGNED_BYTE, conversionBuffer);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void Graphics3::Texture::unlock() {
							 | 
						||
| 
								 | 
							
									// if (conversionBuffer != nullptr) {
							 | 
						||
| 
								 | 
							
									// convertImageToPow2(format, (u8*)data, width, height, conversionBuffer, texWidth, texHeight);
							 | 
						||
| 
								 | 
							
									glBindTexture(GL_TEXTURE_2D, texture);
							 | 
						||
| 
								 | 
							
									glCheckErrors();
							 | 
						||
| 
								 | 
							
									// glTexImage2D(GL_TEXTURE_2D, 0, (format == Image::RGBA32) ? GL_RGBA : GL_LUMINANCE, texWidth, texHeight, 0, (format == Image::RGBA32) ? GL_RGBA :
							 | 
						||
| 
								 | 
							
									// GL_LUMINANCE, GL_UNSIGNED_BYTE, conversionBuffer);
							 | 
						||
| 
								 | 
							
									if (convertType(format) == GL_FLOAT) {
							 | 
						||
| 
								 | 
							
										glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texWidth, texHeight, convertFormat(format), GL_FLOAT, hdrData);
							 | 
						||
| 
								 | 
							
										glCheckErrors();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else {
							 | 
						||
| 
								 | 
							
										glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texWidth, texHeight, convertFormat(format), GL_UNSIGNED_BYTE, data);
							 | 
						||
| 
								 | 
							
										glCheckErrors();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									// }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void Graphics3::Texture::clear(int x, int y, int z, int width, int height, int depth, uint color) {
							 | 
						||
| 
								 | 
							
								#ifdef GL_VERSION_4_4
							 | 
						||
| 
								 | 
							
									static float clearColor[4];
							 | 
						||
| 
								 | 
							
									clearColor[0] = ((color & 0x00ff0000) >> 16) / 255.0f;
							 | 
						||
| 
								 | 
							
									clearColor[1] = ((color & 0x0000ff00) >> 8) / 255.0f;
							 | 
						||
| 
								 | 
							
									clearColor[2] = (color & 0x000000ff) / 255.0f;
							 | 
						||
| 
								 | 
							
									clearColor[3] = ((color & 0xff000000) >> 24) / 255.0f;
							 | 
						||
| 
								 | 
							
									GLenum target = depth > 1 ? GL_TEXTURE_3D : GL_TEXTURE_2D;
							 | 
						||
| 
								 | 
							
									glBindTexture(target, texture);
							 | 
						||
| 
								 | 
							
									glClearTexSubImage(texture, 0, x, y, z, width, height, depth, convertFormat(format), convertType(format), clearColor);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifdef KINC_IOS
							 | 
						||
| 
								 | 
							
								void Texture::upload(u8 *data) {
							 | 
						||
| 
								 | 
							
									glBindTexture(GL_TEXTURE_2D, texture);
							 | 
						||
| 
								 | 
							
									glCheckErrors();
							 | 
						||
| 
								 | 
							
									glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texWidth, texHeight, convertFormat(format), GL_UNSIGNED_BYTE, data);
							 | 
						||
| 
								 | 
							
									glCheckErrors();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void Graphics3::Texture::generateMipmaps(int levels) {
							 | 
						||
| 
								 | 
							
									GLenum target = depth > 1 ? GL_TEXTURE_3D : GL_TEXTURE_2D;
							 | 
						||
| 
								 | 
							
									glBindTexture(target, texture);
							 | 
						||
| 
								 | 
							
									glCheckErrors();
							 | 
						||
| 
								 | 
							
									glGenerateMipmap(target);
							 | 
						||
| 
								 | 
							
									glCheckErrors();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void Graphics3::Texture::setMipmap(Texture *mipmap, int level) {
							 | 
						||
| 
								 | 
							
									int convertedType = convertType(mipmap->format);
							 | 
						||
| 
								 | 
							
									bool isHdr = convertedType == GL_FLOAT;
							 | 
						||
| 
								 | 
							
									GLenum target = depth > 1 ? GL_TEXTURE_3D : GL_TEXTURE_2D;
							 | 
						||
| 
								 | 
							
									glBindTexture(target, texture);
							 | 
						||
| 
								 | 
							
									glCheckErrors();
							 | 
						||
| 
								 | 
							
									if (isHdr) {
							 | 
						||
| 
								 | 
							
										glTexImage2D(target, level, convertInternalFormat(mipmap->format), mipmap->texWidth, mipmap->texHeight, 0, convertFormat(mipmap->format), convertedType,
							 | 
						||
| 
								 | 
							
										             mipmap->hdrData);
							 | 
						||
| 
								 | 
							
										glCheckErrors();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									else {
							 | 
						||
| 
								 | 
							
										glTexImage2D(target, level, convertInternalFormat(mipmap->format), mipmap->texWidth, mipmap->texHeight, 0, convertFormat(mipmap->format), convertedType,
							 | 
						||
| 
								 | 
							
										             mipmap->data);
							 | 
						||
| 
								 | 
							
										glCheckErrors();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 |