JNIEXPORT void JNICALL Java_org_lwjgl_opengl_NVVertexBufferUnifiedMemory_nglNormalFormatNV(JNIEnv *env, jclass clazz, jint type, jint stride, jlong function_pointer) { glNormalFormatNVPROC glNormalFormatNV = (glNormalFormatNVPROC)((intptr_t)function_pointer); glNormalFormatNV(type, stride); }
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(); } } }