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(); }
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(); }
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(); }
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(); }
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; } }