inline void VL_glVertexAttribLPointer(GLuint name, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer) { if(glVertexAttribLPointer) glVertexAttribLPointer(name, size, type, stride, pointer); else if(glVertexAttribLPointerEXT) glVertexAttribLPointerEXT(name, size, type, stride, pointer); else VL_UNSUPPORTED_FUNC(); }
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_EXTVertexAttrib64bit_nglVertexAttribLPointerEXTBO(JNIEnv *env, jclass clazz, jint index, jint size, jint type, jint stride, jlong pointer_buffer_offset, jlong function_pointer) { const GLvoid *pointer_address = (const GLvoid *)(intptr_t)offsetToPointer(pointer_buffer_offset); glVertexAttribLPointerEXTPROC glVertexAttribLPointerEXT = (glVertexAttribLPointerEXTPROC)((intptr_t)function_pointer); glVertexAttribLPointerEXT(index, size, type, stride, pointer_address); }