GL3: shared UBOs instead of normal uniforms; warping water

This commit is contained in:
Daniel Gibson 2017-02-18 21:48:56 +01:00
parent 6e07ff0a2d
commit d7b5c7e86e
6 changed files with 463 additions and 231 deletions

View file

@ -266,11 +266,6 @@ GL3_Draw_Fill(int x, int y, int w, int h, int c)
color.c = d_8to24table[c];
for(i=0; i<3; ++i)
{
cf[i] = color.v[i] * (1.0f/255.0f);
}
GLfloat vBuf[8] = {
// X, Y
x, y+h,
@ -279,12 +274,16 @@ GL3_Draw_Fill(int x, int y, int w, int h, int c)
x+w, y
};
for(i=0; i<3; ++i)
{
gl3state.uniCommonData.color[i] = color.v[i] * (1.0f/255.0f);
}
GL3_UpdateUBOCommon();
GL3_UseProgram(gl3state.si2Dcolor.shaderProgram);
GL3_BindVAO(vao2Dcolor);
glUniform4f(gl3state.si2Dcolor.uniColor, cf[0], cf[1], cf[2], 1.0f);
glBindBuffer(GL_ARRAY_BUFFER, vbo2D);
glBufferData(GL_ARRAY_BUFFER, sizeof(vBuf), vBuf, GL_STREAM_DRAW);
@ -296,6 +295,7 @@ GL3_Draw_FadeScreen(void)
{
float w = vid.width;
float h = vid.height;
int i=0;
GLfloat vBuf[8] = {
// X, Y
@ -307,13 +307,19 @@ GL3_Draw_FadeScreen(void)
glEnable(GL_BLEND);
for(i=0; i<3; ++i)
{
gl3state.uniCommonData.color[i] = 0.0f;
}
gl3state.uniCommonData.color[3] = 0.6f;
GL3_UpdateUBOCommon();
GL3_UseProgram(gl3state.si2Dcolor.shaderProgram);
GL3_BindVAO(vao2Dcolor);
glUniform4f(gl3state.si2Dcolor.uniColor, 0, 0, 0, 0.6f);
glBindBuffer(GL_ARRAY_BUFFER, vbo2D);
glBufferData(GL_ARRAY_BUFFER, sizeof(vBuf), vBuf, GL_STREAM_DRAW);

View file

@ -25,12 +25,13 @@
* =======================================================================
*/
#define HANDMADE_MATH_IMPLEMENTATION
#include "header/HandmadeMath.h"
#include "../../header/ref.h"
#include "header/local.h"
#define HANDMADE_MATH_IMPLEMENTATION
#include "header/HandmadeMath.h"
// TODO: put this in local.h ?
#define REF_VERSION "Yamagi Quake II OpenGL3 Refresher"
@ -553,6 +554,8 @@ GL3_Init(void)
GL3_Draw_InitLocal();
GL3_SurfInit();
R_Printf(PRINT_ALL, "\n");
return true;
}
@ -567,6 +570,7 @@ GL3_Shutdown(void)
GL3_Mod_FreeAll();
GL3_ShutdownImages();
GL3_SurfShutdown();
GL3_Draw_ShutdownLocal();
GL3_ShutdownShaders();
@ -829,10 +833,19 @@ GL3_SetGL2D(void)
hmm_mat4 transMatr = HMM_Orthographic(0, vid.width, vid.height, 0, -99999, 99999);
/*
glUseProgram(gl3state.si2Dcolor.shaderProgram);
glUniformMatrix4fv(gl3state.si2Dcolor.uniProjMatrix , 1, GL_FALSE, transMatr.Elements[0]);
glUseProgram(gl3state.si2D.shaderProgram);
glUniformMatrix4fv(gl3state.si2D.uniProjMatrix , 1, GL_FALSE, transMatr.Elements[0]);
*/
//memcpy(gl3state.uni2DData.transMat4, transMatr.Elements, 4*4*sizeof(GLfloat));
for(int i=0; i<4; ++i)
for(int j=0; j<4; ++j)
gl3state.uni2DData.transMat4[i][j] = transMatr.Elements[i][j];
GL3_UpdateUBO2D();
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
@ -923,10 +936,6 @@ SetupGL(void)
}};
// now rotate by view angles
/*hmm_mat4 rotMat = HMM_Rotate(-gl3_newrefdef.viewangles[2], HMM_Vec3(1, 0, 0));
rotMat = HMM_MultiplyMat4( rotMat, HMM_Rotate(-gl3_newrefdef.viewangles[0], HMM_Vec3(0, 1, 0)) );
rotMat = HMM_MultiplyMat4( rotMat, HMM_Rotate(-gl3_newrefdef.viewangles[1], HMM_Vec3(0, 0, 1)) );
*/
hmm_mat4 rotMat = rotAroundAxisXYZ(-gl3_newrefdef.viewangles[2], -gl3_newrefdef.viewangles[0], -gl3_newrefdef.viewangles[1]);
viewMat = HMM_MultiplyMat4( viewMat, rotMat );
@ -938,10 +947,12 @@ SetupGL(void)
gl3_world_matrix = viewMat;
}
// TODO: set matrices as uniforms in relevant shaders
glUseProgram(gl3state.si3D.shaderProgram);
glUniformMatrix4fv(gl3state.si3D.uniProjMatrix, 1, GL_FALSE, gl3_projectionMatrix.Elements[0]);
glUniformMatrix4fv(gl3state.si3D.uniModelViewMatrix, 1, GL_FALSE, gl3_world_matrix.Elements[0]);
memcpy(gl3state.uni3DData.transProjMat4, gl3_projectionMatrix.Elements, sizeof(gl3state.uni3DData.transProjMat4));
memcpy(gl3state.uni3DData.transModelViewMat4, gl3_world_matrix.Elements, sizeof(gl3state.uni3DData.transProjMat4));
gl3state.uni3DData.time = gl3_newrefdef.time;
GL3_UpdateUBO3D();
#if 0
glMatrixMode(GL_MODELVIEW);
@ -1134,9 +1145,9 @@ GL3_RenderView(refdef_t *fd)
GL3_RenderDlights();
R_DrawParticles();
R_DrawAlphaSurfaces();
#endif // 0
GL3_DrawAlphaSurfaces();
#if 0
R_Flash();
if (gl_speeds->value)
@ -1316,7 +1327,9 @@ GL3_BeginFrame(float camera_separation)
vid_gamma->modified = false;
intensity->modified = false;
GL3_SetGammaAndIntensity();
gl3state.uniCommonData.gamma = 1.0f/vid_gamma->value;
gl3state.uniCommonData.intensity = intensity->value;
GL3_UpdateUBOCommon();
}
// Clamp overbrightbits

