Make sprite rendering use vertex arrays, as a test for detection of vertex array support (tests only for OpenGL 1.1 or better, at the moment, no driver blacklist yet).

This commit is contained in:
Ragnvald Maartmann-Moe IV 2003-03-20 19:58:18 +00:00
parent 4ea47fc261
commit 88c2735d9c
12 changed files with 299 additions and 52 deletions

View file

@ -45,6 +45,8 @@ void BuildSurfaceDisplayList (msurface_t *fa);
void gl_lightmap_init (void);
void GL_BuildLightmaps (struct model_s **models, int num_models);
void R_BlendLightmaps (void);
void R_CalcLightmaps (void);
void R_CalcAndBlendLightmaps (void); // FIXME: temporary hack
extern void (*R_BuildLightMap) (msurface_t *surf);
#endif // __QF_GL_lightmap_h

View file

@ -66,7 +66,6 @@ extern lightstyle_t r_lightstyle[MAX_LIGHTSTYLES];
#define TOP_RANGE 16 // soldier uniform colors
#define BOTTOM_RANGE 96
typedef struct entity_s
{
vec3_t origin;
@ -129,10 +128,7 @@ typedef struct
int ambientlight;
} refdef_t;
/*
REFRESH
*/
// REFRESH ====================================================================
extern int reinit_surfcache;
@ -160,14 +156,11 @@ void R_RemoveEfrags (entity_t *ent);
void R_NewMap (model_t *worldmodel, struct model_s **models, int num_models);
// LordHavoc: relative bmodel lighting
void R_PushDlights (const vec3_t entorigin);
void R_DrawWaterSurfaces (void);
/*
Surface cache related
*/
// Surface cache related ==========
extern int reinit_surfcache; // if 1, surface cache is currently empty
extern qboolean r_cache_thrash; // set if thrashing the surface cache
extern qboolean r_inhibit_viewmodel;
@ -201,7 +194,6 @@ struct progs_s;
void R_Progs_Init (struct progs_s *pr);
void R_DrawAliasModel (entity_t *e);
void R_DrawSpriteModel (entity_t *e);
void R_MarkLeaves (void);

View file

@ -85,6 +85,7 @@ void R_DrawParticles (void);
struct cvar_s;
void R_MaxParticlesCheck (struct cvar_s *r_particles,
struct cvar_s *r_particles_max);
void R_InitSprites (void);
extern unsigned int r_maxparticles;
extern unsigned int numparticles;

View file

@ -257,6 +257,7 @@ void R_DrawParticles (void);
void R_InitParticles (void);
inline void R_ClearParticles (void);
void R_ReadPointFile_f (void);
void R_InitSprites (void);
void R_SurfacePatch (void);
extern int r_amodels_drawn;

View file

@ -52,6 +52,7 @@ typedef struct varray_t2f_c4f_n3f_v3f_s {
GLfloat vertex[3];
} varray_t2f_c4f_n3f_v3f_t;
extern qboolean gl_va_capable;
extern int vaelements;
//extern varray_t2f_c4f_n3f_v3f_t *modelVertexArray
@ -64,4 +65,14 @@ extern float *textCoords;
extern float *textVertices;
extern int tVAsize;
extern varray_t2f_c4ub_v3f_t *spriteVertexArray;
extern int sVAsize;
/*
extern varray_t2f_c4ub_v3f_t *polyVertexArray;
extern float *polyCoords;
extern float *polyVertices
extern int polyVAsize;
*/
#endif // __qf_varrays_h

View file

