GL3: Rework 2D drawing, Rotation-Matrix stuff; common vtx attr layout

kind of messy commit with all the shit from last weekend, finished now

Most importantly the common vertex attribute layout stuff using
glBindAttribLocation()
This commit is contained in:
Daniel Gibson 2017-02-19 05:47:35 +01:00
parent 0d81fd6080
commit 6e07ff0a2d
6 changed files with 305 additions and 138 deletions

View file

@ -152,7 +152,7 @@ R_TexEnv(GLenum mode)
if (mode != lastmodes[gl_state.currenttmu])
{
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, mode);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, mode); // FIXME: shouldn't this be glTexEnvi() ?
lastmodes[gl_state.currenttmu] = mode;
}
}

View file

@ -31,29 +31,55 @@ unsigned d_8to24table[256];
gl3image_t *draw_chars;
static GLuint vbo2D = 0, vao2D = 0, vao2Dcolor = 0; // vao2D is for textured rendering, vao2Dcolor for color-only
void
GL3_Draw_InitLocal(void)
{
/* load console characters */
draw_chars = GL3_FindImage("pics/conchars.pcx", it_pic);
glGenVertexArrays(1, &gl3state.vao2D);
glBindVertexArray(gl3state.vao2D);
// set up attribute layout for 2D textured rendering
glGenVertexArrays(1, &vao2D);
glBindVertexArray(vao2D);
glGenBuffers(1, &gl3state.vbo2D);
glBindBuffer(GL_ARRAY_BUFFER, gl3state.vbo2D); // TODO ??
glGenBuffers(1, &vbo2D);
glBindBuffer(GL_ARRAY_BUFFER, vbo2D);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
GL3_UseProgram(gl3state.si2D.shaderProgram);
glEnableVertexAttribArray(GL3_ATTRIB_POSITION);
// Note: the glVertexAttribPointer() configuration is stored in the VAO, not the shader or sth
// (that's why I use one VAO per 2D shader)
qglVertexAttribPointer(GL3_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 4*sizeof(float), 0);
glEnableVertexAttribArray(GL3_ATTRIB_TEXCOORD);
qglVertexAttribPointer(GL3_ATTRIB_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 4*sizeof(float), 2*sizeof(float));
// set up attribute layout for 2D flat color rendering
glGenVertexArrays(1, &vao2Dcolor);
glBindVertexArray(vao2Dcolor);
glBindBuffer(GL_ARRAY_BUFFER, vbo2D); // yes, both VAOs share the same VBO
GL3_UseProgram(gl3state.si2Dcolor.shaderProgram);
glEnableVertexAttribArray(GL3_ATTRIB_POSITION);
qglVertexAttribPointer(GL3_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), 0);
GL3_BindVAO(0);
}
void
GL3_Draw_ShutdownLocal(void)
{
glDeleteBuffers(1, &gl3state.vbo2D);
gl3state.vbo2D = 0;
glDeleteVertexArrays(1, &gl3state.vao2D);
gl3state.vao2D = 0;
glDeleteBuffers(1, &vbo2D);
vbo2D = 0;
glDeleteVertexArrays(1, &vao2D);
vao2D = 0;
glDeleteVertexArrays(1, &vao2Dcolor);
vao2Dcolor = 0;
}
// bind the texture before calling this
@ -79,18 +105,16 @@ drawTexturedRectangle(float x, float y, float w, float h,
x+w, y, sh, tl
};
glBindVertexArray(gl3state.vao2D);
GL3_BindVAO(vao2D);
glBindBuffer(GL_ARRAY_BUFFER, gl3state.vbo2D);
// Note: while vao2D "remembers" its vbo for drawing, binding the vao does *not*
// implicitly bind the vbo, so I need to explicitly bind it before glBufferData()
glBindBuffer(GL_ARRAY_BUFFER, vbo2D);
glBufferData(GL_ARRAY_BUFFER, sizeof(vBuf), vBuf, GL_STREAM_DRAW);
glEnableVertexAttribArray(gl3state.si2D.attribPosition);
qglVertexAttribPointer(gl3state.si2D.attribPosition, 2, GL_FLOAT, GL_FALSE, 4*sizeof(float), 0);
glEnableVertexAttribArray(gl3state.si2D.attribTexCoord);
qglVertexAttribPointer(gl3state.si2D.attribTexCoord, 2, GL_FLOAT, GL_FALSE, 4*sizeof(float), 2*sizeof(float));
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
//glMultiDrawArrays(mode, first, count, drawcount) ??
}
/*
@ -124,6 +148,9 @@ GL3_Draw_CharScaled(int x, int y, int num, float scale)
scaledSize = 8*scale;
// TODO: batchen?
GL3_UseProgram(gl3state.si2D.shaderProgram);
GL3_Bind(draw_chars->texnum);
drawTexturedRectangle(x, y, scaledSize, scaledSize, fcol, frow, fcol+size, frow+size);
}
@ -175,6 +202,7 @@ GL3_Draw_StretchPic(int x, int y, int w, int h, char *pic)
return;
}
GL3_UseProgram(gl3state.si2D.shaderProgram);
GL3_Bind(gl->texnum);
drawTexturedRectangle(x, y, w, h, gl->sl, gl->tl, gl->sh, gl->th);
@ -190,6 +218,7 @@ GL3_Draw_PicScaled(int x, int y, char *pic, float factor)
return;
}
GL3_UseProgram(gl3state.si2D.shaderProgram);
GL3_Bind(gl->texnum);
drawTexturedRectangle(x, y, gl->width*factor, gl->height*factor, gl->sl, gl->tl, gl->sh, gl->th);
@ -210,6 +239,7 @@ GL3_Draw_TileClear(int x, int y, int w, int h, char *pic)
return;
}
GL3_UseProgram(gl3state.si2D.shaderProgram);
GL3_Bind(image->texnum);
drawTexturedRectangle(x, y, w, h, x/64.0f, y/64.0f, (x+w)/64.0f, (y+h)/64.0f);
@ -241,29 +271,24 @@ GL3_Draw_Fill(int x, int y, int w, int h, int c)
cf[i] = color.v[i] * (1.0f/255.0f);
}
GLfloat vBuf[24] = {
// X, Y, R, G, B, A
x, y+h, cf[0], cf[1], cf[2], 1.0f,
x, y, cf[0], cf[1], cf[2], 1.0f,
x+w, y+h, cf[0], cf[1], cf[2], 1.0f,
x+w, y, cf[0], cf[1], cf[2], 1.0f
GLfloat vBuf[8] = {
// X, Y
x, y+h,
x, y,
x+w, y+h,
x+w, y
};
glUseProgram(gl3state.si2Dcolor.shaderProgram);
GL3_UseProgram(gl3state.si2Dcolor.shaderProgram);
glBindVertexArray(gl3state.vao2D);
GL3_BindVAO(vao2Dcolor);
glBindBuffer(GL_ARRAY_BUFFER, gl3state.vbo2D);
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);
glEnableVertexAttribArray(gl3state.si2Dcolor.attribPosition);
qglVertexAttribPointer(gl3state.si2Dcolor.attribPosition, 2, GL_FLOAT, GL_FALSE, 6*sizeof(float), 0);
glEnableVertexAttribArray(gl3state.si2Dcolor.attribColor);
qglVertexAttribPointer(gl3state.si2Dcolor.attribColor, 2, GL_FLOAT, GL_FALSE, 6*sizeof(float), 2*sizeof(float));
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glUseProgram(gl3state.si2D.shaderProgram);
}
void
@ -272,29 +297,34 @@ GL3_Draw_FadeScreen(void)
float w = vid.width;
float h = vid.height;
GLfloat vBuf[24] = {
// X, Y, R, G, B, A
0, h, 0.0f, 0.0f, 0.0f, 0.8f,
0, 0, 0.0f, 0.0f, 0.0f, 0.8f,
w, h, 0.0f, 0.0f, 0.0f, 0.8f,
w, 0, 0.0f, 0.0f, 0.0f, 0.8f
GLfloat vBuf[8] = {
// X, Y
0, h,
0, 0,
w, h,
w, 0
};
glUseProgram(gl3state.si2Dcolor.shaderProgram);
glEnable(GL_BLEND);
glBindVertexArray(gl3state.vao2D);
glBindBuffer(GL_ARRAY_BUFFER, gl3state.vbo2D);
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);
glEnableVertexAttribArray(gl3state.si2Dcolor.attribPosition);
qglVertexAttribPointer(gl3state.si2Dcolor.attribPosition, 2, GL_FLOAT, GL_FALSE, 6*sizeof(float), 0);
glEnableVertexAttribArray(gl3state.si2Dcolor.attribColor);
qglVertexAttribPointer(gl3state.si2Dcolor.attribColor, 2, GL_FLOAT, GL_FALSE, 6*sizeof(float), 2*sizeof(float));
//glEnableVertexAttribArray(gl3state.si2Dcolor.attribPosition);
//qglVertexAttribPointer(gl3state.si2Dcolor.attribPosition, 2, GL_FLOAT, GL_FALSE, 4*sizeof(float), 0);
//glEnableVertexAttribArray(gl3state.si2Dcolor.attribColor);
//qglVertexAttribPointer(gl3state.si2Dcolor.attribColor, 2, GL_FLOAT, GL_FALSE, 6*sizeof(float), 2*sizeof(float));
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glUseProgram(gl3state.si2D.shaderProgram);
glDisable(GL_BLEND);
}
void
@ -325,6 +355,8 @@ GL3_Draw_StretchRaw(int x, int y, int w, int h, int cols, int rows, byte *data)
}
}
GL3_UseProgram(gl3state.si2D.shaderProgram);
GLuint glTex;
glGenTextures(1, &glTex);
glBindTexture(GL_TEXTURE_2D, glTex);

View file

@ -114,16 +114,74 @@ cvar_t *gl_dynamic;
cvar_t *gl3_debugcontext;
// Yaw-Pitch-Roll
// equivalent to R_z * R_y * R_x where R_x is the trans matrix for rotating around X axis for aroundXdeg
static hmm_mat4 rotAroundAxisZYX(float aroundZdeg, float aroundYdeg, float aroundXdeg)
{
#if 0
// TODO: make sure this code is equivalent to the naive multiplications below
// Naming of variables is consistent with http://planning.cs.uiuc.edu/node102.html
// and https://de.wikipedia.org/wiki/Roll-Nick-Gier-Winkel#.E2.80.9EZY.E2.80.B2X.E2.80.B3-Konvention.E2.80.9C
float alpha = HMM_ToRadians(aroundZdeg);
float beta = HMM_ToRadians(aroundYdeg);
float gamma = HMM_ToRadians(aroundXdeg);
float sinA = HMM_SinF(alpha);
float cosA = HMM_CosF(alpha);
// TODO: or sincosf(alpha, &sinA, &cosA); ?? (not standard conform)
float sinB = HMM_SinF(beta);
float cosB = HMM_CosF(beta);
float sinG = HMM_SinF(gamma);
float cosG = HMM_CosF(gamma);
hmm_mat4 ret = {{
{ cosA*cosB, sinA*cosB, -sinB, 0 }, // first *column*
{ cosA*sinB*sinG - sinA*cosG, sinA*sinB*sinG + cosA*cosG, cosB*sinG, 0 }, // cosA*sinB und cosA*sinG 2x genutzt
{ cosA*sinB*cosG + sinA*sinG, sinA*sinB*cosG - cosA*sinG, cosB*cosG, 0 }, // sinA*sinB und sinA*cosG auch
{ 0, 0, 0, 1 } // sinB*sinG und sinB*cosG auch
}};
return ret;
#else
hmm_mat4 ret = HMM_Rotate(aroundZdeg, HMM_Vec3(0, 0, 1));
ret = HMM_MultiplyMat4(ret, HMM_Rotate(aroundYdeg, HMM_Vec3(0, 1, 0)));
ret = HMM_MultiplyMat4(ret, HMM_Rotate(aroundXdeg, HMM_Vec3(1, 0, 0)));
return ret;
#endif
}
void
GL3_RotateForEntity(entity_t *e)
{
STUB_ONCE("TODO: Implement for OpenGL3!");
// angles: pitch (around y), yaw (around z), roll (around x)
// rot matrices to be multiplied in order Z, Y, X (yaw, pitch, roll)
hmm_mat4 rotMat = rotAroundAxisZYX(e->angles[1], -e->angles[0], -e->angles[2]);
#if 1
hmm_mat4 transMat = HMM_Translate( HMM_Vec3(e->origin[0], e->origin[1], e->origin[2]) );
hmm_mat4 modelViewMat = HMM_MultiplyMat4(gl3_world_matrix, transMat);
modelViewMat = HMM_MultiplyMat4(modelViewMat, rotMat);
#else
// TODO: I /think/ I could just set the translation in the end instead of multiplying above
hmm_mat4 modelViewMat = HMM_MultiplyMat4(gl3_world_matrix, rotMat);
for(int i=0; i<3; ++i) modelViewMat.Elements[3][i] = e->origin[i];
#endif
// TODO: set in shaders
#if 0
glTranslatef(e->origin[0], e->origin[1], e->origin[2]);
glRotatef(e->angles[1], 0, 0, 1);
glRotatef(-e->angles[0], 0, 1, 0);
glRotatef(-e->angles[2], 1, 0, 0);
// angles: pitch (around y), yaw (around z), roll (around x)
glRotatef(e->angles[1], 0, 0, 1); // yaw
glRotatef(-e->angles[0], 0, 1, 0); // pitch
glRotatef(-e->angles[2], 1, 0, 0); // roll
#endif // 0
}
@ -782,6 +840,30 @@ GL3_SetGL2D(void)
// glColor4f(1, 1, 1, 1); // FIXME: change to GL3 code!
}
// equivalent to R_x * R_y * R_z where R_x is the trans matrix for rotating around X axis for aroundXdeg
static hmm_mat4 rotAroundAxisXYZ(float aroundXdeg, float aroundYdeg, float aroundZdeg)
{
float alpha = HMM_ToRadians(aroundXdeg);
float beta = HMM_ToRadians(aroundYdeg);
float gamma = HMM_ToRadians(aroundZdeg);
float sinA = HMM_SinF(alpha);
float cosA = HMM_CosF(alpha);
float sinB = HMM_SinF(beta);
float cosB = HMM_CosF(beta);
float sinG = HMM_SinF(gamma);
float cosG = HMM_CosF(gamma);
hmm_mat4 ret = {{
{ cosB*cosG, sinA*sinB*cosG + cosA*sinG, -cosA*sinB*cosG + sinA*sinG, 0 }, // first *column*
{ -cosB*sinG, -sinA*sinB*sinG + cosA*cosG, cosA*sinB*sinG + sinA*cosG, 0 },
{ sinB, -sinA*cosB, cosA*cosB, 0 },
{ 0, 0, 0, 1 }
}};
return ret;
}
static void
SetupGL(void)
{
@ -832,17 +914,26 @@ SetupGL(void)
/* set up view matrix (world coordinates -> eye coordinates) */
{
hmm_vec3 trans = HMM_Vec3(-gl3_newrefdef.vieworg[0], -gl3_newrefdef.vieworg[1], -gl3_newrefdef.vieworg[2]);
// first put Z axis going up
hmm_mat4 viewMat = HMM_MultiplyMat4( HMM_Rotate(-90, HMM_Vec3(1, 0, 0)), HMM_Rotate(90, HMM_Vec3(0, 0, 1)) );
// now rotate by view angles
viewMat = HMM_MultiplyMat4( viewMat, HMM_Rotate(-gl3_newrefdef.viewangles[2], HMM_Vec3(1, 0, 0)) );
viewMat = HMM_MultiplyMat4( viewMat, HMM_Rotate(-gl3_newrefdef.viewangles[0], HMM_Vec3(0, 1, 0)) );
viewMat = HMM_MultiplyMat4( viewMat, HMM_Rotate(-gl3_newrefdef.viewangles[1], HMM_Vec3(0, 0, 1)) );
// .. and apply translation for current position
viewMat = HMM_MultiplyMat4( viewMat, HMM_Translate(trans) );
hmm_mat4 viewMat = {{
{ 0, 0, -1, 0 }, // first *column* (the matrix is colum-major)
{ -1, 0, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 0, 1 }
}};
// TODO: maybe there is a better way to do this, maybe similar to HMM_LookAt() ?
// 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 );
// .. and apply translation for current position
hmm_vec3 trans = HMM_Vec3(-gl3_newrefdef.vieworg[0], -gl3_newrefdef.vieworg[1], -gl3_newrefdef.vieworg[2]);
viewMat = HMM_MultiplyMat4( viewMat, HMM_Translate(trans) );
gl3_world_matrix = viewMat;
}

