Beispiel #1
0
void SS3OPiece::DrawForList() const
{
	if (!HasGeometryData())
		return;

	BindVertexAttribVBOs();
	vboIndices.Bind(GL_ELEMENT_ARRAY_BUFFER);
	switch (primType) {
		case S3O_PRIMTYPE_TRIANGLES: {
			glDrawRangeElements(GL_TRIANGLES, 0, vertices.size() - 1, indices.size(), GL_UNSIGNED_INT, vboIndices.GetPtr());
		} break;
		case S3O_PRIMTYPE_TRIANGLE_STRIP: {
			#ifdef GLEW_NV_primitive_restart
			if (globalRendering->supportRestartPrimitive) {
				// this is not compiled into display lists, but executed immediately
				glPrimitiveRestartIndexNV(-1U);
				glEnableClientState(GL_PRIMITIVE_RESTART_NV);
			}
			#endif

			glDrawRangeElements(GL_TRIANGLE_STRIP, 0, vertices.size() - 1, indices.size(), GL_UNSIGNED_INT, vboIndices.GetPtr());

			#ifdef GLEW_NV_primitive_restart
			if (globalRendering->supportRestartPrimitive) {
				glDisableClientState(GL_PRIMITIVE_RESTART_NV);
			}
			#endif
		} break;
		case S3O_PRIMTYPE_QUADS: {
			glDrawRangeElements(GL_QUADS, 0, vertices.size() - 1, indices.size(), GL_UNSIGNED_INT, vboIndices.GetPtr());
		} break;
	}
	vboIndices.Unbind();
	UnbindVertexAttribVBOs();
}
Beispiel #2
0
void S3DOPiece::DrawForList() const
{
	if (!HasGeometryData())
		return;

	BindVertexAttribVBOs();
	vboIndices.Bind(GL_ELEMENT_ARRAY_BUFFER);
	glDrawRangeElements(GL_TRIANGLES, 0, (vboAttributes.GetSize() - 1) / sizeof(S3DOVertex), vboIndices.GetSize() / sizeof(unsigned), GL_UNSIGNED_INT, vboIndices.GetPtr());
	vboIndices.Unbind();
	UnbindVertexAttribVBOs();
}
Beispiel #3
0
void SS3OPiece::UploadGeometryVBOs()
{
	if (!HasGeometryData())
		return;

	//FIXME share 1 VBO for ALL models
	vboAttributes.Bind(GL_ARRAY_BUFFER);
	vboAttributes.New(vertices.size() * sizeof(SS3OVertex), GL_STATIC_DRAW, &vertices[0]);
	vboAttributes.Unbind();

	vboIndices.Bind(GL_ELEMENT_ARRAY_BUFFER);
	vboIndices.New(indices.size() * sizeof(unsigned int), GL_STATIC_DRAW, &indices[0]);
	vboIndices.Unbind();

	// NOTE: wasteful to keep these around, but still needed (eg. for Shatter())
	// vertices.clear();
	// indices.clear();
}
Beispiel #4
0
void SAssPiece::DrawForList() const
{
	if (!HasGeometryData())
		return;

	/*
	 * since aiProcess_SortByPType is being used,
	 * we're sure we'll get only 1 type here,
	 * so combination check isn't needed, also
	 * anything more complex than triangles is
	 * being split thanks to aiProcess_Triangulate
	 */
	BindVertexAttribVBOs();
	vboIndices.Bind(GL_ELEMENT_ARRAY_BUFFER);
	glDrawRangeElements(GL_TRIANGLES, 0, vertices.size() - 1, indices.size(), GL_UNSIGNED_INT, vboIndices.GetPtr());
	vboIndices.Unbind();
	UnbindVertexAttribVBOs();
}
Beispiel #5
0
void SS3OPiece::SetVertexTangents()
{
	if (!HasGeometryData())
		return;

	if (primType == S3O_PRIMTYPE_QUADS)
		return;

	unsigned stride = 0;

	switch (primType) {
		case S3O_PRIMTYPE_TRIANGLES: {
			stride = 3;
		} break;
		case S3O_PRIMTYPE_TRIANGLE_STRIP: {
			stride = 1;
		} break;
	}

	// for triangle strips, the piece vertex _indices_ are defined
	// by the draw order of the vertices numbered <v, v + 1, v + 2>
	// for v in [0, n - 2]
	const unsigned vrtMaxNr = (stride == 1)?
		indices.size() - 2:
		indices.size();

	// set the triangle-level S- and T-tangents
	for (unsigned vrtNr = 0; vrtNr < vrtMaxNr; vrtNr += stride) {
		bool flipWinding = false;

		if (primType == S3O_PRIMTYPE_TRIANGLE_STRIP) {
			flipWinding = ((vrtNr & 1) == 1);
		}

		const int v0idx = indices[vrtNr                      ];
		const int v1idx = indices[vrtNr + (flipWinding? 2: 1)];
		const int v2idx = indices[vrtNr + (flipWinding? 1: 2)];

		if (v1idx == -1 || v2idx == -1) {
			// not a valid triangle, skip
			// to start of next tri-strip
			vrtNr += 3; continue;
		}

		const SS3OVertex* vrt0 = &vertices[v0idx];
		const SS3OVertex* vrt1 = &vertices[v1idx];
		const SS3OVertex* vrt2 = &vertices[v2idx];

		const float3& p0 = vrt0->pos;
		const float3& p1 = vrt1->pos;
		const float3& p2 = vrt2->pos;

		const float2& tc0 = vrt0->texCoords[0];
		const float2& tc1 = vrt1->texCoords[0];
		const float2& tc2 = vrt2->texCoords[0];

		const float x1x0 = p1.x - p0.x, x2x0 = p2.x - p0.x;
		const float y1y0 = p1.y - p0.y, y2y0 = p2.y - p0.y;
		const float z1z0 = p1.z - p0.z, z2z0 = p2.z - p0.z;

		const float s1 = tc1.x - tc0.x, s2 = tc2.x - tc0.x;
		const float t1 = tc1.y - tc0.y, t2 = tc2.y - tc0.y;

		// if d is 0, texcoors are degenerate
		const float d = (s1 * t2 - s2 * t1);
		const bool  b = (d > -0.0001f && d < 0.0001f);
		const float r = b? 1.0f: 1.0f / d;

		// note: not necessarily orthogonal to each other
		// or to vertex normal (only to the triangle plane)
		const float3 sdir((t2 * x1x0 - t1 * x2x0) * r, (t2 * y1y0 - t1 * y2y0) * r, (t2 * z1z0 - t1 * z2z0) * r);
		const float3 tdir((s1 * x2x0 - s2 * x1x0) * r, (s1 * y2y0 - s2 * y1y0) * r, (s1 * z2z0 - s2 * z1z0) * r);

		vertices[v0idx].sTangent += sdir;
		vertices[v1idx].sTangent += sdir;
		vertices[v2idx].sTangent += sdir;

		vertices[v0idx].tTangent += tdir;
		vertices[v1idx].tTangent += tdir;
		vertices[v2idx].tTangent += tdir;
	}

	// set the smoothed per-vertex tangents
	for (int vrtIdx = vertices.size() - 1; vrtIdx >= 0; vrtIdx--) {
		float3& n = vertices[vrtIdx].normal;
		float3& s = vertices[vrtIdx].sTangent;
		float3& t = vertices[vrtIdx].tTangent;
		int h = 1;

		if (math::isnan(n.x) || math::isnan(n.y) || math::isnan(n.z)) {
			n = FwdVector;
		}
		if (s == ZeroVector) { s = RgtVector; }
		if (t == ZeroVector) { t =  UpVector; }

		h = ((n.cross(s)).dot(t) < 0.0f)? -1: 1;
		s = (s - n * n.dot(s));
		s = s.SafeANormalize();
		t = (s.cross(n)) * h;

		// t = (s.cross(n));
		// h = ((s.cross(t)).dot(n) >= 0.0f)? 1: -1;
		// t = t * h;
	}
}