Просмотр исходного кода

Added render buffers as separate class, fixed depth not working in render textures

Ivan Safrin 10 лет назад
Родитель
Сommit
b6a7092fbc

+ 3 - 1
include/polycode/core/PolyGPUDrawBuffer.h

@@ -31,6 +31,8 @@
 
 namespace Polycode {
     
+    class RenderBuffer;
+    
     class _PolyExport LightInfo {
         public:
             unsigned short importance;
@@ -84,7 +86,7 @@ namespace Polycode {
         GPUDrawBuffer();
         ~GPUDrawBuffer();
         
-        Texture *targetFramebuffer;
+        RenderBuffer *targetFramebuffer;
         Matrix4 projectionMatrix;
         Matrix4 viewMatrix;
         Matrix4 cameraMatrix;

+ 3 - 1
include/polycode/core/PolyOpenGLGraphicsInterface.h

@@ -86,7 +86,9 @@ namespace Polycode {
         void endDrawCall();
         void setBlendingMode(unsigned int blendingMode);
         
-        void bindFramebuffer(Texture *framebufferTexture);
+        void createRenderBuffer(RenderBuffer *renderBuffer);
+        void destroyRenderBuffer(RenderBuffer *renderBuffer);
+        void bindRenderBuffer(RenderBuffer *renderBuffer);
         
         void createVertexBuffer(VertexDataArray *dataArray);
         void createIndexBuffer(IndexDataArray *dataArray);

+ 13 - 4
include/polycode/core/PolyRenderer.h

@@ -39,6 +39,9 @@ THE SOFTWARE.
 
 namespace Polycode {
     
+    class Texture;
+    class RenderBuffer;
+    
     class _PolyExport GraphicsInterface : public PolyBase {
         public:
             GraphicsInterface();
@@ -61,9 +64,6 @@ namespace Polycode {
             virtual void createIndexBuffer(IndexDataArray *dataArray) = 0;
             virtual void destroyBuffer(RenderDataArray *array) = 0;
         
-        
-            virtual void bindFramebuffer(Texture *framebufferTexture) = 0;
-        
             virtual void drawIndices(int type, IndexDataArray *indexArray) = 0;
             virtual void drawArrays(int type, unsigned int vertexCount) = 0;
         
@@ -78,6 +78,10 @@ namespace Polycode {
         
             virtual void setWireframeMode(bool val) = 0;
         
+            virtual void createRenderBuffer(RenderBuffer *renderBuffer) = 0;
+            virtual void destroyRenderBuffer(RenderBuffer *renderBuffer) = 0;
+            virtual void bindRenderBuffer(RenderBuffer *buffer) = 0;
+        
             virtual void beginDrawCall() = 0;
             virtual void endDrawCall() = 0;
     };
@@ -134,6 +138,8 @@ namespace Polycode {
             static const int JOB_DESTROY_SHADER = 9;
             static const int JOB_DESTROY_PROGRAM = 10;
             static const int JOB_DESTROY_BUFFER = 11;
+            static const int JOB_CREATE_RENDER_BUFFER = 12;
+            static const int JOB_DESTROY_RENDER_BUFFER = 13;
         
         protected:
         
@@ -154,7 +160,7 @@ namespace Polycode {
             LightInfoBinding lights[RENDERER_MAX_LIGHTS];
         
     };
-    
+
     class _PolyExport Renderer : public PolyBase {
 	public:
         
@@ -167,6 +173,9 @@ namespace Polycode {
         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, bool framebufferTexture);
         
+        RenderBuffer *createRenderBuffer(unsigned int width, unsigned int height, bool attachDepthBuffer);
+        void destroyRenderBuffer(RenderBuffer *buffer);
+        
         void destroyTexture(Texture *texture);
 
         void processDrawBuffer(GPUDrawBuffer *buffer);

+ 1 - 1
include/polycode/core/PolyScene.h

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

+ 3 - 7
include/polycode/core/PolySceneRenderTexture.h

@@ -30,6 +30,7 @@ namespace Polycode {
 	class Camera;
 	class Texture;
     class Renderer;
+    class RenderBuffer;
     class Image;
 	
 	/**
@@ -76,14 +77,9 @@ namespace Polycode {
 		protected:
         
             Renderer *renderer;
-		
-			Texture *filterColorBufferTexture;
-			Texture *filterZBufferTexture;
-		
             unsigned int textureFormat;
-		
-			Texture *depthTexture;		
-			Texture *targetTexture;
+            RenderBuffer *targetFramebuffer;
+        
 			Scene *targetScene;
 			Camera *targetCamera;
 	};

+ 20 - 2
include/polycode/core/PolyTexture.h

@@ -52,16 +52,34 @@ namespace Polycode {
             bool createMipmaps;
             unsigned int anisotropy;
             bool framebufferTexture;
+            bool depthTexture;
         
             static const int FILTERING_NEAREST = 0;
             static const int FILTERING_LINEAR = 1;
         
-            void *frameBufferPlatformData;
-        
 		protected:
 
 			int pixelSize;
 			int width;
 			int height;
 	};
+    
+    class _PolyExport RenderBuffer {
+        public:
+            RenderBuffer(unsigned int width, unsigned int height, bool attachDepthBuffer);
+
+            unsigned int getWidth();
+            unsigned int getHeight();
+        
+            Texture *colorTexture;
+            Texture *depthTexture;
+
+            void *platformData;
+            void *depthBufferPlatformData;
+        private:
+        
+            unsigned int width;
+            unsigned int height;
+    };
+    
 }

+ 63 - 15
src/core/PolyOpenGLGraphicsInterface.cpp

@@ -325,12 +325,58 @@ void OpenGLGraphicsInterface::drawArrays(int type, unsigned int vertexCount) {
     glDrawArrays(getGLDrawMode(type), 0, vertexCount);
 }
 
+void OpenGLGraphicsInterface::createRenderBuffer(RenderBuffer *renderBuffer) {
+    if(!renderBuffer->platformData) {
+        renderBuffer->platformData = (void*) new GLuint;
+        glGenFramebuffers(1, (GLuint*)renderBuffer->platformData);
+        glBindFramebuffer(GL_FRAMEBUFFER, *((GLuint*)renderBuffer->platformData));
+    }
+    
+    renderBuffer->colorTexture->framebufferTexture = true;
+    createTexture(renderBuffer->colorTexture);
+    
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *((GLuint*)renderBuffer->colorTexture->platformData), 0);
+    
+    if(renderBuffer->depthTexture) {
+        
+        renderBuffer->depthBufferPlatformData = (void*) new GLuint;
+        glGenRenderbuffers(1, (GLuint*)renderBuffer->depthBufferPlatformData);
+        glBindRenderbuffer(GL_FRAMEBUFFER, *((GLuint*)renderBuffer->depthBufferPlatformData));
+        
+        renderBuffer->depthTexture->framebufferTexture = true;
+        renderBuffer->depthTexture->depthTexture = true;
+        renderBuffer->depthTexture->filteringMode = Texture::FILTERING_LINEAR;
+        createTexture(renderBuffer->depthTexture);
+        
+        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, *((GLuint*)renderBuffer->depthTexture->platformData), 0);
+    }
+    
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
+}
+
+void OpenGLGraphicsInterface::destroyRenderBuffer(RenderBuffer *renderBuffer) {
+    glDeleteFramebuffers(1, (GLuint*)renderBuffer->platformData);
+    if(renderBuffer->colorTexture) {
+        destroyTexture(renderBuffer->colorTexture);
+    }
+    if(renderBuffer->depthTexture) {
+        destroyTexture(renderBuffer->depthTexture);
+        glDeleteRenderbuffers(1, (GLuint*)renderBuffer->depthBufferPlatformData);
+        delete (GLuint*)renderBuffer->depthBufferPlatformData;
+    }
+    delete (GLuint*)renderBuffer->platformData;
+    delete renderBuffer;
+}
 
-void OpenGLGraphicsInterface::bindFramebuffer(Texture *framebufferTexture) {
-    if(framebufferTexture) {
-        glBindFramebuffer(GL_FRAMEBUFFER, *((GLuint*) framebufferTexture->frameBufferPlatformData));
+void OpenGLGraphicsInterface::bindRenderBuffer(RenderBuffer *renderBuffer) {
+    if(renderBuffer) {
+        glBindFramebuffer(GL_FRAMEBUFFER, *((GLuint*) renderBuffer->platformData));
+        if(renderBuffer->depthBufferPlatformData) {
+            glBindRenderbuffer(GL_RENDERBUFFER, *((GLuint*) renderBuffer->depthBufferPlatformData));            
+        }
     } else {
         glBindFramebuffer(GL_FRAMEBUFFER, 0);
+        glBindRenderbuffer(GL_RENDERBUFFER, 0);
     }
 }
 
@@ -342,13 +388,6 @@ void OpenGLGraphicsInterface::destroyTexture(Texture *texture) {
 
 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;
@@ -390,6 +429,20 @@ void OpenGLGraphicsInterface::createTexture(Texture *texture) {
             break;
     }
     
+    if(texture->depthTexture) {
+        glTextureType = GL_DEPTH_COMPONENT;
+        
+        if(texture->type == Image::IMAGE_FP16) {
+            pixelType = GL_FLOAT;
+            glTextureFormat = GL_DEPTH_COMPONENT16;
+        } else {
+            pixelType = GL_UNSIGNED_BYTE;
+            glTextureFormat = GL_DEPTH_COMPONENT;
+        }
+        
+        glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);
+        glRenderbufferStorage(GL_RENDERBUFFER, glTextureFormat, texture->getWidth(), texture->getHeight());
+    }
     
     switch(texture->filteringMode) {
         case Texture::FILTERING_LINEAR:
@@ -433,11 +486,6 @@ void OpenGLGraphicsInterface::createTexture(Texture *texture) {
         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);
 }
 

+ 24 - 2
src/core/PolyRenderer.cpp

@@ -78,7 +78,7 @@ void RenderThread::processDrawBuffer(GPUDrawBuffer *buffer) {
     ++currentDebugFrameInfo.buffersProcessed;
     
     if(buffer->targetFramebuffer) {
-        graphicsInterface->bindFramebuffer(buffer->targetFramebuffer);
+        graphicsInterface->bindRenderBuffer(buffer->targetFramebuffer);
     }
     
     graphicsInterface->setViewport(buffer->viewport.x, buffer->viewport.y, buffer->viewport.w, buffer->viewport.h);
@@ -248,7 +248,7 @@ void RenderThread::processDrawBuffer(GPUDrawBuffer *buffer) {
     }
     
     if(buffer->targetFramebuffer) {
-        graphicsInterface->bindFramebuffer(NULL);
+        graphicsInterface->bindRenderBuffer(NULL);
     }
     
 }
@@ -274,6 +274,18 @@ void RenderThread::processJob(const RendererThreadJob &job) {
             graphicsInterface->destroyTexture(texture);
         }
         break;
+        case JOB_CREATE_RENDER_BUFFER:
+        {
+            RenderBuffer *buffer = (RenderBuffer*) job.data;
+            graphicsInterface->createRenderBuffer(buffer);
+        }
+        break;
+        case JOB_DESTROY_RENDER_BUFFER:
+        {
+            RenderBuffer *buffer = (RenderBuffer*) job.data;
+            graphicsInterface->destroyRenderBuffer(buffer);
+        }
+            break;
         case JOB_PROCESS_DRAW_BUFFER:
         {
             GPUDrawBuffer *buffer = (GPUDrawBuffer*) job.data;
@@ -423,6 +435,16 @@ Texture *Renderer::createTexture(unsigned int width, unsigned int height, char *
     return texture;
 }
 
+RenderBuffer *Renderer::createRenderBuffer(unsigned int width, unsigned int height, bool attachDepthBuffer) {
+    RenderBuffer *buffer = new RenderBuffer(width, height, attachDepthBuffer);
+    renderThread->enqueueJob(RenderThread::JOB_CREATE_RENDER_BUFFER, (void*)buffer);
+    return buffer;
+}
+
+void Renderer::destroyRenderBuffer(RenderBuffer *buffer) {
+    renderThread->enqueueJob(RenderThread::JOB_DESTROY_RENDER_BUFFER, (void*)buffer);
+}
+
 Shader *Renderer::createShader(ShaderProgram *vertexProgram, ShaderProgram *fragmentProgram) {
     Shader *shader = new Shader();
     shader->vertexProgram = vertexProgram;

+ 1 - 1
src/core/PolyScene.cpp

@@ -215,7 +215,7 @@ void Scene::setEntityVisibility(Entity *entity, Camera *camera) {
     }
 }
 
-void Scene::Render(Camera *targetCamera, Texture *targetFramebuffer) {
+void Scene::Render(Camera *targetCamera, RenderBuffer *targetFramebuffer) {
     if(!targetCamera && !activeCamera)
         return;
     if(!targetCamera)

+ 10 - 22
src/core/PolySceneRenderTexture.cpp

@@ -32,7 +32,7 @@ using namespace Polycode;
 
 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);
+    targetFramebuffer = Services()->getRenderer()->createRenderBuffer(renderWidth, renderHeight, true);
     
 	this->targetScene = targetScene;
 	this->targetCamera = targetCamera;
@@ -46,15 +46,8 @@ SceneRenderTexture::SceneRenderTexture(Scene *targetScene, Camera *targetCamera,
 void SceneRenderTexture::resizeRenderTexture(int newWidth, int newHeight) {
 
 	if(newWidth > 0 && newHeight > 0) {
-        // RENDERER_TODO
-        /*
-		CoreServices::getInstance()->getRenderer()->destroyTexture(targetTexture);
-		CoreServices::getInstance()->getRenderer()->destroyTexture(depthTexture);	
-		CoreServices::getInstance()->getRenderer()->destroyTexture(filterColorBufferTexture);
-		CoreServices::getInstance()->getRenderer()->destroyTexture(filterZBufferTexture);	
-*/
-        targetTexture = Services()->getRenderer()->createTexture(newWidth, newHeight, NULL, false, false, textureFormat, Services()->getMaterialManager()->getTextureFilteringMode(), 0, true);
-
+        Services()->getRenderer()->destroyRenderBuffer(targetFramebuffer);
+        targetFramebuffer = Services()->getRenderer()->createRenderBuffer(newWidth, newHeight, true);
 	}
 }
 	
@@ -63,11 +56,11 @@ Scene *SceneRenderTexture::getTargetScene() {
 }
 
 Texture *SceneRenderTexture::getFilterColorBufferTexture() {
-	return filterColorBufferTexture;
+	return NULL;
 }
 
 Texture *SceneRenderTexture::getFilterZBufferTexture() {
-	return filterZBufferTexture;
+	return NULL;
 }
 
 Camera *SceneRenderTexture::getTargetCamera() {
@@ -76,11 +69,12 @@ Camera *SceneRenderTexture::getTargetCamera() {
 
 void SceneRenderTexture::Render() {
     
+    // RENDERER_TODO
 //    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);
+        targetCamera->setViewport(Polycode::Rectangle(0.0, 0.0, targetFramebuffer->getWidth(), targetFramebuffer->getHeight()));
+        targetScene->Render(targetCamera, targetFramebuffer);
    // }
 }
 
@@ -91,16 +85,10 @@ Image *SceneRenderTexture::saveToImage() {
 }
 
 Texture *SceneRenderTexture::getTargetTexture() {
-	return targetTexture;
+	return targetFramebuffer->colorTexture;
 }
 
 SceneRenderTexture::~SceneRenderTexture() {
 	CoreServices::getInstance()->getSceneManager()->unregisterRenderTexture(this);
-    // RENDERER_TODO
-    /*
-	CoreServices::getInstance()->getRenderer()->destroyTexture(targetTexture);
-	CoreServices::getInstance()->getRenderer()->destroyTexture(depthTexture);	
-	CoreServices::getInstance()->getRenderer()->destroyTexture(filterColorBufferTexture);
-	CoreServices::getInstance()->getRenderer()->destroyTexture(filterZBufferTexture);	
-     */
+    Services()->getRenderer()->destroyRenderBuffer(targetFramebuffer);
 }

+ 20 - 1
src/core/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, 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) {
+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), depthTexture(false) {
     
 	switch(type) {
 		case Image::IMAGE_RGB:
@@ -107,3 +107,22 @@ Texture::Texture(Image *image) : Resource(Resource::RESOURCE_TEXTURE) {
 	memcpy(this->textureData, image->getPixels(), image->getWidth()*image->getHeight()*pixelSize);	
 
 }
+
+RenderBuffer::RenderBuffer(unsigned int width, unsigned int height, bool attachDepthBuffer) : platformData(NULL), width(width), height(height), depthBufferPlatformData(NULL) {
+    colorTexture = new Texture(width, height, NULL, false, false);
+    if(attachDepthBuffer) {
+        depthTexture = new Texture(width, height, NULL, false, false);
+    } else {
+        depthTexture = NULL;
+    }
+    
+}
+
+unsigned int RenderBuffer::getWidth() {
+    return width;
+}
+
+unsigned int RenderBuffer::getHeight() {
+    return height;
+}
+