View file

@ -32,10 +32,14 @@
static GLuint
CompileShader(GLenum shaderType, const char* shaderSrc)
CompileShader(GLenum shaderType, const char* shaderSrc, const char* shaderSrc2)
{
GLuint shader = glCreateShader(shaderType);
glShaderSource(shader, 1, &shaderSrc, NULL);
const char* sources[2] = { shaderSrc, shaderSrc2 };
int numSources = shaderSrc2 != NULL ? 2 : 1;
glShaderSource(shader, numSources, sources, NULL);
glCompileShader(shader);
GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
@ -99,6 +103,12 @@ CreateShaderProgram(int numShaders, const GLuint* shaders)
glAttachShader(shaderProgram, shaders[i]);
}
// make sure all shaders use the same attribute locations for common attributes
// (so the same VAO can easily be used with different shaders)
glBindAttribLocation(shaderProgram, GL3_ATTRIB_POSITION, "position");
glBindAttribLocation(shaderProgram, GL3_ATTRIB_TEXCOORD, "texCoord");
glBindAttribLocation(shaderProgram, GL3_ATTRIB_LMTEXCOORD, "lmTexCoord");
// the following line is not necessary/implicit (as there's only one output)
// glBindFragDataLocation(shaderProgram, 0, "outColor"); XXX would this even be here?
@ -149,8 +159,8 @@ CreateShaderProgram(int numShaders, const GLuint* shaders)
#define MULTILINE_STRING(...) #__VA_ARGS__
static const char* vertexSrc2D = MULTILINE_STRING(#version 150\n
in vec2 texCoord;
in vec2 position;
in vec2 position; // GL3_ATTRIB_POSITION
in vec2 texCoord; // GL3_ATTRIB_TEXCOORD
uniform mat4 trans;
@ -190,45 +200,57 @@ 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 vec4 color;
in vec2 position;
in vec2 position; // GL3_ATTRIB_POSITION
uniform mat4 trans;
out vec4 passColor;
void main()
{
gl_Position = trans * vec4(position, 0.0, 1.0);
passColor = color;
}
);
static const char* fragmentSrc2Dcolor = MULTILINE_STRING(#version 150\n
in vec4 passColor;
uniform float gamma; // this is 1.0/vid_gamma
uniform float intensity;
uniform vec4 color;
out vec4 outColor;
void main()
{
vec3 col = passColor.rgb * intensity;
vec3 col = color.rgb * intensity;
outColor.rgb = pow(col, vec3(gamma));
outColor.a = passColor.a;
outColor.a = color.a;
}
);
static const char* vertexSrc3D = MULTILINE_STRING(#version 150\n
in vec2 texCoord;
in vec3 position;
static const char* vertexCommon3D = MULTILINE_STRING(#version 150\n
in vec3 position; // GL3_ATTRIB_POSITION
in vec2 texCoord; // GL3_ATTRIB_TEXCOORD
in vec2 lmTexCoord; // GL3_ATTRIB_LMTEXCOORD
out vec2 passTexCoord;
// TODO: uniform blocks
);
static const char* fragmentCommon3D = MULTILINE_STRING(#version 150\n
in vec2 passTexCoord;
out vec4 outColor;
// TODO: uniform blocks
);
static const char* vertexSrc3D = MULTILINE_STRING(
uniform mat4 transProj;
uniform mat4 transModelView;
out vec2 passTexCoord;
void main()
{
gl_Position = transProj * transModelView * vec4(position, 1.0);
@ -236,15 +258,12 @@ static const char* vertexSrc3D = MULTILINE_STRING(#version 150\n
}
);
static const char* fragmentSrc3D = MULTILINE_STRING(#version 150\n
in vec2 passTexCoord;
static const char* fragmentSrc3D = MULTILINE_STRING(
uniform sampler2D tex;
uniform float gamma; // this is 1.0/vid_gamma
uniform float intensity;
out vec4 outColor;
void main()
{
vec4 texel = texture(tex, passTexCoord);
@ -258,8 +277,34 @@ static const char* fragmentSrc3D = MULTILINE_STRING(#version 150\n
}
);
#undef MULTILINE_STRING
/* TODO: UBOs
layout (std140) uniform common_data
{
float gamma;
float intensity;
vec4 color; // really?
};
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)
{
@ -273,14 +318,13 @@ initShader2D(gl3ShaderInfo_t* shaderInfo, const char* vertSrc, const char* fragS
glDeleteProgram(shaderInfo->shaderProgram);
}
shaderInfo->attribColor = shaderInfo->attribPosition = shaderInfo->attribTexCoord = -1;
shaderInfo->uniProjMatrix = shaderInfo->uniModelViewMatrix = -1;
shaderInfo->uniColor = shaderInfo->uniProjMatrix = shaderInfo->uniModelViewMatrix = -1;
shaderInfo->shaderProgram = 0;
shaders2D[0] = CompileShader(GL_VERTEX_SHADER, vertSrc);
shaders2D[0] = CompileShader(GL_VERTEX_SHADER, vertSrc, NULL);
if(shaders2D[0] == 0) return false;
shaders2D[1] = CompileShader(GL_FRAGMENT_SHADER, fragSrc);
shaders2D[1] = CompileShader(GL_FRAGMENT_SHADER, fragSrc, NULL);
if(shaders2D[1] == 0)
{
glDeleteShader(shaders2D[0]);
@ -301,18 +345,7 @@ initShader2D(gl3ShaderInfo_t* shaderInfo, const char* vertSrc, const char* fragS
shaderInfo->shaderProgram = prog;
glUseProgram(prog);
i = glGetAttribLocation(prog, "position");
if( i == -1)
{
R_Printf(PRINT_ALL, "WARNING: Couldn't get 'position' attribute in shader\n");
return false;
}
shaderInfo->attribPosition = i;
// the following line will set it to -1 for the textured case, that's ok.
shaderInfo->attribColor = glGetAttribLocation(prog, "color");
// the following line will set it to -1 for the color-only case, that's ok.
shaderInfo->attribTexCoord = glGetAttribLocation(prog, "texCoord");
shaderInfo->uniColor = glGetUniformLocation(prog, "color");
i = glGetUniformLocation(prog, "trans");
if( i == -1)
@ -338,14 +371,13 @@ initShader3D(gl3ShaderInfo_t* shaderInfo, const char* vertSrc, const char* fragS
glDeleteProgram(shaderInfo->shaderProgram);
}
shaderInfo->attribColor = shaderInfo->attribPosition = shaderInfo->attribTexCoord = -1;
shaderInfo->uniProjMatrix = shaderInfo->uniModelViewMatrix = -1;
shaderInfo->uniColor = shaderInfo->uniProjMatrix = shaderInfo->uniModelViewMatrix = -1;
shaderInfo->shaderProgram = 0;
shaders3D[0] = CompileShader(GL_VERTEX_SHADER, vertSrc);
shaders3D[0] = CompileShader(GL_VERTEX_SHADER, vertexCommon3D, vertSrc);
if(shaders3D[0] == 0) return false;
shaders3D[1] = CompileShader(GL_FRAGMENT_SHADER, fragSrc);
shaders3D[1] = CompileShader(GL_FRAGMENT_SHADER, fragmentCommon3D, fragSrc);
if(shaders3D[1] == 0)
{
glDeleteShader(shaders3D[0]);
@ -366,18 +398,7 @@ initShader3D(gl3ShaderInfo_t* shaderInfo, const char* vertSrc, const char* fragS
shaderInfo->shaderProgram = prog;
glUseProgram(prog);
i = glGetAttribLocation(prog, "position");
if( i == -1)
{
R_Printf(PRINT_ALL, "WARNING: Couldn't get 'position' attribute in shader\n");
return false;
}
shaderInfo->attribPosition = i;
// the following line will set it to -1 for the textured case, that's ok.
shaderInfo->attribColor = glGetAttribLocation(prog, "color");
// the following line will set it to -1 for the color-only case, that's ok.
shaderInfo->attribTexCoord = glGetAttribLocation(prog, "texCoord");
shaderInfo->uniColor = glGetUniformLocation(prog, "color");
i = glGetUniformLocation(prog, "transProj");
if( i == -1)
@ -414,6 +435,7 @@ qboolean GL3_InitShaders(void)
R_Printf(PRINT_ALL, "WARNING: Failed to create shader program for textured 3D rendering!\n");
return false;
}
gl3state.currentShaderProgram = 0;
GL3_SetGammaAndIntensity();

View file

@ -96,42 +96,37 @@ GL3_DrawGLPoly(glpoly_t *p)
v = p->verts[0];
// v: blocks of 7 floats: (X, Y, Z) (S1, T1), (S2, T2)
// apparently (S2, T2) is not used here?
// apparently (S2, T2) is not used here, probably for lightmap?
STUB_ONCE("TODO: Implement!");
glUseProgram(gl3state.si3D.shaderProgram); // TODO: needed each time?!
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);
glBindVertexArray(vao);
GL3_BindVAO(vao);
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo); // TODO ??
glEnableVertexAttribArray(gl3state.si3D.attribPosition);
qglVertexAttribPointer(gl3state.si3D.attribPosition, 3, GL_FLOAT, GL_FALSE, VERTEXSIZE*sizeof(GLfloat), 0);
glEnableVertexAttribArray(GL3_ATTRIB_POSITION);
qglVertexAttribPointer(GL3_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, VERTEXSIZE*sizeof(GLfloat), 0);
glEnableVertexAttribArray(gl3state.si3D.attribTexCoord);
qglVertexAttribPointer(gl3state.si3D.attribTexCoord, 2, GL_FLOAT, GL_FALSE, VERTEXSIZE*sizeof(GLfloat), 3*sizeof(float));
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));
}
glUseProgram(gl3state.si3D.shaderProgram);
GL3_UseProgram(gl3state.si3D.shaderProgram); // TODO: needed each time?! maybe call this once in DrawTextureChains()?
glBindVertexArray(vao);
GL3_BindVAO(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, VERTEXSIZE*sizeof(GLfloat)*p->numverts, v, GL_STREAM_DRAW);
/*
glEnableVertexAttribArray(gl3state.si3D.attribPosition);
qglVertexAttribPointer(gl3state.si3D.attribPosition, 3, GL_FLOAT, GL_FALSE, VERTEXSIZE*sizeof(GLfloat), 0);
glEnableVertexAttribArray(gl3state.si3D.attribTexCoord);
qglVertexAttribPointer(gl3state.si3D.attribTexCoord, 2, GL_FLOAT, GL_FALSE, VERTEXSIZE*sizeof(GLfloat), 3*sizeof(GLfloat));
*/
glDrawArrays(GL_TRIANGLE_FAN, 0, p->numverts);
@ -598,6 +593,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)
{
if (((fa->styles[maps] >= 32) ||

View file

@ -62,6 +62,14 @@ qglVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normaliz
glVertexAttribPointer(index, size, type, normalized, stride, (const void*)offset);
}
// attribute locations for vertex shaders
enum {
GL3_ATTRIB_POSITION = 0,
GL3_ATTRIB_TEXCOORD = 1, // for normal texture
GL3_ATTRIB_LMTEXCOORD = 2, // for lightmap
// TODO: more? maybe normal and color?
};
// TODO: do we need the following configurable?
static const int gl3_solid_format = GL_RGB;
static const int gl3_alpha_format = GL_RGBA;
@ -96,10 +104,7 @@ typedef struct
{
GLuint shaderProgram;
GLint attribPosition;
GLint attribTexCoord;
GLint attribColor;
GLint uniColor;
GLint uniProjMatrix; // for 2D shaders this is the only one used
GLint uniModelViewMatrix; // TODO: or even pass as 2 matrices?
@ -129,10 +134,10 @@ typedef struct
//qboolean hwgamma;
GLuint currentVAO;
GLuint currentShaderProgram;
gl3ShaderInfo_t si2D; // shader for rendering 2D with textures
gl3ShaderInfo_t si2Dcolor; // shader for rendering 2D with flat colors
GLuint vbo2D; // this vbo is reused for all 2D drawing (HUD, movies, menu, console, ..)
GLuint vao2D; // same for this vao
gl3ShaderInfo_t si3D;
@ -208,7 +213,7 @@ extern float gl3depthmin, gl3depthmax;
extern cplane_t frustum[4];
vec3_t gl3_origin;
extern vec3_t gl3_origin;
extern gl3image_t *gl3_notexture; /* use for bad textures */
extern gl3image_t *gl3_particletexture; /* little dot for particles */
@ -216,6 +221,26 @@ extern gl3image_t *gl3_particletexture; /* little dot for particles */
extern int gl_filter_min;
extern int gl_filter_max;
static inline void
GL3_UseProgram(GLuint shaderProgram)
{
if(shaderProgram != gl3state.currentShaderProgram)
{
gl3state.currentShaderProgram = shaderProgram;
glUseProgram(shaderProgram);
}
}
static inline void
GL3_BindVAO(GLuint vao)
{
if(vao != gl3state.currentVAO)
{
gl3state.currentVAO = vao;
glBindVertexArray(vao);
}
}
extern qboolean GL3_CullBox(vec3_t mins, vec3_t maxs);
extern void GL3_RotateForEntity(entity_t *e);
@ -309,6 +334,7 @@ extern void GL3_MarkLeaves(void);
// gl3_shaders.c
extern qboolean GL3_InitShaders(void);
extern void GL3_ShutdownShaders(void);
extern void GL3_SetGammaAndIntensity(void);