Updated krmodel file format to support bone weights, physics collider meshes, and variable combinations of vertex attributes

--HG--
extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%40183
This commit is contained in:
kearwood
2012-12-10 21:09:14 +00:00
parent 317522edd3
commit 4f5fd10e71
17 changed files with 382 additions and 155 deletions

View File

@@ -350,7 +350,7 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
getContext().getTextureManager()->selectTexture(0, m_pSkyBoxTexture);
// Render a full screen quad
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, true, false, false, true, false);
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, true, false, false, true, false, false, false);
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
}
@@ -465,7 +465,7 @@ void KRCamera::renderFrame(KRScene &scene, float deltaTime) {
KRMat4 projectionMatrix = getProjectionMatrix();
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_3D_CUBE, KRENGINE_VBO_3D_CUBE_SIZE, true, false, false, false, false);
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_3D_CUBE, KRENGINE_VBO_3D_CUBE_SIZE, true, false, false, false, false, false, false);
for(std::map<KRAABB, int>::iterator itr=m_viewport.getVisibleBounds().begin(); itr != m_viewport.getVisibleBounds().end(); itr++) {
KRMat4 matModel = KRMat4();
matModel.scale((*itr).first.size() / 2.0f);
@@ -683,7 +683,7 @@ void KRCamera::renderPost()
}
// Update attribute values.
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, true, false, false, true, false);
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, true, false, false, true, false, false, false);
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
@@ -755,9 +755,9 @@ void KRCamera::renderPost()
#if GL_OES_vertex_array_object
GLDEBUG(glBindVertexArrayOES(0));
#endif
m_pContext->getModelManager()->configureAttribs(true, false, false, true, false);
GLDEBUG(glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_TEXUVA, 2, GL_FLOAT, 0, 0, charTexCoords));
GLDEBUG(glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, charVertices));
m_pContext->getModelManager()->configureAttribs(true, false, false, true, false, false, false);
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_TEXUVA, 2, GL_FLOAT, 0, 0, charTexCoords));
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, charVertices));
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
iPos++;

View File

@@ -135,7 +135,7 @@ void KRDirectionalLight::render(KRCamera *pCamera, std::vector<KRLight *> &light
GLDEBUG(glDisable(GL_DEPTH_TEST));
// Render a full screen quad
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, true, false, false, true, false);
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, true, false, false, true, false, false, false);
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
}
}

View File

@@ -201,7 +201,7 @@ void KRLight::render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KR
GLDEBUG(glUniform1f(pParticleShader->m_uniforms[KRShader::KRENGINE_UNIFORM_FLARE_SIZE], m_dust_particle_size));
m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), KRModelManager::KRENGINE_MAX_RANDOM_PARTICLES * 3 * sizeof(KRModelManager::RandomParticleVertexData), true, false, false, true, false);
m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), KRModelManager::KRENGINE_MAX_RANDOM_PARTICLES * 3 * sizeof(KRModelManager::RandomParticleVertexData), true, false, false, true, false, false, false);
GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, particle_count*3));
}
}
@@ -228,7 +228,7 @@ void KRLight::render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KR
KRVector2(slice_near, slice_spacing).setUniform(pFogShader->m_uniforms[KRShader::KRENGINE_UNIFORM_SLICE_DEPTH_SCALE]);
(m_color * pCamera->volumetric_environment_intensity * m_intensity * -slice_spacing / 1000.0f).setUniform(pFogShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_COLOR]);
m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getVolumetricLightingVertexes(), KRModelManager::KRENGINE_MAX_VOLUMETRIC_PLANES * 6 * sizeof(KRModelManager::VolumetricLightingVertexData), true, false, false, false, false);
m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getVolumetricLightingVertexes(), KRModelManager::KRENGINE_MAX_VOLUMETRIC_PLANES * 6 * sizeof(KRModelManager::VolumetricLightingVertexData), true, false, false, false, false, false, false);
GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, slice_count*6));
}
@@ -253,7 +253,7 @@ void KRLight::render(KRCamera *pCamera, std::vector<KRLight *> &lights, const KR
m_flareSize
));
m_pContext->getTextureManager()->selectTexture(0, m_pFlareTexture);
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, true, false, false, true, false);
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, true, false, false, true, false, false, false);
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
}
}

View File

