Lightmaps are packed into bigger textures

VBO support
This commit is contained in:
cholleme 2004-02-07 20:44:14 +00:00
parent 61fc69eadf
commit 106fe4c3da

View file

@ -30,11 +30,6 @@ int lightmap_bytes; // 1, 2, or 4
int lightmap_textures = 0; int lightmap_textures = 0;
#define MAX_LIGHTMAPS 256
glpoly_t *lightmap_polys[MAX_LIGHTMAPS];
/* /*
==================================================== ====================================================
Global vertex table stuff: Global vertex table stuff:
@ -46,7 +41,6 @@ The global vertex table contains world+brush model+static models+curve vertices.
buffer (on the Hunk) buffer (on the Hunk)
==================================================== ====================================================
*/ */
mmvertex_t *globalVertexTable = NULL;
mmvertex_t *tempVertices = NULL; mmvertex_t *tempVertices = NULL;
int tempVerticesSize = 0; int tempVerticesSize = 0;
@ -57,7 +51,7 @@ int R_GetNextVertexIndex(void) {
return numTempVertices; return numTempVertices;
} }
/* /*
Returns the index of the vertex the date was copied to... Returns the index of the vertex the data was copied to...
*/ */
int R_AllocateVertexInTemp(vec3_t pos, float texture [2], float lightmap[2], byte color[4]) { int R_AllocateVertexInTemp(vec3_t pos, float texture [2], float lightmap[2], byte color[4]) {
@ -91,17 +85,66 @@ int R_AllocateVertexInTemp(vec3_t pos, float texture [2], float lightmap[2], byt
tempVertices[numTempVertices].color[i] = color[i]; tempVertices[numTempVertices].color[i] = color[i];
} }
globalVertexTable = tempVertices;
numTempVertices++; numTempVertices++;
return numTempVertices-1; return numTempVertices-1;
} }
vertexdef_t worldVertexDef;
void R_CopyVerticesToHunk(void) void R_CopyVerticesToHunk(void)
{ {
globalVertexTable = Hunk_Alloc(numTempVertices*sizeof(mmvertex_t)); vec3_t *vecs;
Q_memcpy(globalVertexTable,tempVertices,numTempVertices*sizeof(mmvertex_t)); int i,j;
//Position, texture coords and color
//Setup the vertexdef for the world
Q_memset(&worldVertexDef, 0, sizeof(vertexdef_t));
worldVertexDef.vertices = GL_StaticAlloc(numTempVertices*sizeof(mmvertex_t), tempVertices);
worldVertexDef.vertexstride = sizeof(mmvertex_t);
worldVertexDef.texcoords = GL_OffsetDriverPtr(worldVertexDef.vertices, 12);
worldVertexDef.texcoordstride = sizeof(mmvertex_t);
worldVertexDef.lightmapcoords = GL_OffsetDriverPtr(worldVertexDef.vertices, 20);
worldVertexDef.lightmapstride = sizeof(mmvertex_t);
worldVertexDef.colors = GL_OffsetDriverPtr(worldVertexDef.vertices, 28);
worldVertexDef.colorstride = sizeof(mmvertex_t);
free(tempVertices); free(tempVertices);
//Tangent space basis
vecs = malloc(numTempVertices*sizeof(vec3_t));
//tangents
for (i=0; i<cl.worldmodel->numsurfaces; i++) {
msurface_t *s = &cl.worldmodel->surfaces[i];
glpoly_t *p = s->polys;
if (!p) continue;
for (j=0; j<p->numverts; j++) {
VectorCopy(s->tangent,vecs[p->firstvertex+j]);
}
}
worldVertexDef.tangents = GL_StaticAlloc(numTempVertices*sizeof(vec3_t), vecs);
//binormals
for (i=0; i<cl.worldmodel->numsurfaces; i++) {
msurface_t *s = &cl.worldmodel->surfaces[i];
glpoly_t *p = s->polys;
if (!p) continue;
for (j=0; j<p->numverts; j++) {
VectorCopy(s->binormal,vecs[p->firstvertex+j]);
}
}
worldVertexDef.binormals = GL_StaticAlloc(numTempVertices*sizeof(vec3_t), vecs);
//normals
for (i=0; i<cl.worldmodel->numsurfaces; i++) {
msurface_t *s = &cl.worldmodel->surfaces[i];
glpoly_t *p = s->polys;
if (!p) continue;
for (j=0; j<p->numverts; j++) {
VectorCopy(s->plane->normal,vecs[p->firstvertex+j]);
}
}
worldVertexDef.normals = GL_StaticAlloc(numTempVertices*sizeof(vec3_t), vecs);
Con_Printf("Copied %i vertices to hunk\n",numTempVertices); Con_Printf("Copied %i vertices to hunk\n",numTempVertices);
numVertices = numTempVertices; numVertices = numTempVertices;
@ -110,6 +153,7 @@ void R_CopyVerticesToHunk(void)
numTempVertices = 0; numTempVertices = 0;
} }
/*
void R_EnableVertexTable(int fields) { void R_EnableVertexTable(int fields) {
glVertexPointer(3, GL_FLOAT, VERTEXSIZE*sizeof(float), globalVertexTable); glVertexPointer(3, GL_FLOAT, VERTEXSIZE*sizeof(float), globalVertexTable);
@ -145,7 +189,7 @@ void R_DisableVertexTable(int fields) {
} }
qglClientActiveTextureARB(GL_TEXTURE0_ARB); qglClientActiveTextureARB(GL_TEXTURE0_ARB);
} }
*/
void R_RenderDynamicLightmaps (msurface_t *fa); void R_RenderDynamicLightmaps (msurface_t *fa);
/* /*
@ -164,9 +208,6 @@ extern float speedscale; // for top sky and bottom sky
void DrawGLWaterPoly (glpoly_t *p); void DrawGLWaterPoly (glpoly_t *p);
void DrawGLWaterPolyLightmap (glpoly_t *p); void DrawGLWaterPolyLightmap (glpoly_t *p);
//lpMTexFUNC qgl MTexCoord2fSGIS = NULL;
//lpSelTexFUNC qgl SelectTextureSGIS = NULL;
/* NV_register_combiners command function pointers /* NV_register_combiners command function pointers
PENTA: I put them here because mtex functions are above it, and I hadent't any ispiration for some other place. PENTA: I put them here because mtex functions are above it, and I hadent't any ispiration for some other place.
*/ */
@ -301,20 +342,17 @@ PFNGLVERTEXATTRIBS4FVNVPROC qglVertexAttribs4fvNV = NULL;
PFNGLVERTEXATTRIBS4SVNVPROC qglVertexAttribs4svNV = NULL; PFNGLVERTEXATTRIBS4SVNVPROC qglVertexAttribs4svNV = NULL;
PFNGLVERTEXATTRIBS4UBVNVPROC qglVertexAttribs4ubvNV = NULL; PFNGLVERTEXATTRIBS4UBVNVPROC qglVertexAttribs4ubvNV = NULL;
// <AWE> There are some diffs with the function parameters. wgl stuff not present with MacOS X. -DC- and SDL PFNGLBINDBUFFERARBPROC qglBindBufferARB = NULL;
#if defined (__APPLE__) || defined (MACOSX) || defined (SDL) || defined (__glx__) PFNGLDELETEBUFFERSARBPROC qglDeleteBuffersARB = NULL;
PFNGLGENBUFFERSARBPROC qglGenBuffersARB = NULL;
PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC qglFlushVertexArrayRangeAPPLE = NULL; PFNGLISBUFFERARBPROC qglIsBufferARB = NULL;
PFNGLVERTEXARRAYRANGEAPPLEPROC qglVertexArrayRangeAPPLE = NULL; PFNGLBUFFERDATAARBPROC qglBufferDataARB = NULL;
PFNGLBUFFERSUBDATAARBPROC qglBufferSubDataARB = NULL;
#else PFNGLGETBUFFERSUBDATAARBPROC qglGetBufferSubDataARB = NULL;
PFNGLMAPBUFFERARBPROC qglMapBufferARB = NULL;
PFNGLFLUSHVERTEXARRAYRANGENVPROC qglFlushVertexArrayRangeNV = NULL; PFNGLUNMAPBUFFERARBPROC qglUnmapBufferARB = NULL;
PFNGLVERTEXARRAYRANGENVPROC glVertexArrayRangeNV = NULL; PFNGLGETBUFFERPARAMETERIVARBPROC qglGetBufferParameterivARB = NULL;
PFNWGLALLOCATEMEMORYNVPROC wglAllocateMemoryNV = NULL; PFNGLGETBUFFERPOINTERVARBPROC qglGetBufferPointervARB = NULL;
PFNWGLFREEMEMORYNVPROC wglFreeMemoryNV = NULL;
#endif /* __APPLE__ || MACOSX */
qboolean mtexenabled = false; qboolean mtexenabled = false;
@ -338,7 +376,7 @@ void GL_EnableMultitexture(void)
} }
} }
/*
void R_RenderBrushPolyCaustics (msurface_t *fa) void R_RenderBrushPolyCaustics (msurface_t *fa)
{ int i; { int i;
float *v; float *v;
@ -356,7 +394,7 @@ void R_RenderBrushPolyCaustics (msurface_t *fa)
glEnd (); glEnd ();
} }
*/
/* /*
================ ================
DrawTextureChains DrawTextureChains
@ -528,7 +566,7 @@ void DrawBlendedTextureChains (void)
glDepthMask (1); glDepthMask (1);
} }
void R_DrawBrushModelCaustics (entity_t *e); //void R_DrawBrushModelCaustics (entity_t *e);
/* /*
============= =============
@ -538,6 +576,7 @@ Tenebrae does "real cauistics", projected textures on all things including ents
(Other mods seem to just add an extra, not properly projected layer to the polygons in the world.) (Other mods seem to just add an extra, not properly projected layer to the polygons in the world.)
============= =============
*/ */
/*
void R_DrawCaustics(void) { void R_DrawCaustics(void) {
msurface_t *s; msurface_t *s;
@ -627,12 +666,12 @@ void R_DrawCaustics(void) {
glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T); glDisable(GL_TEXTURE_GEN_T);
} }
*/
/* /*
================= =================
R_DrawBrushModel R_DrawBrushModel
================= =================
*/ *//*
void R_DrawBrushModelCaustics (entity_t *e) void R_DrawBrushModelCaustics (entity_t *e)
{ {
vec3_t mins, maxs; vec3_t mins, maxs;
@ -714,7 +753,7 @@ e->angles[0] = -e->angles[0]; // stupid quake bug
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glPopMatrix (); glPopMatrix ();
} }
*/
/* /*
================= =================
R_DrawBrushModel R_DrawBrushModel
@ -922,13 +961,6 @@ void R_RecursiveWorldNode (mnode_t *node)
*/ */
(*mark)->texturechain = (*mark)->shader->texturechain; (*mark)->texturechain = (*mark)->shader->texturechain;
(*mark)->shader->texturechain = (*mark); (*mark)->shader->texturechain = (*mark);
if (!((*mark)->flags & (SURF_DRAWSKY | SURF_DRAWTURB))) {
(*mark)->polys->chain = lightmap_polys[(*mark)->lightmaptexturenum];
lightmap_polys[(*mark)->lightmaptexturenum] = (*mark)->polys;
}
(*mark)->visframe = r_framecount; (*mark)->visframe = r_framecount;
mark++; mark++;
} while (--c); } while (--c);
@ -1105,21 +1137,11 @@ void R_InitDrawWorld (void)
currenttexture = -1; currenttexture = -1;
glColor3f (1,1,1); glColor3f (1,1,1);
memset (lightmap_polys, 0, sizeof(lightmap_polys));
//#ifdef QUAKE2
R_ClearSkyBox ();
//#endif
//if (mirror) Con_Printf("RWorldn\n");
//mark visible polygons/ents
worldbox = emptyBox(); worldbox = emptyBox();
R_RecursiveWorldNode (cl.worldmodel->nodes); R_RecursiveWorldNode (cl.worldmodel->nodes);
//#ifdef QUAKE2
if (gl_wireframe.value) return; if (gl_wireframe.value) return;
R_DrawSkyBox (); R_DrawSkyBox ();
//if (gl_fog.value) glEnable(GL_FOG);
//#endif
} }
/* /*
@ -1209,7 +1231,22 @@ void R_MarkLeaves (void)
============================================================================= =============================================================================
*/ */
#define LIGHTMAP_WIDTH 128 void SaveTGA (const char *filename, unsigned char *pixels, int width, int height) {
TargaHeader targa_header;
FILE *fout;
int i;
fout = fopen(filename, "wb");
//fwrite(pixels, 1, width*height*4, fout);
for (i=0; i<width*height; i++) {
int ind = i*3;
fputc(pixels[ind+0],fout);
fputc(pixels[ind+1],fout);
fputc(pixels[ind+2],fout);
}
fclose(fout);
}
/* /*
================== ==================
@ -1237,10 +1274,12 @@ void GL_BuildLightmaps (void)
lightmap_bytes = 4; lightmap_bytes = 4;
if (!COM_CheckParm("-externallight")) { if (!COM_CheckParm("-externallight")) {
byte *packed, *deluxPack;
int lmIndex;
char name[512];
//no lightmaps in bsp make everything black... //no lightmaps in bsp make everything black...
if (!cl.worldmodel->numlightmaps) { if (!cl.worldmodel->numlightmaps) {
int black = 0; int black = 0;
Con_Printf("No lightmaps in map, defaulting to black.\n"); Con_Printf("No lightmaps in map, defaulting to black.\n");
GL_Bind(lightmap_textures); GL_Bind(lightmap_textures);
@ -1251,28 +1290,100 @@ void GL_BuildLightmaps (void)
for (i=0; i<cl.worldmodel->numsurfaces; i++) { for (i=0; i<cl.worldmodel->numsurfaces; i++) {
cl.worldmodel->surfaces[i].lightmaptexturenum = 0; cl.worldmodel->surfaces[i].lightmaptexturenum = 0;
} }
cl.worldmodel->numlightmaps = 1;
for (i=0; i<numVertices; i++) { Cvar_Set("sh_delux","0");
globalVertexTable[i].color[0] = 0;
globalVertexTable[i].color[1] = 0;
globalVertexTable[i].color[2] = 0;
globalVertexTable[i].color[3] = 0;
}
return; return;
} }
//Load lightmaps stored in the bsp lump //Load lightmaps stored in the bsp lump
for (i=0 ; i<cl.worldmodel->numlightmaps ; i++) packed = malloc(PACKED_LIGHTMAP_WIDTH*PACKED_LIGHTMAP_WIDTH*3);
deluxPack = malloc(PACKED_LIGHTMAP_WIDTH*PACKED_LIGHTMAP_WIDTH*3);
for (i=0 ; i<cl.worldmodel->numlightmaps ; i+=2)
{ {
int lmIndex = i/2; //Delux not counted
int ofsX = LIGHTMAP_COLUMN(lmIndex)*FILE_LIGHTMAP_WIDTH;
int ofsY = LIGHTMAP_ROW(lmIndex)*FILE_LIGHTMAP_WIDTH;
int x,y,z;
//Con_Printf("Lightmap %i (texnum: %i)\n",i,lightmap_textures + i); //Copy light color
GL_Bind(lightmap_textures + i); byte *lmap = cl.worldmodel->lightdata+(lmIndex*2*FILE_LIGHTMAP_WIDTH*FILE_LIGHTMAP_WIDTH*3);
for (x=0; x<FILE_LIGHTMAP_WIDTH; x++) {
for (y=0; y<FILE_LIGHTMAP_WIDTH; y++) {
int pInd = ((ofsY+y)*PACKED_LIGHTMAP_WIDTH+ofsX+x)*3;
int fInd = (y*FILE_LIGHTMAP_WIDTH+x)*3;
packed[pInd+0] = lmap[fInd+0];
packed[pInd+1] = lmap[fInd+1];
packed[pInd+2] = lmap[fInd+2];
}
}
//Delux
lmap = cl.worldmodel->lightdata+((lmIndex*2+1)*FILE_LIGHTMAP_WIDTH*FILE_LIGHTMAP_WIDTH*3);
for (x=0; x<FILE_LIGHTMAP_WIDTH; x++) {
for (y=0; y<FILE_LIGHTMAP_WIDTH; y++) {
int pInd = ((ofsY+y)*PACKED_LIGHTMAP_WIDTH+ofsX+x)*3;
int fInd = (y*FILE_LIGHTMAP_WIDTH+x)*3;
deluxPack[pInd+0] = lmap[fInd+0];
deluxPack[pInd+1] = lmap[fInd+1];
deluxPack[pInd+2] = lmap[fInd+2];
}
}
if ((lmIndex%PACKED_LIGHTMAP_COUNT) == PACKED_LIGHTMAP_COUNT-1) {
sprintf(name,"PackLight%i.raw",(lmIndex/PACKED_LIGHTMAP_COUNT)/2);
SaveTGA(name, packed, PACKED_LIGHTMAP_WIDTH, PACKED_LIGHTMAP_WIDTH);
sprintf(name,"PackDelux%i.raw",(lmIndex/PACKED_LIGHTMAP_COUNT)/2+1);
SaveTGA(name, deluxPack, PACKED_LIGHTMAP_WIDTH, PACKED_LIGHTMAP_WIDTH);
//Color
GL_Bind(lightmap_textures + ((lmIndex/PACKED_LIGHTMAP_COUNT)*2));
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D (GL_TEXTURE_2D, 0, 3
, PACKED_LIGHTMAP_WIDTH, PACKED_LIGHTMAP_WIDTH, 0,
gl_lightmap_format, GL_UNSIGNED_BYTE,packed);
//Delux
GL_Bind(lightmap_textures + ((lmIndex/PACKED_LIGHTMAP_COUNT)*2+1));
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D (GL_TEXTURE_2D, 0, 3
, PACKED_LIGHTMAP_WIDTH, PACKED_LIGHTMAP_WIDTH, 0,
gl_lightmap_format, GL_UNSIGNED_BYTE,deluxPack);
}
}
//Upload an eventual incomplete last one
lmIndex = cl.worldmodel->numlightmaps/2;
if (((lmIndex)%PACKED_LIGHTMAP_COUNT) != PACKED_LIGHTMAP_COUNT-1) {
sprintf(name,"PackLight%i.raw",(lmIndex/PACKED_LIGHTMAP_COUNT)*2);
SaveTGA(name, packed, 512, 512);
sprintf(name,"PackDelux%i.raw",(lmIndex/PACKED_LIGHTMAP_COUNT)*2+1);
SaveTGA(name, deluxPack, 512, 512);
//Color
GL_Bind(lightmap_textures + ((lmIndex*2)/PACKED_LIGHTMAP_COUNT));
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D (GL_TEXTURE_2D, 0, 3 glTexImage2D (GL_TEXTURE_2D, 0, 3
, LIGHTMAP_WIDTH, LIGHTMAP_WIDTH, 0, , PACKED_LIGHTMAP_WIDTH, PACKED_LIGHTMAP_WIDTH, 0,
gl_lightmap_format, GL_UNSIGNED_BYTE, gl_lightmap_format, GL_UNSIGNED_BYTE,packed);
cl.worldmodel->lightdata+(i*LIGHTMAP_WIDTH*LIGHTMAP_WIDTH*3)); //Delux
GL_Bind(lightmap_textures + ((lmIndex*2+1)/PACKED_LIGHTMAP_COUNT));
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D (GL_TEXTURE_2D, 0, 3
, PACKED_LIGHTMAP_WIDTH, PACKED_LIGHTMAP_WIDTH, 0,
gl_lightmap_format, GL_UNSIGNED_BYTE,deluxPack);
} }
cl.worldmodel->numlightmaps = (cl.worldmodel->numlightmaps/PACKED_LIGHTMAP_COUNT)+1;
Con_Printf("GL_BuildLightmaps: %i unused lightmap slots\n", cl.worldmodel->numlightmaps%PACKED_LIGHTMAP_COUNT);
free(packed);
free(deluxPack);
} else { } else {
//Load externally stored lightmaps //Load externally stored lightmaps
int old_tex_ext; int old_tex_ext;