mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-22 20:51:31 +00:00
GL3: Support dynamic lights (mostly) + changes for that
Dynamic lights on normal world brushes work, on brush-based entities probably not yet properly. For this I need the model matrix in the shader to transform vertex positions and normals to worldspace (they already are for world brushes, but not entities that might rotate and move etc). Furthermore, while they dynamic lights look nice and smooth they might need some fine tuning in the shader.. For this to work there are two bigger changes: * the vertex data for brushes (gl3_3D_vtx_t) now also contains the vertex normal - glpoly_t contains array of gl3_3D_vtx_t instead of 7 floats * 3D shaders now have in vec3 normal, bound to GL3_ATTRIB_NORMAL * There's a new UBO for light data: uniLights, containing an array of up to 32 dynamic lights, with data copied from gl3_newrefdef.dlights
This commit is contained in:
parent
6547e08c1a
commit
d5cf8c2852
7 changed files with 235 additions and 75 deletions
|
@ -110,10 +110,26 @@ GL3_PushDlights(void)
|
|||
|
||||
l = gl3_newrefdef.dlights;
|
||||
|
||||
gl3state.uniLightsData.numDynLights = gl3_newrefdef.num_dlights;
|
||||
|
||||
for (i = 0; i < gl3_newrefdef.num_dlights; i++, l++)
|
||||
{
|
||||
gl3UniDynLight* udl = &gl3state.uniLightsData.dynLights[i];
|
||||
GL3_MarkLights(l, 1 << i, gl3_worldmodel->nodes);
|
||||
|
||||
VectorCopy(l->origin, udl->origin);
|
||||
VectorCopy(l->color, udl->color);
|
||||
udl->intensity = l->intensity;
|
||||
}
|
||||
|
||||
assert(MAX_DLIGHTS == 32 && "If MAX_DLIGHTS changes, remember to adjust the uniform buffer definition in the shader!");
|
||||
|
||||
if(i < MAX_DLIGHTS)
|
||||
{
|
||||
memset(&gl3state.uniLightsData.dynLights[i], 0, (MAX_DLIGHTS-i)*sizeof(gl3state.uniLightsData.dynLights[0]));
|
||||
}
|
||||
|
||||
GL3_UpdateUBOLights();
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -126,6 +126,7 @@ GL3_LM_BuildPolygonFromSurface(msurface_t *fa)
|
|||
float s, t;
|
||||
glpoly_t *poly;
|
||||
vec3_t total;
|
||||
vec3_t normal;
|
||||
|
||||
/* reconstruct the polygon */
|
||||
pedges = currentmodel->edges;
|
||||
|
@ -135,14 +136,25 @@ GL3_LM_BuildPolygonFromSurface(msurface_t *fa)
|
|||
|
||||
/* draw texture */
|
||||
poly = Hunk_Alloc(sizeof(glpoly_t) +
|
||||
(lnumverts - 4) * VERTEXSIZE * sizeof(float));
|
||||
(lnumverts - 4) * sizeof(gl3_3D_vtx_t));
|
||||
poly->next = fa->polys;
|
||||
poly->flags = fa->flags;
|
||||
fa->polys = poly;
|
||||
poly->numverts = lnumverts;
|
||||
|
||||
VectorCopy(fa->plane->normal, normal);
|
||||
|
||||
if(fa->flags & SURF_PLANEBACK)
|
||||
{
|
||||
// if for some reason the normal sticks to the back of the plane, invert it
|
||||
// so it's usable for the shader
|
||||
for (i=0; i<3; ++i) normal[i] = -normal[i];
|
||||
}
|
||||
|
||||
for (i = 0; i < lnumverts; i++)
|
||||
{
|
||||
gl3_3D_vtx_t* vert = &poly->vertices[i];
|
||||
|
||||
lindex = currentmodel->surfedges[fa->firstedge + i];
|
||||
|
||||
if (lindex > 0)
|
||||
|
@ -163,9 +175,9 @@ GL3_LM_BuildPolygonFromSurface(msurface_t *fa)
|
|||
t /= fa->texinfo->image->height;
|
||||
|
||||
VectorAdd(total, vec, total);
|
||||
VectorCopy(vec, poly->verts[i]);
|
||||
poly->verts[i][3] = s;
|
||||
poly->verts[i][4] = t;
|
||||
VectorCopy(vec, vert->pos);
|
||||
vert->texCoord[0] = s;
|
||||
vert->texCoord[1] = t;
|
||||
|
||||
/* lightmap texture coordinates */
|
||||
s = DotProduct(vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
|
||||
|
@ -180,8 +192,10 @@ GL3_LM_BuildPolygonFromSurface(msurface_t *fa)
|
|||
t += 8;
|
||||
t /= BLOCK_HEIGHT * 16; /* fa->texinfo->texture->height; */
|
||||
|
||||
poly->verts[i][5] = s;
|
||||
poly->verts[i][6] = t;
|
||||
vert->lmTexCoord[0] = s;
|
||||
vert->lmTexCoord[1] = t;
|
||||
|
||||
VectorCopy(normal, vert->normal);
|
||||
}
|
||||
|
||||
poly->numverts = lnumverts;
|
||||
|
|
|
@ -109,6 +109,7 @@ CreateShaderProgram(int numShaders, const GLuint* shaders)
|
|||
glBindAttribLocation(shaderProgram, GL3_ATTRIB_TEXCOORD, "texCoord");
|
||||
glBindAttribLocation(shaderProgram, GL3_ATTRIB_LMTEXCOORD, "lmTexCoord");
|
||||
glBindAttribLocation(shaderProgram, GL3_ATTRIB_COLOR, "vertColor");
|
||||
glBindAttribLocation(shaderProgram, GL3_ATTRIB_NORMAL, "normal");
|
||||
|
||||
// the following line is not necessary/implicit (as there's only one output)
|
||||
// glBindFragDataLocation(shaderProgram, 0, "outColor"); XXX would this even be here?
|
||||
|
@ -260,9 +261,9 @@ static const char* vertexCommon3D = MULTILINE_STRING(#version 150\n
|
|||
in vec2 texCoord; // GL3_ATTRIB_TEXCOORD
|
||||
in vec2 lmTexCoord; // GL3_ATTRIB_LMTEXCOORD
|
||||
in vec4 vertColor; // GL3_ATTRIB_COLOR
|
||||
in vec3 normal; // GL3_ATTRIB_NORMAL
|
||||
|
||||
out vec2 passTexCoord;
|
||||
out vec2 passLMcoord;
|
||||
|
||||
// for UBO shared between all 3D shaders
|
||||
layout (std140) uniform uni3D
|
||||
|
@ -314,19 +315,55 @@ static const char* vertexSrc3D = MULTILINE_STRING(
|
|||
void main()
|
||||
{
|
||||
passTexCoord = texCoord;
|
||||
passLMcoord = lmTexCoord;
|
||||
gl_Position = transProj * transModelView * vec4(position, 1.0);
|
||||
}
|
||||
);
|
||||
|
||||
static const char* vertexSrc3DlmOnly = MULTILINE_STRING(
|
||||
static const char* vertexSrc3Dflow = MULTILINE_STRING(
|
||||
|
||||
// it gets attributes and uniforms from vertexCommon3D
|
||||
|
||||
void main()
|
||||
{
|
||||
//passTexCoord = texCoord;
|
||||
passTexCoord = lmTexCoord-lmOffset;
|
||||
passTexCoord = texCoord + vec2(0, scroll);
|
||||
gl_Position = transProj * transModelView * vec4(position, 1.0);
|
||||
}
|
||||
);
|
||||
|
||||
static const char* vertexSrc3Dlm = MULTILINE_STRING(
|
||||
|
||||
// it gets attributes and uniforms from vertexCommon3D
|
||||
|
||||
out vec2 passLMcoord;
|
||||
out vec3 passWorldCoord;
|
||||
out vec3 passNormal;
|
||||
|
||||
void main()
|
||||
{
|
||||
passTexCoord = texCoord;
|
||||
passLMcoord = lmTexCoord;
|
||||
passWorldCoord = position; // TODO: multiply with model matrix for brush-based entities
|
||||
passNormal = normalize(normal); // TODO: multiply with model matrix and normalize
|
||||
|
||||
gl_Position = transProj * transModelView * vec4(position, 1.0);
|
||||
}
|
||||
);
|
||||
|
||||
static const char* vertexSrc3DlmFlow = MULTILINE_STRING(
|
||||
|
||||
// it gets attributes and uniforms from vertexCommon3D
|
||||
|
||||
out vec2 passLMcoord;
|
||||
out vec3 passWorldCoord;
|
||||
out vec3 passNormal;
|
||||
|
||||
void main()
|
||||
{
|
||||
passTexCoord = texCoord + vec2(0, scroll);
|
||||
passLMcoord = lmTexCoord;
|
||||
passWorldCoord = position; // TODO: multiply with model matrix for brush-based entities
|
||||
passNormal = normalize(normal); // TODO: multiply with model matrix and normalize
|
||||
|
||||
gl_Position = transProj * transModelView * vec4(position, 1.0);
|
||||
}
|
||||
);
|
||||
|
@ -352,6 +389,19 @@ static const char* fragmentSrc3Dlm = MULTILINE_STRING(
|
|||
|
||||
// it gets attributes and uniforms from fragmentCommon3D
|
||||
|
||||
struct DynLight { // gl3UniDynLight in C
|
||||
vec3 lightOrigin;
|
||||
float _pad;
|
||||
vec3 lightColor;
|
||||
float lightIntensity;
|
||||
};
|
||||
|
||||
layout (std140) uniform uniLights
|
||||
{
|
||||
DynLight dynLights[32];
|
||||
uint numDynLights;
|
||||
};
|
||||
|
||||
uniform sampler2D tex;
|
||||
|
||||
uniform sampler2D lightmap0;
|
||||
|
@ -362,6 +412,8 @@ static const char* fragmentSrc3Dlm = MULTILINE_STRING(
|
|||
uniform vec4 lmScales[4];
|
||||
|
||||
in vec2 passLMcoord;
|
||||
in vec3 passWorldCoord;
|
||||
in vec3 passNormal;
|
||||
|
||||
void main()
|
||||
{
|
||||
|
@ -376,6 +428,39 @@ static const char* fragmentSrc3Dlm = MULTILINE_STRING(
|
|||
lmTex += texture(lightmap2, passLMcoord) * lmScales[2];
|
||||
lmTex += texture(lightmap3, passLMcoord) * lmScales[3];
|
||||
|
||||
float planeDist = -dot(passNormal, passWorldCoord); // signed dist to origin, hopefully like msurface_t->plane->dist
|
||||
|
||||
// TODO: or is hardcoding 32 better?
|
||||
for(uint i=uint(0); i<numDynLights; ++i)
|
||||
{
|
||||
// I made the following up, it's probably not too cool..
|
||||
// it basically checks if the light is on the right side of the surface
|
||||
// and, if it is, sets intensity according to distance between light and pixel on surface
|
||||
|
||||
// signed distance between light and plane
|
||||
float fdist = dot(passNormal, dynLights[i].lightOrigin) + planeDist;
|
||||
|
||||
if(fdist < 0) continue; // light is on wrong side of the plane
|
||||
|
||||
vec3 lightToPos = dynLights[i].lightOrigin - passWorldCoord;
|
||||
float distLightToPos = length(lightToPos);
|
||||
float fact = max(0, dynLights[i].lightIntensity - distLightToPos - 64); // FIXME: really - 64 for DLIGHT_CUTOFF?
|
||||
|
||||
lmTex.rgb += dynLights[i].lightColor * fact * (1.0/256.0);
|
||||
|
||||
/* // the following is kinda like phong and doesn't work yet
|
||||
|
||||
if(fdist < 0) continue; // light is on wrong side of the plane
|
||||
float fact = dot(passNormal, normalize(dynLights[i].lightOrigin-passWorldCoord));
|
||||
vec3 lightToPos = dynLights[i].lightOrigin - passWorldCoord;
|
||||
float distLightToPos = length(lightToPos);
|
||||
fact *= (dynLights[i].lightIntensity - distLightToPos);
|
||||
//fact -= fdist;
|
||||
fact = max(fact, 0);
|
||||
lmTex.rgb += dynLights[i].lightColor * fact * (1.0/256.0);
|
||||
*/
|
||||
}
|
||||
|
||||
lmTex.rgb *= overbrightbits;
|
||||
outColor = lmTex*texel;
|
||||
outColor.rgb = pow(outColor.rgb, vec3(gamma)); // apply gamma correction to result
|
||||
|
@ -471,17 +556,6 @@ static const char* vertexSrc3Dwater = MULTILINE_STRING(
|
|||
}
|
||||
);
|
||||
|
||||
static const char* vertexSrc3Dflow = MULTILINE_STRING(
|
||||
|
||||
// it gets attributes and uniforms from vertexCommon3D
|
||||
void main()
|
||||
{
|
||||
passTexCoord = texCoord + vec2(0, scroll);
|
||||
passLMcoord = lmTexCoord;
|
||||
gl_Position = transProj * transModelView * vec4(position, 1.0);
|
||||
}
|
||||
);
|
||||
|
||||
static const char* vertexSrcAlias = MULTILINE_STRING(
|
||||
|
||||
// it gets attributes and uniforms from vertexCommon3D
|
||||
|
@ -589,7 +663,8 @@ static const char* fragmentSrcParticles = MULTILINE_STRING(
|
|||
enum {
|
||||
GL3_BINDINGPOINT_UNICOMMON,
|
||||
GL3_BINDINGPOINT_UNI2D,
|
||||
GL3_BINDINGPOINT_UNI3D
|
||||
GL3_BINDINGPOINT_UNI3D,
|
||||
GL3_BINDINGPOINT_UNILIGHTS
|
||||
};
|
||||
|
||||
static qboolean
|
||||
|
@ -760,6 +835,28 @@ initShader3D(gl3ShaderInfo_t* shaderInfo, const char* vertSrc, const char* fragS
|
|||
|
||||
goto err_cleanup;
|
||||
}
|
||||
blockIndex = glGetUniformBlockIndex(prog, "uniLights");
|
||||
if(blockIndex != GL_INVALID_INDEX)
|
||||
{
|
||||
GLint blockSize;
|
||||
glGetActiveUniformBlockiv(prog, blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize);
|
||||
if(blockSize != sizeof(gl3state.uniLightsData))
|
||||
{
|
||||
R_Printf(PRINT_ALL, "WARNING: OpenGL driver disagrees with us about UBO size of 'uniLights'\n");
|
||||
R_Printf(PRINT_ALL, " OpenGL says %d, we say %d\n", blockSize, (int)sizeof(gl3state.uniLightsData));
|
||||
|
||||
goto err_cleanup;
|
||||
}
|
||||
|
||||
glUniformBlockBinding(prog, blockIndex, GL3_BINDINGPOINT_UNILIGHTS);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: warn about this? only the lightmapped shaders have/need this..
|
||||
R_Printf(PRINT_ALL, "WARNING: Couldn't find uniform block index 'uniLights'\n");
|
||||
|
||||
//goto err_cleanup;
|
||||
}
|
||||
|
||||
// make sure texture is GL_TEXTURE0
|
||||
GLint texLoc = glGetUniformLocation(prog, "tex");
|
||||
|
@ -842,7 +939,13 @@ static void initUBOs(void)
|
|||
glBindBuffer(GL_UNIFORM_BUFFER, gl3state.uni3DUBO);
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, GL3_BINDINGPOINT_UNI3D, gl3state.uni3DUBO);
|
||||
glBufferData(GL_UNIFORM_BUFFER, sizeof(gl3state.uni3DData), &gl3state.uni3DData, GL_DYNAMIC_DRAW);
|
||||
gl3state.currentUBO = gl3state.uni3DUBO;
|
||||
|
||||
glGenBuffers(1, &gl3state.uniLightsUBO);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, gl3state.uniLightsUBO);
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, GL3_BINDINGPOINT_UNILIGHTS, gl3state.uniLightsUBO);
|
||||
glBufferData(GL_UNIFORM_BUFFER, sizeof(gl3state.uniLightsData), &gl3state.uniLightsData, GL_DYNAMIC_DRAW);
|
||||
|
||||
gl3state.currentUBO = gl3state.uniLightsUBO;
|
||||
}
|
||||
|
||||
qboolean GL3_InitShaders(void)
|
||||
|
@ -859,7 +962,7 @@ qboolean GL3_InitShaders(void)
|
|||
R_Printf(PRINT_ALL, "WARNING: Failed to create shader program for color-only 2D rendering!\n");
|
||||
return false;
|
||||
}
|
||||
if(!initShader3D(&gl3state.si3Dlm, vertexSrc3D, fragmentSrc3Dlm))
|
||||
if(!initShader3D(&gl3state.si3Dlm, vertexSrc3Dlm, fragmentSrc3Dlm))
|
||||
{
|
||||
R_Printf(PRINT_ALL, "WARNING: Failed to create shader program for textured 3D rendering with lightmap!\n");
|
||||
return false;
|
||||
|
@ -886,7 +989,7 @@ qboolean GL3_InitShaders(void)
|
|||
R_Printf(PRINT_ALL, "WARNING: Failed to create shader program for water rendering!\n");
|
||||
return false;
|
||||
}
|
||||
if(!initShader3D(&gl3state.si3DlmFlow, vertexSrc3Dflow, fragmentSrc3Dlm))
|
||||
if(!initShader3D(&gl3state.si3DlmFlow, vertexSrc3DlmFlow, fragmentSrc3Dlm))
|
||||
{
|
||||
R_Printf(PRINT_ALL, "WARNING: Failed to create shader program for scrolling textured 3D rendering with lightmap!\n");
|
||||
return false;
|
||||
|
@ -941,10 +1044,10 @@ void GL3_ShutdownShaders(void)
|
|||
*si = siZero;
|
||||
}
|
||||
|
||||
// let's (ab)use the fact that all 3 UBO handles are consecutive fields
|
||||
// let's (ab)use the fact that all 4 UBO handles are consecutive fields
|
||||
// of the gl3state struct
|
||||
glDeleteBuffers(3, &gl3state.uniCommonUBO);
|
||||
gl3state.uniCommonUBO = gl3state.uni2DUBO = gl3state.uni3DUBO = 0;
|
||||
glDeleteBuffers(4, &gl3state.uniCommonUBO);
|
||||
gl3state.uniCommonUBO = gl3state.uni2DUBO = gl3state.uni3DUBO = gl3state.uniLightsUBO = 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
@ -1008,3 +1111,8 @@ void GL3_UpdateUBO3D(void)
|
|||
{
|
||||
updateUBO(gl3state.uni3DUBO, sizeof(gl3state.uni3DData), &gl3state.uni3DData);
|
||||
}
|
||||
|
||||
void GL3_UpdateUBOLights(void)
|
||||
{
|
||||
updateUBO(gl3state.uniLightsUBO, sizeof(gl3state.uniLightsData), &gl3state.uniLightsData);
|
||||
}
|
||||
|
|
|
@ -44,7 +44,8 @@ extern int numgl3textures;
|
|||
void GL3_SurfInit(void)
|
||||
{
|
||||
// init the VAO and VBO for the standard vertexdata: 7 floats
|
||||
// (X, Y, Z), (S, T), (LMS, LMT) - last two for lightmap
|
||||
// (X, Y, Z), (S, T), (LMS, LMT), (normX, normY, normZ) - last two groups for lightmap/dynlights
|
||||
// TODO: remove LMS, LMT? only used for lightmapped surfaces, but those need normal as well for dyn lights
|
||||
|
||||
glGenVertexArrays(1, &gl3state.vao3D);
|
||||
GL3_BindVAO(gl3state.vao3D);
|
||||
|
@ -53,13 +54,16 @@ void GL3_SurfInit(void)
|
|||
GL3_BindVBO(gl3state.vbo3D);
|
||||
|
||||
glEnableVertexAttribArray(GL3_ATTRIB_POSITION);
|
||||
qglVertexAttribPointer(GL3_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, VERTEXSIZE*sizeof(GLfloat), 0);
|
||||
qglVertexAttribPointer(GL3_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(gl3_3D_vtx_t), 0);
|
||||
|
||||
glEnableVertexAttribArray(GL3_ATTRIB_TEXCOORD);
|
||||
qglVertexAttribPointer(GL3_ATTRIB_TEXCOORD, 2, GL_FLOAT, GL_FALSE, VERTEXSIZE*sizeof(GLfloat), 3*sizeof(GLfloat));
|
||||
qglVertexAttribPointer(GL3_ATTRIB_TEXCOORD, 2, GL_FLOAT, GL_FALSE, sizeof(gl3_3D_vtx_t), offsetof(gl3_3D_vtx_t, texCoord));
|
||||
|
||||
glEnableVertexAttribArray(GL3_ATTRIB_LMTEXCOORD);
|
||||
qglVertexAttribPointer(GL3_ATTRIB_LMTEXCOORD, 2, GL_FLOAT, GL_FALSE, VERTEXSIZE*sizeof(GLfloat), 5*sizeof(GLfloat));
|
||||
qglVertexAttribPointer(GL3_ATTRIB_LMTEXCOORD, 2, GL_FLOAT, GL_FALSE, sizeof(gl3_3D_vtx_t), offsetof(gl3_3D_vtx_t, lmTexCoord));
|
||||
|
||||
glEnableVertexAttribArray(GL3_ATTRIB_NORMAL);
|
||||
qglVertexAttribPointer(GL3_ATTRIB_NORMAL, 3, GL_FLOAT, GL_FALSE, sizeof(gl3_3D_vtx_t), offsetof(gl3_3D_vtx_t, normal));
|
||||
|
||||
|
||||
// init VAO and VBO for model vertexdata: 9 floats
|
||||
|
@ -168,11 +172,9 @@ TextureAnimation(mtexinfo_t *tex)
|
|||
void
|
||||
GL3_DrawGLPoly(glpoly_t *p)
|
||||
{
|
||||
float* v = p->verts[0];
|
||||
|
||||
GL3_BindVAO(gl3state.vao3D);
|
||||
GL3_BindVBO(gl3state.vbo3D);
|
||||
glBufferData(GL_ARRAY_BUFFER, VERTEXSIZE*sizeof(GLfloat)*p->numverts, v, GL_STREAM_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(gl3_3D_vtx_t)*p->numverts, p->vertices, GL_STREAM_DRAW);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, p->numverts);
|
||||
}
|
||||
|
@ -201,7 +203,7 @@ GL3_DrawGLFlowingPoly(msurface_t *fa)
|
|||
GL3_BindVAO(gl3state.vao3D);
|
||||
GL3_BindVBO(gl3state.vbo3D);
|
||||
|
||||
glBufferData(GL_ARRAY_BUFFER, VERTEXSIZE*sizeof(GLfloat)*p->numverts, p->verts[0], GL_STREAM_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(gl3_3D_vtx_t)*p->numverts, p->vertices, GL_STREAM_DRAW);
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, p->numverts);
|
||||
}
|
||||
|
||||
|
@ -241,10 +243,10 @@ DrawTriangleOutlines(void)
|
|||
|
||||
for (k=0; k<3; k++)
|
||||
{
|
||||
vtx[0+k] = p->verts [ 0 ][ k ];
|
||||
vtx[3+k] = p->verts [ j - 1 ][ k ];
|
||||
vtx[6+k] = p->verts [ j ][ k ];
|
||||
vtx[9+k] = p->verts [ 0 ][ k ];
|
||||
vtx[0+k] = p->vertices [ 0 ][ k ];
|
||||
vtx[3+k] = p->vertices [ j - 1 ][ k ];
|
||||
vtx[6+k] = p->vertices [ j ][ k ];
|
||||
vtx[9+k] = p->vertices [ 0 ][ k ];
|
||||
}
|
||||
|
||||
glEnableClientState( GL_VERTEX_ARRAY );
|
||||
|
|
|
@ -71,6 +71,9 @@ R_SubdividePolygon(int numverts, float *verts, msurface_t *warpface)
|
|||
float s, t;
|
||||
vec3_t total;
|
||||
float total_s, total_t;
|
||||
vec3_t normal;
|
||||
|
||||
VectorCopy(warpface->plane->normal, normal);
|
||||
|
||||
if (numverts > 60)
|
||||
{
|
||||
|
@ -150,7 +153,7 @@ R_SubdividePolygon(int numverts, float *verts, msurface_t *warpface)
|
|||
}
|
||||
|
||||
/* add a point in the center to help keep warp valid */
|
||||
poly = Hunk_Alloc(sizeof(glpoly_t) + ((numverts - 4) + 2) * VERTEXSIZE * sizeof(float));
|
||||
poly = Hunk_Alloc(sizeof(glpoly_t) + ((numverts - 4) + 2) * sizeof(gl3_3D_vtx_t));
|
||||
poly->next = warpface->polys;
|
||||
warpface->polys = poly;
|
||||
poly->numverts = numverts + 2;
|
||||
|
@ -160,7 +163,7 @@ R_SubdividePolygon(int numverts, float *verts, msurface_t *warpface)
|
|||
|
||||
for (i = 0; i < numverts; i++, verts += 3)
|
||||
{
|
||||
VectorCopy(verts, poly->verts[i + 1]);
|
||||
VectorCopy(verts, poly->vertices[i + 1].pos);
|
||||
s = DotProduct(verts, warpface->texinfo->vecs[0]);
|
||||
t = DotProduct(verts, warpface->texinfo->vecs[1]);
|
||||
|
||||
|
@ -168,16 +171,19 @@ R_SubdividePolygon(int numverts, float *verts, msurface_t *warpface)
|
|||
total_t += t;
|
||||
VectorAdd(total, verts, total);
|
||||
|
||||
poly->verts[i + 1][3] = s;
|
||||
poly->verts[i + 1][4] = t;
|
||||
poly->vertices[i + 1].texCoord[0] = s;
|
||||
poly->vertices[i + 1].texCoord[1] = t;
|
||||
VectorCopy(normal, poly->vertices[i + 1].normal);
|
||||
}
|
||||
|
||||
VectorScale(total, (1.0 / numverts), poly->verts[0]);
|
||||
poly->verts[0][3] = total_s / numverts;
|
||||
poly->verts[0][4] = total_t / numverts;
|
||||
VectorScale(total, (1.0 / numverts), poly->vertices[0].pos);
|
||||
poly->vertices[0].texCoord[0] = total_s / numverts;
|
||||
poly->vertices[0].texCoord[1] = total_t / numverts;
|
||||
VectorCopy(normal, poly->vertices[0].normal);
|
||||
|
||||
/* copy first vertex to last */
|
||||
memcpy(poly->verts[i + 1], poly->verts[1], sizeof(poly->verts[0]));
|
||||
//memcpy(poly->vertices[i + 1], poly->vertices[1], sizeof(poly->vertices[0]));
|
||||
poly->vertices[i + 1] = poly->vertices[1];
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -249,7 +255,7 @@ GL3_EmitWaterPolys(msurface_t *fa)
|
|||
for (bp = fa->polys; bp != NULL; bp = bp->next)
|
||||
{
|
||||
int numverts = bp->numverts;
|
||||
glBufferData(GL_ARRAY_BUFFER, VERTEXSIZE*sizeof(GLfloat)*numverts, bp->verts[0], GL_STREAM_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(gl3_3D_vtx_t)*numverts, bp->vertices, GL_STREAM_DRAW);
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, numverts);
|
||||
}
|
||||
}
|
||||
|
@ -574,7 +580,7 @@ GL3_AddSkySurface(msurface_t *fa)
|
|||
{
|
||||
for (i = 0; i < p->numverts; i++)
|
||||
{
|
||||
VectorSubtract(p->verts[i], gl3_origin, verts[i]);
|
||||
VectorSubtract(p->vertices[i].pos, gl3_origin, verts[i]);
|
||||
}
|
||||
|
||||
ClipSkyPolygon(p->numverts, verts[0], 0);
|
||||
|
|
|
@ -70,7 +70,7 @@ enum {
|
|||
GL3_ATTRIB_TEXCOORD = 1, // for normal texture
|
||||
GL3_ATTRIB_LMTEXCOORD = 2, // for lightmap
|
||||
GL3_ATTRIB_COLOR = 3, // per-vertex color
|
||||
// TODO: more? maybe normal
|
||||
GL3_ATTRIB_NORMAL = 4, // vertex normal
|
||||
};
|
||||
|
||||
// TODO: do we need the following configurable?
|
||||
|
@ -142,6 +142,21 @@ typedef struct
|
|||
GLfloat _padding[2]; // again, some padding to ensure this has right size
|
||||
} gl3Uni3D_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vec3_t origin;
|
||||
GLfloat _padding;
|
||||
vec3_t color;
|
||||
GLfloat intensity;
|
||||
} gl3UniDynLight;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gl3UniDynLight dynLights[MAX_DLIGHTS];
|
||||
GLuint numDynLights;
|
||||
GLfloat _padding[3];
|
||||
} gl3UniLights_t;
|
||||
|
||||
enum {
|
||||
// width and height used to be 128, so now we should be able to get the same lightmap data
|
||||
// that used 32 lightmaps before into one, so 4 lightmaps should be enough
|
||||
|
@ -171,14 +186,10 @@ typedef struct
|
|||
GLuint currenttexture; // bound to GL_TEXTURE0
|
||||
int currentlightmap; // lightmap_textureIDs[currentlightmap] bound to GL_TEXTURE1
|
||||
GLuint currenttmu; // GL_TEXTURE0 or GL_TEXTURE1
|
||||
//int currenttmu; // 0 for textures, 1 for lightmaps
|
||||
//GLenum currenttarget;
|
||||
|
||||
//float camera_separation;
|
||||
//enum stereo_modes stereo_mode;
|
||||
|
||||
//qboolean hwgamma;
|
||||
|
||||
GLuint currentVAO;
|
||||
GLuint currentVBO;
|
||||
GLuint currentEBO;
|
||||
|
@ -205,7 +216,7 @@ typedef struct
|
|||
// NOTE: make sure siParticle is always the last shaderInfo (or adapt GL3_ShutdownShaders())
|
||||
gl3ShaderInfo_t siParticle; // for particles. surprising, right?
|
||||
|
||||
GLuint vao3D, vbo3D; // for brushes etc, using 7 floats as vertex input (x,y,z, s,t, lms,lmt)
|
||||
GLuint vao3D, vbo3D; // for brushes etc, using 1 floats as vertex input (x,y,z, s,t, lms,lmt, normX,normY,normZ)
|
||||
GLuint vaoAlias, vboAlias, eboAlias; // for models, using 9 floats as (x,y,z, s,t, r,g,b,a)
|
||||
GLuint vaoParticle, vboParticle; // for particles, using 9 floats (x,y,z, size,distance, r,g,b,a)
|
||||
|
||||
|
@ -213,9 +224,11 @@ typedef struct
|
|||
gl3UniCommon_t uniCommonData;
|
||||
gl3Uni2D_t uni2DData;
|
||||
gl3Uni3D_t uni3DData;
|
||||
gl3UniLights_t uniLightsData;
|
||||
GLuint uniCommonUBO;
|
||||
GLuint uni2DUBO;
|
||||
GLuint uni3DUBO;
|
||||
GLuint uniLightsUBO;
|
||||
|
||||
} gl3state_t;
|
||||
|
||||
|
@ -274,22 +287,6 @@ typedef struct
|
|||
byte lightmap_buffers[MAX_LIGHTMAPS_PER_SURFACE][4 * BLOCK_WIDTH * BLOCK_HEIGHT];
|
||||
} gl3lightmapstate_t;
|
||||
|
||||
// used for vertex array elements when drawing brushes, sprites, sky and more
|
||||
// (ok, it has the layout used for rendering brushes, but is not used there)
|
||||
typedef struct gl3_3D_vtx_s {
|
||||
vec3_t pos;
|
||||
float texCoord[2];
|
||||
float lmTexCoord[2]; // lightmap texture coordinate (sometimes unused)
|
||||
} gl3_3D_vtx_t;
|
||||
|
||||
// used for vertex array elements when drawing models
|
||||
typedef struct gl3_alias_vtx_s {
|
||||
GLfloat pos[3];
|
||||
GLfloat texCoord[2];
|
||||
GLfloat color[4];
|
||||
} gl3_alias_vtx_t;
|
||||
|
||||
|
||||
extern gl3model_t *gl3_worldmodel;
|
||||
extern gl3model_t *currentmodel;
|
||||
extern entity_t *currententity;
|
||||
|
@ -466,6 +463,7 @@ extern void GL3_ShutdownShaders(void);
|
|||
extern void GL3_UpdateUBOCommon(void);
|
||||
extern void GL3_UpdateUBO2D(void);
|
||||
extern void GL3_UpdateUBO3D(void);
|
||||
extern void GL3_UpdateUBOLights(void);
|
||||
|
||||
// ############ Cvars ###########
|
||||
|
||||
|
|
|
@ -43,9 +43,25 @@ enum {
|
|||
SURF_DRAWBACKGROUND = 0x40,
|
||||
SURF_UNDERWATER = 0x80,
|
||||
|
||||
VERTEXSIZE = 7
|
||||
//VERTEXSIZE = 7 - is 10 now, and I use a struct - TODO: REMOVE!
|
||||
};
|
||||
|
||||
// used for vertex array elements when drawing brushes, sprites, sky and more
|
||||
// (ok, it has the layout used for rendering brushes, but is not used there)
|
||||
typedef struct gl3_3D_vtx_s {
|
||||
vec3_t pos;
|
||||
float texCoord[2];
|
||||
float lmTexCoord[2]; // lightmap texture coordinate (sometimes unused)
|
||||
vec3_t normal;
|
||||
} gl3_3D_vtx_t;
|
||||
|
||||
// used for vertex array elements when drawing models
|
||||
typedef struct gl3_alias_vtx_s {
|
||||
GLfloat pos[3];
|
||||
GLfloat texCoord[2];
|
||||
GLfloat color[4];
|
||||
} gl3_alias_vtx_t;
|
||||
|
||||
/* in memory representation */
|
||||
typedef struct
|
||||
{
|
||||
|
@ -83,7 +99,7 @@ typedef struct glpoly_s
|
|||
struct glpoly_s *chain;
|
||||
int numverts;
|
||||
int flags; /* for SURF_UNDERWATER (not needed anymore?) */
|
||||
float verts[4][VERTEXSIZE]; /* variable sized (xyz s1t1 s2t2) */
|
||||
gl3_3D_vtx_t vertices[4]; /* variable sized */
|
||||
} glpoly_t;
|
||||
|
||||
typedef struct msurface_s
|
||||
|
|
Loading…
Reference in a new issue