Example #1
0
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);
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_NVVertexBufferUnifiedMemory_nglVertexFormatNV(JNIEnv *env, jclass clazz, jint size, jint type, jint stride, jlong function_pointer) {
	glVertexFormatNVPROC glVertexFormatNV = (glVertexFormatNVPROC)((intptr_t)function_pointer);
	glVertexFormatNV(size, type, stride);
}
Example #3
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();
		}
	}
}