mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2025-02-21 11:21:52 +00:00
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:
parent
0d81fd6080
commit
6e07ff0a2d
6 changed files with 305 additions and 138 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) ||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue