mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-31 05:00:35 +00:00
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:
parent
f958afad53
commit
c3801d46e5
5 changed files with 165 additions and 4 deletions
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
130
libs/video/renderer/gl/gl_mod_iqm.c
Normal file
130
libs/video/renderer/gl/gl_mod_iqm.c
Normal 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 ();
|
||||
}
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue