소스 검색

Added Support for MacOSX in gameplay and gameplay samples

Sean Paul Taylor 14 년 전
부모
커밋
f6e0465593
38개의 변경된 파일664개의 추가작업 그리고 243개의 파일을 삭제
  1. 2 0
      gameplay/res/shaders/bumped-specular.fsh
  2. 3 1
      gameplay/res/shaders/bumped-specular.vsh
  3. 2 0
      gameplay/res/shaders/bumped.fsh
  4. 2 0
      gameplay/res/shaders/colored-specular.fsh
  5. 3 1
      gameplay/res/shaders/colored-specular.vsh
  6. 2 0
      gameplay/res/shaders/colored.fsh
  7. 3 1
      gameplay/res/shaders/colored.vsh
  8. 2 0
      gameplay/res/shaders/diffuse-specular.fsh
  9. 3 1
      gameplay/res/shaders/diffuse-specular.vsh
  10. 2 0
      gameplay/res/shaders/diffuse.fsh
  11. 3 1
      gameplay/res/shaders/diffuse.vsh
  12. 2 0
      gameplay/res/shaders/parallax-specular.fsh
  13. 3 1
      gameplay/res/shaders/parallax-specular.vsh
  14. 2 0
      gameplay/res/shaders/parallax.fsh
  15. 3 1
      gameplay/res/shaders/parallax.vsh
  16. 4 2
      gameplay/res/shaders/solid.fsh
  17. 1 1
      gameplay/res/shaders/solid.vsh
  18. 2 0
      gameplay/res/shaders/textured.fsh
  19. 2 1
      gameplay/src/AnimationClip.cpp
  20. 0 1
      gameplay/src/AnimationController.cpp
  21. 144 10
      gameplay/src/AudioBuffer.cpp
  22. 4 0
      gameplay/src/AudioBuffer.h
  23. 34 8
      gameplay/src/AudioController.cpp
  24. 2 1
      gameplay/src/AudioController.h
  25. 22 11
      gameplay/src/Base.h
  26. 1 1
      gameplay/src/Curve.cpp
  27. 17 3
      gameplay/src/Effect.cpp
  28. 3 2
      gameplay/src/FileSystem.cpp
  29. 1 2
      gameplay/src/Font.cpp
  30. 2 2
      gameplay/src/Joint.cpp
  31. 318 17
      gameplay/src/PlatformMacOSX.mm
  32. 2 3
      gameplay/src/Properties.cpp
  33. 1 1
      gameplay/src/RenderState.cpp
  34. 0 1
      gameplay/src/SpriteBatch.cpp
  35. 0 2
      gameplay/src/Texture.h
  36. 13 167
      gameplay/src/gameplay-main-macosx.mm
  37. 23 0
      gameplay/src/gameplay-main-qnx.cpp
  38. 31 0
      gameplay/src/gameplay-main-win32.cpp

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

@@ -1,4 +1,6 @@
+#ifdef OPENGL_ES
 precision highp float;
+#endif
 
 // Uniforms
 uniform vec3 u_lightColor;                  // Light color.

+ 3 - 1
gameplay/res/shaders/bumped-specular.vsh

@@ -229,7 +229,9 @@ void main()
     gl_Position = u_worldViewProjectionMatrix * position;
 
     // Transform the normal, tangent and binormals to  view space.
-    mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix);
+    mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix[0].xyz,
+                                                u_inverseTransposeWorldViewMatrix[1].xyz,
+                                                u_inverseTransposeWorldViewMatrix[2].xyz);
     vec3 tangentVector  = normalize(inverseTransposeWorldViewMatrix * tangent);
     vec3 normalVector = normalize(inverseTransposeWorldViewMatrix * normal);
     vec3 binormalVector = normalize(inverseTransposeWorldViewMatrix * binormal);

+ 2 - 0
gameplay/res/shaders/bumped.fsh

@@ -1,4 +1,6 @@
+#ifdef OPENGL_ES
 precision highp float;
+#endif
 
 // Uniforms
 uniform vec3 u_lightColor;                   // Light color.

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

@@ -1,4 +1,6 @@
+#ifdef OPENGL_ES
 precision highp float;
+#endif
 
 // Uniforms
 uniform vec3 u_lightColor;                      // Light color

+ 3 - 1
gameplay/res/shaders/colored-specular.vsh

@@ -180,7 +180,9 @@ void main()
     gl_Position = u_worldViewProjectionMatrix * position;
 
     // Transform normal to view space.
-    mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix);
+    mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix[0].xyz,
+                                                u_inverseTransposeWorldViewMatrix[1].xyz,
+                                                u_inverseTransposeWorldViewMatrix[2].xyz);
     v_normalVector = inverseTransposeWorldViewMatrix * normal;
 
     // Compute the camera direction.

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

@@ -1,4 +1,6 @@
+#ifdef OPENGL_ES
 precision highp float;
+#endif
 
 // Uniforms
 uniform vec3 u_lightColor;                      // Light color

+ 3 - 1
gameplay/res/shaders/colored.vsh

@@ -173,7 +173,9 @@ void main()
     gl_Position = u_worldViewProjectionMatrix * position;
 
     // Transform normal to view space.
-    mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix);
+    mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix[0].xyz,
+                                                u_inverseTransposeWorldViewMatrix[1].xyz,
+                                                u_inverseTransposeWorldViewMatrix[2].xyz);
     v_normalVector = inverseTransposeWorldViewMatrix * normal;
 
     // Apply light.

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

@@ -1,4 +1,6 @@
+#ifdef OPENGL_ES
 precision highp float;
+#endif
 
 // Uniforms
 uniform vec3 u_lightColor;                      // Light color

+ 3 - 1
gameplay/res/shaders/diffuse-specular.vsh

@@ -179,7 +179,9 @@ void main()
     gl_Position = u_worldViewProjectionMatrix * position;
 
     // Transform normal to view space.
