size_t VAOManager::getVertexPitch(enum VTXTYPE tp) const { switch (tp) { case VTXTYPE_STANDARD: return getVertexPitchFromType(video::EVT_STANDARD); case VTXTYPE_TCOORD: return getVertexPitchFromType(video::EVT_2TCOORDS); case VTXTYPE_TANGENT: return getVertexPitchFromType(video::EVT_TANGENTS); default: assert(0 && "Wrong vtxtype"); return -1; } }
void shadeMeshFaces(scene::IMesh *mesh) { if (mesh == NULL) return; u32 mc = mesh->getMeshBufferCount(); for (u32 j = 0; j < mc; j++) { scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); const u32 stride = getVertexPitchFromType(buf->getVertexType()); u32 vertex_count = buf->getVertexCount(); u8 *vertices = (u8 *)buf->getVertices(); for (u32 i = 0; i < vertex_count; i++) { video::S3DVertex *vertex = (video::S3DVertex *)(vertices + i * stride); video::SColor &vc = vertex->Color; if (vertex->Normal.Y < -0.5) { applyFacesShading (vc, 0.447213); } else if (vertex->Normal.Z > 0.5) { applyFacesShading (vc, 0.670820); } else if (vertex->Normal.Z < -0.5) { applyFacesShading (vc, 0.670820); } else if (vertex->Normal.X > 0.5) { applyFacesShading (vc, 0.836660); } else if (vertex->Normal.X < -0.5) { applyFacesShading (vc, 0.836660); } } } }
void translateMesh(scene::IMesh *mesh, v3f vec) { if (mesh == NULL) return; core::aabbox3d<f32> bbox; bbox.reset(0, 0, 0); u32 mc = mesh->getMeshBufferCount(); for (u32 j = 0; j < mc; j++) { scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); const u32 stride = getVertexPitchFromType(buf->getVertexType()); u32 vertex_count = buf->getVertexCount(); u8 *vertices = (u8 *)buf->getVertices(); for (u32 i = 0; i < vertex_count; i++) ((video::S3DVertex *)(vertices + i * stride))->Pos += vec; buf->recalculateBoundingBox(); // calculate total bounding box if (j == 0) bbox = buf->getBoundingBox(); else bbox.addInternalBox(buf->getBoundingBox()); } mesh->setBoundingBox(bbox); }
GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb) { GLMesh result = {}; if (!mb) return result; result.IndexCount = mb->getIndexCount(); switch (mb->getIndexType()) { case irr::video::EIT_16BIT: { result.IndexType = GL_UNSIGNED_SHORT; break; } case irr::video::EIT_32BIT: { result.IndexType = GL_UNSIGNED_INT; break; } default: { assert(0 && "Wrong index size"); } } result.VAOType = mb->getVertexType(); result.Stride = getVertexPitchFromType(result.VAOType); result.IndexCount = mb->getIndexCount(); switch (mb->getPrimitiveType()) { case scene::EPT_POINTS: result.PrimitiveType = GL_POINTS; break; case scene::EPT_TRIANGLE_STRIP: result.PrimitiveType = GL_TRIANGLE_STRIP; break; case scene::EPT_TRIANGLE_FAN: result.PrimitiveType = GL_TRIANGLE_FAN; break; case scene::EPT_LINES: result.PrimitiveType = GL_LINES; break; case scene::EPT_TRIANGLES: result.PrimitiveType = GL_TRIANGLES; break; case scene::EPT_POINT_SPRITES: case scene::EPT_LINE_LOOP: case scene::EPT_POLYGON: case scene::EPT_LINE_STRIP: case scene::EPT_QUAD_STRIP: case scene::EPT_QUADS: assert(0 && "Unsupported primitive type"); } for (unsigned i = 0; i < 6; i++) result.textures[i] = mb->getMaterial().getTexture(i); result.TextureMatrix = 0; result.VAOType = mb->getVertexType(); return result; }
void draw2DVertexPrimitiveList(video::ITexture *tex, const void* vertices, u32 vertexCount, const void* indexList, u32 primitiveCount, video::E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, video::E_INDEX_TYPE iType) { if (!irr_driver->isGLSL()) { irr_driver->getVideoDriver()->draw2DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType); return; } GLuint tmpvao, tmpvbo, tmpibo; primitiveCount += 2; glGenVertexArrays(1, &tmpvao); glBindVertexArray(tmpvao); glGenBuffers(1, &tmpvbo); glBindBuffer(GL_ARRAY_BUFFER, tmpvbo); glBufferData(GL_ARRAY_BUFFER, vertexCount * getVertexPitchFromType(vType), vertices, GL_STREAM_DRAW); glGenBuffers(1, &tmpibo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tmpibo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, primitiveCount * sizeof(u16), indexList, GL_STREAM_DRAW); VertexUtils::bindVertexArrayAttrib(vType); glUseProgram(UIShader::Primitive2DList::getInstance()->Program); UIShader::Primitive2DList::getInstance()->setUniforms(); const video::SOverrideMaterial &m = irr_driver->getVideoDriver()->getOverrideMaterial(); compressTexture(tex, false); UIShader::Primitive2DList::getInstance()->SetTextureUnits({ getTextureGLuint(tex) }); glDrawElements(GL_TRIANGLE_FAN, primitiveCount, GL_UNSIGNED_SHORT, 0); glDeleteVertexArrays(1, &tmpvao); glDeleteBuffers(1, &tmpvbo); glDeleteBuffers(1, &tmpibo); }
void setMeshColorByNormalXYZ(scene::IMesh *mesh, const video::SColor &colorX, const video::SColor &colorY, const video::SColor &colorZ) { if (mesh == NULL) return; u16 mc = mesh->getMeshBufferCount(); for (u16 j = 0; j < mc; j++) { scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); const u32 stride = getVertexPitchFromType(buf->getVertexType()); u32 vertex_count = buf->getVertexCount(); u8 *vertices = (u8 *)buf->getVertices(); for (u32 i = 0; i < vertex_count; i++) { video::S3DVertex *vertex = (video::S3DVertex *)(vertices + i * stride); f32 x = fabs(vertex->Normal.X); f32 y = fabs(vertex->Normal.Y); f32 z = fabs(vertex->Normal.Z); if (x >= y && x >= z) vertex->Color = colorX; else if (y >= z) vertex->Color = colorY; else vertex->Color = colorZ; } } }
void rotateMeshYZby(scene::IMesh *mesh, f64 degrees) { u16 mc = mesh->getMeshBufferCount(); for (u16 j = 0; j < mc; j++) { scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); const u32 stride = getVertexPitchFromType(buf->getVertexType()); u32 vertex_count = buf->getVertexCount(); u8 *vertices = (u8 *)buf->getVertices(); for (u32 i = 0; i < vertex_count; i++) ((video::S3DVertex *)(vertices + i * stride))->Pos.rotateYZBy(degrees); } }
void setMeshColor(scene::IMesh *mesh, const video::SColor &color) { if (mesh == NULL) return; u32 mc = mesh->getMeshBufferCount(); for (u32 j = 0; j < mc; j++) { scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); const u32 stride = getVertexPitchFromType(buf->getVertexType()); u32 vertex_count = buf->getVertexCount(); u8 *vertices = (u8 *)buf->getVertices(); for (u32 i = 0; i < vertex_count; i++) ((video::S3DVertex *)(vertices + i * stride))->Color = color; } }
// ---------------------------------------------------------------------------- void draw2DVertexPrimitiveList(video::ITexture *tex, const void* vertices, u32 vertexCount, const void* indexList, u32 primitiveCount, video::E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, video::E_INDEX_TYPE iType) { if (!CVS->isGLSL()) { irr_driver->getVideoDriver() ->draw2DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType); return; } GLuint tmpvao, tmpvbo, tmpibo; primitiveCount += 2; glGenVertexArrays(1, &tmpvao); glBindVertexArray(tmpvao); glGenBuffers(1, &tmpvbo); glBindBuffer(GL_ARRAY_BUFFER, tmpvbo); glBufferData(GL_ARRAY_BUFFER, vertexCount * getVertexPitchFromType(vType), vertices, GL_STREAM_DRAW); glGenBuffers(1, &tmpibo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tmpibo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, primitiveCount * sizeof(u16), indexList, GL_STREAM_DRAW); VertexUtils::bindVertexArrayAttrib(vType); Primitive2DList::getInstance()->use(); Primitive2DList::getInstance()->setUniforms(1.0f); Primitive2DList::getInstance()->setTextureUnits(tex->getOpenGLTextureName()); glDrawElements(GL_TRIANGLE_FAN, primitiveCount, GL_UNSIGNED_SHORT, 0); glDeleteVertexArrays(1, &tmpvao); glDeleteBuffers(1, &tmpvbo); glDeleteBuffers(1, &tmpibo); } // draw2DVertexPrimitiveList
GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb) { GLMesh result = {}; if (!mb) return result; glBindVertexArray(0); glGenBuffers(1, &(result.vertex_buffer)); glGenBuffers(1, &(result.index_buffer)); glBindBuffer(GL_ARRAY_BUFFER, result.vertex_buffer); const void* vertices = mb->getVertices(); const u32 vertexCount = mb->getVertexCount(); const irr::video::E_VERTEX_TYPE vType = mb->getVertexType(); result.Stride = getVertexPitchFromType(vType); const c8* vbuf = static_cast<const c8*>(vertices); glBufferData(GL_ARRAY_BUFFER, vertexCount * result.Stride, vbuf, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, result.index_buffer); const void* indices = mb->getIndices(); u32 indexCount = mb->getIndexCount(); GLenum indexSize; switch (mb->getIndexType()) { case irr::video::EIT_16BIT: { indexSize = sizeof(u16); result.IndexType = GL_UNSIGNED_SHORT; break; } case irr::video::EIT_32BIT: { indexSize = sizeof(u32); result.IndexType = GL_UNSIGNED_INT; break; } default: { assert(0 && "Wrong index size"); } } glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount * indexSize, indices, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); result.IndexCount = mb->getIndexCount(); switch (mb->getPrimitiveType()) { case scene::EPT_POINTS: result.PrimitiveType = GL_POINTS; break; case scene::EPT_TRIANGLE_STRIP: result.PrimitiveType = GL_TRIANGLE_STRIP; break; case scene::EPT_TRIANGLE_FAN: result.PrimitiveType = GL_TRIANGLE_FAN; break; case scene::EPT_LINES: result.PrimitiveType = GL_LINES; break; case scene::EPT_TRIANGLES: result.PrimitiveType = GL_TRIANGLES; break; case scene::EPT_POINT_SPRITES: case scene::EPT_LINE_LOOP: case scene::EPT_POLYGON: case scene::EPT_LINE_STRIP: case scene::EPT_QUAD_STRIP: case scene::EPT_QUADS: assert(0 && "Unsupported primitive type"); } ITexture *tex; for (unsigned i = 0; i < 6; i++) { tex = mb->getMaterial().getTexture(i); if (tex) result.textures[i] = getTextureGLuint(tex); else result.textures[i] = 0; } return result; }
GLuint createVAO(GLuint vbo, GLuint idx, video::E_VERTEX_TYPE type) { GLuint vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); assert(vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); switch (type) { case video::EVT_STANDARD: // Position glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, getVertexPitchFromType(type), 0); // Normal glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, getVertexPitchFromType(type), (GLvoid*)12); // Color glEnableVertexAttribArray(2); glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, getVertexPitchFromType(type), (GLvoid*)24); // Texcoord glEnableVertexAttribArray(3); glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, getVertexPitchFromType(type), (GLvoid*)28); break; case video::EVT_2TCOORDS: // Position glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, getVertexPitchFromType(type), 0); // Normal glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, getVertexPitchFromType(type), (GLvoid*)12); // Color glEnableVertexAttribArray(2); glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, getVertexPitchFromType(type), (GLvoid*)24); // Texcoord glEnableVertexAttribArray(3); glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, getVertexPitchFromType(type), (GLvoid*)28); // SecondTexcoord glEnableVertexAttribArray(4); glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, getVertexPitchFromType(type), (GLvoid*)36); break; case video::EVT_TANGENTS: // Position glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, getVertexPitchFromType(type), 0); // Normal glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, getVertexPitchFromType(type), (GLvoid*)12); // Color glEnableVertexAttribArray(2); glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, getVertexPitchFromType(type), (GLvoid*)24); // Texcoord glEnableVertexAttribArray(3); glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, getVertexPitchFromType(type), (GLvoid*)28); // Tangent glEnableVertexAttribArray(5); glVertexAttribPointer(5, 3, GL_FLOAT, GL_FALSE, getVertexPitchFromType(type), (GLvoid*)36); // Bitangent glEnableVertexAttribArray(6); glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, getVertexPitchFromType(type), (GLvoid*)48); break; default: assert(0 && "Wrong vertex type"); } assert(idx); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idx); return vao; }
void rotateMeshBy6dFacedir(scene::IMesh *mesh, int facedir) { int axisdir = facedir >> 2; facedir &= 0x03; u16 mc = mesh->getMeshBufferCount(); for (u16 j = 0; j < mc; j++) { scene::IMeshBuffer *buf = mesh->getMeshBuffer(j); const u32 stride = getVertexPitchFromType(buf->getVertexType()); u32 vertex_count = buf->getVertexCount(); u8 *vertices = (u8 *)buf->getVertices(); for (u32 i = 0; i < vertex_count; i++) { video::S3DVertex *vertex = (video::S3DVertex *)(vertices + i * stride); switch (axisdir) { case 0: if (facedir == 1) vertex->Pos.rotateXZBy(-90); else if (facedir == 2) vertex->Pos.rotateXZBy(180); else if (facedir == 3) vertex->Pos.rotateXZBy(90); break; case 1: // z+ vertex->Pos.rotateYZBy(90); if (facedir == 1) vertex->Pos.rotateXYBy(90); else if (facedir == 2) vertex->Pos.rotateXYBy(180); else if (facedir == 3) vertex->Pos.rotateXYBy(-90); break; case 2: //z- vertex->Pos.rotateYZBy(-90); if (facedir == 1) vertex->Pos.rotateXYBy(-90); else if (facedir == 2) vertex->Pos.rotateXYBy(180); else if (facedir == 3) vertex->Pos.rotateXYBy(90); break; case 3: //x+ vertex->Pos.rotateXYBy(-90); if (facedir == 1) vertex->Pos.rotateYZBy(90); else if (facedir == 2) vertex->Pos.rotateYZBy(180); else if (facedir == 3) vertex->Pos.rotateYZBy(-90); break; case 4: //x- vertex->Pos.rotateXYBy(90); if (facedir == 1) vertex->Pos.rotateYZBy(-90); else if (facedir == 2) vertex->Pos.rotateYZBy(180); else if (facedir == 3) vertex->Pos.rotateYZBy(90); break; case 5: vertex->Pos.rotateXYBy(-180); if (facedir == 1) vertex->Pos.rotateXZBy(90); else if (facedir == 2) vertex->Pos.rotateXZBy(180); else if (facedir == 3) vertex->Pos.rotateXZBy(-90); break; default: break; } } } }