Begin work on rendering iqm models.

No chance of working yet, but the shaders compile :)
This commit is contained in:
Bill Currie 2012-05-11 12:49:14 +09:00
parent 078cb10caf
commit 0becd35b65
7 changed files with 303 additions and 3 deletions

40
include/QF/GLSL/qf_iqm.h Normal file
View file

@ -0,0 +1,40 @@
/*
qf_iqm.h
GLSL specific IQM stuff
Copyright (C) 2012 Bill Currie <bill@taniwha.org>
Author: Bill Currie <bill@taniwha.org>
Date: 2012/5/11
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
*/
#ifndef __QF_GLSL_qf_iqm_h
#define __QF_GLSL_qf_iqm_h
#include "QF/iqm.h"
void glsl_R_InitIQM (void);
void glsl_R_DrawIQM (void);
void glsl_R_IQMBegin (void);
void glsl_R_IQMEnd (void);
#endif//__QF_GLSL_qf_iqm_h

View file

@ -17,7 +17,7 @@ nobase_pkginclude_HEADERS = \
GL/qf_vid.h GL/types.h \
\
GLSL/defines.h GLSL/funcs.h GLSL/qf_alias.h GLSL/qf_bsp.h \
GLSL/qf_funcs_list.h GLSL/qf_lightmap.h GLSL/qf_particles.h \
GLSL/qf_funcs_list.h GLSL/qf_iqm.h GLSL/qf_lightmap.h GLSL/qf_particles.h \
GLSL/qf_textures.h GLSL/qf_vid.h GLSL/types.h \
\
plugin/cd.h plugin/console.h plugin/general.h plugin/input.h \

View file

@ -4,17 +4,19 @@ AM_CFLAGS= @PREFER_PIC@
INCLUDES= -I$(top_srcdir)/include $(GLX_CFLAGS)
shader_src= \
iqm.frag iqm.vert \
quake2d.frag quakebsp.frag quakebsp.vert quakeico.vert quakemdl.frag \
quakemdl.vert quakepar.frag quakepar.vert quakepnt.frag quakepnt.vert \
quakeskb.frag quakeski.frag quakesky.vert quakespr.frag quakespr.vert \
quaketrb.frag quaketxt.vert
shader_gen= \
iqm.fc iqm.vc \
quake2d.fc quakebsp.fc quakebsp.vc quakeico.vc quakemdl.fc quakemdl.vc \
quakepar.fc quakepar.vc quakepnt.fc quakepnt.vc quakeskb.fc quakeski.fc \
quakesky.vc quakespr.fc quakespr.vc quaketrb.fc quaketxt.vc
glsl_src = \
glsl_alias.c glsl_bsp.c glsl_draw.c glsl_fog.c glsl_lightmap.c \
glsl_alias.c glsl_bsp.c glsl_draw.c glsl_fog.c glsl_iqm.c glsl_lightmap.c \
glsl_main.c glsl_particles.c glsl_screen.c glsl_sprite.c glsl_textures.c \
qfglsl.c vid_common_glsl.c

View file

