// Perf impact (test was only done on a gs dump): // Normal (fast): Message:Buffer detailed info: Buffer object 9 (bound to // GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_STREAM_COPY) will use VIDEO // memory as the source for buffer object operations. // // Persistent (slower): Message:Buffer detailed info: Buffer object 8 // (bound to GL_PIXEL_UNPACK_BUFFER_ARB, usage hint is GL_DYNAMIC_DRAW) // will use DMA CACHED memory as the source for buffer object operations void Init() { gl_GenBuffers(countof(m_pool), m_pool); m_texture_storage = GLLoader::found_GL_ARB_buffer_storage; // Code is really faster on MT driver. So far only nvidia support it if (!(GLLoader::nvidia_buggy_driver && theApp.GetConfig("enable_nvidia_multi_thread", 1))) m_texture_storage &= (theApp.GetConfig("ogl_texture_storage", 0) == 1); for (size_t i = 0; i < countof(m_pool); i++) { BindPbo(); if (m_texture_storage) { gl_BufferStorage(GL_PIXEL_UNPACK_BUFFER, m_pbo_size, NULL, create_flags); m_map[m_current_pbo] = (char*)gl_MapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, m_pbo_size, map_flags); m_fence[m_current_pbo] = 0; } else { gl_BufferData(GL_PIXEL_UNPACK_BUFFER, m_pbo_size, NULL, GL_STREAM_COPY); m_map[m_current_pbo] = NULL; } NextPbo(); } UnbindPbo(); }
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; } }