Render iqm models in GL.

There are still many issues to sort out, but the basics are working.

Problems:
	rendered fullbright (no lighting done)
	normals are ignored
	extra textures (glow etc) not used/loaded

4 models on the screen don't seem to be a problem.
This commit is contained in:
Bill Currie 2012-05-17 15:58:29 +09:00
parent f958afad53
commit c3801d46e5
5 changed files with 165 additions and 4 deletions

View File

@ -31,11 +31,19 @@
#define __QF_GL_qf_iqm_h
#include "QF/iqm.h"
#include "QF/render.h"
typedef struct glsliqm_s {
int *textures;
iqmblend_t *blend_palette; // includes base data from iqm
int palette_size; // includes base data from iqm
iqmvertexarray *position;
iqmvertexarray *texcoord;
iqmvertexarray *normal;
iqmvertexarray *bindices;
iqmvertexarray *color;
} gliqm_t;
void gl_R_DrawIQMModel (entity_t *ent);
#endif//__QF_GL_qf_iqm_h

View File

@ -98,9 +98,22 @@ gl_Mod_IQMFinish (model_t *mod)
{
iqm_t *iqm = (iqm_t *) mod->aliashdr;
gliqm_t *gl;
int i;
mod->clear = gl_iqm_clear;
iqm->extra_data = gl = calloc (1, sizeof (gliqm_t));
gl_iqm_load_textures (iqm);
gl->blend_palette = Mod_IQMBuildBlendPalette (iqm, &gl->palette_size);
for (i = 0; i < iqm->num_arrays; i++) {
if (iqm->vertexarrays[i].type == IQM_POSITION)
gl->position = &iqm->vertexarrays[i];
if (iqm->vertexarrays[i].type == IQM_TEXCOORD)
gl->texcoord = &iqm->vertexarrays[i];
if (iqm->vertexarrays[i].type == IQM_NORMAL)
gl->normal = &iqm->vertexarrays[i];
if (iqm->vertexarrays[i].type == IQM_BLENDINDEXES)
gl->bindices = &iqm->vertexarrays[i];
if (iqm->vertexarrays[i].type == IQM_COLOR)
gl->color = &iqm->vertexarrays[i];
}
}

View File

@ -7,8 +7,8 @@ noinst_LTLIBRARIES= libgl.la
gl_src = \
gl_draw.c gl_dyn_lights.c gl_dyn_part.c gl_dyn_textures.c \
gl_fog.c gl_graph.c gl_lightmap.c gl_mod_alias.c gl_mod_sprite.c \
gl_rmain.c gl_rmisc.c gl_rsurf.c gl_screen.c gl_sky.c \
gl_fog.c gl_graph.c gl_lightmap.c gl_mod_alias.c gl_mod_iqm.c \
gl_mod_sprite.c gl_rmain.c gl_rmisc.c gl_rsurf.c gl_screen.c gl_sky.c \
gl_sky_clip.c gl_textures.c gl_warp.c qfgl_ext.c vid_common_gl.c vtxarray.c
libgl_la_SOURCES= $(gl_src)

View File

