瀏覽代碼

Added ability to bind a global framebuffer at the start of every render, added ability for Cameras to use global framebuffer as color input, allowing post processing filters to be applied to everything that has been rendered on screen so far

Ivan Safrin 11 年之前
父節點
當前提交
11b46b0dfa

+ 4 - 1
Core/Contents/Include/PolyCamera.h

@@ -309,11 +309,14 @@ namespace Polycode {
              */
 			int getProjectionMode() const { return projectionMode; }
 
+            void setUseGlobalFramebuffer(bool val);
+            bool getUseGlobalFramebuffer() const;
 
 		protected:
 
+            bool useGlobalFramebuffer;
 			int projectionMode;
-
+        
 			Matrix4 projectionMatrix;
 
 			Polycode::Rectangle viewport;

+ 12 - 2
Core/Contents/Include/PolyRenderer.h

@@ -93,8 +93,8 @@ namespace Polycode {
 
 		virtual void Resize(int xRes, int yRes) = 0;
 		
-		virtual void BeginRender() = 0;
-		virtual void EndRender() = 0;
+        virtual void BeginRender();
+        virtual void EndRender();
 		
 		virtual Cubemap *createCubemap(Texture *t0, Texture *t1, Texture *t2, Texture *t3, Texture *t4, Texture *t5) = 0;		
 		virtual Texture *createTexture(unsigned int width, unsigned int height, char *textureData, bool clamp, bool createMipmaps, int type=Image::IMAGE_RGBA) = 0;
@@ -301,6 +301,12 @@ namespace Polycode {
         void loadVertexColorIdentity();
         void multiplyVertexColor(const Color &color);
         
+        void setRenderToGlobalFramebuffer(bool val);
+        bool getRenderToGlobalFramebuffer() const;
+        
+        Texture *getGlobalColorFramebuffer() const;
+        Texture *getGlobalDepthFramebuffer() const;
+        
 	protected:
 		virtual void initOSSpecific() {};
         
@@ -337,6 +343,10 @@ namespace Polycode {
         
 		PolycodeShaderModule* currentShaderModule;
 		std::vector <PolycodeShaderModule*> shaderModules;
+        
+        bool renderToGlobalFramebuffer;
+        Texture *globalColorFramebuffer;
+        Texture *globalDepthFramebuffer;
 
 		std::vector<LightInfo> lights;
 		std::vector<LightInfo> pointLights;

+ 47 - 12
Core/Contents/Source/PolyCamera.cpp

@@ -49,6 +49,7 @@ Camera::Camera(Scene *parentScene) : Entity() {
 	topLeftOrtho = false;
     orthoSizeX = 1.0;
 	orthoSizeY = 1.0;
+    useGlobalFramebuffer = false;
 }
 
 Camera::~Camera() {	
@@ -60,6 +61,14 @@ Camera::~Camera() {
 	delete zBufferSceneTexture;
 }
 
+void Camera::setUseGlobalFramebuffer(bool val) {
+    useGlobalFramebuffer = val;
+}
+
+bool Camera::getUseGlobalFramebuffer() const {
+    return useGlobalFramebuffer;
+}
+
 void Camera::setClippingPlanes(Number nearClipPlane, Number farClipPlane) {
 	this->nearClipPlane = nearClipPlane;
 	this->farClipPlane = farClipPlane;	
@@ -361,38 +370,57 @@ void Camera::drawFilter(Texture *targetTexture, Number targetTextureWidth, Numbe
 	if(!filterShaderMaterial)
 		return;
 		
-	Texture *finalTargetColorTexture;
-	Texture *finalTargetZTexture;	
+	Texture *finalTargetColorTexture = NULL;
+	Texture *finalTargetZTexture = NULL;
 		
 	if(targetTexture) {	
 		finalTargetColorTexture = targetColorTexture;
 		finalTargetZTexture = targetZTexture;		
 		renderer->setViewportSize(targetTextureWidth, targetTextureHeight);		
 	} else {
-		finalTargetColorTexture = originalSceneTexture;
-		finalTargetZTexture = zBufferSceneTexture;	
-		renderer->setViewportSize(renderer->getXRes(), renderer->getYRes());
+        if(!useGlobalFramebuffer) {
+            finalTargetColorTexture = originalSceneTexture;
+            finalTargetZTexture = zBufferSceneTexture;
+        }
+        renderer->setViewportSize(renderer->getXRes(), renderer->getYRes());
 	}
-	renderer->bindFrameBufferTexture(finalTargetColorTexture);
-	renderer->bindFrameBufferTextureDepth(finalTargetZTexture);
+    
+    if(finalTargetColorTexture) {
+        renderer->bindFrameBufferTexture(finalTargetColorTexture);
+    }
+    if(finalTargetZTexture) {
+        renderer->bindFrameBufferTextureDepth(finalTargetZTexture);
+    }
 	parentScene->Render(this);
-	renderer->unbindFramebuffers();
+    
+    if(finalTargetColorTexture && finalTargetZTexture) {
+        renderer->unbindFramebuffers();
+    }
 
 
-	ShaderBinding* materialBinding;		
+	ShaderBinding* materialBinding;
 	for(int i=0; i < filterShaderMaterial->getNumShaders(); i++) {
 		materialBinding = filterShaderMaterial->getShaderBinding(i);
 		
 		for(int j=0; j < materialBinding->getNumColorTargetBindings(); j++) {
 			RenderTargetBinding *colorBinding = materialBinding->getColorTargetBinding(j);
 			materialBinding->clearTexture(colorBinding->name);
-			materialBinding->addTexture(colorBinding->name, finalTargetColorTexture);
+            
+            if(finalTargetColorTexture) {
+                materialBinding->addTexture(colorBinding->name, finalTargetColorTexture);
+            } else {
+                materialBinding->addTexture(colorBinding->name, renderer->getGlobalColorFramebuffer());
+            }
 		}
 
 		for(int j=0; j < materialBinding->getNumDepthTargetBindings(); j++) {
 			RenderTargetBinding *depthBinding = materialBinding->getDepthTargetBinding(j);
 			materialBinding->clearTexture(depthBinding->name);
-			materialBinding->addTexture(depthBinding->name, finalTargetZTexture);
+            if(finalTargetZTexture) {
+                materialBinding->addTexture(depthBinding->name, finalTargetZTexture);
+            } else {
+                materialBinding->addTexture(depthBinding->name, renderer->getGlobalDepthFramebuffer());
+            }
 		}
 		
 		renderer->applyMaterial(filterShaderMaterial, localShaderOptions[i], i, true);
@@ -406,6 +434,13 @@ void Camera::drawFilter(Texture *targetTexture, Number targetTextureWidth, Numbe
 					renderer->drawScreenQuad(targetTextureWidth, targetTextureHeight);
 					renderer->unbindFramebuffers();									
 				} else {
+                    // global framebuffer ONLY used for input
+                    // we must unbind it here.
+                    // this is a bit of a hack, a better system
+                    // would be to define override buffers
+                    if(useGlobalFramebuffer) {
+                        renderer->unbindFramebuffers();
+                    }
 					renderer->setViewportSize(renderer->getXRes(), renderer->getYRes());
 					renderer->clearScreen();
 					renderer->loadIdentity();
@@ -494,5 +529,5 @@ void Camera::doCameraTransform() {
 	Matrix4 camMatrix = getConcatenatedMatrix();
 	renderer->setCameraMatrix(camMatrix);	
 	camMatrix = camMatrix.Inverse();
-	renderer->multModelviewMatrix(camMatrix);		
+	renderer->multModelviewMatrix(camMatrix);
 }

+ 4 - 0
Core/Contents/Source/PolyGLRenderer.cpp

@@ -640,6 +640,9 @@ void OpenGLRenderer::setPerspectiveDefaults() {
 }
 
 void OpenGLRenderer::BeginRender() {
+    
+    Renderer::BeginRender();
+    
 	if(doClearBuffer) {
 		glClearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a);
 		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -1027,6 +1030,7 @@ void OpenGLRenderer::setVertexColor(Number r, Number g, Number b, Number a) {
 }
 
 void OpenGLRenderer::EndRender() {
+    Renderer::EndRender();
 ///	glFlush();
 //	glFinish();	
 }

+ 44 - 0
Core/Contents/Source/PolyRenderer.cpp

@@ -51,6 +51,50 @@ Renderer::Renderer() : clearColor(0.2, 0.2, 0.2, 0.0), currentTexture(NULL), lig
     backingResolutionScaleX = 1.0;
     backingResolutionScaleY = 1.0;
     overrideMaterial = NULL;
+    renderToGlobalFramebuffer = false;
+    globalColorFramebuffer = NULL;
+    globalDepthFramebuffer = NULL;
+}
+
+void Renderer::setRenderToGlobalFramebuffer(bool val) {
+    
+    if(val == renderToGlobalFramebuffer) {
+        return;
+    }
+    
+    renderToGlobalFramebuffer = val;
+    
+    if(renderToGlobalFramebuffer) {
+        createRenderTextures(&globalColorFramebuffer, &globalDepthFramebuffer, getXRes(), getYRes(), false);
+    } else {
+        delete globalColorFramebuffer;
+        delete globalDepthFramebuffer;
+    }
+}
+
+void Renderer::BeginRender() {
+    if(renderToGlobalFramebuffer) {
+        bindFrameBufferTexture(globalColorFramebuffer);
+        bindFrameBufferTextureDepth(globalDepthFramebuffer);
+    }
+}
+
+void Renderer::EndRender() {
+    if(renderToGlobalFramebuffer) {
+        unbindFramebuffers();
+    }
+}
+
+bool Renderer::getRenderToGlobalFramebuffer() const {
+    return renderToGlobalFramebuffer;
+}
+
+Texture *Renderer::getGlobalColorFramebuffer() const {
+    return globalColorFramebuffer;
+}
+
+Texture *Renderer::getGlobalDepthFramebuffer() const {
+    return globalDepthFramebuffer;
 }
 
 void Renderer::setOverrideMaterial(Material *material) {