@ -0,0 +1,191 @@
/*
glsl_iqm.c
GLSL IQM rendering
Copyright (C) 2012 Bill Currie <bill@taniwha.org>
Author: Bill Currie <bill@taniwha.org>
Date: 2012/5/11
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/GLSL/defines.h"
#include "QF/GLSL/funcs.h"
#include "QF/GLSL/qf_iqm.h"
#include "QF/GLSL/qf_textures.h"
#include "QF/GLSL/qf_vid.h"
#include "r_internal.h"
static const char iqm_vert[] =
#include "iqm.vc"
;
static const char iqm_frag[] =
#include "iqm.fc"
;
static struct {
int program;
shaderparam_t mvp_matrix;
shaderparam_t bonemats;
shaderparam_t vcolor;
shaderparam_t vweights;
shaderparam_t vbones;
shaderparam_t texcoord;
shaderparam_t vtangent;
shaderparam_t vnormal;
shaderparam_t position;
shaderparam_t fog;
} iqm_shader = {
0,
{"mvp_mat", 1},
{"bonemats", 1},
{"vcolor", 0},
{"vweights", 0},
{"vbones", 0},
{"texcoord", 0},
{"vtangent", 0},
{"vnormal", 0},
{"position", 0},
{"fog", 1},
};
static struct va_attr_s {
shaderparam_t *attr;
GLint size;
GLenum type;
GLboolean normalized;
} vertex_attribs[] = {
{&iqm_shader.position, 3, GL_FLOAT, 0},
{&iqm_shader.texcoord, 2, GL_FLOAT, 0},
{&iqm_shader.vnormal, 3, GL_FLOAT, 0},
{&iqm_shader.vtangent, 4, GL_FLOAT, 0},
{&iqm_shader.vbones, 4, GL_UNSIGNED_BYTE, 0},
{&iqm_shader.vweights, 4, GL_UNSIGNED_BYTE, 1},
{&iqm_shader.vcolor, 4, GL_UNSIGNED_BYTE, 1},
};
static mat4_t iqm_vp;
void
glsl_R_InitIQM (void)
{
int vert;
int frag;
vert = GLSL_CompileShader ("iqm.vert", iqm_vert, GL_VERTEX_SHADER);
frag = GLSL_CompileShader ("iqm.frag", iqm_frag, GL_FRAGMENT_SHADER);
iqm_shader.program = GLSL_LinkProgram ("iqm", vert, frag);
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.mvp_matrix);
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.bonemats);
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.vcolor);
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.vweights);
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.vbones);
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.texcoord);
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.vtangent);
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.vnormal);
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.position);
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.fog);
}
static void
set_arrays (iqm_t *iqm)
{
int i;
uint32_t j;
struct va_attr_s *attr;
iqmvertexarray *va;
for (i = 0, j = 0; i < iqm->num_arrays; i++) {
va = &iqm->vertexarrays[i];
if (va->type > IQM_COLOR)
Sys_Error ("iqm: unknown array type");
if (j > va->type)
Sys_Error ("iqm: array order bogus");
while (j < va->type)
qfeglDisableVertexAttribArray (vertex_attribs[j++].attr->location);
attr = &vertex_attribs[j];
qfeglEnableVertexAttribArray (attr->attr->location);
qfeglVertexAttribPointer (attr->attr->location, attr->size,
attr->type, attr->normalized, iqm->stride,
(byte *) 0 + va->offset);
}
while (j <= IQM_COLOR)
qfeglDisableVertexAttribArray (vertex_attribs[j++].attr->location);
}
void
glsl_R_DrawIQM (void)
{
entity_t *ent = currententity;
model_t *model = ent->model;
iqm_t *iqm = (iqm_t *) model->aliashdr;
set_arrays (iqm);
}
// All iqm models are drawn in a batch, so avoid thrashing the gl state
void
glsl_R_IQMBegin (void)
{
quat_t fog;
// pre-multiply the view and projection matricies
Mat4Mult (glsl_projection, glsl_view, iqm_vp);
qfeglUseProgram (iqm_shader.program);
VectorCopy (glsl_Fog_GetColor (), fog);
fog[3] = glsl_Fog_GetDensity () / 64.0;
qfeglUniform4fv (iqm_shader.fog.location, 1, fog);
}
void
glsl_R_IQMEnd (void)
{
int i;
qfeglBindBuffer (GL_ARRAY_BUFFER, 0);
qfeglBindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0);
for (i = 0; i <= IQM_COLOR; i++)
qfeglDisableVertexAttribArray (vertex_attribs[i].attr->location);
}

View file

@ -51,6 +51,7 @@
#include "QF/GLSL/funcs.h"
#include "QF/GLSL/qf_alias.h"
#include "QF/GLSL/qf_bsp.h"
#include "QF/GLSL/qf_iqm.h"
#include "QF/GLSL/qf_lightmap.h"
#include "QF/GLSL/qf_textures.h"
@ -162,6 +163,15 @@ R_RenderEntities (void)
}
glsl_R_AliasEnd ();
glsl_R_IQMBegin ();
for (ent = r_ent_queue; ent; ent = ent->next) {
if (ent->model->type != mod_iqm)
continue;
currententity = ent;
glsl_R_DrawIQM ();
}
glsl_R_IQMEnd ();
glsl_R_SpriteBegin ();
for (ent = r_ent_queue; ent; ent = ent->next) {
if (ent->model->type != mod_sprite)
@ -246,6 +256,7 @@ glsl_R_Init (void)
SCR_Init ();
glsl_R_InitBsp ();
glsl_R_InitAlias ();
glsl_R_InitIQM ();
glsl_R_InitSprites ();
glsl_R_InitParticles ();
glsl_Fog_Init ();

View file

@ -0,0 +1,56 @@
uniform sampler2D texture;
uniform sampler2D normalmap;
uniform vec4 lights[8];
uniform vec4 fog;
varying vec3 bitangent;
varying vec3 tangent;
varying vec3 normal;
varying vec2 st;
varying vec4 color;
float
sqr (float x)
{
return x * x;
}
vec4
fogBlend (vec4 color)
{
float f;
vec4 fog_color = vec4 (fog.rgb, 1.0);
f = exp (-sqr (fog.a / gl_FragCoord.w));
return mix (fog_color, color, f);
}
vec3
calc_light (vec3 n, int ind)
{
vec3 d;
d = lights[ind].xyz - gl_FragCoord.xyz;
return vec3 (lights[ind].w * dot (d, n) / dot (d, d));
}
void
main (void)
{
mat3 tbn = mat3 (tangent, bitangent, normal);
vec3 norm, light;
vec4 col;
norm = texture2D (normalmap, st).xyz;
norm = tbn * norm;
light += calc_light (norm, 0);
light += calc_light (norm, 1);
light += calc_light (norm, 2);
light += calc_light (norm, 3);
light += calc_light (norm, 4);
light += calc_light (norm, 5);
light += calc_light (norm, 6);
light += calc_light (norm, 7);
col = texture2D (texture, st) * color * vec4 (light, 1.0);
gl_FragColor = fogBlend (col);
}

View file

@ -49,7 +49,7 @@ main (void)
t = vtangent.xyz;
t += 2.0 * cross (q0.xyz, cross (q0.xyz, t) + q0.w * t);
gl_Position = mvp_mat * vec4 (v, 1.0);
mat3 rot = mat3 (mvp_mat[0].xyz, mvp_mat[1].xyz, mvp_mat[3].xyz)
mat3 rot = mat3 (mvp_mat[0].xyz, mvp_mat[1].xyz, mvp_mat[3].xyz);
normal = rot * n;
tangent = rot * t;
bitangent = cross (normal, tangent) * vtangent.w;