-    mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix);
+    mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix[0].xyz,
+                                                u_inverseTransposeWorldViewMatrix[1].xyz,
+                                                u_inverseTransposeWorldViewMatrix[2].xyz);
     v_normalVector = inverseTransposeWorldViewMatrix * normal;
 
     // Compute the camera direction.

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

@@ -1,4 +1,6 @@
+#ifdef OPENGL_ES
 precision highp float;
+#endif
 
 // Uniforms
 uniform vec3 u_lightColor;                      // Light color

+ 3 - 1
gameplay/res/shaders/diffuse.vsh

@@ -178,7 +178,9 @@ void main()
     gl_Position = u_worldViewProjectionMatrix * position;
 
     // Transform normal to view space.
-    mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix);
+    mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix[0].xyz,
+                                                u_inverseTransposeWorldViewMatrix[1].xyz,
+                                                u_inverseTransposeWorldViewMatrix[2].xyz);
     v_normalVector = inverseTransposeWorldViewMatrix * normal;
 
     // Apply light.

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

@@ -1,4 +1,6 @@
+#ifdef OPENGL_ES
 precision highp float;
+#endif
 
 // Uniforms
 uniform vec3 u_lightColor;                      // Light color.

+ 3 - 1
gameplay/res/shaders/parallax-specular.vsh

@@ -99,7 +99,9 @@ void main()
     gl_Position = u_worldViewProjectionMatrix * a_position;
 
     // Transform the normal, tangent and binormals to  view space.
-    mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix);
+    mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix[0].xyz,
+                                                u_inverseTransposeWorldViewMatrix[1].xyz,
+                                                u_inverseTransposeWorldViewMatrix[2].xyz);
     vec3 tangentVector  = normalize(inverseTransposeWorldViewMatrix * a_tangent);
     vec3 normalVector = normalize(inverseTransposeWorldViewMatrix * a_normal);
     vec3 binormalVector = normalize(inverseTransposeWorldViewMatrix * a_binormal);

+ 2 - 0
gameplay/res/shaders/parallax.fsh

@@ -1,4 +1,6 @@
+#ifdef OPENGL_ES
 precision highp float;
+#endif
 
 // Uniforms
 uniform vec3 u_lightColor;                      // Light color.

+ 3 - 1
gameplay/res/shaders/parallax.vsh

@@ -99,7 +99,9 @@ void main()
     gl_Position = u_worldViewProjectionMatrix * a_position;
 
     // Transform the normal, tangent and binormals to  view space.
-    mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix);
+    mat3 inverseTransposeWorldViewMatrix = mat3(u_inverseTransposeWorldViewMatrix[0].xyz,
+                                                u_inverseTransposeWorldViewMatrix[1].xyz,
+                                                u_inverseTransposeWorldViewMatrix[2].xyz);
     vec3 tangentVector  = normalize(inverseTransposeWorldViewMatrix * a_tangent);
     vec3 normalVector = inverseTransposeWorldViewMatrix * a_normal;
     vec3 binormalVector = inverseTransposeWorldViewMatrix * a_binormal;

+ 4 - 2
gameplay/res/shaders/solid.fsh

@@ -1,6 +1,8 @@
-precision mediump float;
+#ifdef OPENGL_ES
+precision highp float;
+#endif
 
-// Diffuse color
+// Uniforms
 uniform vec4 u_diffuseColor;        // Diffuse color
 
 void main()

+ 1 - 1
gameplay/res/shaders/solid.vsh

@@ -1,4 +1,4 @@
-// Uniform
+// Uniforms
 uniform mat4 u_worldViewProjectionMatrix;        // Matrix to transform a position to clip space.
 
 // Inputs

+ 2 - 0
gameplay/res/shaders/textured.fsh

@@ -1,4 +1,6 @@
+#ifdef OPENGL_ES
 precision highp float;
+#endif
 
 // Uniforms
 uniform sampler2D u_diffuseTexture;     // Diffuse texture

+ 2 - 1
gameplay/src/AnimationClip.cpp

