Extending Ifc::batch to handle deformable models | << Home
batch_deform.vert
attribute vec3 vtx_pos;
attribute vec3 vtx_nrm;
attribute vec2 vtx_tex;
attribute vec4 vtx_clr;
attribute vec4 vtx_wgt;
attribute vec4 vtx_idx;
uniform mat4 prm_viewproj;
uniform mat4 prm_xforms[128];
varying vec4 pix_clr;
void main() {
pix_clr = vtx_clr;
ivec4 idx = ivec4(vtx_idx);
mat4 m = prm_xforms[idx.x] * vtx_wgt.x
+ prm_xforms[idx.y] * vtx_wgt.y
+ prm_xforms[idx.z] * vtx_wgt.z
+ prm_xforms[idx.w] * vtx_wgt.w;
vec3 pos = (m * vec4(vtx_pos, 1.0)).xyz;
gl_Position = prm_viewproj * vec4(pos, 1.0);
}
draw_simple_ogl.cpp
static void batch_impl(cxModelWork* pWk, const int ibat, const Draw::Mode mode, const Draw::Context* pCtx) {
if (mode == Draw::DRWMODE_SHADOW_CAST) return;
if (!pCtx) return;
if (!pWk) return;
sxModelData* pMdl = pWk->mpData;
if (!pMdl) return;
if (!pMdl->ck_batch_id(ibat)) return;
bool skinFlg = pMdl->has_skin();
const sxModelData::Batch* pBat = pMdl->get_batch_ptr(ibat);
if (!pBat) return;
GPUProgram* pProg = nullptr;
GLsizei stride = 0;
if (skinFlg) { pProg = &s_progDeform;
stride = (GLsizei)(sizeof(GPUGeom) + sizeof(GPUSkin)); } else {
pProg = &s_progStatic;
stride = (GLsizei)sizeof(GPUGeom);
}
if (stride <= 0) return;
if (!pProg) return;
if (!pProg->is_valid()) return;
pProg->use();
/* batch data origin in VB */
size_t vbOrg = pBat->mMinIdx * stride;
/* set geometry buffers and vertex description */
GLuint vbo = GPUModel::get_vertex_buffer(pMdl);
GLuint ibo = GPUModel::get_index_buffer(pMdl);
if (!(vbo > 0 && ibo > 0)) return;
glBindBuffer(GL_ARRAY_BUFFER, vbo);
pProg->enable_vertex_vec3("vtx_pos", stride, vbOrg + offsetof(GPUGeom, pos));
pProg->enable_vertex_vec3("vtx_nrm", stride, vbOrg + offsetof(GPUGeom, nrm));
pProg->enable_vertex_vec2("vtx_tex", stride, vbOrg + offsetof(GPUGeom, tex));
pProg->enable_vertex_vec4("vtx_clr", stride, vbOrg + offsetof(GPUGeom, clr)); if (skinFlg) {
size_t skOrg = vbOrg + sizeof(GPUGeom);
pProg->enable_vertex_vec4("vtx_wgt", stride, skOrg + offsetof(GPUSkin, wgt));
pProg->enable_vertex_vec4("vtx_idx", stride, skOrg + offsetof(GPUSkin, idx));
} glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
/* set rendering options */
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CW);
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
/* set parameters */ if (skinFlg) {
pProg->set_transform_matrices("prm_xforms", pWk->mpSkinXforms, pMdl->mSknNum);
} pProg->set_matrix("prm_viewproj", pCtx->view.mViewProjMtx);
pProg->draw_triangles(pBat->mTriNum, pBat->mIdxOrg);
pProg->disable_vertex_inputs();
}
Extending Ifc::batch to handle deformable models | << Home
|