@ -0,0 +1,130 @@
/*
gl_mod_iqm.c
GL IQM rendering
Copyright (C) 2012 Bill Currie <bill@taniwha.org>
Author: Bill Currie <bill@taniwha.org>
Date: 2012/5/17
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#define NH_DEFINE
#include "namehack.h"
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include <stdlib.h>
#include "QF/cvar.h"
#include "QF/render.h"
#include "QF/skin.h"
#include "QF/sys.h"
#include "QF/GL/defines.h"
#include "QF/GL/funcs.h"
#include "QF/GL/qf_iqm.h"
#include "QF/GL/qf_rmain.h"
#include "QF/GL/qf_vid.h"
#include "r_internal.h"
//FIXME this is really lame: normals are ignored. also, it could be
//faster
static void
gl_draw_iqm_frame (iqm_t *iqm, gliqm_t *gl, iqmframe_t *frame, iqmmesh *mesh)
{
byte *vert;
uint32_t i, j;
qfglBegin (GL_TRIANGLES);
for (i = 0; i < mesh->num_triangles; i++) {
int vind = (mesh->first_triangle + i) * 3;
for (j = 0; j < 3; j++) {
vert = iqm->vertices + iqm->elements[vind + j] * iqm->stride;
if (gl->texcoord)
qfglTexCoord2fv ((float *) (vert + gl->texcoord->offset));
if (gl->color)
qfglColor4bv ((GLbyte *) (vert + gl->color->offset));
if (gl->bindices) {
vec3_t position;
uint32_t bind = *(uint32_t *) (vert + gl->bindices->offset);
vec_t *f = (vec_t *) &frame[bind];
float *v = (float *) (vert + gl->position->offset);
Mat4MultVec (f, v, position);
VectorScale (position, 8, position);
qfglVertex3fv (position);
} else {
qfglVertex3fv ((float *) (vert + gl->position->offset));
}
}
}
qfglEnd ();
}
void
gl_R_DrawIQMModel (entity_t *ent)
{
model_t *model = ent->model;
iqm_t *iqm = (iqm_t *) model->aliashdr;
gliqm_t *gl = (gliqm_t *) iqm->extra_data;
int data_size;
float blend;
iqmframe_t *frame;
int i, j;
model = ent->model;
data_size = (gl->palette_size - iqm->num_joints) * sizeof (iqmframe_t);
blend = R_IQMGetLerpedFrames (ent, iqm);
frame = R_IQMBlendFrames (iqm, ent->pose1, ent->pose2, blend, data_size);
for (i = iqm->num_joints; i < gl->palette_size; i++) {
vec_t *mat = (vec_t *) &frame[i];
iqmblend_t *blend = &gl->blend_palette[i];
vec_t *f;
f = (vec_t *) &frame[blend->indices[0]];
Mat4Scale (f, blend->weights[0] / 255.0, mat);
for (j = 1; j < 4; j++) {
if (!blend->weights[j])
break;
f = (vec_t *) &frame[blend->indices[j]];
Mat4MultAdd (mat, blend->weights[j] / 255.0, f, mat);
}
}
qfglPushMatrix ();
gl_R_RotateForEntity (ent);
qfglScalef (ent->scale, ent->scale, ent->scale);
for (i = 0; i < iqm->num_meshes; i++) {
qfglBindTexture (GL_TEXTURE_2D, gl->textures[i]);
gl_draw_iqm_frame (iqm, gl, frame, &iqm->meshes[i]);
}
qfglPopMatrix ();
}

View File

@ -55,6 +55,7 @@
#include "QF/GL/defines.h"
#include "QF/GL/funcs.h"
#include "QF/GL/qf_draw.h"
#include "QF/GL/qf_iqm.h"
#include "QF/GL/qf_rlight.h"
#include "QF/GL/qf_rmain.h"
#include "QF/GL/qf_rsurf.h"
@ -214,7 +215,7 @@ R_DrawEntitiesOnList (void)
} else if (gl_tess) {
qfglEnable (GL_NORMALIZE);
}
for (ent = r_ent_queue; ent; ent = ent->next) {
if (ent->model->type != mod_alias)
continue;
@ -227,7 +228,6 @@ R_DrawEntitiesOnList (void)
qfglDisable (GL_NORMALIZE);
qfglDisable (GL_LIGHTING);
qfglDisable (GL_CULL_FACE);
if (gl_tess)
qfglDisable (GL_PN_TRIANGLES_ATI);
if (gl_affinemodels->int_val)
@ -248,6 +248,16 @@ R_DrawEntitiesOnList (void)
qglActiveTexture (gl_mtex_enum + 0);
}
for (ent = r_ent_queue; ent; ent = ent->next) {
if (ent->model->type != mod_iqm)
continue;
currententity = ent;
gl_R_DrawIQMModel (currententity);
}
qfglColor3ubv (color_white);
qfglDisable (GL_CULL_FACE);
qfglEnable (GL_ALPHA_TEST);
if (gl_va_capable)
qfglInterleavedArrays (GL_T2F_C4UB_V3F, 0, gl_spriteVertexArray);