void Destroy() { if (m_texture_storage) { for (size_t i = 0; i < countof(m_pool); i++) { m_map[i] = NULL; m_offset[i] = 0; gl_DeleteSync(m_fence[i]); // Don't know if we must do it gl_BindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pool[i]); gl_UnmapBuffer(GL_PIXEL_UNPACK_BUFFER); } gl_BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); } gl_DeleteBuffers(countof(m_pool), m_pool); }
void UnbindPbo() { gl_BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); }
void BindPbo() { gl_BindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pool[m_current_pbo]); }
void GLSLStaticViewer::render(const Camera& cam, const bouge::AffineMatrix& model) const { // This is a small, but effective, optimization that unfortunately GCC doesn't do. static const std::string uModelViewProjectionMatrix = "uModelViewProjectionMatrix"; static const std::string uModelViewMatrix = "uModelViewMatrix"; static const std::string uNormalMatrix = "uNormalMatrix"; static const std::string uAmbient = "uAmbient"; static const std::string ambient = "ambient"; static const std::string ambient2 = "uMaterialAmbient"; static const std::string uDiffuse = "uDiffuse"; static const std::string diffuse = "diffuse"; static const std::string diffuse2 = "uMaterialDiffuse"; static const std::string uSpecular = "uSpecular"; static const std::string specular = "specular"; static const std::string specular2 = "uMaterialSpecular"; static const std::string uShininess = "uShininess"; static const std::string shininess = "shininess"; static const std::string uDiffTex = "uDiffTex"; Viewer::render(cam, model); m_shaderToUse->use(); AffineMatrix mv = cam.view() * model; AffineMatrix id = mv * mv.inverse(); m_shaderToUse->uniformMatrix4fv(uModelViewProjectionMatrix, 1, false, (cam.viewproj() * model).array16f()); m_shaderToUse->uniformMatrix4fv(uModelViewMatrix, 1, false, mv.array16f()); m_shaderToUse->uniformMatrix3fv(uNormalMatrix, 1, true, mv.array9fInverse()); gl_BindVertexArray(m_VAOIds[0]); // Now, render each submesh of the mesh one after. It may need to get split // for example if it has too many bones. for(CoreHardwareMesh::iterator i = m_hwmesh->begin() ; i != m_hwmesh->end() ; ++i) { const CoreHardwareSubMesh& submesh = *i; // We set the per-submesh material options. // Here, we can assume the material exists, as we did the // "integrity checks" after the loading already. CoreMaterialPtr pMat = m_modelInst->materialForSubmesh(submesh.submeshName()); if(pMat->hasProprety(ambient)) { m_shaderToUse->uniform3fv(uAmbient, 1, &pMat->propretyAsFvec(ambient)[0]); } else if(pMat->hasProprety(ambient2)) { m_shaderToUse->uniform3fv(uAmbient, 1, &pMat->propretyAsFvec(ambient2)[0]); } if(pMat->hasProprety(diffuse)) { m_shaderToUse->uniform3fv(uDiffuse, 1, &pMat->propretyAsFvec(diffuse)[0]); } else if(pMat->hasProprety(diffuse2)) { m_shaderToUse->uniform3fv(uDiffuse, 1, &pMat->propretyAsFvec(diffuse2)[0]); } if(pMat->hasProprety(specular)) { m_shaderToUse->uniform3fv(uSpecular, 1, &pMat->propretyAsFvec(specular)[0]); if(pMat->hasProprety(shininess)) { m_shaderToUse->uniformf(uShininess, pMat->propretyAsFvec(shininess)[0]); } } else if(pMat->hasProprety(specular2)) { m_shaderToUse->uniform3fv(uSpecular, 1, &pMat->propretyAsFvec(specular2)[0]); m_shaderToUse->uniformf(uShininess, pMat->propretyAsFvec(specular2)[3]); } if(pMat->userData) { static_cast<TextureUserData*>(pMat->userData.get())->tex->selectTexture(0); m_shaderToUse->uniformi(uDiffTex, 0); } glDrawElements(GL_TRIANGLES, submesh.faceCount() * m_hwmesh->indicesPerFace(), BOUGE_FACE_INDEX_TYPE_GL, (const GLvoid*)(submesh.startIndex()*sizeof(BOUGE_FACE_INDEX_TYPE))); } gl_BindVertexArray(0); gl_BindBuffer(GL_ARRAY_BUFFER, 0); gl_BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); checkError("GLSLStaticViewer::render"); }
void GLSLStaticViewer::loadHardwareMesh(bool stride) { gl_GenBuffers(dimension_of(m_VBOIds), m_VBOIds); gl_GenVertexArrays(dimension_of(m_VAOIds), m_VAOIds); gl_BindVertexArray(m_VAOIds[0]); m_hwmesh = CoreHardwareMeshPtr(new CoreHardwareMesh(m_model->mesh(), 0, 0, 3)); // We allow two names for stuff just to be more compatible. std::string normal = m_hwmesh->hasAttrib("aVertexNormal") ? "aVertexNormal" : "normal"; std::string texco = m_hwmesh->hasAttrib("aVertexTextureCo") ? "aVertexTextureCo" : "texcoord0"; if(stride) { bool hasTexCo = m_hwmesh->hasAttrib(texco); m_shaderToUse = hasTexCo ? m_shaderWithTexture : m_shaderNoTexture; std::size_t coordsOffset = 0; std::size_t normalsOffset = m_hwmesh->coordsPerVertex(); std::size_t texCoOffset = normalsOffset + m_hwmesh->attribCoordsPerVertex(normal); std::size_t floatsPerVertex = texCoOffset + (hasTexCo ? m_hwmesh->attribCoordsPerVertex(texco) : 0); m_stride = floatsPerVertex * sizeof(float); // Here, we compile all the vertex data into a single interleaved buffer. std::vector<float> data(floatsPerVertex * m_hwmesh->vertexCount()); m_hwmesh->writeCoords(&data[coordsOffset], m_stride); m_hwmesh->writeAttrib(normal, &data[normalsOffset], m_stride); if(hasTexCo) m_hwmesh->writeAttrib(texco, &data[texCoOffset], m_stride); // Upload that data into the VBO gl_BindBuffer(GL_ARRAY_BUFFER, m_VBOIds[1]); gl_BufferData(GL_ARRAY_BUFFER, data.size() * sizeof(float), &data[0], GL_STATIC_DRAW); // And setup the vertex attribute positions. gl_EnableVertexAttribArray(m_shaderToUse->attrib("aVertex")); gl_VertexAttribPointer(m_shaderToUse->attrib("aVertex"), m_hwmesh->coordsPerVertex(), GL_FLOAT, GL_FALSE, m_stride, (const GLvoid*)(coordsOffset * sizeof(float))); if(m_shaderToUse->hasAttrib("aNormal")) { gl_EnableVertexAttribArray(m_shaderToUse->attrib("aNormal")); gl_VertexAttribPointer(m_shaderToUse->attrib("aNormal"), m_hwmesh->attribCoordsPerVertex(normal), GL_FLOAT, GL_FALSE, m_stride, (const GLvoid*)(normalsOffset * sizeof(float))); } if(hasTexCo && m_shaderToUse->hasAttrib("aTexCo")) { gl_EnableVertexAttribArray(m_shaderToUse->attrib("aTexCo")); gl_VertexAttribPointer(m_shaderToUse->attrib("aTexCo"), m_hwmesh->attribCoordsPerVertex(texco), GL_FLOAT, GL_FALSE, m_stride, (const GLvoid*)(texCoOffset * sizeof(float))); } } else { // TODO use unstrided VBOs too. } // Faces work in the same way, regardless the vertex format. // Here, we only support triangles. gl_BindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_VBOIds[0]); gl_BufferData(GL_ELEMENT_ARRAY_BUFFER, m_hwmesh->faceCount() * m_hwmesh->indicesPerFace() * sizeof(BOUGE_FACE_INDEX_TYPE), &m_hwmesh->faceIndices()[0], GL_STATIC_DRAW); gl_BindVertexArray(0); std::cout << "The hardware mesh has " << m_hwmesh->vertexCount() << " vertices and " << m_hwmesh->faceCount() << " faces." << std::endl; std::cout << "It has been subdivided in the following " << m_hwmesh->submeshCount() << " submeshes:" << std::endl; for(CoreHardwareMesh::iterator i = m_hwmesh->begin() ; i != m_hwmesh->end() ; ++i) { std::cout << " * submesh with " << i->faceCount() << " faces, " << i->boneCount() << " bones, start index: " << i->startIndex() << std::endl; } }