@@ -104,7 +104,8 @@ void KRModel::loadPack(KRDataBlock *data) {
clearData();
delete m_pData;
m_pData = data;
pack_header *pHeader = (pack_header *)m_pData->getStart();
updateAttributeOffsets();
pack_header *pHeader = getHeader();
m_minPoint = KRVector3(pHeader->minx, pHeader->miny, pHeader->minz);
m_maxPoint = KRVector3(pHeader->maxx, pHeader->maxy, pHeader->maxz);
}
@@ -232,7 +233,7 @@ vector<KRModel::Submesh *> KRModel::getSubmeshes() {
}
void KRModel::renderSubmesh(int iSubmesh) {
VertexData *pVertexData = getVertexData();
unsigned char *pVertexData = getVertexData();
pack_header *pHeader = (pack_header *)m_pData->getStart();
int cBuffers = (pHeader->vertex_count + MAX_VBO_SIZE - 1) / MAX_VBO_SIZE;
@@ -246,7 +247,7 @@ void KRModel::renderSubmesh(int iSubmesh) {
int cVertexes = pSubmesh->vertex_count;
while(cVertexes > 0) {
GLsizei cBufferVertexes = iBuffer < cBuffers - 1 ? MAX_VBO_SIZE : pHeader->vertex_count % MAX_VBO_SIZE;
int vertex_size = sizeof(VertexData) ;
int vertex_size = m_vertex_size;
assert(pVertexData + iBuffer * MAX_VBO_SIZE * vertex_size >= m_pData->getStart());
void *vbo_end = (unsigned char *)pVertexData + iBuffer * MAX_VBO_SIZE * vertex_size + vertex_size * cBufferVertexes;
@@ -254,7 +255,9 @@ void KRModel::renderSubmesh(int iSubmesh) {
assert(vbo_end <= buffer_end);
assert(cBufferVertexes <= 65535);
m_pContext->getModelManager()->bindVBO((unsigned char *)pVertexData + iBuffer * MAX_VBO_SIZE * vertex_size, vertex_size * cBufferVertexes, true, true, true, true, true);
m_pContext->getModelManager()->bindVBO((unsigned char *)pVertexData + iBuffer * MAX_VBO_SIZE * vertex_size, vertex_size * cBufferVertexes, has_vertex_attribute(KRENGINE_ATTRIB_VERTEX), has_vertex_attribute(KRENGINE_ATTRIB_NORMAL), has_vertex_attribute(KRENGINE_ATTRIB_TANGENT), has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA), has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB), has_vertex_attribute(KRENGINE_ATTRIB_BONEINDEXES),
has_vertex_attribute(KRENGINE_ATTRIB_BONEWEIGHTS));
if(iVertex + cVertexes >= MAX_VBO_SIZE) {
@@ -274,27 +277,51 @@ void KRModel::renderSubmesh(int iSubmesh) {
}
}
KRModel::VertexData *KRModel::getVertexData() {
unsigned char *KRModel::getVertexData() const {
pack_header *pHeader = (pack_header *)m_pData->getStart();
pack_material *pPackMaterials = (pack_material *)(pHeader+1);
return (VertexData *)(pPackMaterials + pHeader->submesh_count);
return (unsigned char *)(pPackMaterials + pHeader->submesh_count);
}
void KRModel::LoadData(std::vector<KRVector3> vertices, std::vector<KRVector2> uva, std::vector<KRVector2> uvb, std::vector<KRVector3> normals, std::vector<KRVector3> tangents, std::vector<int> submesh_starts, std::vector<int> submesh_lengths, std::vector<std::string> material_names) {
clearData();
bool calculate_normals = true;
bool calculate_tangents = true;
__int32_t vertex_attrib_flags = 0;
if(vertices.size()) {
vertex_attrib_flags |= (1 << KRENGINE_ATTRIB_VERTEX);
}
if(normals.size() || calculate_normals) {
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_NORMAL);
}
if(tangents.size() || calculate_tangents) {
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TANGENT);
}
if(uva.size()) {
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVA);
}
if(uvb.size()) {
vertex_attrib_flags += (1 << KRENGINE_ATTRIB_TEXUVB);
}
size_t vertex_size = VertexSizeForAttributes(vertex_attrib_flags);
int submesh_count = submesh_lengths.size();
int vertex_count = vertices.size();
size_t new_file_size = sizeof(pack_header) + sizeof(pack_material) * submesh_count + sizeof(VertexData) * vertex_count;
size_t new_file_size = sizeof(pack_header) + sizeof(pack_material) * submesh_count + vertex_size * vertex_count;
m_pData->expand(new_file_size);
pack_header *pHeader = (pack_header *)m_pData->getStart();
memset(pHeader, 0, sizeof(pack_header));
pHeader->vertex_attrib_flags = vertex_attrib_flags;
pHeader->submesh_count = submesh_lengths.size();
pHeader->vertex_count = vertices.size();
strcpy(pHeader->szTag, "KROBJPACK1.0 ");
strcpy(pHeader->szTag, "KROBJPACK1.1 ");
updateAttributeOffsets();
pack_material *pPackMaterials = (pack_material *)(pHeader+1);
@@ -307,14 +334,12 @@ void KRModel::LoadData(std::vector<KRVector3> vertices, std::vector<KRVector2> u
bool bFirstVertex = true;
VertexData *pVertexData = (VertexData *)(pPackMaterials + pHeader->submesh_count);
VertexData *pVertex = pVertexData;
// VertexData *pVertexData = (VertexData *)(pPackMaterials + pHeader->submesh_count);
// VertexData *pVertex = pVertexData;
memset(getVertexData(), 0, m_vertex_size * vertices.size());
for(int iVertex=0; iVertex < vertices.size(); iVertex++) {
memset(pVertex, 0, sizeof(VertexData));
KRVector3 source_vertex = vertices[iVertex];
pVertex->vertex.x = source_vertex.x;
pVertex->vertex.y = source_vertex.y;
pVertex->vertex.z = source_vertex.z;
setVertexPosition(iVertex, source_vertex);
if(bFirstVertex) {
bFirstVertex = false;
m_minPoint = source_vertex;
@@ -328,43 +353,25 @@ void KRModel::LoadData(std::vector<KRVector3> vertices, std::vector<KRVector2> u
if(source_vertex.z > m_maxPoint.z) m_maxPoint.z = source_vertex.z;
}
if(uva.size() > iVertex) {
KRVector2 source_uva = uva[iVertex];
pVertex->uva.u = source_uva.x;
pVertex->uva.v = source_uva.y;
setVertexUVA(iVertex, uva[iVertex]);
} else {
pVertex->uva.u = 0.0;
pVertex->uva.v = 0.0;
setVertexUVA(iVertex, KRVector2::Zero());
}
if(uvb.size() > iVertex) {
KRVector2 source_uvb = uvb[iVertex];
pVertex->uvb.u = source_uvb.x;
pVertex->uvb.v = source_uvb.y;
setVertexUVB(iVertex, uvb[iVertex]);
} else {
pVertex->uvb.u = 0.0;
pVertex->uvb.v = 0.0;
setVertexUVB(iVertex, KRVector2::Zero());
}
if(normals.size() > iVertex) {
KRVector3 source_normal = normals[iVertex];
pVertex->normal.x = source_normal.x;
pVertex->normal.y = source_normal.y;
pVertex->normal.z = source_normal.z;
setVertexNormal(iVertex, normals[iVertex]);
} else {
pVertex->normal.x = 0.0f;
pVertex->normal.y = 0.0f;
pVertex->normal.z = 0.0f;
setVertexNormal(iVertex, KRVector3::Zero());
}
if(tangents.size() > iVertex) {
KRVector3 source_tangent = tangents[iVertex];
pVertex->tangent.x = source_tangent.x;
pVertex->tangent.y = source_tangent.y;
pVertex->tangent.z = source_tangent.z;
setVertexTangent(iVertex, tangents[iVertex]);
} else {
pVertex->tangent.x = 0.0f;
pVertex->tangent.y = 0.0f;
pVertex->tangent.z = 0.0f;
setVertexTangent(iVertex, KRVector3::Zero());
}
pVertex++;
}
pHeader->minx = m_minPoint.x;
@@ -377,67 +384,53 @@ void KRModel::LoadData(std::vector<KRVector3> vertices, std::vector<KRVector2> u
// Calculate missing surface normals and tangents
//cout << " Calculate surface normals and tangents\n";
VertexData *pStart = pVertexData;
VertexData *pEnd = pStart + vertex_count;
for(VertexData *pVertex = pStart; pVertex < pEnd; pVertex+=3) {
KRVector3 p1(pVertex[0].vertex.x, pVertex[0].vertex.y, pVertex[0].vertex.z);
KRVector3 p2(pVertex[1].vertex.x, pVertex[1].vertex.y, pVertex[1].vertex.z);
KRVector3 p3(pVertex[2].vertex.x, pVertex[2].vertex.y, pVertex[2].vertex.z);
for(int iVertex=0; iVertex < vertices.size(); iVertex+= 3) {
KRVector3 p1 = getVertexPosition(iVertex);
KRVector3 p2 = getVertexPosition(iVertex+1);
KRVector3 p3 = getVertexPosition(iVertex+2);
KRVector3 v1 = p2 - p1;
KRVector3 v2 = p3 - p1;
// -- Calculate normal --
if(pVertex->normal.x == 0 && pVertex->normal.y == 0 && pVertex->normal.z == 0) {
KRVector3 normal = KRVector3::Cross(v1, v2);
normal.normalize();
pVertex[0].normal.x = normal.x;
pVertex[0].normal.y = normal.y;
pVertex[0].normal.z = normal.z;
pVertex[1].normal.x = normal.x;
pVertex[1].normal.y = normal.y;
pVertex[1].normal.z = normal.z;
pVertex[2].normal.x = normal.x;
pVertex[2].normal.y = normal.y;
pVertex[2].normal.z = normal.z;
// -- Calculate normal if missing --
if(calculate_normals) {
KRVector3 first_normal = getVertexNormal(iVertex);
if(first_normal.x == 0.0f && first_normal.y == 0.0f && first_normal.z == 0.0f) {
// Note - We don't take into consideration smoothing groups or smoothing angles when generating normals; all generated normals represent flat shaded polygons
KRVector3 normal = KRVector3::Cross(v1, v2);
normal.normalize();
setVertexNormal(iVertex, normal);
setVertexNormal(iVertex+1, normal);
setVertexNormal(iVertex+2, normal);
}
}
// -- Calculate tangent vector for normal mapping --
if(pVertex->tangent.x == 0 && pVertex->tangent.y == 0 && pVertex->tangent.z == 0) {
TexCoord st1; // = pVertex[2].texcoord;
TexCoord st2; // = pVertex[1].texcoord;
st1.u = pVertex[1].uva.u - pVertex[0].uva.u;
st1.v = pVertex[1].uva.v - pVertex[0].uva.v;
st2.u = pVertex[2].uva.u - pVertex[0].uva.u;
st2.v = pVertex[2].uva.v - pVertex[0].uva.v;
double coef = 1/ (st1.u * st2.v - st2.u * st1.v);
pVertex[0].tangent.x = coef * ((v1.x * st2.v) + (v2.x * -st1.v));
pVertex[0].tangent.y = coef * ((v1.y * st2.v) + (v2.y * -st1.v));
pVertex[0].tangent.z = coef * ((v1.z * st2.v) + (v2.z * -st1.v));
KRVector3 tangent(
coef * ((v1.x * st2.v) + (v2.x * -st1.v)),
coef * ((v1.y * st2.v) + (v2.y * -st1.v)),
coef * ((v1.z * st2.v) + (v2.z * -st1.v))
);
tangent.normalize();
pVertex[0].tangent.x = tangent.x;
pVertex[0].tangent.y = tangent.y;
pVertex[0].tangent.z = tangent.z;
pVertex[1].tangent.x = tangent.x;
pVertex[1].tangent.y = tangent.y;
pVertex[1].tangent.z = tangent.z;
pVertex[2].tangent.x = tangent.x;
pVertex[2].tangent.y = tangent.y;
pVertex[2].tangent.z = tangent.z;
if(calculate_tangents) {
KRVector3 first_tangent = getVertexTangent(iVertex);
if(first_tangent.x == 0.0f && first_tangent.y == 0.0f && first_tangent.z == 0.0f) {
KRVector2 uv0 = getVertexUVA(iVertex);
KRVector2 uv1 = getVertexUVA(iVertex + 1);
KRVector2 uv2 = getVertexUVA(iVertex + 2);
KRVector2 st1 = KRVector2(uv1.x - uv0.x, uv1.y - uv0.y);
KRVector2 st2 = KRVector2(uv2.x - uv0.x, uv2.y - uv0.y);
double coef = 1/ (st1.x * st2.y - st2.x * st1.y);
KRVector3 tangent(
coef * ((v1.x * st2.y) + (v2.x * -st1.y)),
coef * ((v1.y * st2.y) + (v2.y * -st1.y)),
coef * ((v1.z * st2.y) + (v2.z * -st1.y))
);
tangent.normalize();
setVertexTangent(iVertex, tangent);
setVertexTangent(iVertex+1, tangent);
setVertexTangent(iVertex+2, tangent);
}
}
}
}
@@ -472,3 +465,158 @@ bool KRModel::lod_sort_predicate(const KRModel *m1, const KRModel *m2)
return m1->m_lodCoverage > m2->m_lodCoverage;
}
bool KRModel::has_vertex_attribute(vertex_attrib_t attribute_type) const
{
return (getHeader()->vertex_attrib_flags & (1 << attribute_type)) != 0;
}
KRModel::pack_header *KRModel::getHeader() const
{
return (pack_header *)m_pData->getStart();
}
KRModel::pack_material *KRModel::getSubmesh(int mesh_index)
{
return (pack_material *)(getHeader()+1) + mesh_index;
}
unsigned char *KRModel::getVertexData(int index) const
{
return getVertexData() + m_vertex_size * index;
}
int KRModel::getSubmeshCount()
{
pack_header *header = (pack_header *)m_pData->getStart();
return header->submesh_count;
}
int KRModel::getVertexCount(int submesh)
{
return getSubmesh(submesh)->vertex_count;
}
KRVector3 KRModel::getVertexPosition(int index) const
{
if(has_vertex_attribute(KRENGINE_ATTRIB_VERTEX)) {
return KRVector3((float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_VERTEX]));
} else {
return KRVector3::Zero();
}
}
KRVector3 KRModel::getVertexNormal(int index) const
{
if(has_vertex_attribute(KRENGINE_ATTRIB_NORMAL)) {
return KRVector3((float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_NORMAL]));
} else {
return KRVector3::Zero();
}
}
KRVector3 KRModel::getVertexTangent(int index) const
{
if(has_vertex_attribute(KRENGINE_ATTRIB_TANGENT)) {
return KRVector3((float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TANGENT]));
} else {
return KRVector3::Zero();
}
}
KRVector2 KRModel::getVertexUVA(int index) const
{
if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVA)) {
return KRVector2((float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVA]));
} else {
return KRVector2::Zero();
}
}
KRVector2 KRModel::getVertexUVB(int index) const
{
if(has_vertex_attribute(KRENGINE_ATTRIB_TEXUVB)) {
return KRVector2((float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVB]));
} else {
return KRVector2::Zero();
}
}
void KRModel::setVertexPosition(int index, const KRVector3 &v)
{
float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_VERTEX]);
vert[0] = v.x;
vert[1] = v.y;
vert[2] = v.z;
}
void KRModel::setVertexNormal(int index, const KRVector3 &v)
{
float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_NORMAL]);
vert[0] = v.x;
vert[1] = v.y;
vert[2] = v.z;
}
void KRModel::setVertexTangent(int index, const KRVector3 & v)
{
float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TANGENT]);
vert[0] = v.x;
vert[1] = v.y;
vert[2] = v.z;
}
void KRModel::setVertexUVA(int index, const KRVector2 &v)
{
float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVA]);
vert[0] = v.x;
vert[1] = v.y;
}
void KRModel::setVertexUVB(int index, const KRVector2 &v)
{
float *vert = (float *)(getVertexData(index) + m_vertex_attribute_offset[KRENGINE_ATTRIB_TEXUVB]);
vert[0] = v.x;
vert[1] = v.y;
}
size_t KRModel::VertexSizeForAttributes(__int32_t vertex_attrib_flags)
{
size_t data_size = 0;
if(vertex_attrib_flags & (1 << KRENGINE_ATTRIB_VERTEX)) {
data_size += sizeof(float) * 3;
}
if(vertex_attrib_flags & (1 << KRENGINE_ATTRIB_NORMAL)) {
data_size += sizeof(float) * 3;
}
if(vertex_attrib_flags & (1 << KRENGINE_ATTRIB_TANGENT)) {
data_size += sizeof(float) * 3;
}
if(vertex_attrib_flags & (1 << KRENGINE_ATTRIB_TEXUVA)) {
data_size += sizeof(float) * 2;
}
if(vertex_attrib_flags & (1 << KRENGINE_ATTRIB_TEXUVB)) {
data_size += sizeof(float) * 2;
}
if(vertex_attrib_flags & (1 << KRENGINE_ATTRIB_BONEINDEXES)) {
data_size += 4; // 4 bytes
}
if(vertex_attrib_flags & (1 << KRENGINE_ATTRIB_BONEWEIGHTS)) {
data_size += sizeof(float) * 4;
}
return data_size;
}
void KRModel::updateAttributeOffsets()
{
pack_header *header = getHeader();
int mask = 0;
for(int i=0; i < KRENGINE_NUM_ATTRIBUTES; i++) {
if(has_vertex_attribute((vertex_attrib_t)i)) {
m_vertex_attribute_offset[i] = VertexSizeForAttributes(header->vertex_attrib_flags & mask);
} else {
m_vertex_attribute_offset[i] = -1;
}
mask = (mask << 1) & 1;
}
m_vertex_size = VertexSizeForAttributes(header->vertex_attrib_flags);
}

View File

@@ -89,6 +89,22 @@ public:
KRVector3 getMinPoint() const;
KRVector3 getMaxPoint() const;
typedef enum {
KRENGINE_ATTRIB_VERTEX = 0,
KRENGINE_ATTRIB_NORMAL,
KRENGINE_ATTRIB_TANGENT,
KRENGINE_ATTRIB_TEXUVA,
KRENGINE_ATTRIB_TEXUVB,
KRENGINE_ATTRIB_BONEINDEXES,
KRENGINE_ATTRIB_BONEWEIGHTS,
KRENGINE_NUM_ATTRIBUTES
} vertex_attrib_t;
typedef enum {
KRENGINE_MODEL_FORMAT_TRIANGLES = 1,
KRENGINE_MODEL_FORMAT_INDEXED
} model_format_t;
typedef struct {
GLint start_vertex;
GLsizei vertex_count;
@@ -114,8 +130,6 @@ public:
TexCoord uvb;
} VertexData;
VertexData *getVertexData();
vector<Submesh *> getSubmeshes();
typedef struct {
@@ -129,6 +143,20 @@ public:
static bool lod_sort_predicate(const KRModel *m1, const KRModel *m2);
bool has_vertex_attribute(vertex_attrib_t attribute_type) const;
int getSubmeshCount();
int getVertexCount(int submesh);
KRVector3 getVertexPosition(int index) const;
KRVector3 getVertexNormal(int index) const;
KRVector3 getVertexTangent(int index) const;
KRVector2 getVertexUVA(int index) const;
KRVector2 getVertexUVB(int index) const;
void setVertexPosition(int index, const KRVector3 &v);
void setVertexNormal(int index, const KRVector3 &v);
void setVertexTangent(int index, const KRVector3 & v);
void setVertexUVA(int index, const KRVector2 &v);
void setVertexUVB(int index, const KRVector2 &v);
private:
int m_lodCoverage; // This LOD level is activated when the bounding box of the model will cover less than this percent of the screen (100 = highest detail model)
@@ -144,17 +172,31 @@ private:
typedef struct {
char szTag[16];
float minx, miny, minz, maxx, maxy, maxz;
int32_t format_type; // 0 == Triangle list, 1 == Indexed list, rest are reserved (model_format_t enum)
int32_t vertex_attrib_flags;
int32_t vertex_count;
int32_t submesh_count;
float minx, miny, minz, maxx, maxy, maxz; // Axis aligned bounding box, in model's coordinate space
unsigned char reserved[412]; // Pad out to 512 bytes
} pack_header;
vector<Submesh *> m_submeshes;
int m_vertex_attribute_offset[KRENGINE_NUM_ATTRIBUTES];
int m_vertex_size;
void updateAttributeOffsets();
void clearData();
void clearBuffers();
void setName(const std::string name);
static size_t VertexSizeForAttributes(__int32_t vertex_attrib_flags);
pack_material *getSubmesh(int mesh_index);
unsigned char *getVertexData() const;
unsigned char *getVertexData(int index) const;
pack_header *getHeader() const;
};

View File

@@ -101,7 +101,7 @@ void KRModelManager::unbindVBO() {
}
}
void KRModelManager::bindVBO(GLvoid *data, GLsizeiptr size, bool enable_vertex, bool enable_normal, bool enable_tangent, bool enable_uva, bool enable_uvb) {
void KRModelManager::bindVBO(GLvoid *data, GLsizeiptr size, bool enable_vertex, bool enable_normal, bool enable_tangent, bool enable_uva, bool enable_uvb, bool enable_bone_indexes, bool enable_bone_weights) {
if(m_currentVBO.data != data || m_currentVBO.size != size) {
@@ -111,7 +111,7 @@ void KRModelManager::bindVBO(GLvoid *data, GLsizeiptr size, bool enable_vertex,
GLDEBUG(glBindVertexArrayOES(m_currentVBO.vao_handle));
#else
GLDEBUG(glBindBuffer(GL_ARRAY_BUFFER, m_currentVBO.vbo_handle));
configureAttribs(enable_vertex, enable_normal, enable_tangent, enable_uva, enable_uvb);
configureAttribs(enable_vertex, enable_normal, enable_tangent, enable_uva, enable_uvb, enable_bone_indexes, enable_bone_weights);
#endif
} else if(m_vbosPool.find(data) != m_vbosPool.end()) {
m_currentVBO = m_vbosPool[data];
@@ -121,7 +121,7 @@ void KRModelManager::bindVBO(GLvoid *data, GLsizeiptr size, bool enable_vertex,
GLDEBUG(glBindVertexArrayOES(m_currentVBO.vao_handle));
#else
GLDEBUG(glBindBuffer(GL_ARRAY_BUFFER, m_currentVBO.vbo_handle));
configureAttribs(enable_vertex, enable_normal, enable_tangent, enable_uva, enable_uvb);
configureAttribs(enable_vertex, enable_normal, enable_tangent, enable_uva, enable_uvb, enable_bone_indexes, enable_bone_weights);
#endif
} else {
@@ -153,7 +153,7 @@ void KRModelManager::bindVBO(GLvoid *data, GLsizeiptr size, bool enable_vertex,
GLDEBUG(glBindBuffer(GL_ARRAY_BUFFER, m_currentVBO.vbo_handle));
GLDEBUG(glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW));
m_vboMemUsed += size;
configureAttribs(enable_vertex, enable_normal, enable_tangent, enable_uva, enable_uvb);
configureAttribs(enable_vertex, enable_normal, enable_tangent, enable_uva, enable_uvb, enable_bone_indexes, enable_bone_weights);
m_currentVBO.size = size;
m_currentVBO.data = data;
@@ -163,76 +163,102 @@ void KRModelManager::bindVBO(GLvoid *data, GLsizeiptr size, bool enable_vertex,
}
}
void KRModelManager::configureAttribs(bool enable_vertex, bool enable_normal, bool enable_tangent, bool enable_uva, bool enable_uvb)
void KRModelManager::configureAttribs(bool enable_vertex, bool enable_normal, bool enable_tangent, bool enable_uva, bool enable_uvb, bool enable_bone_indexes, bool enable_bone_weights)
{
if(enable_vertex) {
GLDEBUG(glEnableVertexAttribArray(KRShader::KRENGINE_ATTRIB_VERTEX));
GLDEBUG(glEnableVertexAttribArray(KRModel::KRENGINE_ATTRIB_VERTEX));
} else {
GLDEBUG(glDisableVertexAttribArray(KRShader::KRENGINE_ATTRIB_VERTEX));
GLDEBUG(glDisableVertexAttribArray(KRModel::KRENGINE_ATTRIB_VERTEX));
}
if(enable_normal) {
GLDEBUG(glEnableVertexAttribArray(KRShader::KRENGINE_ATTRIB_NORMAL));
GLDEBUG(glEnableVertexAttribArray(KRModel::KRENGINE_ATTRIB_NORMAL));
} else {
GLDEBUG(glDisableVertexAttribArray(KRShader::KRENGINE_ATTRIB_NORMAL));
GLDEBUG(glDisableVertexAttribArray(KRModel::KRENGINE_ATTRIB_NORMAL));
}
if(enable_tangent) {
GLDEBUG(glEnableVertexAttribArray(KRShader::KRENGINE_ATTRIB_TANGENT));
GLDEBUG(glEnableVertexAttribArray(KRModel::KRENGINE_ATTRIB_TANGENT));
} else {
GLDEBUG(glDisableVertexAttribArray(KRShader::KRENGINE_ATTRIB_TANGENT));
GLDEBUG(glDisableVertexAttribArray(KRModel::KRENGINE_ATTRIB_TANGENT));
}
if(enable_uva) {
GLDEBUG(glEnableVertexAttribArray(KRShader::KRENGINE_ATTRIB_TEXUVA));
GLDEBUG(glEnableVertexAttribArray(KRModel::KRENGINE_ATTRIB_TEXUVA));
} else {
GLDEBUG(glDisableVertexAttribArray(KRShader::KRENGINE_ATTRIB_TEXUVA));
GLDEBUG(glDisableVertexAttribArray(KRModel::KRENGINE_ATTRIB_TEXUVA));
}
if(enable_uvb) {
GLDEBUG(glEnableVertexAttribArray(KRShader::KRENGINE_ATTRIB_TEXUVB));
GLDEBUG(glEnableVertexAttribArray(KRModel::KRENGINE_ATTRIB_TEXUVB));
} else {
GLDEBUG(glDisableVertexAttribArray(KRShader::KRENGINE_ATTRIB_TEXUVB));
GLDEBUG(glDisableVertexAttribArray(KRModel::KRENGINE_ATTRIB_TEXUVB));
}
if(enable_bone_indexes) {
GLDEBUG(glEnableVertexAttribArray(KRModel::KRENGINE_ATTRIB_BONEINDEXES));
} else {
GLDEBUG(glDisableVertexAttribArray(KRModel::KRENGINE_ATTRIB_BONEINDEXES));
}
if(enable_bone_weights) {
GLDEBUG(glEnableVertexAttribArray(KRModel::KRENGINE_ATTRIB_BONEWEIGHTS));
} else {
GLDEBUG(glDisableVertexAttribArray(KRModel::KRENGINE_ATTRIB_BONEWEIGHTS));
}
int data_size = 0;
if(enable_vertex) {
data_size += sizeof(KRModel::KRVector3D);
data_size += sizeof(GLfloat) * 3;
}
if(enable_normal) {
data_size += sizeof(KRModel::KRVector3D);
data_size += sizeof(GLfloat) * 3;
}
if(enable_tangent) {
data_size += sizeof(KRModel::KRVector3D);
data_size += sizeof(GLfloat) * 3;
}
if(enable_uva) {
data_size += sizeof(KRModel::TexCoord);
data_size += sizeof(GLfloat) * 2;
}
if(enable_uvb) {
data_size += sizeof(KRModel::TexCoord);
data_size += sizeof(GLfloat) * 2;
}
if(enable_bone_indexes ) {
data_size += 4; // 4 bytes
}
if(enable_bone_weights) {
data_size += sizeof(GLfloat) * 4;
}
int offset = 0;
if(enable_vertex) {
GLDEBUG(glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_VERTEX, 3, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset)));
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_VERTEX, 3, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset)));
offset += sizeof(KRModel::KRVector3D);
}
if(enable_normal) {
GLDEBUG(glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_NORMAL, 3, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset)));
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_NORMAL, 3, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset)));
offset += sizeof(KRModel::KRVector3D);
}
if(enable_tangent) {
GLDEBUG(glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_TANGENT, 3, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset)));
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_TANGENT, 3, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset)));
offset += sizeof(KRModel::KRVector3D);
}
if(enable_uva) {
GLDEBUG(glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_TEXUVA, 2, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset)));
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_TEXUVA, 2, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset)));
offset += sizeof(KRModel::TexCoord);
}
if(enable_uvb) {
GLDEBUG(glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_TEXUVB, 2, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset)));
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_TEXUVB, 2, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset)));
offset += sizeof(KRModel::TexCoord);
}
if(enable_bone_indexes ) {
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_BONEINDEXES, 1, GL_UNSIGNED_BYTE, 0, data_size, BUFFER_OFFSET(offset)));
offset += 4; // 4 bytes
}
if(enable_bone_weights) {
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_BONEWEIGHTS, 4, GL_FLOAT, 0, data_size, BUFFER_OFFSET(offset)));
offset += sizeof(GLfloat) * 4;
}
}
long KRModelManager::getMemUsed()

View File

@@ -60,11 +60,11 @@ public:
std::multimap<std::string, KRModel *> getModels();
void bindVBO(GLvoid *data, GLsizeiptr size, bool enable_vertex, bool enable_normal, bool enable_tangent, bool enable_uva, bool enable_uvb);
void bindVBO(GLvoid *data, GLsizeiptr size, bool enable_vertex, bool enable_normal, bool enable_tangent, bool enable_uva, bool enable_uvb, bool enable_bone_indexes, bool enable_bone_weights);
void unbindVBO();
long getMemUsed();
void configureAttribs(bool enable_vertex, bool enable_normal, bool enable_tangent, bool enable_uva, bool enable_uvb);
void configureAttribs(bool enable_vertex, bool enable_normal, bool enable_tangent, bool enable_uva, bool enable_uvb, bool enable_bone_indexes, bool enable_bone_weights);
typedef struct {

View File

@@ -79,7 +79,7 @@ void KRParticleSystemNewtonian::render(KRCamera *pCamera, std::vector<KRLight *>
1.0f
));
m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), particle_count * 3 * sizeof(KRModelManager::RandomParticleVertexData), true, false, false, true, false);
m_pContext->getModelManager()->bindVBO((void *)m_pContext->getModelManager()->getRandomParticles(), particle_count * 3 * sizeof(KRModelManager::RandomParticleVertexData), true, false, false, true, false, false, false);
GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, particle_count*3));
}
}

View File

@@ -112,13 +112,13 @@ void KRPointLight::render(KRCamera *pCamera, std::vector<KRLight *> &lights, con
GLDEBUG(glDisable(GL_DEPTH_TEST));
// Render a full screen quad
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, true, false, false, true, false);
m_pContext->getModelManager()->bindVBO((void *)KRENGINE_VBO_2D_SQUARE, KRENGINE_VBO_2D_SQUARE_SIZE, true, false, false, true, false, false, false);
GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
} else {
#if GL_OES_vertex_array_object
GLDEBUG(glBindVertexArrayOES(0));
#endif
m_pContext->getModelManager()->configureAttribs(true, false, false, false, false);
m_pContext->getModelManager()->configureAttribs(true, false, false, false, false, false, false);
// Render sphere of light's influence
generateMesh();
@@ -127,7 +127,7 @@ void KRPointLight::render(KRCamera *pCamera, std::vector<KRLight *> &lights, con
GLDEBUG(glDepthFunc(GL_LEQUAL));
GLDEBUG(glDepthRangef(0.0, 1.0));
GLDEBUG(glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_VERTEX, 3, GL_FLOAT, 0, 0, m_sphereVertices));
GLDEBUG(glVertexAttribPointer(KRModel::KRENGINE_ATTRIB_VERTEX, 3, GL_FLOAT, 0, 0, m_sphereVertices));
GLDEBUG(glDrawArrays(GL_TRIANGLES, 0, m_cVertices));
}
}

