2
0
Эх сурвалжийг харах

Added framebuffer support to new renderer

Ivan Safrin 10 жил өмнө
parent
commit
597b073ee1

+ 1 - 0
Core/Contents/Include/PolyGPUDrawBuffer.h

@@ -61,6 +61,7 @@ namespace Polycode {
         GPUDrawBuffer();
         ~GPUDrawBuffer();
         
+        Texture *targetFramebuffer;
         Matrix4 projectionMatrix;
         Matrix4 viewMatrix;
         Color clearColor;

+ 1 - 0
Core/Contents/Include/PolyMaterialManager.h

@@ -84,6 +84,7 @@ namespace Polycode {
         
             void setAnisotropyAmount(unsigned int anisotropy);
             void setTextureFilteringMode(unsigned int textureFilteringMode);
+            unsigned int getTextureFilteringMode();
 						
 			void addMaterial(Material *material);
 			void addShader(Shader *shader);

+ 2 - 0
Core/Contents/Include/PolyOpenGLGraphicsInterface.h

@@ -69,6 +69,8 @@ namespace Polycode {
         void endDrawCall();
         void setBlendingMode(unsigned int blendingMode);
         
+        void bindFramebuffer(Texture *framebufferTexture);
+        
         void createVertexBuffer(VertexDataArray *dataArray);
         void createIndexBuffer(IndexDataArray *dataArray);
         

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

@@ -53,6 +53,7 @@ namespace Polycode {
             virtual void createVertexBuffer(VertexDataArray *dataArray) = 0;
             virtual void createIndexBuffer(IndexDataArray *dataArray) = 0;
 
+            virtual void bindFramebuffer(Texture *framebufferTexture) = 0;
         
             virtual void drawIndices(int type, IndexDataArray *indexArray) = 0;
             virtual void drawArrays(int type, unsigned int vertexCount) = 0;
@@ -129,10 +130,8 @@ namespace Polycode {
         RenderThread *getRenderThread();
 
         Cubemap *createCubemap(Texture *t0, Texture *t1, Texture *t2, Texture *t3, Texture *t4, Texture *t5);
-        Texture *createTexture(unsigned int width, unsigned int height, char *textureData, bool clamp, bool createMipmaps, int type, unsigned int filteringMode, unsigned int anisotropy);
+        Texture *createTexture(unsigned int width, unsigned int height, char *textureData, bool clamp, bool createMipmaps, int type, unsigned int filteringMode, unsigned int anisotropy, bool framebufferTexture);
         void destroyTexture(Texture *texture);
-        void createRenderTextures(Texture **colorBuffer, Texture **depthBuffer, int width, int height, bool floatingPointBuffer);
-        
         void processDrawBuffer(GPUDrawBuffer *buffer);
         
         void setBackingResolutionScale(Number xScale, Number yScale);
@@ -146,7 +145,6 @@ namespace Polycode {
         Number getAnisotropyAmount();
         
         static Vector3 unProject(const Vector3 &position, const Matrix4 &modelMatrix, const Matrix4 &projectionMatrix, const Polycode::Rectangle &viewport);
-
         static Vector3 project(const Vector3 &position, const Matrix4 &modelMatrix, const Matrix4 &projectionMatrix, const Polycode::Rectangle &viewport);
         
         

+ 1 - 1
Core/Contents/Include/PolyScene.h

@@ -128,7 +128,7 @@ namespace Polycode {
 		bool isEnabled();		
 		void setEnabled(bool enabled);
 		
-		void Render(Camera *targetCamera = NULL);
+		void Render(Camera *targetCamera = NULL, Texture *targetFramebuffer = NULL);
 		void RenderDepthOnly(Camera *targetCamera);
         
         void setOverrideMaterial(Material *material);

+ 3 - 2
Core/Contents/Include/PolySceneRenderTexture.h

@@ -22,6 +22,7 @@ THE SOFTWARE.
 
 #pragma once
 #include "PolyGlobals.h"
+#include "PolyImage.h"
 
 namespace Polycode {
 
@@ -44,7 +45,7 @@ namespace Polycode {
 			* @param renderHeight Vertical size of the render texture.
 			* @param floatingPoint Pass true if you want fp16 target renders			
 			*/
-			SceneRenderTexture(Scene *targetScene, Camera *targetCamera, int renderWidth,int renderHeight, bool floatingPoint = false);
+            SceneRenderTexture(Scene *targetScene, Camera *targetCamera, int renderWidth,int renderHeight, unsigned int textureFormat = Image::IMAGE_RGBA);
 			virtual ~SceneRenderTexture();
 						
 			/**
@@ -79,7 +80,7 @@ namespace Polycode {
 			Texture *filterColorBufferTexture;
 			Texture *filterZBufferTexture;
 		
-			bool floatingPoint;
+            unsigned int textureFormat;
 		
 			Texture *depthTexture;		
 			Texture *targetTexture;

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

@@ -30,7 +30,7 @@ namespace Polycode {
 
 	class _PolyExport Texture : public Resource {
 		public:
-            Texture(unsigned int width, unsigned int height, char *textureData,bool clamp, bool createMipmaps, int type=Image::IMAGE_RGBA);
+            Texture(unsigned int width, unsigned int height, char *textureData,bool clamp, bool createMipmaps, int type=Image::IMAGE_RGBA, bool framebufferTexture=false);
 			Texture(Image *image);
 			virtual ~Texture();
 			
@@ -51,10 +51,13 @@ namespace Polycode {
             int filteringMode;
             bool createMipmaps;
             unsigned int anisotropy;
+            bool framebufferTexture;
         
             static const int FILTERING_NEAREST = 0;
             static const int FILTERING_LINEAR = 1;
         
+            void *frameBufferPlatformData;
+        
 		protected:
 
 			int pixelSize;

+ 1 - 1
Core/Contents/Source/PolyGPUDrawBuffer.cpp

@@ -24,7 +24,7 @@
 
 using namespace Polycode;
 
-GPUDrawBuffer::GPUDrawBuffer() {
+GPUDrawBuffer::GPUDrawBuffer() : targetFramebuffer(NULL) {
     
 }
 

+ 5 - 1
Core/Contents/Source/PolyMaterialManager.cpp

@@ -148,7 +148,7 @@ Texture *MaterialManager::createNewTexture(int width, int height, bool clamp, bo
 }
 
 Texture *MaterialManager::createTexture(int width, int height, char *imageData, bool clamp, bool createMipmaps, int type) {
-	Texture *newTexture = CoreServices::getInstance()->getRenderer()->createTexture(width, height, imageData,clamp, createMipmaps, type, textureFilteringMode, anisotropyAmount);
+	Texture *newTexture = CoreServices::getInstance()->getRenderer()->createTexture(width, height, imageData,clamp, createMipmaps, type, textureFilteringMode, anisotropyAmount, false);
 	textures.push_back(newTexture);
     if(!keepTextureData) {
         free(newTexture->textureData);
@@ -165,6 +165,10 @@ void MaterialManager::setTextureFilteringMode(unsigned int textureFilteringMode)
     this->textureFilteringMode = textureFilteringMode;
 }
 
+unsigned int MaterialManager::getTextureFilteringMode() {
+    return textureFilteringMode;
+}
+
 Texture *MaterialManager::createTextureFromImage(Image *image, bool clamp, bool createMipmaps) {
 	Texture *newTexture;
 	newTexture = createTexture(image->getWidth(), image->getHeight(), image->getPixels(),clamp, createMipmaps, image->getType());

+ 33 - 4
Core/Contents/Source/PolyOpenGLGraphicsInterface.cpp

@@ -233,12 +233,32 @@ void OpenGLGraphicsInterface::drawArrays(int type, unsigned int vertexCount) {
     glDrawArrays(getGLDrawMode(type), 0, vertexCount);
 }
 
+
+void OpenGLGraphicsInterface::bindFramebuffer(Texture *framebufferTexture) {
+    if(framebufferTexture) {
+        glBindFramebuffer(GL_FRAMEBUFFER, *((GLuint*) framebufferTexture->frameBufferPlatformData));
+    } else {
+        glBindFramebuffer(GL_FRAMEBUFFER, 0);
+    }
+}
+
 void OpenGLGraphicsInterface::createTexture(Texture *texture) {
+    
+    if(texture->framebufferTexture) {
+        if(!texture->frameBufferPlatformData) {
+            texture->frameBufferPlatformData = (void*) new GLuint;
+            glGenFramebuffers(1, (GLuint*)texture->frameBufferPlatformData);
+            glBindFramebuffer(GL_FRAMEBUFFER, *((GLuint*)texture->frameBufferPlatformData));
+        }
+    }
+    
+    
     if(!texture->platformData) {
         texture->platformData = (void*) new GLuint;
         glGenTextures(1, (GLuint*)texture->platformData);
     }
     
+    
     GLuint textureID = *((GLuint*)texture->platformData);
     
     glBindTexture(GL_TEXTURE_2D, textureID);
@@ -301,15 +321,24 @@ void OpenGLGraphicsInterface::createTexture(Texture *texture) {
             break;
     }
     
-    if(texture->getTextureData()) {
-        glTexImage2D(GL_TEXTURE_2D, 0, glTextureFormat, texture->getWidth(), texture->getHeight(), 0, glTextureType, pixelType, texture->getTextureData());
+    if(texture->framebufferTexture) {
+        glTexImage2D(GL_TEXTURE_2D, 0, glTextureFormat, texture->getWidth(), texture->getHeight(), 0, glTextureType, pixelType, NULL);
+        
+    } else {
+        if(texture->getTextureData()) {
+            glTexImage2D(GL_TEXTURE_2D, 0, glTextureFormat, texture->getWidth(), texture->getHeight(), 0, glTextureType, pixelType, texture->getTextureData());
+        }
     }
     
-    
-    if(texture->createMipmaps) {
+    if(texture->createMipmaps && !texture->framebufferTexture) {
         glGenerateMipmap(GL_TEXTURE_2D);
     }
     
+    if(texture->framebufferTexture) {
+        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureID, 0);
+        glBindFramebuffer(GL_FRAMEBUFFER, 0);
+    }
+    
     glBindTexture(GL_TEXTURE_2D, 0);
 }
 

+ 13 - 6
Core/Contents/Source/PolyRenderer.cpp

@@ -72,12 +72,16 @@ void RenderThread::processDrawBuffer(GPUDrawBuffer *buffer) {
     
     ++currentDebugFrameInfo.buffersProcessed;
     
+    if(buffer->targetFramebuffer) {
+        interface->bindFramebuffer(buffer->targetFramebuffer);
+    }
+    
     interface->setViewport(buffer->viewport.x, buffer->viewport.y, buffer->viewport.w, buffer->viewport.h);
     interface->clearBuffers(buffer->clearColor, buffer->clearColorBuffer, buffer->clearDepthBuffer, true);
     
     projectionMatrixParam->setMatrix4(buffer->projectionMatrix);
     viewMatrixParam->setMatrix4(buffer->viewMatrix);
-    
+
     for(int i=0; i < buffer->drawCalls.size(); i++) {
         
         
@@ -186,6 +190,11 @@ void RenderThread::processDrawBuffer(GPUDrawBuffer *buffer) {
             }
         }
     }
+    
+    if(buffer->targetFramebuffer) {
+        interface->bindFramebuffer(NULL);
+    }
+    
 }
 
 void RenderThread::processJob(const RendererThreadJob &job) {
@@ -330,8 +339,8 @@ void Renderer::endFrame() {
     renderThread->enqueueJob(RenderThread::JOB_END_FRAME, NULL);
 }
 
-Texture *Renderer::createTexture(unsigned int width, unsigned int height, char *textureData, bool clamp, bool createMipmaps, int type, unsigned int filteringMode, unsigned int anisotropy) {
-    Texture *texture = new Texture(width, height, textureData, clamp, createMipmaps, type);
+Texture *Renderer::createTexture(unsigned int width, unsigned int height, char *textureData, bool clamp, bool createMipmaps, int type, unsigned int filteringMode, unsigned int anisotropy, bool framebufferTexture) {
+    Texture *texture = new Texture(width, height, textureData, clamp, createMipmaps, type, framebufferTexture);
     texture->filteringMode = filteringMode;
     texture->anisotropy = anisotropy;
     renderThread->enqueueJob(RenderThread::JOB_CREATE_TEXTURE, (void*)texture);
@@ -368,9 +377,7 @@ void Renderer::createVertexBuffers(Mesh *mesh) {
 void Renderer::destroyTexture(Texture *texture) {
     
 }
-void Renderer::createRenderTextures(Texture **colorBuffer, Texture **depthBuffer, int width, int height, bool floatingPointBuffer) {
-    
-}
+
 Vector3 Renderer::project(const Vector3 &position, const Matrix4 &modelMatrix, const Matrix4 &projectionMatrix, const Polycode::Rectangle &viewport) {
     
     Vector4 in(position);

+ 2 - 1
Core/Contents/Source/PolyScene.cpp

@@ -216,7 +216,7 @@ void Scene::setEntityVisibility(Entity *entity, Camera *camera) {
     }
 }
 
-void Scene::Render(Camera *targetCamera) {
+void Scene::Render(Camera *targetCamera, Texture *targetFramebuffer) {
     if(!targetCamera && !activeCamera)
         return;
     if(!targetCamera)
@@ -226,6 +226,7 @@ void Scene::Render(Camera *targetCamera) {
     drawBuffer->clearColor = clearColor;
     drawBuffer->clearColorBuffer = useClearColor;
     drawBuffer->clearDepthBuffer = useClearDepth;
+    drawBuffer->targetFramebuffer = targetFramebuffer;
     
     drawBuffer->viewport = targetCamera->getViewport();
 ///    drawBuffer->projectionMatrix = targetCamera->

+ 0 - 11
Core/Contents/Source/PolySceneManager.cpp

@@ -74,22 +74,11 @@ void SceneManager::setRenderer(Renderer *renderer) {
 }
 
 void SceneManager::renderVirtual() {
-    
-        // RENDERER_TODO
-    /*
-    
-	bool anyVirtualsRendered = false;
 	for(int i=0;i<renderTextures.size();i++) {
 		if(renderTextures[i]->enabled) {
             renderTextures[i]->Render();
-			anyVirtualsRendered = true;
 		}			
 	}
-	renderer->setViewportSize(renderer->getXRes(), renderer->getYRes());
-	if (anyVirtualsRendered) {
-		renderer->clearScreen();
-	}
-     */
 }
 
 void SceneManager::Render(const Polycode::Rectangle &viewport) {    

+ 14 - 20
Core/Contents/Source/PolySceneRenderTexture.cpp

@@ -30,15 +30,16 @@
 
 using namespace Polycode;
 
-SceneRenderTexture::SceneRenderTexture(Scene *targetScene, Camera *targetCamera, int renderWidth,int renderHeight, bool floatingPoint) {
-	this->floatingPoint = floatingPoint;
-	CoreServices::getInstance()->getRenderer()->createRenderTextures(&targetTexture, &depthTexture, renderWidth, renderHeight, floatingPoint);
+SceneRenderTexture::SceneRenderTexture(Scene *targetScene, Camera *targetCamera, int renderWidth,int renderHeight, unsigned int textureFormat) : textureFormat(textureFormat) {
+    
+    targetTexture = Services()->getRenderer()->createTexture(renderWidth, renderHeight, NULL, false, false, textureFormat, Services()->getMaterialManager()->getTextureFilteringMode(), 0, true);
+    
 	this->targetScene = targetScene;
 	this->targetCamera = targetCamera;
 
-	CoreServices::getInstance()->getRenderer()->createRenderTextures(&filterColorBufferTexture, &filterZBufferTexture, renderWidth, renderHeight, floatingPoint);
 	CoreServices::getInstance()->getSceneManager()->registerRenderTexture(this);
-    renderer = CoreServices::getInstance()->getRenderer();
+    renderer = Services()->getRenderer();
+    
 	enabled = true;
 }
 
@@ -50,8 +51,8 @@ void SceneRenderTexture::resizeRenderTexture(int newWidth, int newHeight) {
 		CoreServices::getInstance()->getRenderer()->destroyTexture(filterColorBufferTexture);
 		CoreServices::getInstance()->getRenderer()->destroyTexture(filterZBufferTexture);	
 
-		CoreServices::getInstance()->getRenderer()->createRenderTextures(&targetTexture, &depthTexture, newWidth, newHeight, floatingPoint);
-		CoreServices::getInstance()->getRenderer()->createRenderTextures(&filterColorBufferTexture, &filterZBufferTexture, newWidth, newHeight, floatingPoint);
+        targetTexture = Services()->getRenderer()->createTexture(newWidth, newHeight, NULL, false, false, textureFormat, Services()->getMaterialManager()->getTextureFilteringMode(), 0, true);
+
 	}
 }
 	
@@ -73,19 +74,12 @@ Camera *SceneRenderTexture::getTargetCamera() {
 
 void SceneRenderTexture::Render() {
     
-    // RENDERER_TODO
-    /*
-    renderer->setViewportSize(targetTexture->getWidth(), targetTexture->getHeight());
-    renderer->loadIdentity();
-    if(targetCamera->hasFilterShader()) {
-        targetCamera->drawFilter(targetTexture, targetTexture->getWidth(), targetTexture->getHeight(), filterColorBufferTexture, filterZBufferTexture);
-    } else {
-        renderer->bindFrameBufferTexture(targetTexture);
-        targetScene->Render(targetCamera);
-        renderer->unbindFramebuffers();
-    }
-    renderer->loadIdentity();
-     */
+//    if(targetCamera->hasFilterShader()) {
+       // targetCamera->drawFilter(targetTexture, targetTexture->getWidth(), targetTexture->getHeight(), filterColorBufferTexture, filterZBufferTexture);
+  //  } else {
+        targetCamera->setViewport(Polycode::Rectangle(0.0, 0.0, targetTexture->getWidth(), targetTexture->getHeight()));
+        targetScene->Render(targetCamera, targetTexture);
+   // }
 }
 
 Image *SceneRenderTexture::saveToImage() {

+ 10 - 6
Core/Contents/Source/PolyTexture.cpp

@@ -26,7 +26,7 @@
 
 using namespace Polycode;
 
-Texture::Texture(unsigned int width, unsigned int height, char *textureData,bool clamp, bool createMipmaps, int type) : Resource(Resource::RESOURCE_TEXTURE), width(width), height(height), clamp(clamp), type(type), createMipmaps(createMipmaps), filteringMode(FILTERING_NEAREST), anisotropy(0) {
+Texture::Texture(unsigned int width, unsigned int height, char *textureData,bool clamp, bool createMipmaps, int type, bool framebufferTexture) : Resource(Resource::RESOURCE_TEXTURE), width(width), height(height), clamp(clamp), type(type), createMipmaps(createMipmaps), filteringMode(FILTERING_NEAREST), anisotropy(0), framebufferTexture(framebufferTexture), frameBufferPlatformData(NULL) {
     
 	switch(type) {
 		case Image::IMAGE_RGB:
@@ -43,11 +43,15 @@ Texture::Texture(unsigned int width, unsigned int height, char *textureData,bool
 		break;
 	}
 	
-	this->textureData = (char*)malloc(width*height*pixelSize);
-	if(textureData)
-		memcpy(this->textureData, textureData, width*height*pixelSize);	
-	else
-		memset(this->textureData, 0, width*height*pixelSize);	
+    if(!framebufferTexture) {
+        this->textureData = (char*)malloc(width*height*pixelSize);
+        if(textureData)
+            memcpy(this->textureData, textureData, width*height*pixelSize);	
+        else
+            memset(this->textureData, 0, width*height*pixelSize);
+    } else {
+        this->textureData = NULL;
+    }
 
 }