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

Added VBO support to new renderer, some more optimizations

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

+ 2 - 32
Core/Contents/Include/PolyMesh.h

@@ -33,22 +33,7 @@ class OSFILE;
 namespace Polycode {
 	
 	class String;
-	
-	class _PolyExport VertexBuffer : public PolyBase {
-		public:	
-			VertexBuffer(){}
-			virtual ~VertexBuffer(){}
-		
-			int getVertexCount() const { return vertexCount;}
-			int getIndexCount() const { return indexCount;}
-		
-			int verticesPerFace;
-			int meshType;
-		protected:
-            int vertexCount;
-            int indexCount;
-			
-	};
+    class Mesh;
 		
 	typedef struct {
 		float x;
@@ -248,20 +233,6 @@ namespace Polycode {
         
             Vector2 getVertexTexCoordAtIndex(unsigned int index);
         
-        
-			/**
-			* Sets the vertex buffer for the mesh.
-			* @param buffer New vertex buffer for mesh.
-			*/			
-			void setVertexBuffer(VertexBuffer *buffer);
-			
-			/**
-			* Returns the vertex buffer for the mesh.
-			* @return The vertex buffer for this mesh.
-			*/
-			VertexBuffer *getVertexBuffer();
-        
-        
             Mesh *Copy() const;
 			
 			/**
@@ -403,8 +374,7 @@ namespace Polycode {
 
             void writeVertexBlock(VertexDataArray *array, OSFILE *outFile);
             void writeIndexBlock(IndexDataArray *array, OSFILE *outFile);
-        
-            VertexBuffer *vertexBuffer;
+
             bool meshHasVertexBuffer;
             int meshType;
 

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

@@ -68,6 +68,9 @@ namespace Polycode {
         void beginDrawCall();
         void setBlendingMode(unsigned int blendingMode);
         
+        void createVertexBuffer(VertexDataArray *dataArray);
+        void createIndexBuffer(IndexDataArray *dataArray);
+        
         void drawIndices(int type, IndexDataArray *indexArray);
         void drawArrays(int type, unsigned int vertexCount);
         

+ 3 - 0
Core/Contents/Include/PolyRenderDataArray.h

@@ -34,6 +34,9 @@ namespace Polycode {
         virtual void *getArrayData();
         virtual unsigned int getDataSize();
         
+        bool hasVBO;
+        void *platformData;
+        
         /**
          * Vertex position array.
          */

+ 6 - 0
Core/Contents/Include/PolyRenderer.h

@@ -51,6 +51,10 @@ namespace Polycode {
             virtual void useShader(Shader *shader) = 0;
             virtual void setBlendingMode(unsigned int blendingMode) = 0;
         
+            virtual void createVertexBuffer(VertexDataArray *dataArray) = 0;
+            virtual void createIndexBuffer(IndexDataArray *dataArray) = 0;
+
+        
             virtual void drawIndices(int type, IndexDataArray *indexArray) = 0;
             virtual void drawArrays(int type, unsigned int vertexCount) = 0;
         
@@ -103,6 +107,7 @@ namespace Polycode {
             static const int JOB_CREATE_PROGRAM = 4;
             static const int JOB_CREATE_SHADER = 5;
             static const int JOB_BEGIN_FRAME = 6;
+            static const int JOB_CREATE_VERTEX_BUFFERS = 7;
         
         protected:
         
@@ -143,6 +148,7 @@ namespace Polycode {
         Number getBackingResolutionScaleY();
         ShaderProgram *createProgram(const String &fileName);
         Shader *createShader(ShaderProgram *vertexProgram, ShaderProgram *fragmentProgram);
+        void createVertexBuffers(Mesh *mesh);
         
         void setAnisotropyAmount(Number amount);
         Number getAnisotropyAmount();

+ 3 - 1
Core/Contents/Include/PolyShader.h

@@ -175,9 +175,11 @@ namespace Polycode {
     
     class AttributeBinding : public PolyBase {
         public:
+            AttributeBinding();
             String name;
             VertexDataArray *vertexData;
             ProgramAttribute *attribute;
+            bool enabled;
     };
 	
 	class RenderTargetBinding : public PolyBase {
@@ -186,7 +188,7 @@ namespace Polycode {
 			String name;
 			int mode;
 			Texture *texture;
-			static const int MODE_IN= 0;
+			static const int MODE_IN = 0;
 			static const int MODE_OUT = 1;
 			static const int MODE_COLOR = 2;
 			static const int MODE_DEPTH = 3;			

+ 1 - 19
Core/Contents/Source/PolyMesh.cpp

@@ -47,7 +47,6 @@ indexArray(RenderDataArray::INDEX_DATA_ARRAY)
     indexedMesh = false;
     meshType = TRI_MESH;
     meshHasVertexBuffer = false;
-    vertexBuffer = NULL;
     loadMesh(fileName);
     useVertexColors = false;
 }
@@ -65,8 +64,7 @@ indexArray(RenderDataArray::INDEX_DATA_ARRAY)
 {
 
     this->meshType = meshType;
-    meshHasVertexBuffer = false;		
-    vertexBuffer = NULL;
+    meshHasVertexBuffer = false;
     useVertexColors = false;
     indexedMesh = false;
 }
@@ -80,9 +78,6 @@ Mesh::~Mesh() {
 }
 
 void Mesh::clearMesh() {
-    if(vertexBuffer)
-        delete vertexBuffer;
-    vertexBuffer = NULL;
     
     vertexPositionArray.data.clear();
     vertexColorArray.data.clear();
@@ -97,19 +92,6 @@ void Mesh::clearMesh() {
     meshHasVertexBuffer = false;
 }
 
-VertexBuffer *Mesh::getVertexBuffer() {
-    return vertexBuffer;
-}
-
-
-void Mesh::setVertexBuffer(VertexBuffer *buffer) {    
-    if(vertexBuffer) {
-        delete vertexBuffer;
-    }
-    vertexBuffer = buffer;
-    meshHasVertexBuffer = true;
-}
-
 Number Mesh::getRadius() {
     Number hRad = 0;
     Number len;

+ 50 - 1
Core/Contents/Source/PolyOpenGLGraphicsInterface.cpp

@@ -168,7 +168,16 @@ void OpenGLGraphicsInterface::useShader(Shader *shader) {
 
 void OpenGLGraphicsInterface::setAttributeInShader(Shader *shader, ProgramAttribute *attribute, AttributeBinding *attributeBinding) {
     GLuint attribLocation = *((GLuint*) attribute->platformData);
-    glVertexAttribPointer(attribLocation, attributeBinding->vertexData->countPerVertex, GL_FLOAT, false, 0, attributeBinding->vertexData->data.data());
+    
+    if(attributeBinding->vertexData->hasVBO) {
+        GLuint bufferID = *((GLuint*) attributeBinding->vertexData->platformData);
+        glBindBuffer(GL_ARRAY_BUFFER, bufferID);
+        glVertexAttribPointer(attribLocation, attributeBinding->vertexData->countPerVertex, GL_FLOAT, false, 0, NULL);
+        glBindBuffer(GL_ARRAY_BUFFER, 0);
+    } else {
+        glVertexAttribPointer(attribLocation, attributeBinding->vertexData->countPerVertex, GL_FLOAT, false, 0, attributeBinding->vertexData->data.data());
+    }
+    
     glEnableVertexAttribArray(attribLocation);
 }
 
@@ -206,7 +215,14 @@ GLenum OpenGLGraphicsInterface::getGLDrawMode(int polycodeMode) {
 }
 
 void OpenGLGraphicsInterface::drawIndices(int type, IndexDataArray *indexArray) {
+    if(indexArray->hasVBO) {
+        GLuint bufferID = *((GLuint*) indexArray->platformData);
+        glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, bufferID);
+        glDrawElements(getGLDrawMode(type), indexArray->data.size(), GL_UNSIGNED_INT, NULL);
+        glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0);
+    } else {
      glDrawElements(getGLDrawMode(type), indexArray->data.size(), GL_UNSIGNED_INT, indexArray->data.data());
+    }
 }
 
 void OpenGLGraphicsInterface::drawArrays(int type, unsigned int vertexCount) {
@@ -343,6 +359,39 @@ void OpenGLGraphicsInterface::createProgram(ShaderProgram *program) {
     *((GLuint*)program->platformData) = programID;
 }
 
+void OpenGLGraphicsInterface::createVertexBuffer(VertexDataArray *dataArray) {
+    if(dataArray->hasVBO) {
+            // delete vbo
+    } else {
+        dataArray->platformData = (new GLuint);
+    }
+    
+    GLuint bufferID;
+    glGenBuffers(1, &bufferID);
+    glBindBuffer(GL_ARRAY_BUFFER, bufferID);
+    glBufferData(GL_ARRAY_BUFFER, dataArray->getDataSize() * sizeof(PolyRendererVertexType), dataArray->getArrayData(), GL_STATIC_DRAW);
+    glBindBuffer(GL_ARRAY_BUFFER, 0);
+    dataArray->hasVBO = true;
+    *((GLuint*)dataArray->platformData) = bufferID;
+}
+
+void OpenGLGraphicsInterface::createIndexBuffer(IndexDataArray *dataArray) {
+
+    if(dataArray->hasVBO) {
+        // delete vbo
+    } else {
+        dataArray->platformData = (new GLuint);
+    }
+    
+    GLuint bufferID;
+    glGenBuffers(1, &bufferID);
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferID);
+    glBufferData(GL_ELEMENT_ARRAY_BUFFER, dataArray->getDataSize() * sizeof(PolyRendererIndexType), dataArray->getArrayData(), GL_STATIC_DRAW);
+    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+    dataArray->hasVBO = true;
+    *((GLuint*)dataArray->platformData) = bufferID;
+}
+
 void OpenGLGraphicsInterface::createShader(Shader *shader) {
     
     shader->expectedParams.clear();

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

@@ -24,8 +24,7 @@
 
 using namespace Polycode;
 
-RenderDataArray::RenderDataArray(unsigned int type) {
-    this->type = type;
+RenderDataArray::RenderDataArray(unsigned int type) : type(type), hasVBO(false), platformData(NULL) {
 }
 
 void *RenderDataArray::getArrayData() {

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

@@ -154,11 +154,16 @@ void RenderThread::processDrawBuffer(GPUDrawBuffer *buffer) {
                     AttributeBinding *attributeBinding = localShaderBinding->getAttributeBinding(a);
                     
                     if(attributeBinding) {
-                        if(!attributeBinding->attribute) {
-                            attributeBinding->attribute = shader->getAttribPointer(attributeBinding->name);
-                        }
-                        if(attributeBinding->attribute) {
-                             interface->setAttributeInShader(shader, attributeBinding->attribute, attributeBinding);
+                        if(attributeBinding->enabled) {
+                            
+                            if(!attributeBinding->attribute) {
+                                attributeBinding->attribute = shader->getAttribPointer(attributeBinding->name);
+                            }
+                            if(attributeBinding->attribute) {
+                                 interface->setAttributeInShader(shader, attributeBinding->attribute, attributeBinding);
+                            } else {
+                                attributeBinding->enabled = false;
+                            }
                         }
                     }
                     
@@ -176,7 +181,6 @@ void RenderThread::processDrawBuffer(GPUDrawBuffer *buffer) {
                     interface->disableAttribute(shader, attribute);
                 }
                 
-
             }
         }
     }
@@ -231,6 +235,17 @@ void RenderThread::processJob(const RendererThreadJob &job) {
             interface->createShader(shader);
         }
         break;
+        case JOB_CREATE_VERTEX_BUFFERS:
+        {
+            Mesh *mesh = (Mesh*) job.data;
+            
+            interface->createVertexBuffer(&mesh->vertexPositionArray);
+            interface->createVertexBuffer(&mesh->vertexTexCoordArray);
+            if(mesh->indexedMesh) {
+                interface->createIndexBuffer(&mesh->indexArray);
+            }
+        }
+        break;
     }
 }
 
@@ -342,6 +357,10 @@ ShaderProgram *Renderer::createProgram(const String &fileName) {
     return program;
 }
 
+void Renderer::createVertexBuffers(Mesh *mesh) {
+    renderThread->enqueueJob(RenderThread::JOB_CREATE_VERTEX_BUFFERS, (void*) mesh);
+}
+
 void Renderer::destroyTexture(Texture *texture) {
     
 }

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

@@ -191,7 +191,8 @@ void SceneMesh::setMaterial(Material *material) {
     localShaderOptions = new ShaderBinding();
     
     localShaderOptions->addAttributeBinding("texCoord", &mesh->vertexTexCoordArray);
-    localShaderOptions->addAttributeBinding("position", &mesh->vertexPositionArray);    
+    localShaderOptions->addAttributeBinding("position", &mesh->vertexPositionArray);
+    localShaderOptions->addAttributeBinding("normal", &mesh->vertexNormalArray);
 	
 }
 

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

@@ -453,6 +453,10 @@ LocalShaderParam *LocalShaderParam::Copy() {
     return copyParam;
 }
 
+AttributeBinding::AttributeBinding() : enabled(true), vertexData(NULL), attribute(NULL) {
+    
+}
+
 AttributeBinding *ShaderBinding::addAttributeBinding(const String &name, VertexDataArray *dataArray) {
     AttributeBinding *binding = new AttributeBinding();
     binding->name = name;