diff options
author | weigao <weigao@multicorewareinc.com> | 2014-06-18 08:21:41 -0700 |
---|---|---|
committer | Markus Mohrhard <markus.mohrhard@collabora.co.uk> | 2014-06-21 04:21:41 +0200 |
commit | 6ef4565efe0393bde8e792d66287a532aea82d31 (patch) | |
tree | 304950eac55a7672b8189402e31eaa9ddeb49928 /chart2 | |
parent | 50a5739cee2b26d9a70c321664f7166a32fa8647 (diff) |
add code to call batch texture render
Includes warning fixes from Markus Mohrhard.
Conflicts:
chart2/source/view/inc/GL3DRenderer.hxx
chart2/source/view/main/GL3DRenderer.cxx
Change-Id: I09da7c49eb11da9ea2bc18a5e13f2fd2c0d6bd8f
Diffstat (limited to 'chart2')
-rw-r--r-- | chart2/source/view/inc/GL3DRenderer.hxx | 42 | ||||
-rw-r--r-- | chart2/source/view/main/GL3DRenderer.cxx | 226 |
2 files changed, 257 insertions, 11 deletions
diff --git a/chart2/source/view/inc/GL3DRenderer.hxx b/chart2/source/view/inc/GL3DRenderer.hxx index 0821cfe67960..9c4c03ff955a 100644 --- a/chart2/source/view/inc/GL3DRenderer.hxx +++ b/chart2/source/view/inc/GL3DRenderer.hxx @@ -141,6 +141,26 @@ struct TextInfo float vertex[12]; }; +struct TextureArrayInfo +{ + size_t subTextureNum; + int textureArrayWidth; + int textureArrayHeight; + GLuint textureID; + + TextureArrayInfo(); +}; + +struct TextInfoBatch +{ + size_t batchNum; + std::vector<glm::vec4> idList; + std::vector<TextureArrayInfo> texture; + std::vector<glm::vec3> vertexList; + std::vector<glm::vec3> textureCoordList; +}; + + struct BatchBarInfo { std::vector <glm::mat4> modelMatrixList; @@ -231,6 +251,18 @@ private: void UpdateBatch3DUniformBlock(); void RenderBatchBars(bool bNewScene); void CheckGLSLVersion(); + void RenderTextShapeBatch(); + void ReleaseTextShapesBatch(); + void CreateTextTextureSingle(const boost::shared_array<sal_uInt8> &bitmapBuf, + ::Size maSizePixels, + glm::vec3 vTopLeft,glm::vec3 vTopRight, + glm::vec3 vBottomRight, glm::vec3 vBottomLeft, + sal_uInt32 nUniqueId); + void CreateTextTextureBatch(const boost::shared_array<sal_uInt8> &bitmapBuf, + ::Size maSizePixels, + glm::vec3 vTopLeft,glm::vec3 vTopRight, + glm::vec3 vBottomRight, glm::vec3 vBottomLeft, + sal_uInt32 nUniqueId); private: struct ShaderResources @@ -286,6 +318,14 @@ private: GLint m_3DBatchNormalID; GLint m_3DBatchColorID; + //Batch render text + bool mbTexBatchSupport; + GLint m_BatchTextProID; + GLint m_BatchTextMatrixID; + GLint m_BatchTextVertexID; + GLint m_BatchTextTexCoordID; + GLint m_BatchTextTexID; + ShaderResources(); ~ShaderResources(); @@ -358,6 +398,7 @@ private: std::vector <TextInfo> m_TextInfoList; std::vector <TextInfo> m_ScreenTextInfoList; GLuint m_TextTexCoordBuf; + GLuint m_TextTexCoordBufBatch; std::vector<glm::vec3> m_Vertices; @@ -388,6 +429,7 @@ private: GLint m_Batch3DActualSizeLight; glm::mat4 m_GlobalScaleMatrix; + TextInfoBatch m_TextInfoBatch; //for 3.0 version int m_iLightNum; glm::vec4 m_Ambient; diff --git a/chart2/source/view/main/GL3DRenderer.cxx b/chart2/source/view/main/GL3DRenderer.cxx index d3db57c572c7..06a1163f2cc1 100644 --- a/chart2/source/view/main/GL3DRenderer.cxx +++ b/chart2/source/view/main/GL3DRenderer.cxx @@ -71,6 +71,14 @@ glm::vec4 getColorAsVector(sal_uInt32 nColor) } +TextureArrayInfo::TextureArrayInfo(): + subTextureNum(0), + textureArrayWidth(0), + textureArrayHeight(0), + textureID(0) +{ +} + OpenGL3DRenderer::OpenGL3DRenderer(): m_iWidth(0) , m_iHeight(0) @@ -111,6 +119,7 @@ OpenGL3DRenderer::OpenGL3DRenderer(): OpenGL3DRenderer::~OpenGL3DRenderer() { + ReleaseShapes(); // delete buffers glDeleteBuffers(1, &m_CubeVertexBuf); glDeleteBuffers(1, &m_CubeNormalBuf); @@ -126,10 +135,18 @@ OpenGL3DRenderer::~OpenGL3DRenderer() glDeleteBuffers(1, &m_Batch3DUBOBuffer); glDeleteBuffers(1, &m_3DUBOBuffer); glDeleteBuffers(1, &m_3DUBOBuffer); + glDeleteBuffers(1, &m_TextTexCoordBufBatch); glDeleteFramebuffers(1, &mnPickingFbo); glDeleteRenderbuffers(1, &mnPickingRboDepth); glDeleteRenderbuffers(1, &mnPickingRboColor); + + for (size_t i = 0; i < m_TextInfoBatch.texture.size(); i++) + { + glDeleteTextures(1, &m_TextInfoBatch.texture[i].textureID); + } + m_TextInfoBatch.texture.clear(); + } OpenGL3DRenderer::ShaderResources::ShaderResources() @@ -162,6 +179,12 @@ OpenGL3DRenderer::ShaderResources::ShaderResources() , m_3DBatchVertexID(0) , m_3DBatchNormalID(0) , m_3DBatchColorID(0) + , mbTexBatchSupport(false) + , m_BatchTextProID(0) + , m_BatchTextMatrixID(0) + , m_BatchTextVertexID(0) + , m_BatchTextTexCoordID(0) + , m_BatchTextTexID(0) { } @@ -172,6 +195,7 @@ OpenGL3DRenderer::ShaderResources::~ShaderResources() glDeleteProgram(m_ScreenTextProID); glDeleteProgram(m_3DProID); glDeleteProgram(m_3DBatchProID); + glDeleteProgram(m_BatchTextProID); } void OpenGL3DRenderer::CheckGLSLVersion() @@ -227,6 +251,27 @@ void OpenGL3DRenderer::ShaderResources::LoadShaders() m_3DBatchVertexID = glGetAttribLocation(m_3DBatchProID, "vertexPositionModelspace"); m_3DBatchNormalID = glGetAttribLocation(m_3DBatchProID, "vertexNormalModelspace"); m_3DBatchColorID = glGetAttribLocation(m_3DBatchProID, "barColor"); + //check whether the texture array is support + GLint numExtensions = 0; + glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions); + for( GLint i = 0; i < numExtensions; ++i ) + { + OUString currExt = ::rtl::OUString::createFromAscii((char*)glGetStringi(GL_EXTENSIONS, i)); + if (currExt == "GL_EXT_texture_array") + { + mbTexBatchSupport = true; + break; + } + } + if (mbTexBatchSupport) + { + m_BatchTextProID = OpenGLHelper::LoadShaders("textVertexShaderBatch", "textFragmentShaderBatch"); + m_BatchTextMatrixID = glGetUniformLocation(m_BatchTextProID, "MVP"); + m_BatchTextTexID = glGetUniformLocation(m_BatchTextProID, "texArray"); + m_BatchTextVertexID = glGetAttribLocation(m_BatchTextProID, "vPosition"); + m_BatchTextTexCoordID = glGetAttribLocation(m_BatchTextProID, "texCoord"); + } + mbTexBatchSupport = m_BatchTextProID ? true : false; } else { @@ -250,11 +295,14 @@ void OpenGL3DRenderer::ShaderResources::LoadShaders() m_3DVertexID = glGetAttribLocation(m_3DProID, "vertexPositionModelspace"); m_3DNormalID = glGetAttribLocation(m_3DProID, "vertexNormalModelspace"); } - m_TextProID = OpenGLHelper::LoadShaders("textVertexShader", "textFragmentShader"); - m_TextMatrixID = glGetUniformLocation(m_TextProID, "MVP"); - m_TextVertexID = glGetAttribLocation(m_TextProID, "vPosition"); - m_TextTexCoordID = glGetAttribLocation(m_TextProID, "texCoord"); - m_TextTexID = glGetUniformLocation(m_TextProID, "TextTex"); + if (!mbTexBatchSupport) + { + m_TextProID = OpenGLHelper::LoadShaders("textVertexShader", "textFragmentShader"); + m_TextMatrixID = glGetUniformLocation(m_TextProID, "MVP"); + m_TextVertexID = glGetAttribLocation(m_TextProID, "vPosition"); + m_TextTexCoordID = glGetAttribLocation(m_TextProID, "texCoord"); + m_TextTexID = glGetUniformLocation(m_TextProID, "TextTex"); + } m_ScreenTextProID = OpenGLHelper::LoadShaders("screenTextVertexShader", "screenTextFragmentShader"); m_ScreenTextVertexID = glGetAttribLocation(m_ScreenTextProID, "vPosition"); @@ -326,6 +374,7 @@ void OpenGL3DRenderer::init() glGenBuffers(1, &m_BatchModelMatrixBuf); glGenBuffers(1, &m_BatchNormalMatrixBuf); glGenBuffers(1, &m_BatchColorBuf); + glGenBuffers(1, &m_TextTexCoordBufBatch); glGenBuffers(1, &m_BoundBox); glBindBuffer(GL_ARRAY_BUFFER, m_BoundBox); glBufferData(GL_ARRAY_BUFFER, sizeof(boundBox), boundBox, GL_STATIC_DRAW); @@ -367,6 +416,7 @@ void OpenGL3DRenderer::init() Init3DUniformBlock(); InitBatch3DUniformBlock(); } + m_TextInfoBatch.batchNum = 512; CHECK_GL_ERROR(); glViewport(0, 0, m_iWidth, m_iHeight); Set3DSenceInfo(0xFFFFFF, true); @@ -1631,11 +1681,11 @@ void OpenGL3DRenderer::CreateScreenTextTexture( m_ScreenTextInfoList.push_back(aTextInfo); } -void OpenGL3DRenderer::CreateTextTexture(const boost::shared_array<sal_uInt8> &bitmapBuf, - ::Size maSizePixels, - const glm::vec3& vTopLeft, const glm::vec3& vTopRight, - const glm::vec3& vBottomRight, const glm::vec3& vBottomLeft, - sal_uInt32 nUniqueId) +void OpenGL3DRenderer::CreateTextTextureSingle(const boost::shared_array<sal_uInt8> &bitmapBuf, + ::Size maSizePixels, + glm::vec3 vTopLeft,glm::vec3 vTopRight, + glm::vec3 vBottomRight, glm::vec3 vBottomLeft, + sal_uInt32 nUniqueId) { long bmpWidth = maSizePixels.Width(); long bmpHeight = maSizePixels.Height(); @@ -1676,6 +1726,92 @@ void OpenGL3DRenderer::CreateTextTexture(const boost::shared_array<sal_uInt8> &b glBindTexture(GL_TEXTURE_2D, 0); CHECK_GL_ERROR(); m_TextInfoList.push_back(aTextInfo); + +} + + +void OpenGL3DRenderer::CreateTextTextureBatch(const boost::shared_array<sal_uInt8> &bitmapBuf, + ::Size maSizePixels, + glm::vec3 vTopLeft,glm::vec3 vTopRight, + glm::vec3 vBottomRight, glm::vec3 vBottomLeft, + sal_uInt32 nUniqueId) +{ + long bmpWidth = maSizePixels.Width(); + long bmpHeight = maSizePixels.Height(); + glm::vec4 id = getColorAsVector(nUniqueId); + m_TextInfoBatch.idList.push_back(id); + m_TextInfoBatch.vertexList.push_back(glm::vec3(vBottomRight.x, vBottomRight.y, vBottomRight.z)); + m_TextInfoBatch.vertexList.push_back(glm::vec3(vTopRight.x, vTopRight.y, vTopRight.z)); + m_TextInfoBatch.vertexList.push_back(glm::vec3(vTopLeft.x, vTopLeft.y, vTopLeft.z)); + m_TextInfoBatch.vertexList.push_back(glm::vec3(vBottomLeft.x, vBottomLeft.y, vBottomLeft.z)); + //find the last vector, which size is small than default batch number; + size_t index = 0; + while ((m_TextInfoBatch.texture.size() > 0) && + (m_TextInfoBatch.texture[index].subTextureNum >= m_TextInfoBatch.batchNum) && + (index < m_TextInfoBatch.texture.size() - 1)) + { + index++; + } + //if the sub texture number of the last texture array reach the largest, create a new textur array + if ((m_TextInfoBatch.texture.size() == 0) || + (m_TextInfoBatch.texture[index].subTextureNum >= m_TextInfoBatch.batchNum)) + { + TextureArrayInfo textureArray; + glGenTextures(1, &textureArray.textureID); + CHECK_GL_ERROR(); + glBindTexture(GL_TEXTURE_2D_ARRAY, textureArray.textureID); + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + CHECK_GL_ERROR(); + textureArray.textureArrayWidth = bmpHeight * 8; + textureArray.textureArrayHeight = bmpHeight; + glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGB, textureArray.textureArrayWidth, textureArray.textureArrayHeight, + m_TextInfoBatch.batchNum, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + CHECK_GL_ERROR(); + if (m_TextInfoBatch.texture.size() > 0) + { + index++; + } + m_TextInfoBatch.texture.push_back(textureArray); + glBindTexture(GL_TEXTURE_2D_ARRAY, 0); + } + glBindTexture(GL_TEXTURE_2D_ARRAY, m_TextInfoBatch.texture[index].textureID); + CHECK_GL_ERROR(); + glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, m_TextInfoBatch.texture[index].subTextureNum, bmpWidth, bmpHeight, 1, GL_RGB, GL_UNSIGNED_BYTE, bitmapBuf.get()); + CHECK_GL_ERROR(); + //calc texture coordinate + m_TextInfoBatch.textureCoordList.push_back(glm::vec3((float)bmpWidth / (float)m_TextInfoBatch.texture[index].textureArrayWidth, + 0, + m_TextInfoBatch.texture[index].subTextureNum)); + m_TextInfoBatch.textureCoordList.push_back(glm::vec3((float)bmpWidth / (float)m_TextInfoBatch.texture[index].textureArrayWidth, + (float)bmpHeight/ (float)m_TextInfoBatch.texture[index].textureArrayHeight, + m_TextInfoBatch.texture[index].subTextureNum)); + m_TextInfoBatch.textureCoordList.push_back(glm::vec3(0, + (float)bmpHeight/ (float)m_TextInfoBatch.texture[index].textureArrayHeight, + m_TextInfoBatch.texture[index].subTextureNum)); + m_TextInfoBatch.textureCoordList.push_back(glm::vec3(0, + 0, + m_TextInfoBatch.texture[index].subTextureNum)); + m_TextInfoBatch.texture[index].subTextureNum++; + glBindTexture(GL_TEXTURE_2D_ARRAY, 0); +} + +void OpenGL3DRenderer::CreateTextTexture(const boost::shared_array<sal_uInt8> &bitmapBuf, + ::Size maSizePixels, + const glm::vec3& vTopLeft, const glm::vec3& vTopRight, + const glm::vec3& vBottomRight, const glm::vec3& vBottomLeft, + sal_uInt32 nUniqueId) +{ + if (maResources.mbTexBatchSupport) + { + CreateTextTextureBatch(bitmapBuf, maSizePixels, vTopLeft, vTopRight, vBottomRight, vBottomLeft, nUniqueId); + } + else + { + CreateTextTextureSingle(bitmapBuf, maSizePixels, vTopLeft, vTopRight, vBottomRight, vBottomLeft, nUniqueId); + } } void OpenGL3DRenderer::ReleaseTextShapes() @@ -1753,7 +1889,67 @@ void OpenGL3DRenderer::RenderScreenTextShape() } CHECK_GL_ERROR(); } +void OpenGL3DRenderer::ReleaseTextShapesBatch() +{ + for (size_t i = 0; i < m_TextInfoBatch.texture.size(); i++) + { + m_TextInfoBatch.texture[i].subTextureNum = 0; + } + m_TextInfoBatch.vertexList.clear(); + m_TextInfoBatch.textureCoordList.clear(); + m_TextInfoBatch.idList.clear(); +} +void OpenGL3DRenderer::RenderTextShapeBatch() +{ + glm::mat4 aMVP = m_3DProjection * m_3DView * m_GlobalScaleMatrix; + glUseProgram(maResources.m_BatchTextProID); + CHECK_GL_ERROR(); + glUniformMatrix4fv(maResources.m_BatchTextMatrixID, 1, GL_FALSE, &aMVP[0][0]); + glEnableVertexAttribArray(maResources.m_BatchTextVertexID); + glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer); + glVertexAttribPointer( + maResources.m_BatchTextVertexID, + 3, // size + GL_FLOAT, // type + GL_FALSE, // normalized? + 0, // stride + (void*)0 // array buffer offset + ); + //tex coord + CHECK_GL_ERROR(); + glEnableVertexAttribArray(maResources.m_BatchTextTexCoordID); + glBindBuffer(GL_ARRAY_BUFFER, m_TextTexCoordBufBatch); + glVertexAttribPointer( + maResources.m_BatchTextTexCoordID, + 3, // size + GL_FLOAT, // type + GL_FALSE, // normalized? + 0, // stride + (void*)0 // array buffer offset + ); + //use texture array to get the vertex + for (size_t i = 0; i < m_TextInfoBatch.texture.size(); i++) + { + int vertexNum = m_TextInfoBatch.texture[i].subTextureNum; + glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer); + glBufferData(GL_ARRAY_BUFFER, 4 * vertexNum * sizeof(glm::vec3), &m_TextInfoBatch.vertexList[4 * i * m_TextInfoBatch.batchNum], GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, m_TextTexCoordBufBatch); + glBufferData(GL_ARRAY_BUFFER, 4 * vertexNum * sizeof(glm::vec3), &m_TextInfoBatch.textureCoordList[4 * i * m_TextInfoBatch.batchNum], GL_STATIC_DRAW); + glBindTexture(GL_TEXTURE_2D_ARRAY, m_TextInfoBatch.texture[i].textureID); + CHECK_GL_ERROR(); + glUniform1i(maResources.m_BatchTextTexID, 0); + CHECK_GL_ERROR(); + //TODO: moggi: get rid fo GL_QUADS + glDrawArrays(GL_QUADS, 0, 4 * vertexNum); + } + glDisableVertexAttribArray(maResources.m_BatchTextVertexID); + CHECK_GL_ERROR(); + glDisableVertexAttribArray(maResources.m_BatchTextTexCoordID); + CHECK_GL_ERROR(); + glBindTexture(GL_TEXTURE_2D_ARRAY, 0); + glUseProgram(0); +} void OpenGL3DRenderer::RenderTextShape() { CHECK_GL_ERROR(); @@ -1869,7 +2065,14 @@ void OpenGL3DRenderer::ProcessUnrenderedShape(bool bNewScene) } } //render text - RenderTextShape(); + if (maResources.mbTexBatchSupport) + { + RenderTextShapeBatch(); + } + else + { + RenderTextShape(); + } // render screen text RenderScreenTextShape(); #if DEBUG_FBO @@ -1929,6 +2132,7 @@ void OpenGL3DRenderer::ReleaseShapes() ReleaseTextShapes(); ReleaseScreenTextShapes(); ReleaseBatchBarInfo(); + ReleaseTextShapesBatch(); } void OpenGL3DRenderer::GetBatchMiddleInfo(const Extrude3DInfo &extrude3D) |