From e8f833e6a39a2394257f9fbb8b755ae74bc74a48 Mon Sep 17 00:00:00 2001 From: chsieh Date: Sat, 18 Dec 2010 23:09:32 -0800 Subject: [PATCH] Migrating OGL resources to their own classes, and not intertwined with UIView. --- Classes/Foundation/Common/GlobalInclude.h | 1 + Classes/Foundation/Common/Print.h | 7 +- .../Foundation/GraphicsServices/OpenGLServices.h | 22 +++- .../Foundation/GraphicsServices/OpenGLServices.m | 2 - .../Foundation/GraphicsServices/OpenGLServices.mm | 18 +++ Classes/Foundation/GraphicsServices/RenderTarget.h | 63 ++++++++ .../Foundation/GraphicsServices/RenderTarget.mm | 150 ++++++++++++++++++++ Classes/Foundation/Hash/DJB2.h | 18 ++-- Littlest.xcodeproj/project.pbxproj | 14 ++- Shaders/Standard/Standard.fsh | 2 +- Shaders/Standard/Standard.vsh | 8 +- 11 files changed, 281 insertions(+), 24 deletions(-) delete mode 100644 Classes/Foundation/GraphicsServices/OpenGLServices.m create mode 100644 Classes/Foundation/GraphicsServices/OpenGLServices.mm create mode 100644 Classes/Foundation/GraphicsServices/RenderTarget.h create mode 100644 Classes/Foundation/GraphicsServices/RenderTarget.mm diff --git a/Classes/Foundation/Common/GlobalInclude.h b/Classes/Foundation/Common/GlobalInclude.h index bf31d87..83fe092 100755 --- a/Classes/Foundation/Common/GlobalInclude.h +++ b/Classes/Foundation/Common/GlobalInclude.h @@ -4,3 +4,4 @@ #include "GlobalDefines.h" #include "GlobalTypes.h" #include "Assert.h" +#include "Print.h" diff --git a/Classes/Foundation/Common/Print.h b/Classes/Foundation/Common/Print.h index c86bdb9..48c0609 100755 --- a/Classes/Foundation/Common/Print.h +++ b/Classes/Foundation/Common/Print.h @@ -1,5 +1,10 @@ #pragma once +#include "GlobalDefines.h" #include -#define Printf(message, ...) printf(message, ##__VA_ARGS__) +#if defined(DEBUG) + #define Printf(message, ...) printf(message, ##__VA_ARGS__) +#else + #define Printf(message, ...) {} +#endif diff --git a/Classes/Foundation/GraphicsServices/OpenGLServices.h b/Classes/Foundation/GraphicsServices/OpenGLServices.h index f59fbac..28c736d 100644 --- a/Classes/Foundation/GraphicsServices/OpenGLServices.h +++ b/Classes/Foundation/GraphicsServices/OpenGLServices.h @@ -1,5 +1,11 @@ #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 @@ -7,14 +13,24 @@ #include #include -//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; }; -*/ diff --git a/Classes/Foundation/GraphicsServices/OpenGLServices.m b/Classes/Foundation/GraphicsServices/OpenGLServices.m deleted file mode 100644 index 9afa6ac..0000000 --- a/Classes/Foundation/GraphicsServices/OpenGLServices.m +++ /dev/null @@ -1,2 +0,0 @@ -#include "OpenGLServices.h" - diff --git a/Classes/Foundation/GraphicsServices/OpenGLServices.mm b/Classes/Foundation/GraphicsServices/OpenGLServices.mm new file mode 100644 index 0000000..d89147e --- /dev/null +++ b/Classes/Foundation/GraphicsServices/OpenGLServices.mm @@ -0,0 +1,18 @@ +#include "OpenGLServices.h" +#include "RenderTarget.h" + +#import + +//---------------------------------------------------------------------------------------- +bool OpenGLServices::setRenderTarget( RenderTarget& renderTarget ) +{ +#if defined(DEBUG) + if (!renderTarget.getFramebuffer() || !glIsFramebuffer( renderTarget.getFramebuffer() )) + { + return false; + } +#endif + + glBindFramebuffer( GL_FRAMEBUFFER, renderTarget.getFramebuffer() ); + return true; +} diff --git a/Classes/Foundation/GraphicsServices/RenderTarget.h b/Classes/Foundation/GraphicsServices/RenderTarget.h new file mode 100644 index 0000000..d9cb866 --- /dev/null +++ b/Classes/Foundation/GraphicsServices/RenderTarget.h @@ -0,0 +1,63 @@ +#pragma once + +#include "Foundation/Common/GlobalInclude.h" + +#include +#include +#include +#include + +@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; +}; diff --git a/Classes/Foundation/GraphicsServices/RenderTarget.mm b/Classes/Foundation/GraphicsServices/RenderTarget.mm new file mode 100644 index 0000000..659f7d6 --- /dev/null +++ b/Classes/Foundation/GraphicsServices/RenderTarget.mm @@ -0,0 +1,150 @@ +#include "RenderTarget.h" + +#import + +//---------------------------------------------------------------------------------------- +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; +} diff --git a/Classes/Foundation/Hash/DJB2.h b/Classes/Foundation/Hash/DJB2.h index 30fa608..31b863f 100755 --- a/Classes/Foundation/Hash/DJB2.h +++ b/Classes/Foundation/Hash/DJB2.h @@ -2,13 +2,12 @@ #include "Foundation/Common/GlobalInclude.h" -//========================== +//---------------------------------------------------------------------------------------- // djb2 string hash function -//-------------------------- -static slInline uint32 StrHash(const char *str) +static slInline uint32_t StrHash(const char* str) { - uint32 hash = 5381; - int32 c = *str; + uint32_t hash = 5381; // seed value + int32_t c = *str; if(!str) { @@ -16,10 +15,11 @@ static slInline uint32 StrHash(const char *str) return 0; } - while ( (*str != 0) ){ - hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ - c = (*str++); + while ( (*str != 0) ) + { + hash = ((hash << 5) + hash) + c; /* hash * 33 + c == ((hash * 32) + hash) + c */ + c = *(str++); } - return hash; + return hash; } \ No newline at end of file diff --git a/Littlest.xcodeproj/project.pbxproj b/Littlest.xcodeproj/project.pbxproj index e58de7d..aa0e0a8 100755 --- a/Littlest.xcodeproj/project.pbxproj +++ b/Littlest.xcodeproj/project.pbxproj @@ -24,7 +24,8 @@ 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 */ @@ -73,7 +74,9 @@ 4B68588512BC288E005667D3 /* LittlestViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LittlestViewController.m; sourceTree = ""; }; 4B90648312B41E6500655D84 /* Standard.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = Standard.vsh; path = Shaders/Standard/Standard.vsh; sourceTree = ""; }; 4B90648512B426FE00655D84 /* Standard.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = Standard.fsh; path = Shaders/Standard/Standard.fsh; sourceTree = ""; }; - 4BA0CD3612BD341500EBB6F0 /* OpenGLServices.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OpenGLServices.m; sourceTree = ""; }; + 4BA0CDCD12BD655200EBB6F0 /* OpenGLServices.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OpenGLServices.mm; sourceTree = ""; }; + 4BA0CDEF12BD6EB200EBB6F0 /* RenderTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderTarget.h; sourceTree = ""; }; + 4BA0CDF012BD6FE100EBB6F0 /* RenderTarget.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RenderTarget.mm; sourceTree = ""; }; 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 = ""; }; /* End PBXFileReference section */ @@ -247,8 +250,10 @@ 4B68587312BC27FD005667D3 /* GraphicsServices */ = { isa = PBXGroup; children = ( - 4BA0CD3612BD341500EBB6F0 /* OpenGLServices.m */, 4B68587412BC27FD005667D3 /* OpenGLServices.h */, + 4BA0CDCD12BD655200EBB6F0 /* OpenGLServices.mm */, + 4BA0CDEF12BD6EB200EBB6F0 /* RenderTarget.h */, + 4BA0CDF012BD6FE100EBB6F0 /* RenderTarget.mm */, ); path = GraphicsServices; sourceTree = ""; @@ -357,7 +362,8 @@ 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; }; diff --git a/Shaders/Standard/Standard.fsh b/Shaders/Standard/Standard.fsh index c334ca1..0fc2083 100644 --- a/Shaders/Standard/Standard.fsh +++ b/Shaders/Standard/Standard.fsh @@ -3,5 +3,5 @@ varying lowp vec4 color_vary; void main() { - gl_FragColor = colorVarying; + gl_FragColor = colorVarying; } diff --git a/Shaders/Standard/Standard.vsh b/Shaders/Standard/Standard.vsh index cd54ddb..e1fc78a 100644 --- a/Shaders/Standard/Standard.vsh +++ b/Shaders/Standard/Standard.vsh @@ -10,9 +10,9 @@ uniform mat3 modelview_transform; 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); } -- 1.7.0.4