void TestGame::engine_render() { buffer_clear(); static float rot = 0; rot += PI / 120; if (rot > 4 * PI) rot -= 4 * PI; camera_.x = (float)sin(rot) * 2.5f; camera_.y = -0.3f; camera_.z = (float)cos(rot) * 2.5f; Matrix4 viewMatrix = matrix_look_at(camera_, Vector3(0, 0, 0), vector_up()); Matrix4 projectionMatrix = matrix_perspective(0.1f, ((float)ENGINE_WIDTH) / ENGINE_HEIGHT, 0.01f, 1.0f); for (int i = 0; i < meshes_count_; i++) { Matrix4 transform = meshes_[i].world * viewMatrix * projectionMatrix; for (int j = 0; j < meshes_[i].face_count; j++) draw_triangle( project(meshes_[i].vertices[meshes_[i].faces[j].a], transform), project(meshes_[i].vertices[meshes_[i].faces[j].b], transform), project(meshes_[i].vertices[meshes_[i].faces[j].c], transform), meshes_[i].texture); } }
// -------------------------------------------------------------------------------------------------------------------- void SimpleSolution::Render(const std::vector<Matrix>& _transforms) { assert(_transforms.size() <= INT_MAX); int xformCount = (int)_transforms.size(); // Program Vec3 dir = { -0.5f, -1, 1 }; Vec3 at = { 0, 0, 0 }; Vec3 up = { 0, 0, 1 }; dir = normalize(dir); Vec3 eye = at - 5 * dir; Matrix view = matrix_look_at(eye, at, up); Matrix view_proj = mProj * view; glUseProgram(mProgram); // Input Layout glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer); glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(RotationCubeProblem::Vertex), (void*)offsetof(RotationCubeProblem::Vertex, pos)); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(RotationCubeProblem::Vertex), (void*)offsetof(RotationCubeProblem::Vertex, normal)); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(RotationCubeProblem::Vertex), (void*)offsetof(RotationCubeProblem::Vertex, texcoord)); glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(RotationCubeProblem::Vertex), (void*)offsetof(RotationCubeProblem::Vertex, color)); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glEnableVertexAttribArray(2); glEnableVertexAttribArray(3); // Rasterizer State glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); glDisable(GL_SCISSOR_TEST); // Blend State glDisable(GL_BLEND); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // Depth Stencil State glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glBindBuffer(GL_UNIFORM_BUFFER, mUniformBuffer1); char *dst = &mStorage[0]; *(Matrix *)dst = view_proj; //BufferData(GL_UNIFORM_BUFFER, mStorage, GL_DYNAMIC_DRAW); glBufferData(GL_UNIFORM_BUFFER, sizeof(Matrix), &(view_proj.x.x), GL_DYNAMIC_DRAW); glBindBuffer(GL_UNIFORM_BUFFER, mUniformBuffer0); static unsigned int batchIndex = 0; batchIndex = batchIndex % _transforms.size(); *(Matrix *)dst = _transforms[1]; BufferData(GL_UNIFORM_BUFFER, mStorage, GL_DYNAMIC_DRAW); glBindBuffer(GL_UNIFORM_BUFFER, 0); glBindBufferRange(GL_UNIFORM_BUFFER, 0, mUniformBuffer0, 0, sizeof(Matrix)); glBindBufferRange(GL_UNIFORM_BUFFER, 1, mUniformBuffer1, 0, sizeof(Matrix)); glDrawElements(GL_TRIANGLES, mIndexCount, GL_UNSIGNED_SHORT, nullptr); }
// -------------------------------------------------------------------------------------------------------------------- void TexturedQuadsGLNaive::Render(const std::vector<Matrix>& _transforms) { // Program Vec3 dir = { 0, 0, 1 }; Vec3 at = { 0, 0, 0 }; Vec3 up = { 0, 1, 0 }; dir = normalize(dir); Vec3 eye = at - 250 * dir; Matrix view = matrix_look_at(eye, at, up); Matrix view_proj = mProj * view; glUseProgram(mProgram); glUniformMatrix4fv(mUniformLocation.ViewProjection, 1, GL_TRUE, &view_proj.x.x); // We will bind the texture we care about to unit 0, so let the program know now. glUniform1i(mUniformLocation.gTex, 0); // Rasterizer State glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); glFrontFace(GL_CCW); glDisable(GL_SCISSOR_TEST); // Blend State glDisable(GL_BLEND); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // Depth Stencil State glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); size_t xformCount = _transforms.size(); assert(xformCount <= mObjectCount); // Code below assumes at least 1 texture. assert(mTextures.size() > 0); auto texIt = mTextures.begin(); for (size_t u = 0; u < xformCount; ++u) { if (texIt == mTextures.end()) { texIt = mTextures.begin(); } GLuint activeTex = *texIt; ++texIt; glActiveTexture(GL_TEXTURE0 + 0); glBindTexture(GL_TEXTURE_2D, activeTex); Matrix world = transpose(_transforms[u]); glUniformMatrix4fv(mUniformLocation.World, 1, GL_TRUE, &world.x.x); glDrawElements(GL_TRIANGLES, mIndexCount, GL_UNSIGNED_SHORT, nullptr); } }
// -------------------------------------------------------------------------------------------------------------------- void TexturedQuadsGLTextureArrayUniform::Render(const std::vector<Matrix>& _transforms) { // Program Vec3 dir = { 0, 0, 1 }; Vec3 at = { 0, 0, 0 }; Vec3 up = { 0, 1, 0 }; dir = normalize(dir); Vec3 eye = at - 250 * dir; Matrix view = matrix_look_at(eye, at, up); Matrix view_proj = mProj * view; glUseProgram(mProgram); glUniformMatrix4fv(mUniformLocation.ViewProjection, 1, GL_TRUE, &view_proj.x.x); glUniform1iv(mUniformLocation.TexContainer, mTexUnits.size(), mTexUnits.data()); // Input Layout. First the IB glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer); // Then the VBs. glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(TexturedQuadsProblem::Vertex), (void*)offsetof(TexturedQuadsProblem::Vertex, pos)); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedQuadsProblem::Vertex), (void*)offsetof(TexturedQuadsProblem::Vertex, tex)); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); // Rasterizer State glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); glFrontFace(GL_CCW); glDisable(GL_SCISSOR_TEST); // Blend State glDisable(GL_BLEND); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // Depth Stencil State glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glBindBuffer(GL_SHADER_STORAGE_BUFFER, mTransformBuffer); BufferData(GL_SHADER_STORAGE_BUFFER, _transforms, GL_DYNAMIC_DRAW); size_t xformCount = _transforms.size(); assert(xformCount <= mObjectCount); for (size_t u = 0; u < xformCount; ++u) { glUniform1i(mUniformLocation.DrawID, u); glDrawElements(GL_TRIANGLES, mIndexCount, GL_UNSIGNED_SHORT, 0); } }
// -------------------------------------------------------------------------------------------------------------------- void TexturedQuadsGLTextureArrayMultiDrawBuffer::Render(const std::vector<Matrix>& _transforms) { // Program Vec3 dir = { 0, 0, 1 }; Vec3 at = { 0, 0, 0 }; Vec3 up = { 0, 1, 0 }; dir = normalize(dir); Vec3 eye = at - 250 * dir; Matrix view = matrix_look_at(eye, at, up); Matrix view_proj = mProj * view; glUseProgram(mProgram); glUniformMatrix4fv(mUniformLocation.ViewProjection, 1, GL_TRUE, &view_proj.x.x); glUniform1iv(mUniformLocation.TexContainer, mTexUnits.size(), mTexUnits.data()); // Rasterizer State glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); glFrontFace(GL_CCW); glDisable(GL_SCISSOR_TEST); // Blend State glDisable(GL_BLEND); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // Depth Stencil State glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glBindBuffer(GL_SHADER_STORAGE_BUFFER, mTransformBuffer); BufferData(GL_SHADER_STORAGE_BUFFER, _transforms, GL_DYNAMIC_DRAW); size_t xformCount = _transforms.size(); assert(xformCount <= mObjectCount); for (size_t u = 0; u < xformCount; ++u) { DrawElementsIndirectCommand *cmd = &m_commands[u]; cmd->count = mIndexCount; cmd->instanceCount = 1; cmd->firstIndex = 0; cmd->baseVertex = 0; cmd->baseInstance = u; } glBindBuffer(GL_DRAW_INDIRECT_BUFFER, mCommandBuffer); glBufferData(GL_DRAW_INDIRECT_BUFFER, xformCount * sizeof(DrawElementsIndirectCommand), m_commands.data(), GL_DYNAMIC_DRAW); glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, nullptr, xformCount, 0); }
// -------------------------------------------------------------------------------------------------------------------- void UntexturedObjectsGLTexCoord::Render(const std::vector<Matrix>& _transforms) { // Program Vec3 dir = { -0.5f, -1, 1 }; Vec3 at = { 0, 0, 0 }; Vec3 up = { 0, 0, 1 }; dir = normalize(dir); Vec3 eye = at - 250 * dir; Matrix view = matrix_look_at(eye, at, up); Matrix view_proj = mProj * view; glUseProgram(m_prog); glUniformMatrix4fv(mUniformLocation.ViewProjection, 1, GL_TRUE, &view_proj.x.x); // Input Layout glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ib); glBindBuffer(GL_ARRAY_BUFFER, m_vb); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(UntexturedObjectsProblem::Vertex), (void*)offsetof(UntexturedObjectsProblem::Vertex, pos)); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(UntexturedObjectsProblem::Vertex), (void*)offsetof(UntexturedObjectsProblem::Vertex, color)); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); // Rasterizer State glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); glDisable(GL_SCISSOR_TEST); // Blend State glDisable(GL_BLEND); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // Depth Stencil State glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); for (auto it = _transforms.begin(); it != _transforms.end(); ++it) { const Matrix* m = &*it; glVertexAttrib4f(2, m->x.x, m->x.y, m->x.z, m->x.w); glVertexAttrib4f(3, m->y.x, m->y.y, m->y.z, m->y.w); glVertexAttrib4f(4, m->z.x, m->z.y, m->z.z, m->z.w); glVertexAttrib4f(5, m->w.x, m->w.y, m->w.z, m->w.w); glDrawElements(GL_TRIANGLES, mIndexCount, GL_UNSIGNED_SHORT, nullptr); } }
// -------------------------------------------------------------------------------------------------------------------- void UntexturedObjectsGLBufferStorage::Render(const std::vector<Matrix>& _transforms) { const auto objCount = m_commands.size(); const auto xformCount = _transforms.size(); assert(objCount == xformCount); // Program Vec3 dir = { -0.5f, -1, 1 }; Vec3 at = { 0, 0, 0 }; Vec3 up = { 0, 0, 1 }; dir = normalize(dir); Vec3 eye = at - 250 * dir; Matrix view = matrix_look_at(eye, at, up); Matrix view_proj = mProj * view; glUseProgram(m_prog); glUniformMatrix4fv(mUniformLocation.ViewProjection, 1, GL_TRUE, &view_proj.x.x); // Rasterizer State glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); glDisable(GL_SCISSOR_TEST); // Blend State glDisable(GL_BLEND); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // Depth Stencil State glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); for (size_t u = 0; u < objCount; ++u) { DrawElementsIndirectCommand *cmd = &m_commands[u]; cmd->count = mIndexCount; cmd->instanceCount = 1; cmd->firstIndex = 0; cmd->baseVertex = 0; cmd->baseInstance = mUseShaderDrawParameters ? 0 : u; } memcpy(m_transform_ptr, &*_transforms.begin(), sizeof(Matrix) * xformCount); memcpy(m_cmd_ptr, &*m_commands.begin(), sizeof(DrawElementsIndirectCommand) * objCount); glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT); glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, nullptr, objCount, 0); }
// -------------------------------------------------------------------------------------------------------------------- void UntexturedObjectsGLBindless::Render(const std::vector<Matrix>& _transforms) { // Program Vec3 dir = { -0.5f, -1, 1 }; Vec3 at = { 0, 0, 0 }; Vec3 up = { 0, 0, 1 }; dir = normalize(dir); Vec3 eye = at - 250 * dir; Matrix view = matrix_look_at(eye, at, up); Matrix viewProj = mProj * view; glUseProgram(m_prog); glUniformMatrix4fv(mUniformLocation.ViewProjection, 1, GL_TRUE, &viewProj.x.x); // Input Layout glEnableClientState(GL_ELEMENT_ARRAY_UNIFIED_NV); glEnableClientState(GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV); glVertexAttribFormatNV(0, 3, GL_FLOAT, GL_FALSE, sizeof(UntexturedObjectsProblem::Vertex)); glVertexAttribFormatNV(1, 3, GL_FLOAT, GL_FALSE, sizeof(UntexturedObjectsProblem::Vertex)); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); // Rasterizer State glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); glDisable(GL_SCISSOR_TEST); // Blend State glDisable(GL_BLEND); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // Depth Stencil State glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); for (size_t u = 0; u < _transforms.size(); ++u) { glBufferAddressRangeNV(GL_ELEMENT_ARRAY_ADDRESS_NV, 0, m_ib_addrs[u], m_ib_sizes[u]); glBufferAddressRangeNV(GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV, 0, m_vbo_addrs[u] + offsetof(UntexturedObjectsProblem::Vertex, pos), m_vbo_sizes[u] - offsetof(UntexturedObjectsProblem::Vertex, pos)); glBufferAddressRangeNV(GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV, 1, m_vbo_addrs[u] + offsetof(UntexturedObjectsProblem::Vertex, color), m_vbo_sizes[u] - offsetof(UntexturedObjectsProblem::Vertex, color)); glUniformMatrix4fv(mUniformLocation.World, 1, GL_FALSE, &_transforms[u].x.x); glDrawElements(GL_TRIANGLES, mIndexCount, GL_UNSIGNED_SHORT, nullptr); } }
// -------------------------------------------------------------------------------------------------------------------- void UntexturedObjectsGLMultiDraw::Render(const std::vector<Matrix>& _transforms) { size_t count = _transforms.size(); assert(count <= m_commands.size()); // Program Vec3 dir = { -0.5f, -1, 1 }; Vec3 at = { 0, 0, 0 }; Vec3 up = { 0, 0, 1 }; dir = normalize(dir); Vec3 eye = at - 250 * dir; Matrix view = matrix_look_at(eye, at, up); Matrix view_proj = mProj * view; glUseProgram(m_prog); glUniformMatrix4fv(mUniformLocation.ViewProjection, 1, GL_TRUE, &view_proj.x.x); // Rasterizer State glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); glDisable(GL_SCISSOR_TEST); // Blend State glDisable(GL_BLEND); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // Depth Stencil State glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); for (size_t u = 0; u < count; ++u) { DrawElementsIndirectCommand *cmd = &m_commands[u]; cmd->count = mIndexCount; cmd->instanceCount = 1; cmd->firstIndex = 0; cmd->baseVertex = 0; cmd->baseInstance = mUseShaderDrawParameters ? 0 : u; } glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_transform_buffer); glBufferData(GL_SHADER_STORAGE_BUFFER, _transforms.size() * sizeof(Matrix), &*_transforms.begin(), GL_DYNAMIC_DRAW); glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, &*m_commands.begin(), count, 0); }
// -------------------------------------------------------------------------------------------------------------------- void UntexturedObjectsGLDrawLoop::Render(const std::vector<Matrix>& _transforms) { size_t count = _transforms.size(); assert(count <= mObjectCount); // Program Vec3 dir = { -0.5f, -1, 1 }; Vec3 at = { 0, 0, 0 }; Vec3 up = { 0, 0, 1 }; dir = normalize(dir); Vec3 eye = at - 250 * dir; Matrix view = matrix_look_at(eye, at, up); Matrix view_proj = mProj * view; glUseProgram(m_prog); glUniformMatrix4fv(mUniformLocation.ViewProjection, 1, GL_TRUE, &view_proj.x.x); // Rasterizer State glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); glDisable(GL_SCISSOR_TEST); // Blend State glDisable(GL_BLEND); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // Depth Stencil State glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_transform_buffer); glBufferData(GL_SHADER_STORAGE_BUFFER, _transforms.size() * sizeof(Matrix), &*_transforms.begin(), GL_DYNAMIC_DRAW); for (size_t u = 0; u < count; ++u) { glDrawElementsInstancedBaseInstance(GL_TRIANGLES, mIndexCount, GL_UNSIGNED_SHORT, nullptr, 1, u); } }
// -------------------------------------------------------------------------------------------------------------------- void TexturedQuadsGLNaiveUniform::Render(const std::vector<Matrix>& _transforms) { // Program Vec3 dir = { 0, 0, 1 }; Vec3 at = { 0, 0, 0 }; Vec3 up = { 0, 1, 0 }; dir = normalize(dir); Vec3 eye = at - 250 * dir; Matrix view = matrix_look_at(eye, at, up); Matrix view_proj = mProj * view; glUseProgram(mProgram); glUniformMatrix4fv(mUniformLocation.ViewProjection, 1, GL_TRUE, &view_proj.x.x); // We will bind the texture we care about to unit 0, so let the program know now. glUniform1i(mUniformLocation.gTex, 0); // Input Layout. First the IB glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer); // Then the VBs. glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(TexturedQuadsProblem::Vertex), (void*)offsetof(TexturedQuadsProblem::Vertex, pos)); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedQuadsProblem::Vertex), (void*)offsetof(TexturedQuadsProblem::Vertex, tex)); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); // Rasterizer State glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); glFrontFace(GL_CCW); glDisable(GL_SCISSOR_TEST); // Blend State glDisable(GL_BLEND); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // Depth Stencil State glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glBindBuffer(GL_SHADER_STORAGE_BUFFER, mTransformBuffer); BufferData(GL_SHADER_STORAGE_BUFFER, _transforms, GL_DYNAMIC_DRAW); size_t xformCount = _transforms.size(); assert(xformCount <= mObjectCount); // Code below assumes at least 1 texture. assert(mTextures.size() > 0); auto texIt = mTextures.begin(); for (size_t u = 0; u < xformCount; ++u) { // Update the Draw ID (since we cannot use multi_draw here glUniform1i(mUniformLocation.DrawID, u); if (texIt == mTextures.end()) { texIt = mTextures.begin(); } GLuint activeTex = *texIt; ++texIt; glActiveTexture(GL_TEXTURE0 + 0); glBindTexture(GL_TEXTURE_2D, activeTex); glDrawElements(GL_TRIANGLES, mIndexCount, GL_UNSIGNED_SHORT, 0); } }
// -------------------------------------------------------------------------------------------------------------------- void TexturedQuadsGLBindlessMultiDraw::Render(const std::vector<Matrix>& _transforms) { // Program Vec3 dir = { 0, 0, 1 }; Vec3 at = { 0, 0, 0 }; Vec3 up = { 0, 1, 0 }; dir = normalize(dir); Vec3 eye = at - 250 * dir; Matrix view = matrix_look_at(eye, at, up); Matrix view_proj = mProj * view; glUseProgram(mProgram); glUniformMatrix4fv(0, 1, GL_TRUE, &view_proj.x.x); // Input Layout. First the IB glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer); // Then the VBs. glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(TexturedQuadsProblem::Vertex), (void*)offsetof(TexturedQuadsProblem::Vertex, pos)); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedQuadsProblem::Vertex), (void*)offsetof(TexturedQuadsProblem::Vertex, tex)); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); // Rasterizer State glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); glFrontFace(GL_CCW); glDisable(GL_SCISSOR_TEST); // Blend State glDisable(GL_BLEND); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // Depth Stencil State glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); for (auto it = mTexHandles.begin(); it != mTexHandles.end(); ++it) { glMakeTextureHandleResidentARB(*it); } glBindBuffer(GL_SHADER_STORAGE_BUFFER, mTransformBuffer); BufferData(GL_SHADER_STORAGE_BUFFER, _transforms, GL_DYNAMIC_DRAW); size_t xformCount = _transforms.size(); assert(xformCount <= mObjectCount); for (size_t u = 0; u < xformCount; ++u) { DrawElementsIndirectCommand *cmd = &mCommands[u]; cmd->count = mIndexCount; cmd->instanceCount = 1; cmd->firstIndex = 0; cmd->baseVertex = 0; cmd->baseInstance = 0; } glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, &*mCommands.begin(), xformCount, 0); for (auto it = mTexHandles.begin(); it != mTexHandles.end(); ++it) { glMakeTextureHandleNonResidentARB(*it); } }
// -------------------------------------------------------------------------------------------------------------------- void UntexturedObjectsGLBindlessIndirect::Render(const std::vector<Matrix>& _transforms) { const auto xformCount = _transforms.size(); const auto objCount = m_commands.size(); assert(xformCount == objCount); // Program Vec3 dir = { -0.5f, -1, 1 }; Vec3 at = { 0, 0, 0 }; Vec3 up = { 0, 0, 1 }; dir = normalize(dir); Vec3 eye = at - 250 * dir; Matrix view = matrix_look_at(eye, at, up); Matrix view_proj = mProj * view; glUseProgram(m_prog); glUniformMatrix4fv(0, 1, GL_TRUE, &view_proj.x.x); // Input Layout glEnableClientState(GL_ELEMENT_ARRAY_UNIFIED_NV); glEnableClientState(GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glVertexAttribFormatNV(0, 3, GL_FLOAT, GL_FALSE, sizeof(UntexturedObjectsProblem::Vertex)); glVertexAttribFormatNV(1, 3, GL_FLOAT, GL_FALSE, sizeof(UntexturedObjectsProblem::Vertex)); // Rasterizer State glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); glDisable(GL_SCISSOR_TEST); // Blend State glDisable(GL_BLEND); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // Depth Stencil State glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); size_t i = 0; for (auto it = m_commands.begin(); it != m_commands.end(); ++it) { Command *cmd = &*it; cmd->Draw.count = mIndexCount; cmd->Draw.instanceCount = 1; cmd->Draw.firstIndex = 0; cmd->Draw.baseVertex = 0; cmd->Draw.baseInstance = 0; cmd->reserved = 0; cmd->indexBuffer.index = 0; cmd->indexBuffer.reserved = 0; cmd->indexBuffer.address = m_ib_addrs[i]; cmd->indexBuffer.length = m_ib_sizes[i]; cmd->vertexBuffers[0].index = 0; cmd->vertexBuffers[0].reserved = 0; cmd->vertexBuffers[0].address = m_vbo_addrs[i] + offsetof(UntexturedObjectsProblem::Vertex, pos); cmd->vertexBuffers[0].length = m_vbo_sizes[i] - offsetof(UntexturedObjectsProblem::Vertex, pos); cmd->vertexBuffers[1].index = 1; cmd->vertexBuffers[1].reserved = 0; cmd->vertexBuffers[1].address = m_vbo_addrs[i] + offsetof(UntexturedObjectsProblem::Vertex, color); cmd->vertexBuffers[1].length = m_vbo_sizes[i] - offsetof(UntexturedObjectsProblem::Vertex, color); ++i; } memcpy(m_transform_ptr, &*_transforms.begin(), sizeof(Matrix) * xformCount); memcpy(m_cmd_ptr, &*m_commands.begin(), sizeof(Command) * objCount); glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT); // resolveQueries(); // glBeginQuery(GL_TIME_ELAPSED, m_queries[m_currentQueryIssue]); glMultiDrawElementsIndirectBindlessNV(GL_TRIANGLES, GL_UNSIGNED_SHORT, nullptr, objCount, 0, 2); // glEndQuery(GL_TIME_ELAPSED); // m_currentQueryIssue = (m_currentQueryIssue + 1) % kQueryCount; }