#include "GlobalDefines.h"\r
#include "GlobalTypes.h"\r
#include "Assert.h"\r
+#include "Print.h"\r
#pragma once\r
\r
+#include "GlobalDefines.h"\r
#include <stdio.h>\r
\r
-#define Printf(message, ...) printf(message, ##__VA_ARGS__)\r
+#if defined(DEBUG)\r
+ #define Printf(message, ...) printf(message, ##__VA_ARGS__)\r
+#else\r
+ #define Printf(message, ...) {}\r
+#endif\r
#pragma once
+/*****************************************************************************************
+ * This is a wrapper class around all OpenGL API calls in iOS. This completely abstracts
+ * away all mixes between the OS-specific calls in Objective-C and the C-style inteface of
+ * OpenGL.
+ *****************************************************************************************/
+
#include "Foundation/Common/GlobalInclude.h"
#include <OpenGLES/ES1/gl.h>
#include <OpenGLES/ES2/gl.h>
#include <OpenGLES/ES2/glext.h>
-//typedef TextureHandle GLuint;
-/*
+//----------------------------------------------------------------------------------------
+// Some forward declarations
+@class EAGLContext;
+struct RenderTarget;
+
+//----------------------------------------------------------------------------------------
+// Some typedefs for handles. May want to move this to a separate file.
+typedef GLuint TextureHandle;
+
+//----------------------------------------------------------------------------------------
+// Complete C(++) OpenGL wrapper. We will use this to wrap
class OpenGLServices
{
public:
bool init();
+
+ bool setRenderTarget( RenderTarget& renderTarget );
private:
EAGLContext* mGLContext;
};
-*/
+++ /dev/null
-#include "OpenGLServices.h"
-
--- /dev/null
+#include "OpenGLServices.h"
+#include "RenderTarget.h"
+
+#import <QuartzCore/QuartzCore.h>
+
+//----------------------------------------------------------------------------------------
+bool OpenGLServices::setRenderTarget( RenderTarget& renderTarget )
+{
+#if defined(DEBUG)
+ if (!renderTarget.getFramebuffer() || !glIsFramebuffer( renderTarget.getFramebuffer() ))
+ {
+ return false;
+ }
+#endif
+
+ glBindFramebuffer( GL_FRAMEBUFFER, renderTarget.getFramebuffer() );
+ return true;
+}
--- /dev/null
+#pragma once
+
+#include "Foundation/Common/GlobalInclude.h"
+
+#include <OpenGLES/ES1/gl.h>
+#include <OpenGLES/ES1/glext.h>
+#include <OpenGLES/ES2/gl.h>
+#include <OpenGLES/ES2/glext.h>
+
+@class EAGLContext;
+@class CAEAGLLayer;
+
+//----------------------------------------------------------------------------------------
+struct RenderTargetInitParams
+{
+ RenderTargetInitParams();
+
+ EAGLContext* mContext;
+ CAEAGLLayer* mCALayer;
+
+ // Width and height of color vs. depth buffers have to be the same. We don't resize in iOS.
+ int32_t mBufferWidth;
+ int32_t mBufferHeight;
+
+ GLenum mColorFormat;
+ GLenum mDepthStencilFormat;
+
+ uint32_t mFlags;
+};
+
+//----------------------------------------------------------------------------------------
+class RenderTarget
+{
+public:
+ enum RenderTargetFlags
+ {
+ kSystemFramebuffer = 0x1 << 0,
+ };
+
+ const static uint32_t MAX_RENDER_BUFFERS = 2;
+
+ RenderTarget();
+ ~RenderTarget();
+
+ bool init( RenderTargetInitParams& params );
+ void destroy();
+
+ uint32_t getWidth() { return mRenderBufferWidth; }
+ uint32_t getHeight() { return mRenderBufferHeight; }
+ GLuint getFramebuffer() { return mFramebuffer; }
+
+protected:
+ EAGLContext* mContext;
+ GLuint mFramebuffer;
+
+ GLuint mColorBuffer;
+ GLuint mDepthStencilBuffer;
+
+ int32_t mRenderBufferWidth;
+ int32_t mRenderBufferHeight;
+
+ uint32_t mFlags;
+};
--- /dev/null
+#include "RenderTarget.h"
+
+#import <QuartzCore/QuartzCore.h>
+
+//----------------------------------------------------------------------------------------
+RenderTargetInitParams::RenderTargetInitParams() : mContext(NULL),
+ mCALayer(NULL),
+ mBufferWidth(0),
+ mBufferHeight(0),
+ mColorFormat(GL_NONE),
+ mDepthStencilFormat(GL_NONE),
+ mFlags(0)
+{
+}
+
+//----------------------------------------------------------------------------------------
+RenderTarget::RenderTarget() : mContext(NULL),
+ mFramebuffer(0),
+ mColorBuffer(0),
+ mDepthStencilBuffer(0),
+ mRenderBufferWidth(0),
+ mRenderBufferHeight(0),
+ mFlags(0)
+{
+};
+
+//----------------------------------------------------------------------------------------
+RenderTarget::~RenderTarget()
+{
+ if ( mFramebuffer )
+ {
+ AssertMessage( !mFramebuffer, "RenderTarget has not been destroyed yet!" );
+ destroy();
+ }
+ else
+ {
+ mContext = NULL;
+ mFramebuffer = 0;
+ mColorBuffer = 0;
+ mDepthStencilBuffer = 0;
+ mRenderBufferWidth = 0;
+ mRenderBufferHeight = 0;
+ mFlags = 0;
+ }
+};
+
+//----------------------------------------------------------------------------------------
+bool RenderTarget::init( RenderTargetInitParams& params )
+{
+ if (mFramebuffer)
+ {
+ AssertMessage( 0, "RenderTarget already initialized.\n" );
+ return false;
+ }
+
+ mContext = params.mContext;
+ AssertMessage( mContext, "Invalid context provided.\n" );
+
+ // Set the context first.
+ [EAGLContext setCurrentContext:mContext];
+
+ mRenderBufferWidth = params.mBufferWidth;
+ mRenderBufferHeight = params.mBufferHeight;
+
+ if (params.mFlags & kSystemFramebuffer)
+ {
+ [mContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:params.mCALayer];
+ glGetRenderbufferParameteriv( GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &mRenderBufferWidth );
+ glGetRenderbufferParameteriv( GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &mRenderBufferHeight );
+ }
+ else
+ {
+ if (params.mColorFormat != GL_NONE)
+ {
+ glGenRenderbuffers( 1, &mColorBuffer );
+ Assert( mColorBuffer );
+ glBindRenderbuffer( GL_RENDERBUFFER, mColorBuffer );
+ glRenderbufferStorage( GL_RENDERBUFFER, params.mColorFormat, mRenderBufferWidth, mRenderBufferHeight );
+ }
+ }
+
+ if (params.mDepthStencilFormat != GL_NONE)
+ {
+ // If a depth/stencil buffer is needed, we'll create one with the same dimensions as the color buffer.
+ glGenRenderbuffers( 1, &mDepthStencilBuffer );
+ Assert( mDepthStencilBuffer );
+ glBindRenderbuffer( GL_RENDERBUFFER, mDepthStencilBuffer );
+ glRenderbufferStorage( GL_RENDERBUFFER, params.mDepthStencilFormat, mRenderBufferWidth, mRenderBufferHeight );
+ }
+
+ if (mColorBuffer || mDepthStencilBuffer)
+ {
+ // Create framebuffer object.
+ glGenFramebuffers( 1, &mFramebuffer );
+ glBindFramebuffer( GL_FRAMEBUFFER, mFramebuffer );
+
+ if (mColorBuffer)
+ {
+ glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mColorBuffer );
+ }
+
+ if (mDepthStencilBuffer)
+ {
+ glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthStencilBuffer );
+ }
+
+ AssertMessage( glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "Failed to make complete framebuffer object: %x", glCheckFramebufferStatus(GL_FRAMEBUFFER) );
+ }
+ else
+ {
+ return false;
+ }
+
+
+ return true;
+}
+
+//----------------------------------------------------------------------------------------
+void RenderTarget::destroy()
+{
+ if (!mContext)
+ {
+ return;
+ }
+
+ [EAGLContext setCurrentContext:mContext];
+
+ if (mColorBuffer && glIsRenderbuffer(mColorBuffer))
+ {
+ glDeleteRenderbuffers( 1, &mColorBuffer );
+ }
+
+ if (mDepthStencilBuffer && glIsRenderbuffer(mDepthStencilBuffer))
+ {
+ glDeleteRenderbuffers( 1, &mDepthStencilBuffer );
+ }
+
+ if (mFramebuffer)
+ {
+ glDeleteFramebuffers( 1, &mFramebuffer );
+ }
+
+ mContext = NULL;
+ mFramebuffer = 0;
+ mColorBuffer = 0;
+ mDepthStencilBuffer = 0;
+ mRenderBufferWidth = 0;
+ mRenderBufferHeight = 0;
+ mFlags = 0;
+}
\r
#include "Foundation/Common/GlobalInclude.h"\r
\r
-//==========================\r
+//----------------------------------------------------------------------------------------\r
// djb2 string hash function\r
-//--------------------------\r
-static slInline uint32 StrHash(const char *str)\r
+static slInline uint32_t StrHash(const char* str)\r
{\r
- uint32 hash = 5381;\r
- int32 c = *str;\r
+ uint32_t hash = 5381; // seed value\r
+ int32_t c = *str;\r
\r
if(!str)\r
{\r
return 0;\r
}\r
\r
- while ( (*str != 0) ){\r
- hash = ((hash << 5) + hash) + c; /* hash * 33 + c */\r
- c = (*str++);\r
+ while ( (*str != 0) )\r
+ {\r
+ hash = ((hash << 5) + hash) + c; /* hash * 33 + c == ((hash * 32) + hash) + c */\r
+ c = *(str++);\r
}\r
\r
- return hash; \r
+ return hash; \r
}
\ No newline at end of file
4B68588812BC288E005667D3 /* LittlestViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B68588512BC288E005667D3 /* LittlestViewController.m */; };
4B90648412B41E6500655D84 /* Standard.vsh in Resources */ = {isa = PBXBuildFile; fileRef = 4B90648312B41E6500655D84 /* Standard.vsh */; };
4B90648612B426FE00655D84 /* Standard.fsh in Resources */ = {isa = PBXBuildFile; fileRef = 4B90648512B426FE00655D84 /* Standard.fsh */; };
- 4BA0CD3712BD341500EBB6F0 /* OpenGLServices.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BA0CD3612BD341500EBB6F0 /* OpenGLServices.m */; };
+ 4BA0CDCE12BD655200EBB6F0 /* OpenGLServices.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BA0CDCD12BD655200EBB6F0 /* OpenGLServices.mm */; };
+ 4BA0CDF112BD6FE100EBB6F0 /* RenderTarget.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BA0CDF012BD6FE100EBB6F0 /* RenderTarget.mm */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
4B68588512BC288E005667D3 /* LittlestViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LittlestViewController.m; sourceTree = "<group>"; };
4B90648312B41E6500655D84 /* Standard.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = Standard.vsh; path = Shaders/Standard/Standard.vsh; sourceTree = "<group>"; };
4B90648512B426FE00655D84 /* Standard.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = Standard.fsh; path = Shaders/Standard/Standard.fsh; sourceTree = "<group>"; };
- 4BA0CD3612BD341500EBB6F0 /* OpenGLServices.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OpenGLServices.m; sourceTree = "<group>"; };
+ 4BA0CDCD12BD655200EBB6F0 /* OpenGLServices.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OpenGLServices.mm; sourceTree = "<group>"; };
+ 4BA0CDEF12BD6EB200EBB6F0 /* RenderTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderTarget.h; sourceTree = "<group>"; };
+ 4BA0CDF012BD6FE100EBB6F0 /* RenderTarget.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RenderTarget.mm; sourceTree = "<group>"; };
8D1107310486CEB800E47090 /* Littlest-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Littlest-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = "<group>"; };
/* End PBXFileReference section */
4B68587312BC27FD005667D3 /* GraphicsServices */ = {
isa = PBXGroup;
children = (
- 4BA0CD3612BD341500EBB6F0 /* OpenGLServices.m */,
4B68587412BC27FD005667D3 /* OpenGLServices.h */,
+ 4BA0CDCD12BD655200EBB6F0 /* OpenGLServices.mm */,
+ 4BA0CDEF12BD6EB200EBB6F0 /* RenderTarget.h */,
+ 4BA0CDF012BD6FE100EBB6F0 /* RenderTarget.mm */,
);
path = GraphicsServices;
sourceTree = "<group>";
4B68588612BC288E005667D3 /* EAGLView.m in Sources */,
4B68588712BC288E005667D3 /* LittlestAppDelegate.m in Sources */,
4B68588812BC288E005667D3 /* LittlestViewController.m in Sources */,
- 4BA0CD3712BD341500EBB6F0 /* OpenGLServices.m in Sources */,
+ 4BA0CDCE12BD655200EBB6F0 /* OpenGLServices.mm in Sources */,
+ 4BA0CDF112BD6FE100EBB6F0 /* RenderTarget.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
void main()
{
- gl_FragColor = colorVarying;
+ gl_FragColor = colorVarying;
}
void main()
{
- vec3 pos_2D = modelview_transform * position;
- gl_Position = vec4(pos_2D.x, pos_2D.y, 1.0f, pos_2D.z); // don't do computataions where we don't need to!
+ vec3 pos_2D = modelview_transform * position;
+ gl_Position = vec4(pos_2D.x, pos_2D.y, 1.0f, pos_2D.z); // don't do computataions where we don't need to!
- color_vary = color;
- uv01_vary = vec4(uv0, uv1);
+ color_vary = color;
+ uv01_vary = vec4(uv0, uv1);
}