@ -48,6 +48,7 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "QF/sys.h"
#include "QF/texture.h"
#include "QF/tga.h"
#include "QF/va.h"
#include "QF/vid.h"
#include "QF/GL/qf_textures.h"
@ -69,13 +70,12 @@ typedef struct {
#define FLOODFILL_STEP( off, dx, dy ) \
{ \
if (pos[off] == fillcolor) \
{ \
if (pos[off] == fillcolor) { \
pos[off] = 255; \
fifo[inpt].x = x + (dx), fifo[inpt].y = y + (dy); \
inpt = (inpt + 1) & FLOODFILL_FIFO_MASK; \
} \
else if (pos[off] != 255) fdc = pos[off]; \
} else if (pos[off] != 255) \
fdc = pos[off]; \
}
/*
@ -272,16 +272,31 @@ Mod_LoadExternalSkin (maliasskindesc_t *pskindesc, char *filename)
QFile *f;
QFS_FOpenFile (filename, &f);
if (f)
{
if (!f) {
char filename2[MAX_QPATH + 4];
char *foo = filename2;
foo = va ("progs/%s", filename);
QFS_FOpenFile (foo, &f);
}
if (!f) {
char filename2[MAX_QPATH + 4];
char *foo = filename2;
foo = va ("textures/%s", filename);
QFS_FOpenFile (foo, &f);
}
if (f) {
targa = LoadTGA (f);
Qclose (f);
if (targa->format < 4)
pskindesc->texnum = GL_LoadTexture
("", targa->width, targa->height, targa->data, true, false, 3);
(filename, targa->width, targa->height, targa->data, true,
false, 3);
else
pskindesc->texnum = GL_LoadTexture
("", targa->width, targa->height, targa->data, true, true, 4);
(filename, targa->width, targa->height, targa->data, true,
false, 4);
}
}

View file

@ -447,6 +447,24 @@ GL_UploadLightmap (int i)
}
}
void
R_CalcLightmaps (void)
{
int i;
glpoly_t *p;
for (i = 0; i < MAX_LIGHTMAPS; i++) {
p = lightmap_polys[i];
if (!p)
continue;
qfglBindTexture (GL_TEXTURE_2D, lightmap_textures + i);
if (lightmap_modified[i]) {
GL_UploadLightmap (i);
lightmap_modified[i] = false;
}
}
}
void
R_BlendLightmaps (void)
{
@ -457,6 +475,37 @@ R_BlendLightmaps (void)
qfglDepthMask (GL_FALSE); // don't bother writing Z
qfglBlendFunc (GL_DST_COLOR, GL_SRC_COLOR);
for (i = 0; i < MAX_LIGHTMAPS; i++) {
p = lightmap_polys[i];
if (!p)
continue;
qfglBindTexture (GL_TEXTURE_2D, lightmap_textures + i);
for (; p; p = p->chain) {
qfglBegin (GL_POLYGON);
v = p->verts[0];
for (j = 0; j < p->numverts; j++, v += VERTEXSIZE) {
qfglTexCoord2fv (&v[5]);
qfglVertex3fv (v);
}
qfglEnd ();
}
}
// Return to normal blending --KB
qfglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
qfglDepthMask (GL_TRUE); // back to normal Z buffering
}
void
R_CalcAndBlendLightmaps (void)
{
float *v;
int i, j;
glpoly_t *p;
qfglDepthMask (GL_FALSE); // don't bother writing Z
qfglBlendFunc (GL_DST_COLOR, GL_SRC_COLOR);
for (i = 0; i < MAX_LIGHTMAPS; i++) {
p = lightmap_polys[i];
if (!p)

View file

@ -1,7 +1,7 @@
/*
gl_mod_sprite.c
(description)
sprite model rendering
Copyright (C) 1996-1997 Id Software, Inc.
@ -31,6 +31,13 @@
static __attribute__ ((unused)) const char rcsid[] =
"$Id$";
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include "QF/GL/defines.h"
#include "QF/GL/funcs.h"
@ -38,7 +45,20 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "QF/model.h"
#include "QF/render.h"
#include "compat.h"
#include "r_local.h"
#include "r_shared.h"
#include "varrays.h"
int sVAsize;
int *sVAindices;
float *spriteVertices;
float *spriteTexCoords;
float *spriteColors;
varray_t2f_c4ub_v3f_t *spriteVertexArray;
void (*R_DrawSpriteModel) (struct entity_s *ent);
static mspriteframe_t *
R_GetSpriteFrame (entity_t *currententity)
@ -83,14 +103,14 @@ R_GetSpriteFrame (entity_t *currententity)
return pspriteframe;
}
void
R_DrawSpriteModel (entity_t *e)
static void
R_DrawSpriteModel_f (entity_t *e)
{
float modelalpha, color[4];
float *up, *right;
msprite_t *psprite;
mspriteframe_t *frame;
vec3_t point, v_forward, v_right, v_up;
vec3_t point, point1, point2, v_forward, v_right, v_up;
// don't bother culling, it's just a single polygon without a surface cache
frame = R_GetSpriteFrame (e);
@ -115,7 +135,8 @@ R_DrawSpriteModel (entity_t *e)
VectorScale (right, e->scale, right);
}
modelalpha = e->colormod[3];
VectorCopy (e->colormod, color);
modelalpha = color[3] = e->colormod[3];
if (modelalpha < 1.0)
qfglDepthMask (GL_FALSE);
@ -123,28 +144,24 @@ R_DrawSpriteModel (entity_t *e)
qfglBegin (GL_QUADS);
VectorCopy (e->colormod, color);
color[3] = e->colormod[3];
qfglColor4fv (color);
qfglTexCoord2f (0, 1);
VectorMA (e->origin, frame->down, up, point);
VectorMA (point, frame->left, right, point);
VectorMA (e->origin, frame->down, up, point1);
VectorMA (point1, frame->left, right, point);
qfglVertex3fv (point);
qfglTexCoord2f (0, 0);
VectorMA (e->origin, frame->up, up, point);
VectorMA (point, frame->left, right, point);
VectorMA (e->origin, frame->up, up, point2);
VectorMA (point2, frame->left, right, point);
qfglVertex3fv (point);
qfglTexCoord2f (1, 0);
VectorMA (e->origin, frame->up, up, point);
VectorMA (point, frame->right, right, point);
VectorMA (point2, frame->right, right, point);
qfglVertex3fv (point);
qfglTexCoord2f (1, 1);
VectorMA (e->origin, frame->down, up, point);
VectorMA (point, frame->right, right, point);
VectorMA (point1, frame->right, right, point);
qfglVertex3fv (point);
qfglEnd ();
@ -152,3 +169,131 @@ R_DrawSpriteModel (entity_t *e)
if (modelalpha < 1.0)
qfglDepthMask (GL_TRUE);
}
static void
R_DrawSpriteModel_VA_f (entity_t *e)
{
unsigned char modelalpha, color[4];
float *up, *right;
int i;
// unsigned int vacount;
msprite_t *psprite;
mspriteframe_t *frame;
vec3_t point1, point2, v_forward, v_right, v_up;
varray_t2f_c4ub_v3f_t *VA;
VA = spriteVertexArray; // FIXME: Despair
// don't bother culling, it's just a single polygon without a surface cache
frame = R_GetSpriteFrame (e);
psprite = e->model->cache.data;
qfglBindTexture (GL_TEXTURE_2D, frame->gl_texturenum); // FIXME: DESPAIR
if (psprite->type == SPR_ORIENTED) { // bullet marks on walls
AngleVectors (e->angles, v_forward, v_right, v_up);
up = v_up;
right = v_right;
} else if (psprite->type == SPR_VP_PARALLEL_UPRIGHT) {
v_up[0] = 0;
v_up[1] = 0;
v_up[2] = 1;
up = v_up;
right = vright;
} else { // normal sprite
up = vup;
right = vright;
}
if (e->scale != 1.0) {
VectorScale (up, e->scale, up);
VectorScale (right, e->scale, right);
}
for (i = 0; i < 4; i++)
color[i] = e->colormod[i] * 255;
memcpy (VA[0].color, color, 4);
modelalpha = color[3];
if (modelalpha < 255)
qfglDepthMask (GL_FALSE);
VectorMA (e->origin, frame->down, up, point1);
VectorMA (point1, frame->left, right, VA[0].vertex);
memcpy (VA[1].color, color, 4);
VectorMA (e->origin, frame->up, up, point2);
VectorMA (point2, frame->left, right, VA[1].vertex);
memcpy (VA[2].color, color, 4);
VectorMA (point2, frame->right, right, VA[2].vertex);
memcpy (VA[3].color, color, 4);
VectorMA (point1, frame->right, right, VA[3].vertex);
// VA += 4;
// vacount += 4;
// if (vacount + 4 > sVAsize) {
// qfglDrawElements (GL_QUADS, vacount, GL_UNSIGNED_INT, sVAindices);
qfglDrawElements (GL_QUADS, 4, GL_UNSIGNED_INT, sVAindices);
// vacount = 0;
// VA = spriteVertexArray;
// }
if (modelalpha < 255)
qfglDepthMask (GL_TRUE);
}
void
R_InitSprites (void)
{
int i;
if (r_init) {
if (gl_va_capable) { // 0 == gl_va_capable
R_DrawSpriteModel = R_DrawSpriteModel_VA_f;
#if 0
if (vaelements > 3)
sVAsize = min (vaelements - (vaelements % 4), 512);
else
sVAsize = 512;
#else
sVAsize = 4;
#endif
Con_Printf ("Sprites: %i maximum vertex elements.\n", sVAsize);
if (spriteVertexArray)
free (spriteVertexArray);
spriteVertexArray = (varray_t2f_c4ub_v3f_t *)
calloc (sVAsize, sizeof (varray_t2f_c4ub_v3f_t));
qfglInterleavedArrays (GL_T2F_C4UB_V3F, 0, spriteVertexArray);
if (sVAindices)
free (sVAindices);
sVAindices = (int *) calloc (sVAsize, sizeof (int));
for (i = 0; i < sVAsize; i++)
sVAindices[i] = i;
for (i = 0; i < sVAsize / 4; i++) {
spriteVertexArray[i * 4].texcoord[0] = 0.0;
spriteVertexArray[i * 4].texcoord[1] = 1.0;
spriteVertexArray[i * 4 + 1].texcoord[0] = 0.0;
spriteVertexArray[i * 4 + 1].texcoord[1] = 0.0;
spriteVertexArray[i * 4 + 2].texcoord[0] = 1.0;
spriteVertexArray[i * 4 + 2].texcoord[1] = 0.0;
spriteVertexArray[i * 4 + 3].texcoord[0] = 1.0;
spriteVertexArray[i * 4 + 3].texcoord[1] = 1.0;
}
} else {
R_DrawSpriteModel = R_DrawSpriteModel_f;
if (spriteVertexArray) {
free (spriteVertexArray);
spriteVertexArray = 0;
}
if (sVAindices) {
free (sVAindices);
sVAindices = 0;
}
}
}
}

View file

@ -64,6 +64,7 @@ static __attribute__ ((unused)) const char rcsid[] =
#include "r_cvar.h"
#include "r_dynamic.h"
#include "r_local.h"
#include "varrays.h"
#include "view.h"
entity_t r_worldentity;
@ -103,6 +104,8 @@ int d_lightstylevalue[256]; // 8.8 fraction of base light value
vec3_t shadecolor; // Ender (Extend) Colormod
float modelalpha; // Ender (Extend) Alpha
extern void (*R_DrawSpriteModel) (struct entity_s *ent);
void
glrmain_init (void)
@ -197,6 +200,8 @@ R_DrawEntitiesOnList (void)
qfglColor3ubv (color_white);
qfglEnable (GL_ALPHA_TEST);
if (gl_va_capable)
qfglInterleavedArrays (GL_T2F_C4UB_V3F, 0, spriteVertexArray);
for (i = 0; i < r_numvisedicts; i++) {
if (r_visedicts[i]->model->type != mod_sprite)
continue;

View file

@ -63,6 +63,7 @@ static __attribute__ ((unused)) const char rcsid[] =
int r_init = 0;
/*
R_Envmap_f
@ -159,6 +160,7 @@ R_Init (void)
r_init = 1;
R_InitParticles ();
R_InitSprites ();
Draw_InitText ();
}

View file

@ -390,7 +390,7 @@ R_DrawBrushModel (entity_t *e)
}
}
R_BlendLightmaps ();
R_CalcAndBlendLightmaps ();
if (gl_fb_bmodels->int_val)
R_RenderFullbrights ();
@ -502,6 +502,8 @@ R_DrawWorld (void)
DrawTextureChains ();
R_CalcLightmaps ();
R_BlendLightmaps ();
if (gl_fb_bmodels->int_val)

View file

@ -72,6 +72,11 @@ const char *gl_renderer;
const char *gl_vendor;
const char *gl_version;
int gl_major;
int gl_minor;
int gl_release_number;
int gl_va_capable;
int vaelements;
int texture_extension_number = 1;
int gl_filter_min = GL_LINEAR_MIPMAP_NEAREST;
@ -105,7 +110,9 @@ gl_multitexture_f (cvar_t *var)
static void
gl_screenshot_byte_swap_f (cvar_t *var)
{
qfglPixelStorei (GL_PACK_SWAP_BYTES, var->int_val ? GL_TRUE : GL_FALSE);
if (var)
qfglPixelStorei (GL_PACK_SWAP_BYTES,
var->int_val ? GL_TRUE : GL_FALSE);
}
static void
@ -255,7 +262,7 @@ void
GL_Pre_Init (void)
{
if (!GLF_Init()) {
Sys_Error("Can't init video.");
Sys_Error ("Can't init video.");
return;
}
}
@ -263,18 +270,40 @@ GL_Pre_Init (void)
void
GL_Init_Common (void)
{
GL_Common_Init_Cvars ();
gl_version = qfglGetString (GL_VERSION);
if (sscanf (gl_version, "%d.%d", &gl_major, &gl_minor) == 2) {
gl_release_number = 0;
if (gl_major >= 1) {
if (gl_minor >= 1) {
gl_va_capable = true;
} else
gl_va_capable = false;
}
} else if (sscanf (gl_version, "%d.%d.%d", &gl_major, &gl_minor,
&gl_release_number) == 3) {
if (gl_major >= 1) {
if (gl_minor >= 1) {
gl_va_capable = true;
} else
gl_va_capable = false;
}
} else {
Sys_Error ("Malformed OpenGL version string!");
}
Con_Printf ("GL_VERSION: %s\n", gl_version);
gl_vendor = qfglGetString (GL_VENDOR);
Con_Printf ("GL_VENDOR: %s\n", gl_vendor);
gl_renderer = qfglGetString (GL_RENDERER);
Con_Printf ("GL_RENDERER: %s\n", gl_renderer);
gl_version = qfglGetString (GL_VERSION);
Con_Printf ("GL_VERSION: %s\n", gl_version);
gl_extensions = qfglGetString (GL_EXTENSIONS);
Con_Printf ("GL_EXTENSIONS: %s\n", gl_extensions);
if (strstr (gl_renderer, "Mesa DRI Mach64"))
gl_feature_mach64 = true;
GL_Common_Init_Cvars ();
qfglClearColor (0, 0, 0, 0);
qfglCullFace (GL_FRONT);
qfglEnable (GL_TEXTURE_2D);
@ -298,9 +327,6 @@ GL_Init_Common (void)
CheckMultiTextureExtensions ();
CheckVertexArraySize ();
if (strstr(gl_renderer, "Mesa DRI Mach64"))
gl_feature_mach64 = true;
}
void
@ -323,18 +349,16 @@ Tdfx_Init8bitPalette (void)
// Check for 8bit Extensions and initialize them.
int i;
if (is8bit) {
if (is8bit)
return;
}
if (QFGL_ExtensionPresent ("3DFX_set_global_palette")) {
char *oldpal;
GLubyte table[256][4];
QF_gl3DfxSetPaletteEXT qgl3DfxSetPaletteEXT = NULL;
if (!(qgl3DfxSetPaletteEXT = QFGL_ExtensionAddress
("gl3DfxSetPaletteEXT"))) {
if (!(qgl3DfxSetPaletteEXT =
QFGL_ExtensionAddress ("gl3DfxSetPaletteEXT"))) {
Con_Printf ("3DFX_set_global_palette not found.\n");
return;
}
@ -373,9 +397,8 @@ Shared_Init8bitPalette (void)
GLubyte thePalette[256 * 3];
GLubyte *oldPalette, *newPalette;
if (is8bit) {
if (is8bit)
return;
}
if (QFGL_ExtensionPresent ("GL_EXT_shared_texture_palette")) {
if (!(qglColorTableEXT = QFGL_ExtensionAddress ("glColorTableEXT"))) {
@ -409,9 +432,8 @@ VID_Init8bitPalette (void)
if (vid_use8bit->int_val) {
Tdfx_Init8bitPalette ();
Shared_Init8bitPalette ();
if (!is8bit) {
if (!is8bit)
Con_Printf ("\n 8-bit extension not found.\n");
}
} else {
Con_Printf ("disabled.\n");
}