GL3: Static Lightmaps (via blending)

not *that* cool, I wanna render them together with the normal texture..

and dynamic lightmaps are missing so most things look shitty anyway
This commit is contained in:
Daniel Gibson 2017-03-05 03:08:05 +01:00
parent a3865db4bb
commit 2932d995fe
7 changed files with 89 additions and 91 deletions

View file

@ -109,7 +109,7 @@ typedef struct {
int num_entities;
entity_t *entities;
int num_dlights;
int num_dlights; // <= 32 (MAX_DLIGHTS)
dlight_t *dlights;
int num_particles;

View file

@ -30,13 +30,12 @@
#define DLIGHT_CUTOFF 64
static int r_dlightframecount;
vec3_t pointcolor;
cplane_t *lightplane; /* used as shadow plane */
static vec3_t pointcolor;
static cplane_t *lightplane; /* used as shadow plane */
vec3_t lightspot;
static float s_blocklights[34 * 34 * 3];
void
void // bit: 1 << i for light number i, will be or'ed into msurface_t::dlightbits if surface is affected by this light
GL3_MarkLights(dlight_t *light, int bit, mnode_t *node)
{
cplane_t *splitplane;
@ -258,6 +257,9 @@ GL3_LightPoint(vec3_t p, vec3_t color)
end[1] = p[1];
end[2] = p[2] - 2048;
// TODO: don't just aggregate the color, but also save position of brightest+nearest light
// for shadow position and maybe lighting on model?
r = RecursiveLightPoint(gl3_worldmodel->nodes, p, end);
if (r == -1)
@ -277,7 +279,7 @@ GL3_LightPoint(vec3_t p, vec3_t color)
VectorSubtract(currententity->origin,
dl->origin, dist);
add = dl->intensity - VectorLength(dist);
add *= (1.0 / 256);
add *= (1.0f / 256.0f);
if (add > 0)
{
@ -410,7 +412,7 @@ GL3_BuildLightMap(msurface_t *surf, byte *dest, int stride)
if (surf->texinfo->flags &
(SURF_SKY | SURF_TRANS33 | SURF_TRANS66 | SURF_WARP))
{
ri.Sys_Error(ERR_DROP, "R_BuildLightMap called for non-lit surface");
ri.Sys_Error(ERR_DROP, "GL3_BuildLightMap called for non-lit surface");
}
smax = (surf->extents[0] >> 4) + 1;

View file

@ -1,5 +1,6 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
* Copyright (C) 2016-2017 Daniel Gibson
*
* 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
@ -40,28 +41,28 @@ GL3_LM_InitBlock(void)
void
GL3_LM_UploadBlock(qboolean dynamic)
{
STUB_ONCE("TODO: Implement!");
#if 0
int texture;
int height = 0;
if (dynamic)
{
STUB_ONCE("TODO: dynamic lightmap!");
texture = 0;
return;
}
else
{
texture = gl3_lms.current_lightmap_texture;
}
GL3_Bind(gl3state.lightmap_textures + texture);
GL3_Bind(gl3state.lightmap_textureIDs[texture]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
if (dynamic)
{
int i;
STUB_ONCE("TODO: dynamic lightmap!");
for (i = 0; i < BLOCK_WIDTH; i++)
{
if (gl3_lms.allocated[i] > height)
@ -87,7 +88,6 @@ GL3_LM_UploadBlock(qboolean dynamic)
"LM_UploadBlock() - MAX_LIGHTMAPS exceeded\n");
}
}
#endif // 0
}
/*
@ -270,17 +270,12 @@ GL3_LM_BeginBuildingLightmaps(gl3model_t *m)
gl3_newrefdef.lightstyles = lightstyles;
STUB_ONCE("TODO: IMPLEMENT!");
#if 0
if (!gl_state.lightmap_textures)
{
gl3state.lightmap_textures = TEXNUM_LIGHTMAPS;
}
gl3_lms.current_lightmap_texture = 1;
gl3_lms.internal_format = GL_LIGHTMAP_FORMAT;
#if 0
/* initialize the dynamic lightmap texture */
GL3_Bind(gl_state.lightmap_textures + 0);
GL3_Bind(gl3state.lightmap_textureIDs[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, gl3_lms.internal_format,

View file

@ -514,6 +514,8 @@ GL3_Init(void)
R_Printf(PRINT_ALL, " - OpenGL Debug Output: Not Supported\n");
}
// generate texture handles for all possible lightmaps
glGenTextures(MAX_LIGHTMAPS, gl3state.lightmap_textureIDs);
GL3_SetDefaultState();

View file

@ -268,6 +268,7 @@ static const char* vertexCommon3D = MULTILINE_STRING(#version 150\n
{
mat4 transProj;
mat4 transModelView; // TODO: or maybe transViewProj and transModel ??
vec2 lmOffset;
float scroll; // for SURF_FLOWING
float time;
float alpha;
@ -294,6 +295,7 @@ static const char* fragmentCommon3D = MULTILINE_STRING(#version 150\n
{
mat4 transProj;
mat4 transModelView; // TODO: or maybe transViewProj and transModel ??
vec2 lmOffset;
float scroll; // for SURF_FLOWING
float time;
float alpha;
@ -311,6 +313,18 @@ static const char* vertexSrc3D = MULTILINE_STRING(
}
);
static const char* vertexSrc3Dlm = MULTILINE_STRING(
// it gets attributes and uniforms from vertexCommon3D
void main()
{
//passTexCoord = texCoord;
passTexCoord = lmTexCoord-lmOffset;
gl_Position = transProj * transModelView * vec4(position, 1.0);
}
);
static const char* fragmentSrc3D = MULTILINE_STRING(
// it gets attributes and uniforms from fragmentCommon3D
@ -777,6 +791,11 @@ qboolean GL3_InitShaders(void)
R_Printf(PRINT_ALL, "WARNING: Failed to create shader program for flat-colored 3D rendering!\n");
return false;
}
if(!initShader3D(&gl3state.si3Dlm, vertexSrc3Dlm, fragmentSrc3D))
{
R_Printf(PRINT_ALL, "WARNING: Failed to create shader program for blending 3D lightmaps rendering!\n");
return false;
}
if(!initShader3D(&gl3state.si3Dturb, vertexSrc3Dwater, fragmentSrc3D))
{
R_Printf(PRINT_ALL, "WARNING: Failed to create shader program for water rendering!\n");

View file

@ -271,64 +271,26 @@ static void
DrawGLPolyChain(glpoly_t *p, float soffset, float toffset)
{
STUB_ONCE("TODO: Implement!");
#if 0
if ((soffset == 0) && (toffset == 0))
if(gl3state.uni3DData.lmOffset.X != soffset || gl3state.uni3DData.lmOffset.Y != toffset)
{
for ( ; p != 0; p = p->chain)
{
float *v;
v = p->verts[0];
if (v == NULL)
{
fprintf(stderr, "BUGFIX: R_DrawGLPolyChain: v==NULL\n");
return;
}
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glVertexPointer( 3, GL_FLOAT, VERTEXSIZE*sizeof(GLfloat), v );
glTexCoordPointer( 2, GL_FLOAT, VERTEXSIZE*sizeof(GLfloat), v+5 );
glDrawArrays( GL_TRIANGLE_FAN, 0, p->numverts );
glDisableClientState( GL_VERTEX_ARRAY );
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
}
gl3state.uni3DData.lmOffset = HMM_Vec2(soffset, toffset);
GL3_UpdateUBO3D();
}
else
for ( ; p != NULL; p = p->chain)
{
for ( ; p != 0; p = p->chain)
float* v = p->verts[0];
if (v == NULL)
{
float *v;
int j;
v = p->verts[0];
GLfloat tex[2*p->numverts];
unsigned int index_tex = 0;
for ( j = 0; j < p->numverts; j++, v += VERTEXSIZE )
{
tex[index_tex++] = v [ 5 ] - soffset;
tex[index_tex++] = v [ 6 ] - toffset;
}
v = p->verts [ 0 ];
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glVertexPointer( 3, GL_FLOAT, VERTEXSIZE*sizeof(GLfloat), v );
glTexCoordPointer( 2, GL_FLOAT, 0, tex );
glDrawArrays( GL_TRIANGLE_FAN, 0, p->numverts );
glDisableClientState( GL_VERTEX_ARRAY );
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
fprintf(stderr, "BUGFIX: DrawGLPolyChain: v==NULL\n");
return;
}
glBufferData(GL_ARRAY_BUFFER, VERTEXSIZE*sizeof(GLfloat)*p->numverts, v, GL_STREAM_DRAW);
glDrawArrays(GL_TRIANGLE_FAN, 0, p->numverts);
}
#endif // 0
}
/*
@ -353,16 +315,16 @@ BlendLightmaps(void)
}
STUB_ONCE("TODO: Implement!");
#if 0
#if 1
/* don't bother writing Z */
glDepthMask(0);
/* set the appropriate blending mode unless
we're only looking at the lightmaps. */
if (!gl_lightmap->value)
if ( 1 ) // TODO !gl_lightmap->value)
{
glEnable(GL_BLEND);
#if 0
if (gl_saturatelighting->value)
{
glBlendFunc(GL_ONE, GL_ONE);
@ -371,6 +333,10 @@ BlendLightmaps(void)
{
glBlendFunc(GL_ZERO, GL_SRC_COLOR);
}
#endif // 0
glBlendFunc(GL_ZERO, GL_SRC_COLOR);
}
if (currentmodel == gl3_worldmodel)
@ -378,6 +344,10 @@ BlendLightmaps(void)
c_visible_lightmaps = 0;
}
GL3_UseProgram(gl3state.si3Dlm.shaderProgram);
GL3_BindVAO(gl3state.vao3D);
GL3_BindVBO(gl3state.vbo3D);
/* render static lightmaps first */
for (i = 1; i < MAX_LIGHTMAPS; i++)
{
@ -388,7 +358,7 @@ BlendLightmaps(void)
c_visible_lightmaps++;
}
GL3_Bind(gl_state.lightmap_textures + i);
GL3_Bind(gl3state.lightmap_textureIDs[i]);
for (surf = gl3_lms.lightmap_surfaces[i];
surf != 0;
@ -397,11 +367,12 @@ BlendLightmaps(void)
if (surf->polys)
{
// Apply overbright bits to the static lightmaps
/*
if (gl_overbrightbits->value)
{
R_TexEnv(GL_COMBINE_EXT);
glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, gl_overbrightbits->value);
}
} */
DrawGLPolyChain(surf->polys, 0, 0);
}
@ -409,6 +380,7 @@ BlendLightmaps(void)
}
}
#if 0
/* render dynamic lightmaps */
if (gl_dynamic->value)
{
@ -439,7 +411,7 @@ BlendLightmaps(void)
base += (surf->dlight_t * BLOCK_WIDTH +
surf->dlight_s) * LIGHTMAP_BYTES;
R_BuildLightMap(surf, base, BLOCK_WIDTH * LIGHTMAP_BYTES);
GL3_BuildLightMap(surf, base, BLOCK_WIDTH * LIGHTMAP_BYTES);
}
else
{
@ -485,7 +457,7 @@ BlendLightmaps(void)
base += (surf->dlight_t * BLOCK_WIDTH +
surf->dlight_s) * LIGHTMAP_BYTES;
R_BuildLightMap(surf, base, BLOCK_WIDTH * LIGHTMAP_BYTES);
GL3_BuildLightMap(surf, base, BLOCK_WIDTH * LIGHTMAP_BYTES);
}
}
@ -512,6 +484,7 @@ BlendLightmaps(void)
}
}
}
#endif // 0
/* restore state */
glDisable(GL_BLEND);
@ -614,7 +587,7 @@ RenderBrushPoly(msurface_t *fa)
}
STUB_ONCE("TODO: lightmap support (=> esp. LM textures)")
#if 0
// TODO: 2D texture array für lightmaps?
if (is_dynamic)
{
@ -622,12 +595,14 @@ RenderBrushPoly(msurface_t *fa)
(fa->styles[maps] == 0)) &&
(fa->dlightframe != gl3_framecount))
{
// undo dynamic light changes, put into non-dynamic lightmap chain?
unsigned temp[34 * 34];
int smax, tmax;
smax = (fa->extents[0] >> 4) + 1;
tmax = (fa->extents[1] >> 4) + 1;
#if 0
GL3_BuildLightMap(fa, (void *)temp, smax * 4);
GL3_SetCacheState(fa);
@ -638,15 +613,16 @@ RenderBrushPoly(msurface_t *fa)
fa->lightmapchain = gl3_lms.lightmap_surfaces[fa->lightmaptexturenum];
gl3_lms.lightmap_surfaces[fa->lightmaptexturenum] = fa;
#endif // 0
}
else
{
// dynamic lights: add to dynamic lightmap chain
fa->lightmapchain = gl3_lms.lightmap_surfaces[0];
gl3_lms.lightmap_surfaces[0] = fa;
}
}
else
#endif // 0
else // non-dynamic lightmap chain
{
fa->lightmapchain = gl3_lms.lightmap_surfaces[fa->lightmaptexturenum];
gl3_lms.lightmap_surfaces[fa->lightmaptexturenum] = fa;

View file

@ -130,13 +130,22 @@ typedef struct
hmm_mat4 transProjMat4;
hmm_mat4 transModelViewMat4;
hmm_vec2 lmOffset;
GLfloat scroll; // for SURF_FLOWING
GLfloat time; // for warping surfaces like water & possibly other things
GLfloat alpha; // for translucent surfaces (water, glass, ..)
GLfloat _padding; // again, some padding to ensure this has right size
GLfloat _padding[3]; // again, some padding to ensure this has right size
} gl3Uni3D_t;
enum {
BLOCK_WIDTH = 128,
BLOCK_HEIGHT = 128,
LIGHTMAP_BYTES = 4,
MAX_LIGHTMAPS = 128
};
typedef struct
{
// TODO: what of this do we need?
@ -148,6 +157,7 @@ typedef struct
unsigned char *d_16to8table;
//int lightmap_textures;
GLuint lightmap_textureIDs[MAX_LIGHTMAPS]; // instead of lightmap_textures+i use lightmap_textureIDs[i]
//int currenttextures[2];
GLuint currenttexture;
@ -173,6 +183,7 @@ typedef struct
gl3ShaderInfo_t si3Dsky;
gl3ShaderInfo_t si3Dsprite; // for sprites
gl3ShaderInfo_t si3DspriteAlpha; // for sprites with alpha-testing
gl3ShaderInfo_t si3Dlm; // for blended lightmaps TODO: prolly remove and use multitexturing
gl3ShaderInfo_t si3Dalias; // for models
gl3ShaderInfo_t si3DaliasColor; // for models w/ flat colors
@ -235,17 +246,10 @@ enum {MAX_GL3TEXTURES = 1024};
// include this down here so it can use gl3image_t
#include "model.h"
enum {
BLOCK_WIDTH = 128,
BLOCK_HEIGHT = 128,
LIGHTMAP_BYTES = 4,
MAX_LIGHTMAPS = 128
};
typedef struct
{
int internal_format;
int current_lightmap_texture;
int current_lightmap_texture; // index into gl3state.lightmap_textureIDs[]
msurface_t *lightmap_surfaces[MAX_LIGHTMAPS];