View file

@ -158,11 +158,18 @@ CreateShaderProgram(int numShaders, const GLuint* shaders)
#define MULTILINE_STRING(...) #__VA_ARGS__
// ############## shaders for 2D rendering (HUD, menus, console, videos, ..) #####################
static const char* vertexSrc2D = MULTILINE_STRING(#version 150\n
in vec2 position; // GL3_ATTRIB_POSITION
in vec2 texCoord; // GL3_ATTRIB_TEXCOORD
uniform mat4 trans;
// for UBO shared between 2D shaders
layout (std140) uniform uni2D
{
mat4 trans;
};
out vec2 passTexCoord;
@ -174,11 +181,19 @@ static const char* vertexSrc2D = MULTILINE_STRING(#version 150\n
);
static const char* fragmentSrc2D = MULTILINE_STRING(#version 150\n
in vec2 passTexCoord;
// for UBO shared between all shaders (incl. 2D)
layout (std140) uniform uniCommon
{
float gamma;
float intensity;
vec4 color;
};
uniform sampler2D tex;
uniform float gamma; // this is 1.0/vid_gamma
uniform float intensity;
out vec4 outColor;
@ -200,9 +215,14 @@ static const char* fragmentSrc2D = MULTILINE_STRING(#version 150\n
// 2D color only rendering, GL3_Draw_Fill(), GL3_Draw_FadeScreen()
static const char* vertexSrc2Dcolor = MULTILINE_STRING(#version 150\n
in vec2 position; // GL3_ATTRIB_POSITION
uniform mat4 trans;
// for UBO shared between 2D shaders
layout (std140) uniform uni2D
{
mat4 trans;
};
void main()
{
@ -212,9 +232,14 @@ static const char* vertexSrc2Dcolor = MULTILINE_STRING(#version 150\n
static const char* fragmentSrc2Dcolor = MULTILINE_STRING(#version 150\n
uniform float gamma; // this is 1.0/vid_gamma
uniform float intensity;
uniform vec4 color;
// for UBO shared between all shaders (incl. 2D)
layout (std140) uniform uniCommon
{
float gamma;
float intensity;
vec4 color;
};
out vec4 outColor;
@ -226,6 +251,8 @@ static const char* fragmentSrc2Dcolor = MULTILINE_STRING(#version 150\n
}
);
// ############## shaders for 3D rendering #####################
static const char* vertexCommon3D = MULTILINE_STRING(#version 150\n
in vec3 position; // GL3_ATTRIB_POSITION
@ -234,7 +261,14 @@ static const char* vertexCommon3D = MULTILINE_STRING(#version 150\n
out vec2 passTexCoord;
// TODO: uniform blocks
// for UBO shared between all 3D shaders
layout (std140) uniform uni3D
{
mat4 transProj;
mat4 transModelView; // TODO: or maybe transViewProj and transModel ??
float scroll; // for SURF_FLOWING
float time; // or sth like this?
};
);
static const char* fragmentCommon3D = MULTILINE_STRING(#version 150\n
@ -243,13 +277,28 @@ static const char* fragmentCommon3D = MULTILINE_STRING(#version 150\n
out vec4 outColor;
// TODO: uniform blocks
// for UBO shared between all shaders (incl. 2D)
layout (std140) uniform uniCommon
{
float gamma; // this is 1.0/vid_gamma
float intensity;
vec4 color; // really?
};
// for UBO shared between all 3D shaders
layout (std140) uniform uni3D
{
mat4 transProj;
mat4 transModelView; // TODO: or maybe transViewProj and transModel ??
float scroll; // for SURF_FLOWING
float time; // or sth like this?
};
);
static const char* vertexSrc3D = MULTILINE_STRING(
uniform mat4 transProj;
uniform mat4 transModelView;
// it gets attributes and uniforms from vertexCommon3D
void main()
{
@ -260,9 +309,9 @@ static const char* vertexSrc3D = MULTILINE_STRING(
static const char* fragmentSrc3D = MULTILINE_STRING(
// it gets attributes and uniforms from fragmentCommon3D
uniform sampler2D tex;
uniform float gamma; // this is 1.0/vid_gamma
uniform float intensity;
void main()
{
@ -277,39 +326,73 @@ static const char* fragmentSrc3D = MULTILINE_STRING(
}
);
/*
os = v [ 3 ];
ot = v [ 4 ];
float TURBSCALE = (256.0 / (2 * M_PI));
s = os + gl3_turbsin [ (int) ( ( ot * 0.125 + rdt ) * TURBSCALE ) & 255 ];
s += scroll;
tex[index_tex++] = s * ( 1.0 / 64 );
t = ot + gl3_turbsin [ (int) ( ( os * 0.125 + rdt ) * TURBSCALE ) & 255 ];
tex[index_tex++] = t * ( 1.0 / 64 );
*/
static const char* vertexSrc3Dwater = MULTILINE_STRING(
// it gets attributes and uniforms from vertexCommon3D
void main()
{
vec2 tc = texCoord;
tc.s += sin( texCoord.t*0.125 + time ) * 4;
tc.s += scroll;
tc.t += sin( texCoord.s*0.125 + time ) * 4;
tc *= 1.0/64.0; // do this last
passTexCoord = tc;
gl_Position = transProj * transModelView * vec4(position, 1.0);
}
);
static const char* fragmentSrc3Dwater = MULTILINE_STRING(
// it gets attributes and uniforms from fragmentCommon3D
uniform sampler2D tex;
const float PI = 3.141592653589793238462643383; // TODO: put in common
const float TURBSCALE = (256.0 / (2 * PI));
void main()
{
vec4 texel = texture(tex, passTexCoord);
// TODO: something about GL_BLEND vs GL_ALPHATEST etc
// apply gamma correction and intensity
texel.rgb *= intensity;
outColor.rgb = pow(texel.rgb, vec3(gamma));
//outColor.a = texel.a; // I think alpha shouldn't be modified by gamma and intensity
outColor.a = 0.666; // FIXME: set alpha via uniform
}
);
#undef MULTILINE_STRING
/* TODO: UBOs
layout (std140) uniform common_data
{
float gamma;
float intensity;
vec4 color; // really?
enum {
GL3_BINDINGPOINT_UNICOMMON,
GL3_BINDINGPOINT_UNI2D,
GL3_BINDINGPOINT_UNI3D
};
layout (std140) uniform for2D_data
{
mat4 trans;
};
layout (std140) uniform for3D_data
{
mat4 transProj;
mat4 transModelView; // TODO: or maybe transViewProj; and transModel; ??
float scroll; // for SURF_FLOWING
float time; // or sth like this?
};
*/
static qboolean
initShader2D(gl3ShaderInfo_t* shaderInfo, const char* vertSrc, const char* fragSrc)
{
GLuint shaders2D[2] = {0};
GLint i = -1;
GLuint prog = 0;
if(shaderInfo->shaderProgram != 0)
@ -318,7 +401,7 @@ initShader2D(gl3ShaderInfo_t* shaderInfo, const char* vertSrc, const char* fragS
glDeleteProgram(shaderInfo->shaderProgram);
}
shaderInfo->uniColor = shaderInfo->uniProjMatrix = shaderInfo->uniModelViewMatrix = -1;
//shaderInfo->uniColor = shaderInfo->uniProjMatrix = shaderInfo->uniModelViewMatrix = -1;
shaderInfo->shaderProgram = 0;
shaders2D[0] = CompileShader(GL_VERTEX_SHADER, vertSrc, NULL);
@ -343,17 +426,75 @@ initShader2D(gl3ShaderInfo_t* shaderInfo, const char* vertSrc, const char* fragS
}
shaderInfo->shaderProgram = prog;
glUseProgram(prog);
GL3_UseProgram(prog);
shaderInfo->uniColor = glGetUniformLocation(prog, "color");
i = glGetUniformLocation(prog, "trans");
if( i == -1)
// Bind the buffer object to the uniform blocks
GLuint blockIndex = glGetUniformBlockIndex(prog, "uniCommon");
if(blockIndex != GL_INVALID_INDEX)
{
R_Printf(PRINT_ALL, "WARNING: Couldn't get 'trans' uniform in shader\n");
GLint blockSize;
glGetActiveUniformBlockiv(prog, blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize);
if(blockSize != sizeof(gl3state.uniCommonData))
{
R_Printf(PRINT_ALL, "WARNING: OpenGL driver disagrees with us about UBO size of 'uniCommon': %i vs %i\n",
blockSize, (int)sizeof(gl3state.uniCommonData));
// TODO: clean up?
return false;
}
const GLchar *names[] = { "gamma", "intensity", "color" };
GLuint indices[3];
glGetUniformIndices(prog, 3, names, indices);
GLint offset[3];
glGetActiveUniformsiv(prog, 3, indices, GL_UNIFORM_OFFSET, offset);
printf("## uniCommon offsets in shader:");
for(int i=0; i<3; ++i)
{
printf(" offset of '%s' is %d", names[i], offset[i]);
}
printf("\n");
printf("## offsets in C: gamma: %zd intensity: %zd color: %zd\n",
offsetof(gl3UniCommon_t, gamma),
offsetof(gl3UniCommon_t, intensity),
offsetof(gl3UniCommon_t, color));
glUniformBlockBinding(prog, blockIndex, GL3_BINDINGPOINT_UNICOMMON);
// TODO: something with glUniformBlockBinding() !
}
else
{
R_Printf(PRINT_ALL, "WARNING: Couldn't find uniform block index 'uniCommon'\n");
// TODO: clean up?
return false;
}
blockIndex = glGetUniformBlockIndex(prog, "uni2D");
if(blockIndex != GL_INVALID_INDEX)
{
GLint blockSize;
glGetActiveUniformBlockiv(prog, blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize);
if(blockSize != sizeof(gl3state.uni2DData))
{
R_Printf(PRINT_ALL, "WARNING: OpenGL driver disagrees with us about UBO size of 'uni2D'\n");
// TODO: clean up?
return false;
}
glUniformBlockBinding(prog, blockIndex, GL3_BINDINGPOINT_UNI2D);
}
else
{
R_Printf(PRINT_ALL, "WARNING: Couldn't find uniform block index 'uni2D'\n");
// TODO: clean up?
return false;
}
shaderInfo->uniProjMatrix = i;
return true;
}
@ -362,7 +503,6 @@ static qboolean
initShader3D(gl3ShaderInfo_t* shaderInfo, const char* vertSrc, const char* fragSrc)
{
GLuint shaders3D[2] = {0};
GLint i = -1;
GLuint prog = 0;
if(shaderInfo->shaderProgram != 0)
@ -371,7 +511,7 @@ initShader3D(gl3ShaderInfo_t* shaderInfo, const char* vertSrc, const char* fragS
glDeleteProgram(shaderInfo->shaderProgram);
}
shaderInfo->uniColor = shaderInfo->uniProjMatrix = shaderInfo->uniModelViewMatrix = -1;
//shaderInfo->uniColor = shaderInfo->uniProjMatrix = shaderInfo->uniModelViewMatrix = -1;
shaderInfo->shaderProgram = 0;
shaders3D[0] = CompileShader(GL_VERTEX_SHADER, vertexCommon3D, vertSrc);
@ -386,40 +526,109 @@ initShader3D(gl3ShaderInfo_t* shaderInfo, const char* vertSrc, const char* fragS
prog = CreateShaderProgram(2, shaders3D);
if(prog == 0)
{
goto err_cleanup;
}
GL3_UseProgram(prog);
// Bind the buffer object to the uniform blocks
GLuint blockIndex = glGetUniformBlockIndex(prog, "uniCommon");
if(blockIndex != GL_INVALID_INDEX)
{
GLint blockSize;
glGetActiveUniformBlockiv(prog, blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize);
if(blockSize != sizeof(gl3state.uniCommonData))
{
R_Printf(PRINT_ALL, "WARNING: OpenGL driver disagrees with us about UBO size of 'uniCommon'\n");
goto err_cleanup;
}
glUniformBlockBinding(prog, blockIndex, GL3_BINDINGPOINT_UNICOMMON);
}
else
{
R_Printf(PRINT_ALL, "WARNING: Couldn't find uniform block index 'uniCommon'\n");
goto err_cleanup;
}
blockIndex = glGetUniformBlockIndex(prog, "uni3D");
if(blockIndex != GL_INVALID_INDEX)
{
GLint blockSize;
glGetActiveUniformBlockiv(prog, blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize);
if(blockSize != sizeof(gl3state.uni3DData))
{
R_Printf(PRINT_ALL, "WARNING: OpenGL driver disagrees with us about UBO size of 'uni3D'\n");
goto err_cleanup;
}
glUniformBlockBinding(prog, blockIndex, GL3_BINDINGPOINT_UNI3D);
}
else
{
R_Printf(PRINT_ALL, "WARNING: Couldn't find uniform block index 'uni3D'\n");
goto err_cleanup;
}
shaderInfo->shaderProgram = prog;
// I think the shaders aren't needed anymore once they're linked into the program
glDeleteShader(shaders3D[0]);
glDeleteShader(shaders3D[1]);
if(prog == 0)
{
return false;
}
shaderInfo->shaderProgram = prog;
glUseProgram(prog);
shaderInfo->uniColor = glGetUniformLocation(prog, "color");
i = glGetUniformLocation(prog, "transProj");
if( i == -1)
{
R_Printf(PRINT_ALL, "WARNING: Couldn't get 'trans' uniform in shader\n");
return false;
}
shaderInfo->uniProjMatrix = i;
i = glGetUniformLocation(prog, "transModelView");
if( i == -1)
{
R_Printf(PRINT_ALL, "WARNING: Couldn't get 'trans' uniform in shader\n");
return false;
}
shaderInfo->uniModelViewMatrix = i;
return true;
err_cleanup:
if(shaders3D[0] != 0) glDeleteShader(shaders3D[0]);
if(shaders3D[1] != 0) glDeleteShader(shaders3D[1]);
if(prog != 0) glDeleteProgram(prog);
return false;
}
static void initUBOs(void)
{
gl3state.uniCommonData.gamma = 1.0f/vid_gamma->value;
gl3state.uniCommonData.intensity = intensity->value;
GLfloat color[4] = {1, 1, 1, 1};
memcpy(gl3state.uniCommonData.color, color, sizeof(color));
glGenBuffers(1, &gl3state.uniCommonUBO);
glBindBuffer(GL_UNIFORM_BUFFER, gl3state.uniCommonUBO);
glBindBufferBase(GL_UNIFORM_BUFFER, GL3_BINDINGPOINT_UNICOMMON, gl3state.uniCommonUBO);
glBufferData(GL_UNIFORM_BUFFER, sizeof(gl3state.uniCommonData), &gl3state.uniCommonData, GL_DYNAMIC_DRAW);
// the matrix will be set to something more useful later, before being used
memset(gl3state.uni2DData.transMat4, 0, sizeof(gl3state.uni2DData.transMat4));
glGenBuffers(1, &gl3state.uni2DUBO);
glBindBuffer(GL_UNIFORM_BUFFER, gl3state.uni2DUBO);
glBindBufferBase(GL_UNIFORM_BUFFER, GL3_BINDINGPOINT_UNI2D, gl3state.uni2DUBO);
glBufferData(GL_UNIFORM_BUFFER, sizeof(gl3state.uni2DData), &gl3state.uni2DData, GL_DYNAMIC_DRAW);
memset(&gl3state.uni3DData, 0, sizeof(gl3state.uni3DData));
// the matrices will be set to something more useful later, before being used
gl3state.uni3DData.scroll = 0.0f;
gl3state.uni3DData.time = 0.0f;
glGenBuffers(1, &gl3state.uni3DUBO);
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);
}
qboolean GL3_InitShaders(void)
{
initUBOs();
if(!initShader2D(&gl3state.si2D, vertexSrc2D, fragmentSrc2D))
{
R_Printf(PRINT_ALL, "WARNING: Failed to create shader program for textured 2D rendering!\n");
@ -435,11 +644,13 @@ qboolean GL3_InitShaders(void)
R_Printf(PRINT_ALL, "WARNING: Failed to create shader program for textured 3D rendering!\n");
return false;
}
if(!initShader3D(&gl3state.si3Dturb, vertexSrc3Dwater, fragmentSrc3Dwater))
{
R_Printf(PRINT_ALL, "WARNING: Failed to create shader program for water rendering!\n");
return false;
}
gl3state.currentShaderProgram = 0;
GL3_SetGammaAndIntensity();
return true;
}
@ -456,29 +667,25 @@ void GL3_ShutdownShaders(void)
if(gl3state.si3D.shaderProgram != 0)
glDeleteProgram(gl3state.si3D.shaderProgram);
memset(&gl3state.si3D, 0, sizeof(gl3ShaderInfo_t));
glDeleteBuffers(3, &gl3state.uniCommonUBO);
gl3state.uniCommonUBO = gl3state.uni2DUBO = gl3state.uni3DUBO = 0;
}
void GL3_SetGammaAndIntensity(void)
void GL3_UpdateUBOCommon(void)
{
float gamma = 1.0f/vid_gamma->value;
float intens = intensity->value;
int i=0;
GLint progs[] = { gl3state.si2D.shaderProgram, gl3state.si2Dcolor.shaderProgram,
gl3state.si3D.shaderProgram };
for(i=0; i<sizeof(progs)/sizeof(progs[0]); ++i)
{
glUseProgram(progs[i]);
GLint uni = glGetUniformLocation(progs[i], "gamma");
if(uni != -1)
{
glUniform1f(uni, gamma);
}
uni = glGetUniformLocation(progs[i], "intensity");
if(uni != -1)
{
glUniform1f(uni, intens);
}
}
glBindBuffer(GL_UNIFORM_BUFFER, gl3state.uniCommonUBO);
glBufferData(GL_UNIFORM_BUFFER, sizeof(gl3state.uniCommonData), &gl3state.uniCommonData, GL_DYNAMIC_DRAW);
}
void GL3_UpdateUBO2D(void)
{
glBindBuffer(GL_UNIFORM_BUFFER, gl3state.uni2DUBO);
glBufferData(GL_UNIFORM_BUFFER, sizeof(gl3state.uni2DData), &gl3state.uni2DData, GL_DYNAMIC_DRAW);
}
void GL3_UpdateUBO3D(void)
{
glBindBuffer(GL_UNIFORM_BUFFER, gl3state.uni3DUBO);
glBufferData(GL_UNIFORM_BUFFER, sizeof(gl3state.uni3DData), &gl3state.uni3DData, GL_DYNAMIC_DRAW);
}

View file

@ -40,6 +40,35 @@ gl3lightmapstate_t gl3_lms;
extern gl3image_t gl3textures[MAX_GL3TEXTURES];
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
glGenVertexArrays(1, &gl3state.vao3D);
GL3_BindVAO(gl3state.vao3D);
glGenBuffers(1, &gl3state.vbo3D);
glBindBuffer(GL_ARRAY_BUFFER, gl3state.vbo3D);
glEnableVertexAttribArray(GL3_ATTRIB_POSITION);
qglVertexAttribPointer(GL3_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, VERTEXSIZE*sizeof(GLfloat), 0);
glEnableVertexAttribArray(GL3_ATTRIB_TEXCOORD);
qglVertexAttribPointer(GL3_ATTRIB_TEXCOORD, 2, GL_FLOAT, GL_FALSE, VERTEXSIZE*sizeof(GLfloat), 3*sizeof(GLfloat));
glEnableVertexAttribArray(GL3_ATTRIB_LMTEXCOORD);
qglVertexAttribPointer(GL3_ATTRIB_LMTEXCOORD, 2, GL_FLOAT, GL_FALSE, VERTEXSIZE*sizeof(GLfloat), 5*sizeof(GLfloat));
}
void GL3_SurfShutdown(void)
{
glDeleteBuffers(1, &gl3state.vbo3D);
gl3state.vbo3D = 0;
glDeleteVertexArrays(1, &gl3state.vao3D);
gl3state.vao3D = 0;
}
/*
* Returns true if the box is completely outside the frustom
*/
@ -91,56 +120,16 @@ TextureAnimation(mtexinfo_t *tex)
void
GL3_DrawGLPoly(glpoly_t *p)
{
float *v;
v = p->verts[0];
// v: blocks of 7 floats: (X, Y, Z) (S1, T1), (S2, T2)
// apparently (S2, T2) is not used here, probably for lightmap?
STUB_ONCE("TODO: Implement!");
GL3_UseProgram(gl3state.si3D.shaderProgram); // TODO: needed each time?!
static GLuint vao = 0, vbo = 0; // TODO!!
if(vao == 0) // FIXME: DON'T DO THIS!
{
glGenVertexArrays(1, &vao);
GL3_BindVAO(vao);
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo); // TODO ??
glEnableVertexAttribArray(GL3_ATTRIB_POSITION);
qglVertexAttribPointer(GL3_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, VERTEXSIZE*sizeof(GLfloat), 0);
glEnableVertexAttribArray(GL3_ATTRIB_TEXCOORD);
qglVertexAttribPointer(GL3_ATTRIB_TEXCOORD, 2, GL_FLOAT, GL_FALSE, VERTEXSIZE*sizeof(GLfloat), 3*sizeof(GLfloat));
glEnableVertexAttribArray(GL3_ATTRIB_LMTEXCOORD);
qglVertexAttribPointer(GL3_ATTRIB_LMTEXCOORD, 2, GL_FLOAT, GL_FALSE, VERTEXSIZE*sizeof(GLfloat), 5*sizeof(GLfloat));
}
float* v = p->verts[0];
GL3_UseProgram(gl3state.si3D.shaderProgram); // TODO: needed each time?! maybe call this once in DrawTextureChains()?
GL3_BindVAO(vao);
GL3_BindVAO(gl3state.vao3D);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBindBuffer(GL_ARRAY_BUFFER, gl3state.vbo3D);
glBufferData(GL_ARRAY_BUFFER, VERTEXSIZE*sizeof(GLfloat)*p->numverts, v, GL_STREAM_DRAW);
glDrawArrays(GL_TRIANGLE_FAN, 0, p->numverts);
#if 0
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+3 );
glDrawArrays( GL_TRIANGLE_FAN, 0, p->numverts );
glDisableClientState( GL_VERTEX_ARRAY );
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
#endif // 0
}
void
@ -640,26 +629,29 @@ RenderBrushPoly(msurface_t *fa)
void
GL3_DrawAlphaSurfaces(void)
{
STUB("TODO: implement!");
#if 0
STUB_ONCE("TODO: implement!");
msurface_t *s;
float intens;
/* go back to the world matrix */
glLoadMatrixf(r_world_matrix);
//glLoadMatrixf(r_world_matrix);
memcpy(gl3state.uni3DData.transModelViewMat4, gl3_world_matrix.Elements, 16*sizeof(float));
GL3_UpdateUBO3D();
glEnable(GL_BLEND);
R_TexEnv(GL_MODULATE);
//R_TexEnv(GL_MODULATE);
/* the textures are prescaled up for a better
lighting range, so scale it back down */
intens = gl_state.inverse_intensity;
//intens = gl_state.inverse_intensity;
STUB_ONCE("Something about inverse intensity");
for (s = gl3_alpha_surfaces; s; s = s->texturechain)
for (s = gl3_alpha_surfaces; s != NULL; s = s->texturechain)
{
GL3_Bind(s->texinfo->image->texnum);
c_brush_polys++;
#if 0
if (s->texinfo->flags & SURF_TRANS33)
{
glColor4f(intens, intens, intens, 0.33);
@ -672,27 +664,27 @@ GL3_DrawAlphaSurfaces(void)
{
glColor4f(intens, intens, intens, 1);
}
#endif // 0
if (s->flags & SURF_DRAWTURB)
{
R_EmitWaterPolys(s);
GL3_EmitWaterPolys(s);
}
else if (s->texinfo->flags & SURF_FLOWING)
{
R_DrawGLFlowingPoly(s);
GL3_DrawGLFlowingPoly(s);
}
else
{
R_DrawGLPoly(s->polys);
GL3_DrawGLPoly(s->polys);
}
}
R_TexEnv(GL_REPLACE);
glColor4f(1, 1, 1, 1);
//R_TexEnv(GL_REPLACE);
//glColor4f(1, 1, 1, 1);
glDisable(GL_BLEND);
gl3_alpha_surfaces = NULL;
#endif // 0
}
static void

View file

@ -228,61 +228,30 @@ GL3_SubdivideSurface(msurface_t *fa, gl3model_t* loadmodel)
void
GL3_EmitWaterPolys(msurface_t *fa)
{
glpoly_t *p, *bp;
float *v;
int i;
float s, t, os, ot;
float scroll;
float rdt = gl3_newrefdef.time;
static const float TURBSCALE = (256.0 / (2 * M_PI));
glpoly_t *bp;
float scroll = 0.0f;
if (fa->texinfo->flags & SURF_FLOWING)
{
scroll = -64 * ((gl3_newrefdef.time * 0.5) - (int)(gl3_newrefdef.time * 0.5));
}
else
{
scroll = 0;
scroll = -64.0f * ((gl3_newrefdef.time * 0.5) - (int)(gl3_newrefdef.time * 0.5));
}
// TODO: do the scrolling/warping in shader
for (bp = fa->polys; bp; bp = bp->next)
if(gl3state.uni3DData.scroll != scroll)
{
p = bp;
int numverts = p->numverts;
gl3state.uni3DData.scroll = scroll;
GL3_UpdateUBO3D();
}
GLfloat tex[2*numverts];
unsigned int index_tex = 0;
GL3_UseProgram(gl3state.si3Dturb.shaderProgram);
for ( i = 0, v = p->verts [ 0 ]; i < numverts; i++, v += VERTEXSIZE )
{
os = v [ 3 ];
ot = v [ 4 ];
GL3_BindVAO(gl3state.vao3D);
glBindBuffer(GL_ARRAY_BUFFER, gl3state.vbo3D);
s = os + gl3_turbsin [ (int) ( ( ot * 0.125 + gl3_newrefdef.time ) * TURBSCALE ) & 255 ];
s += scroll;
tex[index_tex++] = s * ( 1.0 / 64 );
t = ot + gl3_turbsin [ (int) ( ( os * 0.125 + rdt ) * TURBSCALE ) & 255 ];
tex[index_tex++] = t * ( 1.0 / 64 );
}
v = p->verts [ 0 ];
STUB_ONCE("TODO: Implement OpenGL3 part!");
#if 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 );
#endif // 0
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);
glDrawArrays(GL_TRIANGLE_FAN, 0, numverts);
}
}

View file

@ -43,6 +43,8 @@
#include "../../ref_shared.h"
#include "HandmadeMath.h"
#define STUB(msg) \
R_Printf(PRINT_ALL, "STUB: %s() %s\n", __FUNCTION__, msg)
@ -64,8 +66,8 @@ qglVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normaliz
// attribute locations for vertex shaders
enum {
GL3_ATTRIB_POSITION = 0,
GL3_ATTRIB_TEXCOORD = 1, // for normal texture
GL3_ATTRIB_POSITION = 0,
GL3_ATTRIB_TEXCOORD = 1, // for normal texture
GL3_ATTRIB_LMTEXCOORD = 2, // for lightmap
// TODO: more? maybe normal and color?
};
@ -104,14 +106,40 @@ typedef struct
{
GLuint shaderProgram;
GLint uniColor;
GLint uniProjMatrix; // for 2D shaders this is the only one used
GLint uniModelViewMatrix; // TODO: or even pass as 2 matrices?
// TODO: probably more uniforms, at least gamma and intensity
//GLint uniColor;
//GLint uniProjMatrix; // for 2D shaders this is the only one used
//GLint uniModelViewMatrix; // TODO: or even pass as 2 matrices?
} gl3ShaderInfo_t;
typedef struct
{
GLfloat gamma;
GLfloat intensity;
// entries of std140 UBOs are aligned to multiples of their own size
// so we'll need to pad accordingly
GLfloat _padding[2];
GLfloat color[4];
} gl3UniCommon_t;
typedef struct
{
GLfloat transMat4[4][4];
} gl3Uni2D_t;
typedef struct
{
GLfloat transProjMat4[4][4];
GLfloat transModelViewMat4[4][4];
GLfloat scroll; // for SURF_FLOWING
GLfloat time; // for warping surfaces like water & possibly other things
GLfloat _padding[2]; // again, some padding to ensure this has right size
} gl3Uni3D_t;
typedef struct
{
// TODO: what of this do we need?
@ -138,8 +166,18 @@ typedef struct
GLuint currentShaderProgram;
gl3ShaderInfo_t si2D; // shader for rendering 2D with textures
gl3ShaderInfo_t si2Dcolor; // shader for rendering 2D with flat colors
gl3ShaderInfo_t si3D;
gl3ShaderInfo_t si3Dturb; // for water etc
GLuint vao3D, vbo3D; // for brushes etc, using 7 floats as vertex input (x,y,z, s,t, lms,lmt)
// UBOs and their data
gl3UniCommon_t uniCommonData;
gl3Uni2D_t uni2DData;
gl3Uni3D_t uni3DData;
GLuint uniCommonUBO;
GLuint uni2DUBO;
GLuint uni3DUBO;
} gl3state_t;
@ -215,6 +253,9 @@ extern cplane_t frustum[4];
extern vec3_t gl3_origin;
hmm_mat4 gl3_projectionMatrix; // eye cord -> clip coord
hmm_mat4 gl3_world_matrix; // the view matrix: world coord -> eye coord
extern gl3image_t *gl3_notexture; /* use for bad textures */
extern gl3image_t *gl3_particletexture; /* little dot for particles */
@ -324,6 +365,8 @@ extern void GL3_AddSkySurface(msurface_t *fa);
// gl3_surf.c
extern void GL3_SurfInit(void);
extern void GL3_SurfShutdown(void);
extern void GL3_DrawGLPoly(glpoly_t *p);
extern void GL3_DrawGLFlowingPoly(msurface_t *fa);
extern void GL3_DrawTriangleOutlines(void);
@ -337,7 +380,9 @@ extern void GL3_MarkLeaves(void);
extern qboolean GL3_InitShaders(void);
extern void GL3_ShutdownShaders(void);
extern void GL3_SetGammaAndIntensity(void);
extern void GL3_UpdateUBOCommon(void);
extern void GL3_UpdateUBO2D(void);
extern void GL3_UpdateUBO3D(void);
// ############ Cvars ###########