JNIEXPORT void JNICALL Java_org_lwjgl_opengl_NVVertexBufferUnifiedMemory_nglColorFormatNV(JNIEnv *env, jclass clazz, jint size, jint type, jint stride, jlong function_pointer) {
	glColorFormatNVPROC glColorFormatNV = (glColorFormatNVPROC)((intptr_t)function_pointer);
	glColorFormatNV(size, type, stride);
}
Example #2
0
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();
		}
	}
}