@@ -12,7 +12,8 @@ namespace gameplay
 {
 
 AnimationClip::AnimationClip(const char* id, Animation* animation, unsigned long startTime, unsigned long endTime)
-    : _id(id), _animation(animation), _startTime(startTime), _endTime(endTime), _elapsedTime(0), _runningTime(0), _channelCount(animation->_channels.size()), _repeatCount(1.0f), _speed(1.0f), _isPlaying(false), _beginListeners(NULL), _endListeners(NULL)
+    : _id(id), _animation(animation), _startTime(startTime), _endTime(endTime), _elapsedTime(0), _runningTime(0), 
+       _channelCount(animation->_channels.size()), _repeatCount(1.0f), _speed(1.0f), _isPlaying(false), _beginListeners(NULL), _endListeners(NULL)
 {
     assert(0 <= startTime && startTime <= animation->_duration && 0 <= endTime && endTime <= animation->_duration);
 

+ 0 - 1
gameplay/src/AnimationController.cpp

@@ -57,7 +57,6 @@ Animation* AnimationController::createAnimation(const char* id, AnimationTarget*
 
 Animation* AnimationController::createAnimationFromTo(const char* id, AnimationTarget* target, int propertyId, float* from, float* to, Curve::InterpolationType type, unsigned long duration)
 {
-    const unsigned int keyCount = 2;
     const unsigned int propertyComponentCount = target->getAnimationPropertyComponentCount(propertyId);
     float* keyValues = new float[2 * propertyComponentCount];
 

+ 144 - 10
gameplay/src/AudioBuffer.cpp

@@ -31,7 +31,7 @@ AudioBuffer* AudioBuffer::create(const char* path)
     assert(path);
 
     // Search the cache for a stream from this file.
-    unsigned int bufferCount = __buffers.size();
+    unsigned int bufferCount = (unsigned int)__buffers.size();
     AudioBuffer* buffer = NULL;
     for (unsigned int i = 0; i < bufferCount; i++)
     {
@@ -44,7 +44,6 @@ AudioBuffer* AudioBuffer::create(const char* path)
     }
 
     ALuint alBuffer;
-    ALboolean loop = AL_TRUE;
     ALCenum al_error;
 
     // Load audio data into a buffer.
@@ -56,18 +55,47 @@ AudioBuffer* AudioBuffer::create(const char* path)
         alDeleteBuffers(1, &alBuffer);
         return NULL;
     }
-
-    std::string fullPath = FileSystem::getResourcePath();
-    fullPath += "/";
-    fullPath += path;
     
     // Load sound file.
-    alBuffer = alutCreateBufferFromFile(fullPath.c_str());
-    if (alBuffer == AL_NONE)
+    FILE* file = FileSystem::openFile(path, "rb");
+    if (!file)
     {
-        LOG_ERROR_VARG("AudioBuffer error (%d) loading file: %s", fullPath.c_str());
-        return NULL;
+        LOG_ERROR_VARG("Invalid audio buffer file: %s", path);
+        goto cleanup;
+    }
+    
+    // Read the file header
+    char header[12];
+    if (fread(header, 1, 12, file) != 12)
+    {
+        LOG_ERROR_VARG("Invalid audio buffer file: %s", path);
+        goto cleanup;
+    }
+    
+    // Check the file format
+    if (memcmp(header, "RIFF", 4) == 0)
+    {
+        if (!AudioBuffer::loadWav(file, alBuffer))
+        {
+            LOG_ERROR_VARG("Invalid wave file: %s", path);
+            goto cleanup;
+        }
+    }
+    else if(memcmp(header, "OGG", 3) == 0)
+    {
+        if (!AudioBuffer::loadOgg(file, alBuffer))
+        {
+            LOG_ERROR_VARG("Invalid ogg file: %s", path);
+            goto cleanup;
+        }
+    }
+    else
+    {
+        LOG_ERROR_VARG("Unsupported audio file: %s", path);
     }
+    
+    
+    fclose(file);
 
     buffer = new AudioBuffer(path, alBuffer);
 
@@ -75,6 +103,112 @@ AudioBuffer* AudioBuffer::create(const char* path)
     __buffers.push_back(buffer);
 
     return buffer;
+    
+cleanup:
+    
+    if (file)
+        fclose(file);
+    if (alBuffer)
+        alDeleteBuffers(1, &alBuffer);
+    return NULL;
+}
+    
+    
+bool AudioBuffer::loadWav(FILE* file, ALuint buffer)
+{
+    char stream[12];
+    
+    // Verify the wave fmt magic value meaning format.
+    if (fread(stream, 1, 8, file) != 8 || memcmp(stream, "fmt ", 4) != 0 )
+        return false;
+    
+    // Check for a valid pcm format.
+    if(fread(stream, 1, 2, file) != 2 || stream[1] != 0 || stream[0] != 1)
+    {
+        LOG_ERROR("Unsupported audio file, not PCM format.");
+        return false;
+    }
+    
+    // Get the channel count (16-bit little-endian)
+    int channels;
+    if (fread(stream, 1, 2, file) != 2)
+        return false;
+    channels  = stream[1]<<8;
+    channels |= stream[0];
+    
+    // Get the sample frequency (32-bit little-endian) 
+    ALuint frequency;
+    if (fread(stream, 1, 4, file) != 4)
+        return false;
+    frequency  = stream[3]<<24;
+    frequency |= stream[2]<<16;
+    frequency |= stream[1]<<8;
+    frequency |= stream[0];
+    
+    // The next 6 bytes hold the block size and bytes-per-second. 
+    // We don't need that info, so just read and ignore it. 
+    // We could use this later if we need to know the duration.
+    if (fread(stream, 1, 6, file) != 6)
+        return false;
+    
+    // Get the bit depth (16-bit little-endian)
+    int bits;
+    if (fread(stream, 1, 2, file) != 2)
+        return false;
+    bits  = stream[1]<<8;
+    bits |= stream[0];
+    
+    
+    // Now convert the given channel count and bit depth into an OpenAL format. 
+    ALuint format = 0;
+    if(bits == 8)
+    {
+        if(channels == 1)
+            format = AL_FORMAT_MONO8;
+        else if(channels == 2)
+            format = AL_FORMAT_STEREO8;
+    }
+    else if(bits == 16)
+    {
+        if(channels == 1)
+            format = AL_FORMAT_MONO16;
+        else if(channels == 2)
+            format = AL_FORMAT_STEREO16;
+    }
+    else
+    {
+        LOG_ERROR_VARG("Incompatible format: (%d, %d)", channels, bits);
+        return false;
+    }
+    
+    // Read the data chunk, which will hold the decoded sample data 
+    if (fread(stream, 1, 4, file) != 4 || memcmp(stream, "data", 4) != 0)
+    {
+        LOG_ERROR("WAV file has no data.");
+        return false;
+    }
+    
+    // Read how much data is remaining and buffer it up.
+    unsigned int dataSize;
+    fread(&dataSize, sizeof(int), 1, file);
+    char* data = new char[dataSize];
+    if (fread(data, sizeof(char), dataSize, file) != dataSize)
+    {
+        LOG_ERROR("WAV file missing data.");
+        SAFE_DELETE_ARRAY(data);
+        return false;
+    }
+    alBufferData(buffer, format, data, dataSize, frequency);
+    SAFE_DELETE_ARRAY(data);
+    return true;
+}
+    
+// TODO:
+bool AudioBuffer::loadOgg(FILE* file, ALuint buffer)
+{
+    LOG_ERROR("Ogg Vorbis not supported yet");
+    
+    return false;
 }
 
 }

+ 4 - 0
gameplay/src/AudioBuffer.h

@@ -41,6 +41,10 @@ private:
      * @return The buffer from a file.
      */
     static AudioBuffer* create(const char* path);
+    
+    static bool loadWav(FILE* file, ALuint buffer);
+    
+    static bool loadOgg(FILE* file, ALuint buffer);
 
     std::string _filePath;
     ALuint _alBuffer;

+ 34 - 8
gameplay/src/AudioController.cpp

@@ -3,17 +3,19 @@
  */
 
 #include "Base.h"
+#include "AudioController.h"
 #include "AudioListener.h"
 #include "AudioBuffer.h"
 #include "AudioSource.h"
-#include "AudioController.h"
+
 
 namespace gameplay
 {
 
 std::list<AudioSource*> AudioController::_playingSources;
 
-AudioController::AudioController()
+AudioController::AudioController() 
+    : _alcDevice(NULL), _alcContext(NULL)
 {
 }
 
@@ -23,19 +25,43 @@ AudioController::~AudioController()
 
 void AudioController::initialize()
 {    
-	alutInit(0, 0);
-
-	ALenum errorID = alutGetError();
-    if ( errorID != ALUT_ERROR_NO_ERROR)
+    _alcDevice = alcOpenDevice (NULL);
+    if (!_alcDevice)
     {
-        LOG_ERROR_VARG("AudioController::initialize() error. Unable to initialize alut: %s\n", alutGetErrorString(errorID));
+        LOG_ERROR("AudioController::initialize() error. Unable to open OpenAL device.\n");
         return;  
     }
+        
+	_alcContext = alcCreateContext(_alcDevice, NULL);
+    ALCenum alcErr = alcGetError(_alcDevice);
+	if (!_alcContext || alcErr != ALC_NO_ERROR)
+    {
+        alcCloseDevice (_alcDevice);
+        LOG_ERROR_VARG("AudioController::initialize() error. Unable to create OpenAL context. Error: %d\n", alcErr);
+        return;
+    }
+    
+    alcMakeContextCurrent(_alcContext);
+    alcErr = alcGetError(_alcDevice);
+    if (alcErr != ALC_NO_ERROR)
+    {
+        LOG_ERROR_VARG("AudioController::initialize() error. Unable to make OpenAL context current. Error: %d\n", alcErr);
+    }
 }
 
 void AudioController::finalize()
 {
-	alutExit();
+    alcMakeContextCurrent(NULL);
+    if (_alcContext)
+    {
+        alcDestroyContext(_alcContext);
+        _alcContext = NULL;
+    }
+    if (_alcDevice)
+    {
+        alcCloseDevice(_alcDevice);
+        _alcDevice = NULL;
+    }
 }
 
 void AudioController::pause()

+ 2 - 1
gameplay/src/AudioController.h

@@ -58,7 +58,8 @@ private:
      */
     void update(long elapsedTime);
 
-
+    ALCdevice* _alcDevice;
+    ALCcontext* _alcContext;
     static std::list<AudioSource*> _playingSources;     // List of currently running sources.
 };
 

+ 22 - 11
gameplay/src/Base.h

@@ -17,12 +17,12 @@
 #include <list>
 #include <stack>
 #include <map>
-#include <hash_map>
 #include <algorithm>
 #include <ctime>
 #include <cstdio>
 #include <limits>
 #include <functional>
+#include <assert.h>
 #include <string.h>
 #include <ctype.h>
 #include <stdint.h>
@@ -105,23 +105,28 @@ extern void printError(const char* format, ...);
 #define M_1_PI                      0.31830988618379067154
 #endif
 
-// Audio (OpenAL/alut)
+// Audio (OpenAL)
 #ifdef __QNX__
 #include <AL/al.h>
 #include <AL/alc.h>
-#include <AL/alut.h>
 #elif WIN32
 #include <al.h>
 #include <alc.h>
-#include <alut.h>
+#elif __APPLE__
+#include <OpenAL/al.h>
+#include <OpenAL/alc.h>
 #endif
 
-// Graphics (OpenGLES/OpenGL/png)
-#define WINDOW_VSYNC        1
-#define WINDOW_FULLSCREEN   0
+// Screen/Window
 #define WINDOW_WIDTH        1024
 #define WINDOW_HEIGHT       600
+#define WINDOW_VSYNC        1
+#define WINDOW_FULLSCREEN   0
 
+// Image
+#include <png.h>
+
+// Graphics (OpenGL)
 #ifdef __QNX__
     #include <EGL/egl.h>
     #include <GLES2/gl2.h>
@@ -131,14 +136,21 @@ extern void printError(const char* format, ...);
     extern PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays;
     extern PFNGLISVERTEXARRAYOESPROC glIsVertexArray;
     #define glClearDepth glClearDepthf
+   #define GL_ES
 #elif WIN32
     #define WIN32_LEAN_AND_MEAN
     #include <GL/glew.h>
     #include <GL/wglew.h>
+#elif __APPLE__
+#include <OpenGL/gl.h>
+#include <OpenGL/glext.h>
+#define glBindVertexArray glBindVertexArrayAPPLE
+#define glDeleteVertexArrays glDeleteVertexArraysAPPLE
+#define glGenVertexArrays glGenVertexArraysAPPLE
+#define glIsVertexArray glIsVertexArrayAPPLE
 #endif
-#include <png.h>
 
-// Attributes
+// Graphics (GLSL)
 #define VERTEX_ATTRIBUTE_POSITION_NAME              "a_position"
 #define VERTEX_ATTRIBUTE_NORMAL_NAME                "a_normal"
 #define VERTEX_ATTRIBUTE_COLOR_NAME                 "a_color"
@@ -211,8 +223,7 @@ extern GLenum __gl_error_code;
 #define GL_LAST_ERROR() __gl_error_code
 
 
-// Missing platform functionality and warnings.
-#ifdef WIN32
+#if defined(WIN32) || defined(__APPLE__)
 
     inline float fminf(float a, float b)
     {

+ 1 - 1
gameplay/src/Curve.cpp

@@ -233,7 +233,7 @@ void Curve::interpolateBezier(float s, Point* from, Point* to, float* dst) const
                 i++;
             }
             // Handle quaternion component.
-            float interpTime = from->time * eq1 + from->outValue[i] * eq2 + to->inValue[i] * eq3 + to->time * eq4;
+            //float interpTime = from->time * eq1 + from->outValue[i] * eq2 + to->inValue[i] * eq3 + to->time * eq4;
             interpolateQuaternion(s, (from->value + i), (to->value + i), (dst + i));
             i += 4;
             quaternionOffsetIndex++;

+ 17 - 3
gameplay/src/Effect.cpp

@@ -6,6 +6,8 @@
 #include "Effect.h"
 #include "FileSystem.h"
 
+#define GL_ES_DEFINE  "#define OPENGL_ES"
+
 namespace gameplay
 {
 
@@ -109,8 +111,15 @@ Effect* Effect::createFromSource(const char* vshPath, const char* vshSource, con
     GLint length;
     GLint success;
 
+    std::string definesStr = (defines == NULL) ? "" : defines;
+
     // Compile vertex shader.
-    shaderSource[0] = defines == NULL ? "" : defines;
+#ifdef GL_ES
+    if (defines)
+        definesStr += "\n";
+    definesStr+= GL_ES_DEFINE;
+#endif
+    shaderSource[0] = definesStr.c_str();
     shaderSource[1] = "\n";
     shaderSource[2] = vshSource;
     GL_ASSERT( vertexShader = glCreateShader(GL_VERTEX_SHADER) );
@@ -135,8 +144,13 @@ Effect* Effect::createFromSource(const char* vshPath, const char* vshSource, con
         return NULL;
     }
 
-    // Compile fragment shader.
-    shaderSource[0] = defines == NULL ? "" : defines;
+    // Compile the fragment shader.
+#ifdef GL_ES
+    if (defines)
+        definesStr += "\n";
+    definesStr+= GL_ES_DEFINE;
+#endif
+    shaderSource[0] = definesStr.c_str();
     shaderSource[1] = "\n";
     shaderSource[2] = fshSource;
     GL_ASSERT( fragmentShader = glCreateShader(GL_FRAGMENT_SHADER) );

+ 3 - 2
gameplay/src/FileSystem.cpp

@@ -34,14 +34,15 @@ FILE* FileSystem::openFile(const char* path, const char* mode)
     fullPath += path;
 
     FILE* fp = fopen(fullPath.c_str(), mode);
-
+    
+// Win32 doesnt support a asset or bundle definitions.
 #ifdef WIN32
-    // HACK: For testing purposes, search the gameplay-resources folder as well.
     if (fp == NULL)
     {
         fullPath = __resourcePath;
         fullPath += "../../gameplay/";
         fullPath += path;
+        
         fp = fopen(fullPath.c_str(), mode);
     }
 #endif

+ 1 - 2
gameplay/src/Font.cpp

@@ -25,7 +25,6 @@
 
 // Default font fragment shader
 #define FONT_FSH \
-    "precision mediump float;" \
     "varying vec2 vtexcoord;" \
     "varying vec4 vcolor;" \
     "uniform sampler2D texture;" \
@@ -178,7 +177,7 @@ void Font::drawText(const char* text, int x, int y, const Vector4& color)
     for (int i = 0; i < length; ++i)
     {
         char c = text[i];
-        unsigned int index = c - 32; // HACK for ASCII
+        int index = c - 32; // HACK for ASCII
         if (index >= 0 && index < _glyphCount)
         {
             Glyph& g = _glyphs[index];

+ 2 - 2
gameplay/src/Joint.cpp

@@ -31,13 +31,13 @@ void Joint::transformChanged()
 {
     Node::transformChanged();
 
-    const char* id = _id.c_str();
+    //const char* id = _id.c_str();
     _jointMatrixDirty = true;
 }
 
 void Joint::updateJointMatrix(const Matrix& bindShape, Vector4* matrixPalette)
 {
-    const char* id = _id.c_str();
+    //const char* id = _id.c_str();
 
     if (_jointMatrixDirty)
     {

+ 318 - 17
gameplay/src/PlatformMacOSX.mm

@@ -1,34 +1,335 @@
 /*
- * PlatformMacOSX.h
+ * PlatformMacOSX.cpp
  */
 
-#ifndef PLATFORMMACOSX_H_
-#define PLATFORMMACOSX_H_
+#ifdef __APPLE__
 
-#ifdef __OBJC__
+#include "Base.h"
+#include "Platform.h"
+#include "FileSystem.h"
+#include "Game.h"
+#include "Input.h"
 
-#import <UIKit/UIKit.h>
-#import <QuartzCore/QuartzCore.h>
+#import <Cocoa/Cocoa.h>
+#import <QuartzCore/CVDisplayLink.h>
+#import <OpenGL/OpenGL.h>
+#import <mach/mach_time.h>
 
+using namespace std;
+using namespace gameplay;
 
-@interface PlatformMacOSX : NSObject <UIApplicationDelegate>
+
+static const float ACCELEROMETER_X_FACTOR = 90.0f / WINDOW_WIDTH;
+static const float ACCELEROMETER_Y_FACTOR = 90.0f / WINDOW_HEIGHT;
+
+static long __timeStart;
+static long __timeAbsolute;
+static bool __vsync = WINDOW_VSYNC;
+static float __pitch;
+static float __roll;
+static int __lx, __ly;
+static bool __hasMouse = false;
+static bool __leftMouseDown = false;
+static bool __rightMouseDown = false;
+static bool __shiftDown = false;
+
+long getMachTimeInMilliseconds()
+{
+    static const int64_t kOneMillion = 1000 * 1000;
+    static mach_timebase_info_data_t s_timebase_info;
+    
+    if (s_timebase_info.denom == 0) 
+        (void) mach_timebase_info(&s_timebase_info);
+    
+    // mach_absolute_time() returns billionth of seconds, so divide by one million to get milliseconds
+    return (long)((mach_absolute_time() * s_timebase_info.numer) / (kOneMillion * s_timebase_info.denom));
+}
+
+@class View;
+
+@interface View : NSOpenGLView <NSWindowDelegate> 
+{
+    CVDisplayLinkRef displayLink;
+    
+    Game* _game;
+}
+@end
+
+
+@implementation View
+
+
+-(void)windowWillClose:(NSNotification*)note 
+{
+    _game->exit();
+    [[NSApplication sharedApplication] terminate:self];
+}
+
+- (CVReturn) getFrameForTime:(const CVTimeStamp*)outputTime
+{
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    
+    [self performSelectorOnMainThread:@selector(update) withObject:nil waitUntilDone:NO];
+    
+    [pool release];
+    return kCVReturnSuccess;
+}
+
+
+-(void) update
+{
+    [[self openGLContext] makeCurrentContext];
+    CGLLockContext((CGLContextObj)[[self openGLContext] CGLContextObj]);
+    _game->frame();
+    CGLFlushDrawable((CGLContextObj)[[self openGLContext] CGLContextObj]);
+    CGLUnlockContext((CGLContextObj)[[self openGLContext] CGLContextObj]);  
+}
+
+static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const CVTimeStamp* outputTime, 
+                                      CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext)
+{
+    CVReturn result = [(View*)displayLinkContext getFrameForTime:outputTime];
+    return result;
+}
+
+- (id) initWithFrame: (NSRect) frame
+{    
+    _game = Game::getInstance();
+    __timeStart = getMachTimeInMilliseconds();
+    NSOpenGLPixelFormatAttribute attrs[] = 
+    {
+        NSOpenGLPFAAccelerated,
+        NSOpenGLPFADoubleBuffer,
+        NSOpenGLPFAColorSize, 32,
+        NSOpenGLPFADepthSize, 24,
+        NSOpenGLPFAAlphaSize, 8,
+        NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersionLegacy,
+        0
+    };
+    
+    NSOpenGLPixelFormat* pf = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
+    if (!pf)
+        NSLog(@"OpenGL pixel format not supported.");
+    
+    self = [super initWithFrame:frame pixelFormat:[pf autorelease]];  
+    
+    return self;
+}
+
+- (void) prepareOpenGL
 {
-    Game _game;
+    [super prepareOpenGL];
+    
+    NSString* bundlePath = [[NSBundle mainBundle] bundlePath];
+    NSString* path = [bundlePath stringByAppendingString:@"/Contents/Resources/"];
+    FileSystem::setResourcePath([path cStringUsingEncoding:NSASCIIStringEncoding]);
+    _game->run(WINDOW_WIDTH, WINDOW_HEIGHT);
+    
+    [[self window] setLevel: NSFloatingWindowLevel];
+    [[self window] makeKeyAndOrderFront: self];
+    [[self window] setTitle: [NSString stringWithUTF8String: ""]];
     
-    NSTimer*  _timer;
-    NSDate* mDate;
-    FLOAT mStartTime;
+    // Make all the OpenGL calls to setup rendering and build the necessary rendering objects
+    [[self openGLContext] makeCurrentContext];
+    // Synchronize buffer swaps with vertical refresh rate
+    GLint swapInt = __vsync ? 1 : 0;
+    [[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
+    
+    // Create a display link capable of being used with all active displays
+    CVDisplayLinkCreateWithActiveCGDisplays(&displayLink);
+    
+    // Set the renderer output callback function
+    CVDisplayLinkSetOutputCallback(displayLink, &MyDisplayLinkCallback, self);
+    
+    CGLContextObj cglContext = (CGLContextObj)[[self openGLContext] CGLContextObj];
+    CGLPixelFormatObj cglPixelFormat = (CGLPixelFormatObj)[[self pixelFormat] CGLPixelFormatObj];
+    CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, cglContext, cglPixelFormat);
+    
+    // Activate the display link
+    CVDisplayLinkStart(displayLink);
 }
 
-- (void)run;
-- (void)frame:(id)sender;
+- (void) dealloc
+{       
+    _game->exit();
+    
+    // Release the display link
+    CVDisplayLinkRelease(displayLink);
+    
+    [super dealloc];
+}
 
-@property (retain) NSTimer* mTimer;
-@property (nonatomic) double mLastFrameTime;
-@property (nonatomic) double mStartTime;
+- (void) mouseDown: (NSEvent*) theEvent
+{
+    NSPoint point = [theEvent locationInWindow];
+    _game->touch(point.x, WINDOW_HEIGHT - point.y, Input::TOUCHEVENT_PRESS);
+    __leftMouseDown = true;
+}
+
+- (void) mouseUp: (NSEvent*) theEvent
+{
+    NSPoint point = [theEvent locationInWindow];
+    __leftMouseDown = false;
+    _game->touch(point.x, WINDOW_HEIGHT - point.y, Input::TOUCHEVENT_RELEASE);
+}
+
+- (void) mouseDragged: (NSEvent*) theEvent
+{
+    NSPoint point = [theEvent locationInWindow];
+    if (__leftMouseDown)
+    {
+        gameplay::Game::getInstance()->touch(point.x, WINDOW_HEIGHT - point.y, gameplay::Input::TOUCHEVENT_MOVE);
+    }
+}
+
+- (void) rightMouseDown: (NSEvent*) theEvent
+{
+    __rightMouseDown = true;
+     NSPoint point = [theEvent locationInWindow];
+    __lx = point.x;
+    __ly = WINDOW_HEIGHT - point.y;
+}
+
+- (void) rightMouseUp: (NSEvent*) theEvent
+{
+   __rightMouseDown = false;
+}
+
+- (void) rightMouseDragged: (NSEvent*) theEvent
+{
+    NSPoint point = [theEvent locationInWindow];
+    if (__rightMouseDown)
+    {
+        // Update the pitch and roll by adding the scaled deltas.
+        __roll += -(float)(point.x - __lx) * ACCELEROMETER_X_FACTOR;
+        __pitch -= (float)(point.y - (WINDOW_HEIGHT - __ly)) * ACCELEROMETER_Y_FACTOR;
+    
+        // Clamp the values to the valid range.
+        __roll = fmaxf(fminf(__roll, 90.0), -90.0);
+        __pitch = fmaxf(fminf(__pitch, 90.0), -90.0);
+    
+        // Update the last X/Y values.
+        __lx = point.x;
+        __ly = (WINDOW_HEIGHT - point.y);
+    }
+}
+
+- (void) mouseEntered:(NSEvent *)theEvent
+{
+    __hasMouse = true;
+}
+
+- (void) mouseExited:(NSEvent *)theEvent
+{
+    __leftMouseDown = false;
+    __rightMouseDown = false;
+    __hasMouse = false;
+}
 
 @end
 
-#endif
+
+namespace gameplay
+{
+
+extern void printError(const char* format, ...)
+{
+    va_list argptr;
+    va_start(argptr, format);
+    vfprintf(stderr, format, argptr);
+    fprintf(stderr, "\n");
+    va_end(argptr);
+}
+    
+    
+Platform::Platform(Game* game)
+: _game(game)
+{
+}
+
+Platform::Platform(const Platform& copy)
+{
+    // hidden
+}
+
+Platform::~Platform()
+{
+}
+
+Platform* Platform::create(Game* game)
+{
+    Platform* platform = new Platform(game);
+    
+    return platform;
+}
+
+int Platform::enterMessagePump()
+{
+    NSAutoreleasePool *pool = [NSAutoreleasePool new];
+    NSApplication* NSApp = [NSApplication sharedApplication];
+    NSRect screenBounds = [[NSScreen mainScreen] frame];
+    NSRect viewBounds = NSMakeRect(0, 0, 1024, 600);
+    
+    View* view = [[View alloc] initWithFrame:viewBounds];
+    
+    NSRect centered = NSMakeRect(NSMidX(screenBounds) - NSMidX(viewBounds),
+                                 NSMidY(screenBounds) - NSMidY(viewBounds),
+                                 viewBounds.size.width, 
+                                 viewBounds.size.height);
+    
+    NSWindow *window = [[NSWindow alloc]
+                        initWithContentRect:centered
+                        styleMask:NSTitledWindowMask | NSClosableWindowMask
+                        backing:NSBackingStoreBuffered
+                        defer:NO];
+    
+    [window setContentView:view];
+    [window setDelegate:view];
+    [view release];
+    
+    [NSApp run];
+    
+    [pool release];
+    return EXIT_SUCCESS;
+}
+    
+long Platform::getAbsoluteTime()
+{
+    __timeAbsolute = getMachTimeInMilliseconds();
+    return __timeAbsolute;
+}
+
+void Platform::setAbsoluteTime(long time)
+{
+    __timeAbsolute = time;
+}
+
+bool Platform::isVsync()
+{
+    return __vsync;
+}
+
+void Platform::setVsync(bool enable)
+{
+    __vsync = enable;
+}
+
+int Platform::getOrientationAngle()
+{
+    return 0;
+}
+
+bool Platform::isAccelerometerSupported()
+{
+    return true;
+}
+
+void Platform::getAccelerometerPitchAndRoll(float* pitch, float* roll)
+{
+    *pitch = __pitch;
+    *roll = __roll;
+}
+    
+}
 
 #endif

+ 2 - 3
gameplay/src/Properties.cpp

@@ -2,10 +2,9 @@
  * Properties.cpp
  */
 
+#include "Base.h"
 #include "Properties.h"
 #include "FileSystem.h"
-#include <xtree>
-#include <sstream>
 
 namespace gameplay
 {
@@ -363,7 +362,7 @@ Properties::Type Properties::getType(const char* name) const
 
     // Parse the value to determine the format
     unsigned int commaCount = 0;
-    unsigned int length = strlen(value);
+    //unsigned int length = strlen(value);
     char* valuePtr = const_cast<char*>(value);
     while (valuePtr = strchr(valuePtr, ','))
     {

+ 1 - 1
gameplay/src/RenderState.cpp

@@ -395,7 +395,7 @@ RenderState::Blend parseBlend(const char* value)
 {
     // Conver the string to uppercase for comparison
     std::string upper(value);
-    std::transform(upper.begin(), upper.end(), upper.begin(), std::toupper);
+    transform(upper.begin(), upper.end(), upper.begin(), toupper);
     if (upper == "ZERO")
         return RenderState::BLEND_ZERO;
     if (upper == "ONE")

+ 0 - 1
gameplay/src/SpriteBatch.cpp

@@ -34,7 +34,6 @@
 
 // Default sprite fragment shader
 #define SPRITE_FSH \
-    "precision mediump float;" \
     "varying vec2 vtexcoord;" \
     "varying vec4 vcolor;" \
     "uniform sampler2D texture;" \

+ 0 - 2
gameplay/src/Texture.h

@@ -27,8 +27,6 @@ public:
         ALPHA = GL_ALPHA,
         RGB888 = GL_RGB,
         RGBA8888 = GL_RGBA,
-        LUMINANCE = GL_LUMINANCE,
-        LUMINANCE_ALPHA = GL_LUMINANCE_ALPHA,
         DEPTH = GL_DEPTH_COMPONENT
     };
 

+ 13 - 167
gameplay/src/gameplay-main-macosx.mm

@@ -1,177 +1,23 @@
-#ifndef GAMEPLAYMAINMACOSX__H
-#define GAMEPLAYMAINMACOSX__H
+#ifndef GAMEPLAYMAINMACOSX_H_
+#define GAMEPLAYMAINMACOSX_H_
 
-#include "gameplay.h"
-
-#ifdef __OBJC__
-
-#import <Cocoa/Cocoa.h>
-#import <OpenGL/gl.h>
-#import <mach/mach_time.h>
-
-@class View;
-
-@interface View : NSOpenGLView <NSWindowDelegate> 
-{
-    NSRect _frameRect;
-    bool _initialized;
-    uint64_t _timeLast;
-    NSTimer* _timer;
-}
-
-- (void) animate;
-
-@end
-
-
-@implementation View
-
--(void)windowWillClose:(NSNotification *)note 
-{
-    [[NSApplication sharedApplication] terminate:self];
-}
-
-- (void) timerFired:(NSTimer*) timer
-{
-    // _game->update();
-    
-    [self display];    
-}
+#ifdef __APPLE__
 
-- (id) initWithFrame: (NSRect) frame
-{
-    _initialized = FALSE;
-    
-    int attribs[] = 
-    {
-        NSOpenGLPFAAccelerated,
-        NSOpenGLPFADoubleBuffer,
-        NSOpenGLPFADepthSize, 24,
-        NSOpenGLPFAAlphaSize, 8,
-        NSOpenGLPFAColorSize, 32,
-        NSOpenGLPFANoRecovery,
-        0
-    };
-    
-    NSOpenGLPixelFormat *fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:(NSOpenGLPixelFormatAttribute*) attribs];
-    
-    self = [self initWithFrame:frame pixelFormat:fmt];
-    
-    [fmt release];
-    
-    _frameRect = frame;
-    _timeLast = mach_absolute_time();
-    _timeLast = [[NSTimer
-                scheduledTimerWithTimeInterval:1.0f/60.0f
-                target:self 
-                selector:@selector(timerFired:)
-                userInfo:nil
-                repeats:YES] retain];
-    
-    return self;
-}
-
-- (void) drawRect:(NSRect) theRect
-{
-    if (!_initialized) 
-    {
-        
-        int transparentWindow = 0;
-        if (transparentWindow) 
-        {
-            int opaque = NO;
-            [[self openGLContext]
-             setValues:&opaque
-             forParameter:NSOpenGLCPSurfaceOpacity];
-            [[self window] setOpaque:NO];
-            [[self window] setAlphaValue:0.99];
-        }
-        
-        //glewInit();
-        // _game->initialize();
-        //const char* szTitle = PezInitialize(PEZ_VIEWPORT_WIDTH, PEZ_VIEWPORT_HEIGHT);
-        _initialized = true;
-        
-        [[self window] setLevel: NSFloatingWindowLevel];
-        [[self window] makeKeyAndOrderFront: self];
-        [[self window] setTitle: [NSString stringWithUTF8String: ""]];
-    }
-    
-    //_game->render();
-    glClear(GL_COLOR_BUFFER_BIT);
-    
-    [[self openGLContext] flushBuffer]; 
-}
-
-- (void) mouseUp: (NSEvent*) theEvent
-{
-    NSPoint curPoint = [theEvent locationInWindow];
-    // _game->touchEvent
-}
-
-- (void) mouseDown: (NSEvent*) theEvent
-{
-    NSPoint curPoint = [theEvent locationInWindow];
-    // _game->touchEvent
-}
+#include "gameplay.h"
+using namespace gameplay;
 
-- (void) onKey: (unichar) character downEvent: (BOOL) flag
-{
-    switch(character) 
-    {
-        case 27:
-        case 'q':
-            [[NSApplication sharedApplication] terminate:self];
-            break;
-    }
-}
 
-- (void) keyDown:(NSEvent *)theEvent
+/**
+ * Main entry point.
+ */
+int main(int argc, char** argv)
 {
-    NSString* characters;
-    unsigned int characterIndex, characterCount;
-    
-    characters = [theEvent charactersIgnoringModifiers];
-    characterCount = [characters length];
-    
-    for (characterIndex = 0; characterIndex < characterCount; characterIndex++)
-    {
-        [self onKey:[characters characterAtIndex:characterIndex] downEvent:YES];
-    }
+    Game* game = Game::getInstance();
+    assert(game != NULL);
+    Platform* platform = Platform::create(game);
+    return platform->enterMessagePump();
 }
 
-@end
-
-int main(int argc, const char* *argv)
-{
-    NSAutoreleasePool *pool = [NSAutoreleasePool new];
-    NSApplication *NSApp = [NSApplication sharedApplication];
-    NSRect frame = NSMakeRect( 0, 0, 1024, 600 );
-    
-    NSRect screenBounds = [[NSScreen mainScreen] frame];
-    NSRect viewBounds = NSMakeRect(0, 0, 1024, 600);
-    
-    View* view = [[View alloc] initWithFrame:viewBounds];
-    
-    NSRect centered = NSMakeRect(NSMidX(screenBounds) - NSMidX(viewBounds),
-                                 NSMidY(screenBounds) - NSMidY(viewBounds),
-                                 viewBounds.size.width, viewBounds.size.height);
-    
-    NSWindow *window = [[NSWindow alloc]
-                        initWithContentRect:centered
-                        styleMask:NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask
-                        backing:NSBackingStoreBuffered
-                        defer:NO];
-    
-    [window setContentView:view];
-    [window setDelegate:view];
-    [view release];
-    
-    [NSApp run];
-    
-    [pool release];
-    return EXIT_SUCCESS;
-}
 
 #endif
 

+ 23 - 0
gameplay/src/gameplay-main-qnx.cpp

@@ -0,0 +1,23 @@
+#ifndef GAMEPLAYMAINQNX_H_
+#define GAMEPLAYMAINQNX_H_
+
+#ifdef __QNX__
+
+#include "gameplay.h"
+
+using namespace gameplay;
+
+/**
+ * Main entry point.
+ */
+int main(int argc, char** argv)
+{
+    Game* game = Game::getInstance();
+    assert(game != NULL);
+    Platform* platform = Platform::create(game);
+    return platform->enterMessagePump();
+}
+
+#endif
+
+#endif

+ 31 - 0
gameplay/src/gameplay-main-win32.cpp

@@ -0,0 +1,31 @@
+#ifndef GAMEPLAYMAINWIN32_H_
+#define GAMEPLAYMAINWIN32_H_
+
+#ifdef WIN32
+
+#include "gameplay.h"
+using namespace gameplay;
+
+#define GL_VERSION3
+#include <GL/glew.h>
+#include <GL/wglew.h>
+#ifndef _WINDOWS_
+    #define WIN32_LEAN_AND_MEAN
+    #include <windows.h>
+#endif
+
+/**
+ * Main entry point.
+ */
+extern "C" int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR cmdLine, int cmdShow)
+{
+    Game* game = Game::getInstance();
+    assert(game != NULL);
+    Platform* platform = Platform::create(game);
+    return platform->enterMessagePump();
+}
+
+
+#endif
+
+#endif