Quellcode durchsuchen

Merge branch 'next' of https://github.com/blackberry-gaming/GamePlay into next-ablake

Conflicts:
	gameplay/src/Container.cpp
Adam Blake vor 14 Jahren
Ursprung
Commit
79a782f7b6

+ 5 - 5
README.md

@@ -2,17 +2,17 @@
 GamePlay is a open-source, cross-platform 3D native gaming framework making it easy to learn and write mobile and desktop games. 
 
 ## Supported Mobile Platforms
-- BlackBerry PlayBook 1/2 (using BlackBerry Native SDK 2)
+- BlackBerry PlayBook 2 (using BlackBerry Native SDK 2)
 - Google Android 4 (using Google Android NDK 7)
-- Apple iOS 4/5 (using Apple XCode 4)
+- Apple iOS 5 (using Apple XCode 4)
 
 ## Supported Desktop Platforms
-- Apple MacOS X (using Apple XCode 4)
 - Microsoft Windows XP/7 (using Microsoft Visual Studio 2010)
-    * Requires [Creative OpenAL 1.1] (http://connect.creativelabs.com/openal/Downloads/Forms/AllItems.aspx)
+- Apple MacOS X (using Apple XCode 4)
+    * Both require [Creative OpenAL 1.1] (http://connect.creativelabs.com/openal/Downloads/Forms/AllItems.aspx)
 
 ## Roadmap for 'next' branch
-- UI Overlays
+- Terrain and Water
 - Improvements to Lighting
 - More Samples and Tutorials
 

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

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

+ 4 - 0
gameplay/src/Base.h

@@ -203,6 +203,10 @@ extern void printError(const char* format, ...);
     #define OPENGL_ES
 #elif WIN32
     #define WIN32_LEAN_AND_MEAN
+	#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG                      0x8C00
+	#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG                      0x8C01
+	#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG                     0x8C02
+	#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG                     0x8C03
     #include <GL/glew.h>
 #elif __APPLE__
     #include "TargetConditionals.h"

+ 1 - 0
gameplay/src/PhysicsCharacter.cpp

@@ -105,6 +105,7 @@ PhysicsCharacter::~PhysicsCharacter()
 
     _node->removeListener(this);
     SAFE_RELEASE(_node);
+    SAFE_DELETE(_motionState);
 }
 
 Node* PhysicsCharacter::getNode() const

+ 9 - 0
gameplay/src/PhysicsController.cpp

@@ -5,6 +5,8 @@
 #include "PhysicsMotionState.h"
 #include "Package.h"
 
+#include "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h"
+
 // The initial capacity of the Bullet debug drawer's vertex batch.
 #define INITIAL_CAPACITY 280
 
@@ -679,6 +681,13 @@ btCollisionShape* PhysicsController::createMesh(PhysicsRigidBody* body, const Ve
     return shape;
 }
 
+btCollisionShape* PhysicsController::createHeightfield(int width, int height, void* heightfieldData, float minHeight, float maxHeight)
+{
+    btCollisionShape* shape = bullet_new<btHeightfieldTerrainShape>(width, height, heightfieldData, 1.0f, minHeight, maxHeight, 1, PHY_FLOAT, false);
+    _shapes.push_back(new PhysicsCollisionShape(shape));
+    return shape;
+}
+
 void PhysicsController::addConstraint(PhysicsRigidBody* a, PhysicsRigidBody* b, PhysicsConstraint* constraint)
 {
     a->addConstraint(constraint);

+ 3 - 0
gameplay/src/PhysicsController.h

@@ -329,6 +329,9 @@ private:
     // Creates a triangle mesh collision shape to be used in the creation of a rigid body.
     btCollisionShape* createMesh(PhysicsRigidBody* body, const Vector3& scale);
 
+    // Creates a heightfield collision shape to be used in the creation of a rigid body.
+    btCollisionShape* createHeightfield(int width, int height, void* heightfieldData, float minHeight, float maxHeight);
+
     // Sets up the given constraint for the given two rigid bodies.
     void addConstraint(PhysicsRigidBody* a, PhysicsRigidBody* b, PhysicsConstraint* constraint);
 

+ 1 - 4
gameplay/src/PhysicsRigidBody.cpp

@@ -5,8 +5,6 @@
 #include "PhysicsMotionState.h"
 #include "PhysicsRigidBody.h"
 
-#include "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h"
-
 namespace gameplay
 {
 
@@ -126,8 +124,7 @@ PhysicsRigidBody::PhysicsRigidBody(Node* node, Image* image, float mass,
     SAFE_DELETE_ARRAY(data);
 
     // Create the heightfield collision shape.
-    _shape = bullet_new<btHeightfieldTerrainShape>(_width, _height, _heightfieldData,
-        1.0f, minHeight, maxHeight, 1, PHY_FLOAT, false);
+    _shape = Game::getInstance()->getPhysicsController()->createHeightfield(_width, _height, _heightfieldData, minHeight, maxHeight);
 
     // Offset the heightmap's center of mass according to the way that Bullet calculates the origin 
     // of its heightfield collision shape; see documentation for the btHeightfieldTerrainShape for more info.

+ 138 - 0
gameplay/src/Texture.cpp

@@ -1,6 +1,7 @@
 #include "Base.h"
 #include "Image.h"
 #include "Texture.h"
+#include "FileSystem.h"
 
 namespace gameplay
 {
@@ -72,6 +73,11 @@ Texture* Texture::create(const char* path, bool generateMipmaps)
                     texture = create(image, generateMipmaps);
                 SAFE_RELEASE(image);
             }
+			else if (tolower(ext[1]) == 'p' && tolower(ext[2]) == 'v' && tolower(ext[3]) == 'r')
+			{
+            	// PowerVR Compressed RGBA
+				texture = createCompressedPVR(path);
+			}
             break;
         }
     }
@@ -137,6 +143,138 @@ Texture* Texture::create(Format format, unsigned int width, unsigned int height,
     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)
+		{
+			dataSize = ( max((int)width, 8) * max((int)height, 8) * 4 + 7) / 8;
+		}
+		else
+		{
+			dataSize = ( max((int)width, 16) * max((int)height, 8) * 2 + 7) / 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
 {
     return _width;

+ 11 - 1
gameplay/src/Texture.h

@@ -10,6 +10,10 @@ class Image;
 
 /**
  * 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
 {
@@ -25,7 +29,11 @@ public:
         RGB     = GL_RGB,
         RGBA    = GL_RGBA,
         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();
 
+	static Texture* createCompressedPVR(const char* path);
+
     std::string _path;
     TextureHandle _handle;
     unsigned int _width;