void display() { { // Compute the MVP (Model View Projection matrix) glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f); glm::mat4 ViewTranslate = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -Window.TranlationCurrent.y)); glm::mat4 ViewRotateX = glm::rotate(ViewTranslate, Window.RotationCurrent.y, glm::vec3(1.f, 0.f, 0.f)); glm::mat4 View = glm::rotate(ViewRotateX, Window.RotationCurrent.x, glm::vec3(0.f, 1.f, 0.f)); glm::mat4 Model = glm::mat4(1.0f); glm::mat4 MVP = Projection * View * Model; glBindBuffer(GL_UNIFORM_BUFFER, BufferName[buffer::TRANSFORM]); glm::mat4* Pointer = (glm::mat4*)glMapBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(MVP), GL_MAP_WRITE_BIT); *Pointer = MVP; glUnmapBuffer(GL_UNIFORM_BUFFER); } glViewportIndexedfv(0, &glm::vec4(0, 0, Window.Size.x, Window.Size.y)[0]); glClearBufferfv(GL_COLOR, 0, &glm::vec4(1.0f, 0.5f, 0.0f, 1.0f)[0]); glBindProgramPipeline(PipelineName); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, Texture2DName); glBindBufferBase(GL_UNIFORM_BUFFER, glf::semantic::uniform::TRANSFORM0, BufferName[buffer::TRANSFORM]); glBindVertexArray(VertexArrayName); glBufferAddressRangeNV(GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV, glf::semantic::attr::POSITION, Address, VertexSize); glBufferAddressRangeNV(GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV, glf::semantic::attr::TEXCOORD, Address + sizeof(glm::vec2), VertexSize - sizeof(glm::vec2)); glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, VertexCount, 1, 0); glf::swapBuffers(); }
bool render() { glm::vec2 WindowSize(this->getWindowSize()); { glm::mat4 Projection = glm::perspective(glm::pi<float>() * 0.25f, WindowSize.x / WindowSize.y, 0.1f, 100.0f); glm::mat4 Model = glm::mat4(1.0f); glm::mat4 MVP = Projection * this->view() * Model; glBindBuffer(GL_UNIFORM_BUFFER, BufferName[buffer::TRANSFORM]); glm::mat4* Pointer = (glm::mat4*)glMapBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(MVP), GL_MAP_WRITE_BIT); *Pointer = MVP; glUnmapBuffer(GL_UNIFORM_BUFFER); } glViewportIndexedfv(0, &glm::vec4(0, 0, WindowSize.x, WindowSize.y)[0]); glClearBufferfv(GL_COLOR, 0, &glm::vec4(1.0f, 0.5f, 0.0f, 1.0f)[0]); glBindProgramPipeline(PipelineName); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, TextureName); glBindBufferBase(GL_UNIFORM_BUFFER, semantic::uniform::TRANSFORM0, BufferName[buffer::TRANSFORM]); glBindVertexArray(VertexArrayName); glBufferAddressRangeNV(GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV, semantic::attr::POSITION, Address, VertexSize); glBufferAddressRangeNV(GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV, semantic::attr::TEXCOORD, Address + sizeof(glm::vec2), VertexSize - sizeof(glm::vec2)); glDrawArraysInstancedBaseInstance(GL_TRIANGLES, 0, VertexCount, 1, 0); return true; }
void TopazSample::updateCommandListState() { enum StateObjects { STATE_DRAW, STATE_GEOMETRY_DRAW, STATE_LINES_DRAW, STATES_COUNT }; if (cmdlist.state.programIncarnation != cmdlist.captured.programIncarnation) { glBindFramebuffer(GL_FRAMEBUFFER, fbos.scene); glEnable(GL_DEPTH_TEST); glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(1, 1); glEnableVertexAttribArray(VERTEX_POS); glVertexAttribFormat(VERTEX_POS, 3, GL_FLOAT, GL_FALSE, models.at(0)->getModel()->getCompiledPositionOffset()); glVertexAttribBinding(VERTEX_POS, 0); glBindVertexBuffer(0, 0, 0, models.at(0)->getModel()->getCompiledVertexSize() * sizeof(float)); if (hwsupport) { glBufferAddressRangeNV(GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV, 0, 0, 0); glBufferAddressRangeNV(GL_ELEMENT_ARRAY_ADDRESS_NV, 0, 0, 0); glBufferAddressRangeNV(GL_UNIFORM_BUFFER_ADDRESS_NV, UBO_OBJECT, 0, 0); glBufferAddressRangeNV(GL_UNIFORM_BUFFER_ADDRESS_NV, UBO_SCENE, 0, 0); } shaderPrograms["draw"]->enable(); glStateCaptureNV(cmdlist.stateObjects[STATE_DRAW], GL_TRIANGLES); glBindVertexBuffer(0, 0, 0, sizeof(nv::vec3f)); glStateCaptureNV(cmdlist.stateObjects[STATE_LINES_DRAW], GL_LINES); glDisableVertexAttribArray(VERTEX_POS); glBindFramebuffer(GL_FRAMEBUFFER, 0); glDisable(GL_DEPTH_TEST); } if (hwsupport && ( cmdlist.state.programIncarnation != cmdlist.captured.programIncarnation || cmdlist.state.fboIncarnation != cmdlist.captured.fboIncarnation)) { NVTokenSequence &seq = cmdlist.tokenSequenceList; glCommandListSegmentsNV(cmdlist.tokenCmdList, 1); glListDrawCommandsStatesClientNV(cmdlist.tokenCmdList, 0, (const void**)&seq.offsets[0], &seq.sizes[0], &seq.states[0], &seq.fbos[0], int(seq.states.size())); glCompileCommandListNV(cmdlist.tokenCmdList); } cmdlist.captured = cmdlist.state; }
// -------------------------------------------------------------------------------------------------------------------- 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 ParameterRendererBuffer::activate() { if (m_useUniformBufferUnifiedMemory) { // TODO hack, query alignment from driver! glBufferAddressRangeNV(GL_UNIFORM_BUFFER_ADDRESS_NV, m_uboBinding, m_ubo->getAddress(), (m_uboBlockSize + 0xff) & ~0xff); } else { glBindBufferRange( m_target, m_uboBinding, m_ubo->getGLId(), m_uboOffset, m_uboBlockSize ); } }
void display() { // Compute the MVP (Model View Projection matrix) glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f); glm::mat4 ViewTranslate = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -Window.TranlationCurrent.y)); glm::mat4 ViewRotateX = glm::rotate(ViewTranslate, Window.RotationCurrent.y, glm::vec3(1.f, 0.f, 0.f)); glm::mat4 View = glm::rotate(ViewRotateX, Window.RotationCurrent.x, glm::vec3(0.f, 1.f, 0.f)); glm::mat4 Model = glm::mat4(1.0f); glm::mat4 MVP = Projection * View * Model; glf::checkError("display 4"); glProgramUniformMatrix4fv(ProgramName[program::VERTEX], UniformMVP, 1, GL_FALSE, &MVP[0][0]); glProgramUniform1i(ProgramName[program::FRAGMENT], UniformDiffuse, 0); glf::checkError("display 5"); glViewportIndexedfv(0, &glm::vec4(0, 0, Window.Size.x, Window.Size.y)[0]); glClearBufferfv(GL_COLOR, 0, &glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)[0]); glf::checkError("display 6"); glBindProgramPipeline(PipelineName); glf::checkError("display 7"); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, Texture2DName); glBindVertexArray(VertexArrayName); glf::checkError("display 8"); glBufferAddressRangeNV(GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV, glf::semantic::attr::POSITION, Address, VertexSize); glBufferAddressRangeNV(GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV, glf::semantic::attr::TEXCOORD, Address + sizeof(glm::vec2), VertexSize - sizeof(glm::vec2)); glf::checkError("display 9"); glDrawArraysInstanced(GL_TRIANGLES, 0, VertexCount, 1); glf::checkError("display"); glf::swapBuffers(); }
void RenderEngineGLIndirect::render( RenderGroupGLHandle groupHandle, const dp::rix::core::RenderOptions& /*renderOptions*/ ) { // if dirty, update sorted list RenderGroupGL::ProgramPipelineCaches::iterator glIt; RenderGroupGL::ProgramPipelineCaches::iterator glIt_end = groupHandle->m_programPipelineCaches.end(); for ( glIt = groupHandle->m_programPipelineCaches.begin(); glIt != glIt_end; ++glIt ) { ProgramPipelineGLHandle programPipeline = glIt->first; RenderGroupGLCache* cache = glIt->second.get<RenderGroupGLCache>(); #if RIX_GL_SEPARATE_SHADER_OBJECTS_SUPPORT == 1 glBindProgramPipeline( programPipeline->m_pipelineId ); #else glUseProgram( programPipeline->m_programs[0]->getProgram()->getGLId() ); #endif //if ( giList->m_indirectEntries.size() != giList->m_geometryInstances.size()) if ( !cache->m_initialized ) // TODO support changes { cache->m_initialized = true; RenderGroupGLCache::DrawArrayListEntry triangles; RenderGroupGLCache::DrawArrayListEntry lines; RenderGroupGLCache::DrawArrayListEntry linesStrips; //cache->m_indirectEntries.clear(); //cache->m_indirectCommands.clear(); for (size_t index = 0; index < cache->getGeometryInstances().size(); ++index ) { GeometryInstanceGLHandle gi = cache->getGeometryInstances()[index]; if ( !gi->getGeometry()->getIndices() ) { switch ( gi->getGeometry()->getGeometryDescription()->getPrimitiveType() ) { case GeometryPrimitiveType::TRIANGLES: //drawEntry = &triangles; addArrayIndirectCommand(gi, triangles); break; case GeometryPrimitiveType::LINES: addArrayIndirectCommand(gi, lines); break; case GeometryPrimitiveType::LINE_STRIP: addArrayIndirectCommand(gi, linesStrips); break; default: assert( 0 && "unsupported primitve types"); } } else { //addElementIndirectCommand(cache, gi ); } } addDrawArrayList( cache, triangles, GL_TRIANGLES); addDrawArrayList( cache, lines, GL_LINES ); addDrawArrayList( cache, linesStrips, GL_LINE_STRIP ); for ( size_t idx = 0;idx < cache->m_drawElementsList.size(); ++idx ) { prepareDrawElementsEntry( &cache->m_drawElementsList[idx] ); } } // prepare fixed containers #if 0 GeometryInstanceGLHandle gi = cache->getGeometryInstances()[0]; for ( size_t containerIdx = 0; containerIdx < gi->m_containers.size(); ++containerIdx ) { // debug info auto infos = gi->m_containers[containerIdx].container->m_descriptor->m_parameterInfos; for ( size_t infoIdx = 0; infoIdx < infos.size(); ++infoIdx ) { std::cout << "c: " << containerIdx << ", infoIdX:" << infoIdx << ", name: " << infos[infoIdx].m_name << std::endl; } } #endif assert( !"No implementation available atm"); // TODO update to new interface //gi->m_containers[0].parameters[0]->update( gi->m_containers[0].container->m_data ); // sys_View //gi->m_containers[1].parameters[0]->update( gi->m_containers[1].container->m_data ); // lights for ( size_t idx = 0;idx < cache->m_drawArrayList.size(); ++idx ) { RenderGroupGLCache::DrawArrayListEntry &entry = cache->m_drawArrayList[idx]; glEnableVertexAttribArray( 12 ); dp::gl::bind( GL_ARRAY_BUFFER, entry.m_indirectPointersBuffer->getBuffer() ); glVertexAttribLPointerEXT( 12, 1, GL_UNSIGNED_INT64_NV, 0, 0 ); glVertexAttribDivisor( 12, 1); // TODO update vertex attrib pointer to 64-bit values #define USE_DRAW_INDIRECT_BUFFER #if 0 #if defined(USE_DRAW_INDIRECT_BUFFER) dp::gl::bind( GL_DRAW_INDIRECT_BUFFER, entry.m_indirectCommandsBuffer->getBuffer() ); size_t offset = 0; for (size_t index = 0; index < entry.m_indirectCommands.size(); ++index ) { glDrawArraysIndirect( entry.m_primitiveType, (const void*)(offset) ); offset += sizeof( RenderGroupGLCache::DrawArraysIndirectCommand ); } #else RenderGroupGLCache::DrawArraysIndirectCommand *command = &entry.m_indirectCommands[0]; for (size_t index = 0; index < entry.m_indirectCommands.size(); ++index ) { //glDrawArraysIndirect( entry.m_primitiveType, command ); glDrawArraysInstancedBaseInstance( entry.m_primitiveType, command->first, command->count, command->primCount, command->baseInstance ); //glDrawementsBaseVertex( entry.m_primitiveType, command->count, GL_UN) ++command; } #endif #else #if defined(USE_DRAW_INDIRECT_BUFFER) dp::gl::bind( GL_DRAW_INDIRECT_BUFFER, entry.m_indirectCommandsBuffer->getBuffer() ); glMultiDrawArraysIndirectAMD( entry.m_primitiveType, 0, static_cast<GLsizei>(entry.m_indirectCommands.size()), sizeof( RenderGroupGLCache::DrawArraysIndirectCommand ) ); #else RenderGroupGLCache::DrawArraysIndirectCommand *commands = &entry.m_indirectCommands[0]; glMultiDrawArraysIndirectAMD( entry.m_primitiveType, commands, static_cast<GLuint>(entry.m_indirectCommands.size()), 0 ); #endif #endif } #if 0 unsigned int indirectCommands = 0; glEnable( GL_PRIMITIVE_RESTART ); //glDisable( GL_PRIMITIVE_RESTART ); glPrimitiveRestartIndex( ~0 ); glEnableClientState(GL_ELEMENT_ARRAY_UNIFIED_NV ); glEnableClientState(GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV); glEnableVertexAttribArray( 12 ); glVertexAttribDivisor( 12, 1); glVertexAttribLFormatNV( 12, 1, GL_UNSIGNED_INT64_NV, 0 ); for ( size_t idx = 0;idx < cache->m_drawElementsList.size(); ++idx ) { const RenderGroupGLCache::DrawElementsListEntry& entry = cache->m_drawElementsList[idx]; //dp::gl::bind( GL_ARRAY_BUFFER, entry.m_indirectPointersBuffer ); //glVertexAttribLPointerEXT( 12, 1, GL_UNSIGNED_INT64_NV, 0, 0 ); glBufferAddressRangeNV( GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV, 12, entry.m_indirectPointersBufferAddress, entry.m_indirectPointersBufferRange ); //dp::gl::bind( GL_ELEMENT_ARRAY_BUFFER, entry.m_indexBuffer ); glBufferAddressRangeNV( GL_ELEMENT_ARRAY_ADDRESS_NV, 0, entry.m_indexBufferAddress, entry.m_indexBufferRange ); //glMultiDrawElementsIndirectAMD( entry.m_primitiveType, GL_UNSIGNED_INT, &entry.m_indirectCommands[0], static_cast<GLuint>(entry.m_indirectCommands.size()), 0); //glDrawElementsIndirect( entry.m_primitiveType, GL_UNSIGNED_INT, &entry.m_indirectCommands[0] ); glDrawElementsInstancedBaseVertexBaseInstance( entry.m_primitiveType, entry.m_indirectCommands[0].count, GL_UNSIGNED_INT, 0, 1, entry.m_indirectCommands[0].baseVertex, entry.m_indirectCommands[0].baseInstance ); indirectCommands += static_cast<unsigned int>(entry.m_indirectCommands.size()); } glDisableClientState(GL_ELEMENT_ARRAY_UNIFIED_NV ); glDisableClientState(GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV); #endif //std::cout << "indirect commands " << indirectCommands << ", " << cache->m_drawElementsList.size() << std::endl; } }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_NVVertexBufferUnifiedMemory_nglBufferAddressRangeNV(JNIEnv *env, jclass clazz, jint pname, jint index, jlong address, jlong length, jlong function_pointer) { glBufferAddressRangeNVPROC glBufferAddressRangeNV = (glBufferAddressRangeNVPROC)((intptr_t)function_pointer); glBufferAddressRangeNV(pname, index, address, length); }
void GLRenderer::drawAll(const std::vector<TransformedGPUGeometry> &allGeometry) { Matrix4x4 curObjTrafo; curObjTrafo.setIdentity(); glMatrixMode(GL_MODELVIEW); Matrix4x4 backup = fetchMatrix(GL_MODELVIEW_MATRIX); GLRenderer::beginDrawingMeshes(true); if (m_capabilities->isSupported(RendererCapabilities::EBindless)) { for (std::vector<TransformedGPUGeometry>::const_iterator it = allGeometry.begin(); it != allGeometry.end(); ++it) { const GLGeometry *geo = static_cast<const GLGeometry *>((*it).first); const Matrix4x4 &trafo = (*it).second; const TriMesh *mesh = geo->getTriMesh(); GLuint indexSize = geo->m_size[GLGeometry::EIndexID]; GLuint vertexSize = geo->m_size[GLGeometry::EVertexID]; GLuint64 indexAddr = geo->m_addr[GLGeometry::EIndexID]; GLuint64 vertexAddr = geo->m_addr[GLGeometry::EVertexID]; if (trafo != curObjTrafo) { loadMatrix(backup * trafo); curObjTrafo = trafo; } int stride = geo->m_stride; if (stride != m_stride) { glVertexFormatNV(3, GL_FLOAT, stride); m_stride = stride; } glBufferAddressRangeNV(GL_VERTEX_ARRAY_ADDRESS_NV, 0, vertexAddr, vertexSize); glBufferAddressRangeNV(GL_ELEMENT_ARRAY_ADDRESS_NV, 0, indexAddr, indexSize); size_t size = mesh->getTriangleCount(); if (EXPECT_TAKEN(m_queuedTriangles + size < MTS_GL_MAX_QUEUED_TRIS)) { /* Draw all triangles */ glDrawElements(GL_TRIANGLES, (GLsizei) (size * 3), GL_UNSIGNED_INT, (GLvoid *) 0); m_queuedTriangles += size; } else { /* Spoon-feed them (keeps the OS responsive) */ size_t size = mesh->getTriangleCount(), cur = 0; while (cur < size) { size_t drawAmt = std::min(size - cur, MTS_GL_MAX_QUEUED_TRIS - m_queuedTriangles); if (drawAmt > 0) glDrawElements(GL_TRIANGLES, (GLsizei) (drawAmt * 3), GL_UNSIGNED_INT, (GLuint *) 0 + cur * 3); m_queuedTriangles += drawAmt; cur += drawAmt; if (cur < size) finish(); } } } } else { for (std::vector<TransformedGPUGeometry>::const_iterator it = allGeometry.begin(); it != allGeometry.end(); ++it) { const GLGeometry *geo = static_cast<const GLGeometry *>((*it).first); const Matrix4x4 &trafo = (*it).second; const TriMesh *mesh = geo->getTriMesh(); if (trafo != curObjTrafo) { loadMatrix(backup * trafo); curObjTrafo = trafo; } glBindBuffer(GL_ARRAY_BUFFER, geo->m_id[GLGeometry::EVertexID]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, geo->m_id[GLGeometry::EIndexID]); /* Set up the vertex/normal arrays */ glVertexPointer(3, GL_FLOAT, geo->m_stride, (GLfloat *) 0); size_t size = mesh->getTriangleCount(); if (EXPECT_TAKEN(m_queuedTriangles + size < MTS_GL_MAX_QUEUED_TRIS)) { /* Draw all triangles */ glDrawElements(GL_TRIANGLES, (GLsizei) (size * 3), GL_UNSIGNED_INT, (GLvoid *) 0); m_queuedTriangles += size; } else { /* Spoon-feed them (keeps the OS responsive) */ size_t size = mesh->getTriangleCount(), cur = 0; while (cur < size) { size_t drawAmt = std::min(size - cur, MTS_GL_MAX_QUEUED_TRIS - m_queuedTriangles); if (drawAmt > 0) glDrawElements(GL_TRIANGLES, (GLsizei) (drawAmt * 3), GL_UNSIGNED_INT, (GLuint *) 0 + cur * 3); m_queuedTriangles += drawAmt; cur += drawAmt; if (cur < size) finish(); } } } } GLRenderer::endDrawingMeshes(); if (!curObjTrafo.isIdentity()) loadMatrix(backup); }
void GLRenderer::drawMesh(const GPUGeometry *_geo) { const GLGeometry *geo = static_cast<const GLGeometry *>(_geo); const TriMesh *mesh = geo->getTriMesh(); GLuint indexSize = geo->m_size[GLGeometry::EIndexID]; GLuint vertexSize = geo->m_size[GLGeometry::EVertexID]; /* Draw using vertex buffer objects (bindless if supported) */ if (m_capabilities->isSupported(RendererCapabilities::EBindless)) { GLuint64 indexAddr = geo->m_addr[GLGeometry::EIndexID]; GLuint64 vertexAddr = geo->m_addr[GLGeometry::EVertexID]; int stride = geo->m_stride; if (stride != m_stride) { glVertexFormatNV(3, GL_FLOAT, stride); glNormalFormatNV(GL_FLOAT, stride); glClientActiveTexture(GL_TEXTURE0); glTexCoordFormatNV(2, GL_FLOAT, stride); glClientActiveTexture(GL_TEXTURE1); glTexCoordFormatNV(3, GL_FLOAT, stride); glColorFormatNV(3, GL_FLOAT, stride); m_stride = stride; } glBufferAddressRangeNV(GL_VERTEX_ARRAY_ADDRESS_NV, 0, vertexAddr, vertexSize); if (!m_transmitOnlyPositions) { int pos = 3 * sizeof(GLfloat); if (mesh->hasVertexNormals()) { if (!m_normalsEnabled) { glEnableClientState(GL_NORMAL_ARRAY); m_normalsEnabled = true; } glBufferAddressRangeNV(GL_NORMAL_ARRAY_ADDRESS_NV, 0, vertexAddr + pos, vertexSize - pos); pos += 3 * sizeof(GLfloat); } else if (m_normalsEnabled) { glDisableClientState(GL_NORMAL_ARRAY); m_normalsEnabled = false; } if (mesh->hasVertexTexcoords()) { glClientActiveTexture(GL_TEXTURE0); if (!m_texcoordsEnabled) { glEnableClientState(GL_TEXTURE_COORD_ARRAY); m_texcoordsEnabled = true; } glBufferAddressRangeNV(GL_TEXTURE_COORD_ARRAY_ADDRESS_NV, 0, vertexAddr + pos, vertexSize - pos); pos += 2 * sizeof(GLfloat); } else if (m_texcoordsEnabled) { glClientActiveTexture(GL_TEXTURE0); glDisableClientState(GL_TEXTURE_COORD_ARRAY); m_texcoordsEnabled = false; } /* Pass 'dpdu' as second set of texture coordinates */ if (mesh->hasUVTangents()) { glClientActiveTexture(GL_TEXTURE1); if (!m_tangentsEnabled) { glEnableClientState(GL_TEXTURE_COORD_ARRAY); m_tangentsEnabled = true; } glBufferAddressRangeNV(GL_TEXTURE_COORD_ARRAY_ADDRESS_NV, 1, vertexAddr + pos, vertexSize - pos); pos += 3 * sizeof(GLfloat); } else if (m_tangentsEnabled) { glClientActiveTexture(GL_TEXTURE1); glDisableClientState(GL_TEXTURE_COORD_ARRAY); m_tangentsEnabled = false; } if (mesh->hasVertexColors()) { if (!m_colorsEnabled) { glEnableClientState(GL_COLOR_ARRAY); m_colorsEnabled = true; } glBufferAddressRangeNV(GL_COLOR_ARRAY_ADDRESS_NV, 0, vertexAddr + pos, vertexSize - pos); } else if (m_colorsEnabled) { glDisableClientState(GL_COLOR_ARRAY); m_colorsEnabled = false; } } glBufferAddressRangeNV(GL_ELEMENT_ARRAY_ADDRESS_NV, 0, indexAddr, indexSize); } else { glBindBuffer(GL_ARRAY_BUFFER, geo->m_id[GLGeometry::EVertexID]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, geo->m_id[GLGeometry::EIndexID]); int stride = geo->m_stride; /* Set up the vertex/normal arrays */ glVertexPointer(3, GL_FLOAT, stride, (GLfloat *) 0); if (!m_transmitOnlyPositions) { int pos = 3; if (mesh->hasVertexNormals()) { if (!m_normalsEnabled) { glEnableClientState(GL_NORMAL_ARRAY); m_normalsEnabled = true; } glNormalPointer(GL_FLOAT, stride, (GLfloat *) 0 + pos); pos += 3; } else if (m_normalsEnabled) { glDisableClientState(GL_NORMAL_ARRAY); m_normalsEnabled = false; } if (mesh->hasVertexTexcoords()) { glClientActiveTexture(GL_TEXTURE0); if (!m_texcoordsEnabled) { glEnableClientState(GL_TEXTURE_COORD_ARRAY); m_texcoordsEnabled = true; } glTexCoordPointer(2, GL_FLOAT, stride, (GLfloat *) 0 + pos); pos += 2; } else if (m_texcoordsEnabled) { glClientActiveTexture(GL_TEXTURE0); glDisableClientState(GL_TEXTURE_COORD_ARRAY); m_texcoordsEnabled = false; } /* Pass 'dpdu' as second set of texture coordinates */ if (mesh->hasUVTangents()) { glClientActiveTexture(GL_TEXTURE1); if (!m_tangentsEnabled) { glEnableClientState(GL_TEXTURE_COORD_ARRAY); m_tangentsEnabled = true; } glTexCoordPointer(3, GL_FLOAT, stride, (GLfloat *) 0 + pos); pos += 3; } else if (m_tangentsEnabled) { glClientActiveTexture(GL_TEXTURE1); glDisableClientState(GL_TEXTURE_COORD_ARRAY); m_tangentsEnabled = false; } if (mesh->hasVertexColors()) { if (!m_colorsEnabled) { glEnableClientState(GL_COLOR_ARRAY); m_colorsEnabled = true; } glColorPointer(3, GL_FLOAT, stride, (GLfloat *) 0 + pos); } else if (m_colorsEnabled) { glDisableClientState(GL_COLOR_ARRAY); m_colorsEnabled = false; } } } size_t size = mesh->getTriangleCount(); if (EXPECT_TAKEN(m_queuedTriangles + size < MTS_GL_MAX_QUEUED_TRIS)) { /* Draw all triangles */ glDrawElements(GL_TRIANGLES, (GLsizei) (size * 3), GL_UNSIGNED_INT, (GLvoid *) 0); m_queuedTriangles += size; } else { /* Spoon-feed them (keeps the OS responsive) */ size_t size = mesh->getTriangleCount(), cur = 0; while (cur < size) { size_t drawAmt = std::min(size - cur, MTS_GL_MAX_QUEUED_TRIS - m_queuedTriangles); if (drawAmt > 0) glDrawElements(GL_TRIANGLES, (GLsizei) (drawAmt * 3), GL_UNSIGNED_INT, (GLuint *) 0 + cur * 3); m_queuedTriangles += drawAmt; cur += drawAmt; if (cur < size) finish(); } } }
void ParameterRendererPersistentBufferMappingUnifiedMemory::render(void const* cache) { GLsizeiptr const offset = reinterpret_cast<GLintptr>(cache); glBufferAddressRangeNV(m_target, m_uboBinding, m_uboBaseAddress + offset, m_uboBlockSize); }