COpenGLGrassRenderer::COpenGLGrassRenderer(COpenGLRenderDevice *pRenderDevice) : m_pRenderDevice(pRenderDevice), m_GrassTextureID(0), m_vDefaultGrassSize(0.5f, 1.0f, 0.0f), m_nGrassClusterVBOID(0), m_nGrassClusterIndexVBOID(0), m_nGrassClusterVAOID(0), m_GrassClusterInstanceVBID(0) { m_GrassClusterInstanceArray.ensureStorageAllocated(INIT_GRASSCLUSTERINSTANCE_NUM); // Local Grass Cluster Vertex and Index /* 0 1 |-----------| | | | | | | |-----------| 3 2 */ uint16 grassIndex[6*3] = { 0, 2, 1, 0, 3, 2, 4, 6, 5, 4, 7, 6, 8, 10, 9, 8, 11, 10 }; SGPVertex_GRASS grassLocalVertex[4*3]; Vector3D OffsetVector(m_vDefaultGrassSize.x, 0, 0); Matrix4x4 RotMat; for( int i=-1; i<=1; i++ ) { RotMat.RotationY( i * 60.0f * pi_over_180 ); OffsetVector.RotateWith(RotMat); if( i == 0 ) OffsetVector.Set(m_vDefaultGrassSize.x, 0, 0); grassLocalVertex[(i+1)*4 + 0].x = -OffsetVector.x; grassLocalVertex[(i+1)*4 + 0].y = -OffsetVector.y; grassLocalVertex[(i+1)*4 + 0].z = -OffsetVector.z; grassLocalVertex[(i+1)*4 + 0].tu = 0; grassLocalVertex[(i+1)*4 + 0].tv = 0; grassLocalVertex[(i+1)*4 + 1].x = OffsetVector.x; grassLocalVertex[(i+1)*4 + 1].y = OffsetVector.y; grassLocalVertex[(i+1)*4 + 1].z = OffsetVector.z; grassLocalVertex[(i+1)*4 + 1].tu = 1; grassLocalVertex[(i+1)*4 + 1].tv = 0; grassLocalVertex[(i+1)*4 + 2].x = OffsetVector.x; grassLocalVertex[(i+1)*4 + 2].y = OffsetVector.y; grassLocalVertex[(i+1)*4 + 2].z = OffsetVector.z; grassLocalVertex[(i+1)*4 + 2].tu = 1; grassLocalVertex[(i+1)*4 + 2].tv = 1; grassLocalVertex[(i+1)*4 + 3].x = -OffsetVector.x; grassLocalVertex[(i+1)*4 + 3].y = -OffsetVector.y; grassLocalVertex[(i+1)*4 + 3].z = -OffsetVector.z; grassLocalVertex[(i+1)*4 + 3].tu = 0; grassLocalVertex[(i+1)*4 + 3].tv = 1; } GLsizei nStride = sizeof(SGPVertex_GRASS); // create one GrassCluster VAO and VBO m_pRenderDevice->extGlGenVertexArray(1, &m_nGrassClusterVAOID); m_pRenderDevice->extGlBindVertexArray(m_nGrassClusterVAOID); m_pRenderDevice->extGlGenBuffers(1, &m_nGrassClusterVBOID); m_pRenderDevice->extGlBindBuffer(GL_ARRAY_BUFFER, m_nGrassClusterVBOID); m_pRenderDevice->extGlBufferData(GL_ARRAY_BUFFER, 4*3*nStride, grassLocalVertex, GL_STATIC_DRAW); m_pRenderDevice->extGlEnableVertexAttribArray(0); m_pRenderDevice->extGlVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, nStride, (GLvoid *)BUFFER_OFFSET(0)); m_pRenderDevice->extGlEnableVertexAttribArray(1); m_pRenderDevice->extGlVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, nStride, (GLvoid *)BUFFER_OFFSET(3*sizeof(float))); // Instance VertexBuffer nStride = sizeof(SGPVertex_GRASS_Cluster); m_pRenderDevice->extGlGenBuffers(1, &m_GrassClusterInstanceVBID); m_pRenderDevice->extGlBindBuffer(GL_ARRAY_BUFFER, m_GrassClusterInstanceVBID); m_pRenderDevice->extGlBufferData(GL_ARRAY_BUFFER, INIT_GRASSCLUSTERINSTANCE_NUM * nStride, NULL, GL_STREAM_DRAW); m_pRenderDevice->extGlEnableVertexAttribArray(2); m_pRenderDevice->extGlVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, nStride, (GLvoid *)BUFFER_OFFSET(0)); m_pRenderDevice->extGlVertexAttribDivisor(2, 1); m_pRenderDevice->extGlEnableVertexAttribArray(3); m_pRenderDevice->extGlVertexAttribPointer(3, 4, GL_UNSIGNED_BYTE, GL_TRUE, nStride, (GLvoid *)BUFFER_OFFSET(4*sizeof(float))); m_pRenderDevice->extGlVertexAttribDivisor(3, 1); m_pRenderDevice->extGlEnableVertexAttribArray(4); m_pRenderDevice->extGlVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, nStride, (GLvoid *)BUFFER_OFFSET(4*sizeof(float)+4*sizeof(uint8))); m_pRenderDevice->extGlVertexAttribDivisor(4, 1); m_pRenderDevice->extGlEnableVertexAttribArray(5); m_pRenderDevice->extGlVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, nStride, (GLvoid *)BUFFER_OFFSET(8*sizeof(float)+4*sizeof(uint8))); m_pRenderDevice->extGlVertexAttribDivisor(5, 1); m_pRenderDevice->extGlGenBuffers(1, &m_nGrassClusterIndexVBOID); m_pRenderDevice->extGlBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_nGrassClusterIndexVBOID); m_pRenderDevice->extGlBufferData(GL_ELEMENT_ARRAY_BUFFER, 6*3*sizeof(uint16), grassIndex, GL_STATIC_DRAW); m_pRenderDevice->extGlBindVertexArray(0); }
COpenGLES2GrassRenderer::COpenGLES2GrassRenderer(COpenGLES2RenderDevice *pRenderDevice) : m_pRenderDevice(pRenderDevice), m_GrassTextureID(0), m_vDefaultGrassSize(0.5f, 1.0f, 0.0f), m_nGrassClusterVBOID(0), m_nGrassClusterIndexVBOID(0), m_nGrassClusterVAOID(0) { m_GrassClusterInstanceArray.ensureStorageAllocated(INIT_GRASSCLUSTERINSTANCE_NUM); // Local Grass Cluster Vertex and Index /* 0 1 |-----------| | | | | | | |-----------| 3 2 */ uint16 grassIndex[6*3] = { 0, 2, 1, 0, 3, 2, 4, 6, 5, 4, 7, 6, 8, 10, 9, 8, 11, 10 }; Vector3D OffsetVector(m_vDefaultGrassSize.x, 0, 0); Matrix4x4 RotMat; for( int i=-1; i<=1; i++ ) { RotMat.RotationY( i * 60.0f * pi_over_180 ); OffsetVector.RotateWith(RotMat); if( i == 0 ) OffsetVector.Set(m_vDefaultGrassSize.x, 0, 0); m_grassVertex[(i+1)*4 + 0].x = -OffsetVector.x; m_grassVertex[(i+1)*4 + 0].y = -OffsetVector.y; m_grassVertex[(i+1)*4 + 0].z = -OffsetVector.z; m_grassVertex[(i+1)*4 + 0].tu = 0; m_grassVertex[(i+1)*4 + 0].tv = 0; m_grassVertex[(i+1)*4 + 1].x = OffsetVector.x; m_grassVertex[(i+1)*4 + 1].y = OffsetVector.y; m_grassVertex[(i+1)*4 + 1].z = OffsetVector.z; m_grassVertex[(i+1)*4 + 1].tu = 1; m_grassVertex[(i+1)*4 + 1].tv = 0; m_grassVertex[(i+1)*4 + 2].x = OffsetVector.x; m_grassVertex[(i+1)*4 + 2].y = OffsetVector.y; m_grassVertex[(i+1)*4 + 2].z = OffsetVector.z; m_grassVertex[(i+1)*4 + 2].tu = 1; m_grassVertex[(i+1)*4 + 2].tv = 1; m_grassVertex[(i+1)*4 + 3].x = -OffsetVector.x; m_grassVertex[(i+1)*4 + 3].y = -OffsetVector.y; m_grassVertex[(i+1)*4 + 3].z = -OffsetVector.z; m_grassVertex[(i+1)*4 + 3].tu = 0; m_grassVertex[(i+1)*4 + 3].tv = 1; } GLsizei nStride = sizeof(SGPVertex_GRASS_GLES2); // create one GrassCluster VAO and VBO m_pRenderDevice->extGlGenVertexArray(1, &m_nGrassClusterVAOID); m_pRenderDevice->extGlBindVertexArray(m_nGrassClusterVAOID); glGenBuffers(1, &m_nGrassClusterVBOID); glBindBuffer(GL_ARRAY_BUFFER, m_nGrassClusterVBOID); glBufferData(GL_ARRAY_BUFFER, INIT_GRASSCLUSTERINSTANCE_NUM*4*3*nStride, NULL, GL_STREAM_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, nStride, (GLvoid *)BUFFER_OFFSET(0)); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, nStride, (GLvoid *)BUFFER_OFFSET(4*sizeof(float))); glEnableVertexAttribArray(2); glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, nStride, (GLvoid *)BUFFER_OFFSET(8*sizeof(float))); glEnableVertexAttribArray(3); glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, nStride, (GLvoid *)BUFFER_OFFSET(12*sizeof(float))); glGenBuffers(1, &m_nGrassClusterIndexVBOID); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_nGrassClusterIndexVBOID); glBufferData(GL_ELEMENT_ARRAY_BUFFER, INIT_GRASSCLUSTERINSTANCE_NUM*6*3*sizeof(uint16), NULL, GL_STATIC_DRAW); uint16* pGrassIndex = (uint16*)m_pRenderDevice->extGlMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY_OES); for( uint16 j=0; j<INIT_GRASSCLUSTERINSTANCE_NUM; j++ ) { for( int k=0; k<6*3; k++ ) pGrassIndex[ j*(6*3) + k ] = grassIndex[k] + j*(4*3); } m_pRenderDevice->extGlUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); m_pRenderDevice->extGlBindVertexArray(0); }