diff --git a/include/QF/GL/qf_lightmap.h b/include/QF/GL/qf_lightmap.h index a0f6541b8..667bf0983 100644 --- a/include/QF/GL/qf_lightmap.h +++ b/include/QF/GL/qf_lightmap.h @@ -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 diff --git a/include/QF/render.h b/include/QF/render.h index e1b7ac088..c20fb98f6 100644 --- a/include/QF/render.h +++ b/include/QF/render.h @@ -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); diff --git a/include/r_dynamic.h b/include/r_dynamic.h index 7745fd5bd..ec3402ce9 100644 --- a/include/r_dynamic.h +++ b/include/r_dynamic.h @@ -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; diff --git a/include/r_local.h b/include/r_local.h index 0538d9cbc..48f5a9698 100644 --- a/include/r_local.h +++ b/include/r_local.h @@ -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; diff --git a/include/varrays.h b/include/varrays.h index 6a1b0112f..7fe664cf4 100644 --- a/include/varrays.h +++ b/include/varrays.h @@ -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 diff --git a/libs/models/alias/gl_model_alias.c b/libs/models/alias/gl_model_alias.c index 9ccf02a40..dc58ddbb2 100644 --- a/libs/models/alias/gl_model_alias.c +++ b/libs/models/alias/gl_model_alias.c @@ -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); } } diff --git a/libs/video/renderer/gl/gl_lightmap.c b/libs/video/renderer/gl/gl_lightmap.c index 6c0e5f0e8..026929533 100644 --- a/libs/video/renderer/gl/gl_lightmap.c +++ b/libs/video/renderer/gl/gl_lightmap.c @@ -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) diff --git a/libs/video/renderer/gl/gl_mod_sprite.c b/libs/video/renderer/gl/gl_mod_sprite.c index a08108035..df41da030 100644 --- a/libs/video/renderer/gl/gl_mod_sprite.c +++ b/libs/video/renderer/gl/gl_mod_sprite.c @@ -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 +#endif +#ifdef HAVE_STRINGS_H +# include +#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; + } + } + } +} diff --git a/libs/video/renderer/gl/gl_rmain.c b/libs/video/renderer/gl/gl_rmain.c index 3f8bdb7b6..19c2f967c 100644 --- a/libs/video/renderer/gl/gl_rmain.c +++ b/libs/video/renderer/gl/gl_rmain.c @@ -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; diff --git a/libs/video/renderer/gl/gl_rmisc.c b/libs/video/renderer/gl/gl_rmisc.c index 008dbd942..4d2035096 100644 --- a/libs/video/renderer/gl/gl_rmisc.c +++ b/libs/video/renderer/gl/gl_rmisc.c @@ -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 (); } diff --git a/libs/video/renderer/gl/gl_rsurf.c b/libs/video/renderer/gl/gl_rsurf.c index 426deb205..d704177fa 100644 --- a/libs/video/renderer/gl/gl_rsurf.c +++ b/libs/video/renderer/gl/gl_rsurf.c @@ -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) diff --git a/libs/video/targets/vid_common_gl.c b/libs/video/targets/vid_common_gl.c index 5c74a5bb7..166d7bb9e 100644 --- a/libs/video/targets/vid_common_gl.c +++ b/libs/video/targets/vid_common_gl.c @@ -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"); }