Bläddra i källkod

Merge pull request #174 from blackberry-gaming/next-setaylor

Next setaylor
Sean Paul Taylor 14 år sedan
förälder
incheckning
6ff7651789

+ 0 - 2
gameplay/res/shaders/colored-specular.fsh

@@ -30,8 +30,6 @@ void lighting(vec3 normalVector, vec3 cameraDirection, vec3 lightDirection, floa
 
 
     // Diffuse
     // Diffuse
 	float ddot = abs(dot(normalVector, lightDirection));
 	float ddot = abs(dot(normalVector, lightDirection));
-	if (ddot < 0)
-		ddot = abs(ddot) * 0.25f; // simulate light bounce at partial intensity
     float diffuseIntensity = attenuation * ddot;
     float diffuseIntensity = attenuation * ddot;
     diffuseIntensity = max(0.0, diffuseIntensity);
     diffuseIntensity = max(0.0, diffuseIntensity);
     _diffuseColor = u_lightColor * _baseColor.rgb * diffuseIntensity;
     _diffuseColor = u_lightColor * _baseColor.rgb * diffuseIntensity;

+ 0 - 2
gameplay/res/shaders/diffuse-specular.fsh

@@ -26,8 +26,6 @@ void lighting(vec3 normalVector, vec3 cameraDirection, vec3 lightDirection, floa
 
 
     // Diffuse
     // Diffuse
 	float ddot = dot(normalVector, lightDirection);
 	float ddot = dot(normalVector, lightDirection);
-	if (ddot < 0)
-		ddot = abs(ddot) * 0.25f; // simulate light bounce at partial intensity
     float diffuseIntensity = attenuation * ddot;
     float diffuseIntensity = attenuation * ddot;
     diffuseIntensity = max(0.0, diffuseIntensity);
     diffuseIntensity = max(0.0, diffuseIntensity);
     _diffuseColor = u_lightColor * _baseColor.rgb * diffuseIntensity;
     _diffuseColor = u_lightColor * _baseColor.rgb * diffuseIntensity;

+ 1 - 0
gameplay/src/Base.h

@@ -204,6 +204,7 @@ extern void printError(const char* format, ...);
 #elif WIN32
 #elif WIN32
     #define WIN32_LEAN_AND_MEAN
     #define WIN32_LEAN_AND_MEAN
     #include <GL/glew.h>
     #include <GL/glew.h>
+	#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG		0x8C02
 #elif __APPLE__
 #elif __APPLE__
     #include "TargetConditionals.h"
     #include "TargetConditionals.h"
     #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
     #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR

+ 156 - 0
gameplay/src/Texture.cpp

@@ -1,6 +1,7 @@
 #include "Base.h"
 #include "Base.h"
 #include "Image.h"
 #include "Image.h"
 #include "Texture.h"
 #include "Texture.h"
+#include "FileSystem.h"
 
 
 namespace gameplay
 namespace gameplay
 {
 {
@@ -72,6 +73,11 @@ Texture* Texture::create(const char* path, bool generateMipmaps)
                     texture = create(image, generateMipmaps);
                     texture = create(image, generateMipmaps);
                 SAFE_RELEASE(image);
                 SAFE_RELEASE(image);
             }
             }
+			else if (tolower(ext[1]) == 'p' && tolower(ext[2]) == 'v' && tolower(ext[3]) == 'r')
+			{
+            	// PowerVR Compressed RGBA
+				texture = createCompressedPVR(path);
+			}
             break;
             break;
         }
         }
     }
     }
@@ -137,6 +143,156 @@ Texture* Texture::create(Format format, unsigned int width, unsigned int height,
     return texture;
     return texture;
 }
 }
 
 
+Texture* Texture::createCompressedPVR(const char* path)
+{
+	char PVRTexIdentifier[] = "PVR!";
+
+	enum
+	{
+	    PVRTextureFlagTypePVRTC_2 = 24,
+	    PVRTextureFlagTypePVRTC_4
+	};
+	struct pvr_file_header
+	{
+		unsigned int size;          		// size of the structure
+		unsigned int height;              	// height of surface to be created
+		unsigned int width;               	// width of input surface
+		unsigned int mipmapCount;         	// number of mip-map levels requested
+		unsigned int formatflags;           // pixel format flags
+		unsigned int dataSize;     			// total size in bytes
+		unsigned int bpp;            		// number of bits per pixel
+		unsigned int redBitMask;            // mask for red bit
+		unsigned int greenBitMask;          // mask for green bits
+		unsigned int blueBitMask;           // mask for blue bits
+		unsigned int alphaBitMask;        	// mask for alpha channel
+		unsigned int pvrTag;                // magic number identifying pvr file
+		unsigned int surfaceCount;          // number of surfaces present in the pvr
+	} ;
+
+	FILE* file = FileSystem::openFile(path, "rb");
+	if (file == NULL)
+	{
+		LOG_ERROR_VARG("Failed to load file: %s", path);
+		return NULL;
+	}
+
+	// Read the file header
+	unsigned int size = sizeof(pvr_file_header);
+	pvr_file_header header;
+	unsigned int read = (int)fread(&header, 1, size, file);
+	assert(read == size);
+	if (read != size)
+	{
+		LOG_ERROR_VARG("Read file header error for pvr file: %s (%d < %d)", path, (int)read, (int)size);
+		fclose(file);
+		return NULL;
+	}
+
+	// Proper file header identifier
+	if (PVRTexIdentifier[0] != (char)((header.pvrTag >>  0) & 0xff) ||
+		PVRTexIdentifier[1] != (char)((header.pvrTag >>  8) & 0xff) ||
+	    PVRTexIdentifier[2] != (char)((header.pvrTag >> 16) & 0xff) ||
+	    PVRTexIdentifier[3] != (char)((header.pvrTag >> 24) & 0xff))
+	 {
+		LOG_ERROR_VARG("Invalid PVR texture file: %s", path);
+		fclose(file);
+	    return NULL;
+	}
+	// Format flags for GLenum format
+	GLenum format;
+	unsigned int formatFlags = header.formatflags & 0xff;
+	if (formatFlags == PVRTextureFlagTypePVRTC_4)
+	{
+		format = header.alphaBitMask ? COMPRESSED_RGBA_PVRTC_4BPP : COMPRESSED_RGB_PVRTC_4BPP;
+	}
+	else if (formatFlags == PVRTextureFlagTypePVRTC_2)
+	{
+		format = header.alphaBitMask ? COMPRESSED_RGBA_PVRTC_2BPP : COMPRESSED_RGB_PVRTC_2BPP;
+	}
+	else
+	{
+		LOG_ERROR_VARG("Invalid PVR texture format flags for file: %s", path);
+		fclose(file);
+		return NULL;
+	}
+
+	unsigned char* data = new unsigned char[header.dataSize];
+	read = (int)fread(data, 1, header.dataSize, file);
+	assert(read == header.dataSize);
+	if (read != header.dataSize)
+	{
+		LOG_ERROR_VARG("Read file data error for pvr file: %s (%d < %d)", path, (int)read, (int)header.dataSize);
+		SAFE_DELETE_ARRAY(data);
+		fclose(file);
+		return NULL;
+	}
+	// Close file
+	fclose(file);
+
+	// Load our texture.
+	GLuint textureId;
+	GL_ASSERT( glGenTextures(1, &textureId) );
+	GL_ASSERT( glBindTexture(GL_TEXTURE_2D, textureId) );
+	GL_ASSERT( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, header.mipmapCount > 0 ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR ) );
+
+    Texture* texture = new Texture();
+    texture->_handle = textureId;
+    texture->_width = header.width;
+    texture->_height = header.height;
+
+	// Load the data for each level
+	unsigned int width = header.width;
+	unsigned int height = header.height;
+	unsigned int blockSize = 0;
+	unsigned int widthBlocks = 0;
+	unsigned int heightBlocks = 0;
+	unsigned int bpp = 0;
+	unsigned int dataSize = 0;
+	unsigned char* dataOffset = data;
+
+	for (unsigned int level = 0; level <= header.mipmapCount; level++)
+	{
+		if (formatFlags == PVRTextureFlagTypePVRTC_4)
+		{
+			/*
+			blockSize = 4 * 4; 		// Pixel by pixel block size for 4bpp
+			widthBlocks = width / 4;
+			heightBlocks = height / 4;
+			bpp = 4;
+			*/
+			dataSize = ( max((int)width, 8) * max((int)height, 8) * 4 + 7) / 8;
+		}
+		else
+		{
+			/*
+			blockSize = 8 * 4; 		// Pixel by pixel block size for 2bpp
+			widthBlocks = width / 8;
+			heightBlocks = height / 4;
+			bpp = 2;
+			*/
+			dataSize = ( max((int)width, 16) * max((int)height, 8) * 2 + 7) / 8;
+		}
+
+		/* Clamp to minimum number of blocks
+		if (widthBlocks < 2)
+			widthBlocks = 2;
+		if (heightBlocks < 2)
+			heightBlocks = 2;
+*/
+		//dataSize = widthBlocks * heightBlocks * ((blockSize * bpp) / 8);
+
+		GL_ASSERT( glCompressedTexImage2D(GL_TEXTURE_2D, level, (GLenum)format, width, height, 0, dataSize, dataOffset) );
+
+		dataOffset += dataSize;
+		width = max((int)width >> 1, 1);
+		height = max((int)height >> 1, 1);
+	}
+
+	SAFE_DELETE_ARRAY(data);
+
+	return texture;
+}
+
 unsigned int Texture::getWidth() const
 unsigned int Texture::getWidth() const
 {
 {
     return _width;
     return _width;

+ 11 - 1
gameplay/src/Texture.h

@@ -10,6 +10,10 @@ class Image;
 
 
 /**
 /**
  * Represents a texture.
  * Represents a texture.
+ *
+ * TODO: Addd support for the following: 
+ * COMPRESSED_RGBA_ATITC = GL_ATC_RGBA_EXPLICIT_ALPHA_AMD,
+ * COMPRESSED_RGBA_DXT1 = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
  */
  */
 class Texture : public Ref
 class Texture : public Ref
 {
 {
@@ -25,7 +29,11 @@ public:
         RGB     = GL_RGB,
         RGB     = GL_RGB,
         RGBA    = GL_RGBA,
         RGBA    = GL_RGBA,
         ALPHA   = GL_ALPHA,
         ALPHA   = GL_ALPHA,
-        DEPTH   = GL_DEPTH_COMPONENT
+        DEPTH   = GL_DEPTH_COMPONENT,
+        COMPRESSED_RGB_PVRTC_4BPP = GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG,
+		COMPRESSED_RGBA_PVRTC_4BPP = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG,
+		COMPRESSED_RGB_PVRTC_2BPP = GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG,
+		COMPRESSED_RGBA_PVRTC_2BPP = GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG
     };
     };
 
 
     /**
     /**
@@ -203,6 +211,8 @@ private:
      */
      */
     virtual ~Texture();
     virtual ~Texture();
 
 
+	static Texture* createCompressedPVR(const char* path);
+
     std::string _path;
     std::string _path;
     TextureHandle _handle;
     TextureHandle _handle;
     unsigned int _width;
     unsigned int _width;