View File

@@ -700,6 +700,12 @@ KRNode *LoadMesh(KRNode *parent_node, std::vector<KRResource *> &resources, FbxG
KFbxMesh* pSourceMesh = (KFbxMesh*) pNode->GetNodeAttribute();
KFbxMesh* pMesh = pGeometryConverter->TriangulateMesh(pSourceMesh);
int skin_count = pMesh->GetDeformerCount(FbxDeformer::eSkin);
for(int skin_index=0; skin_index<skin_count; skin_index++) {
FbxSkin *skin = (FbxSkin *)pMesh->GetDeformer(skin_index, FbxDeformer::eSkin);
skin->GetControlPointBlendWeights()
}
KFbxVector4* control_points = pMesh->GetControlPoints();
int polygon_count = pMesh->GetPolygonCount();

View File

@@ -221,7 +221,7 @@ void KRScene::render(KROctreeNode *pOctreeNode, std::map<KRAABB, int> &visibleBo
KRMat4 mvpmatrix = matModel * viewport.getViewProjectionMatrix();
getContext().getModelManager()->bindVBO((void *)KRENGINE_VBO_3D_CUBE, KRENGINE_VBO_3D_CUBE_SIZE, true, false, false, false, false);
getContext().getModelManager()->bindVBO((void *)KRENGINE_VBO_3D_CUBE, KRENGINE_VBO_3D_CUBE_SIZE, true, false, false, false, false, false, false);
// Enable additive blending
if(renderPass != KRNode::RENDER_PASS_FORWARD_TRANSPARENT && renderPass != KRNode::RENDER_PASS_ADDITIVE_PARTICLES && renderPass != KRNode::RENDER_PASS_VOLUMETRIC_EFFECTS_ADDITIVE) {

View File

@@ -88,12 +88,13 @@ KRShader::KRShader(KRContext &context, char *szKey, std::string options, std::st
// Bind attribute locations.
// This needs to be done prior to linking.
GLDEBUG(glBindAttribLocation(m_iProgram, KRENGINE_ATTRIB_VERTEX, "vertex_position"));
GLDEBUG(glBindAttribLocation(m_iProgram, KRENGINE_ATTRIB_NORMAL, "vertex_normal"));
GLDEBUG(glBindAttribLocation(m_iProgram, KRENGINE_ATTRIB_TANGENT, "vertex_tangent"));
GLDEBUG(glBindAttribLocation(m_iProgram, KRENGINE_ATTRIB_TEXUVA, "vertex_uv"));
GLDEBUG(glBindAttribLocation(m_iProgram, KRENGINE_ATTRIB_TEXUVB, "vertex_lightmap_uv"));
GLDEBUG(glBindAttribLocation(m_iProgram, KRModel::KRENGINE_ATTRIB_VERTEX, "vertex_position"));
GLDEBUG(glBindAttribLocation(m_iProgram, KRModel::KRENGINE_ATTRIB_NORMAL, "vertex_normal"));
GLDEBUG(glBindAttribLocation(m_iProgram, KRModel::KRENGINE_ATTRIB_TANGENT, "vertex_tangent"));
GLDEBUG(glBindAttribLocation(m_iProgram, KRModel::KRENGINE_ATTRIB_TEXUVA, "vertex_uv"));
GLDEBUG(glBindAttribLocation(m_iProgram, KRModel::KRENGINE_ATTRIB_TEXUVB, "vertex_lightmap_uv"));
GLDEBUG(glBindAttribLocation(m_iProgram, KRModel::KRENGINE_ATTRIB_BONEINDEXES, "bone_indexes"));
GLDEBUG(glBindAttribLocation(m_iProgram, KRModel::KRENGINE_ATTRIB_BONEWEIGHTS, "bone_weights"));
// Link program.
GLDEBUG(glLinkProgram(m_iProgram));

View File

@@ -60,15 +60,6 @@ public:
#endif
enum {
KRENGINE_ATTRIB_VERTEX,
KRENGINE_ATTRIB_NORMAL,
KRENGINE_ATTRIB_TANGENT,
KRENGINE_ATTRIB_TEXUVA,
KRENGINE_ATTRIB_TEXUVB,
KRENGINE_NUM_ATTRIBUTES
};
enum {
KRENGINE_UNIFORM_MATERIAL_AMBIENT,
KRENGINE_UNIFORM_MATERIAL_DIFFUSE,

View File

@@ -26,6 +26,11 @@ KRVector2::KRVector2(float v) {
y = v;
}
KRVector2::KRVector2(float *v) {
x = v[0];
y = v[1];
}
KRVector2::KRVector2(const KRVector2 &v) {
x = v.x;
y = v.y;

View File

@@ -42,6 +42,7 @@ public:
KRVector2();
KRVector2(float X, float Y);
KRVector2(float v);
KRVector2(float *v);
KRVector2(const KRVector2 &v);
~KRVector2();

View File

@@ -48,6 +48,12 @@ KRVector3::KRVector3(const KRVector3 &v) {
z = v.z;
}
KRVector3::KRVector3(float *v) {
x = v[0];
y = v[1];
z = v[2];
}
KRVector3 KRVector3::Min() {
return KRVector3(-std::numeric_limits<float>::max());
}

View File

@@ -42,6 +42,7 @@ public:
KRVector3();
KRVector3(float X, float Y, float Z);
KRVector3(float v);
KRVector3(float *v);
KRVector3(const KRVector3 &v);
~KRVector3();