mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-11-13 20:27:10 +00:00
started work on shaders.cpp
This commit is contained in:
267
shaders.cpp
Normal file
267
shaders.cpp
Normal file
@@ -0,0 +1,267 @@
|
||||
// gl matrices
|
||||
//-------------
|
||||
|
||||
// #undef CAP_SHADER
|
||||
// #define CAP_SHADER 0
|
||||
|
||||
namespace glhr {
|
||||
|
||||
enum mode { gmColored, gmTextured, gmMAX};
|
||||
|
||||
struct glmatrix {
|
||||
GLfloat a[4][4];
|
||||
GLfloat* operator[] (int i) { return a[i]; }
|
||||
GLfloat* as_array() { return a[0]; }
|
||||
const GLfloat* as_array() const { return a[0]; }
|
||||
};
|
||||
|
||||
glmatrix operator * (glmatrix m1, glmatrix m2) {
|
||||
glmatrix res;
|
||||
for(int i=0; i<4; i++)
|
||||
for(int j=0; j<4; j++) {
|
||||
res[i][j] = 0;
|
||||
for(int k=0; k<4; k++)
|
||||
res[i][j] += m1[i][k] * m2[k][j];
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
glmatrix id() {
|
||||
glmatrix M;
|
||||
for(int i=0; i<4; i++)
|
||||
for(int j=0; j<4; j++)
|
||||
M[i][j] = (i == j);
|
||||
return M;
|
||||
}
|
||||
|
||||
glmatrix scale(ld x, ld y, ld z) {
|
||||
glmatrix tmp;
|
||||
for(int i=0; i<4; i++)
|
||||
for(int j=0; j<4; j++)
|
||||
tmp[i][j] = (i==j);
|
||||
tmp[0][0] = x;
|
||||
tmp[1][1] = y;
|
||||
tmp[2][2] = z;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
glmatrix translate(ld x, ld y, ld z) {
|
||||
glmatrix tmp;
|
||||
for(int i=0; i<4; i++)
|
||||
for(int j=0; j<4; j++)
|
||||
tmp[i][j] = (i==j);
|
||||
tmp[3][0] = x;
|
||||
tmp[3][1] = y;
|
||||
tmp[3][2] = z;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
glmatrix& as_glmatrix(GLfloat o[16]) {
|
||||
glmatrix& tmp = (glmatrix&) (o[0]);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// ** legacy **
|
||||
|
||||
#if !CAP_SHADER
|
||||
|
||||
void new_projection() {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
||||
void projection_multiply(const glmatrix& m) {
|
||||
glMultMatrixf(m.as_array());
|
||||
}
|
||||
|
||||
void set_modelview(const glmatrix& m) {
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadMatrixf(m.as_array());
|
||||
}
|
||||
|
||||
void be_nontextured() { }
|
||||
void be_textured() { }
|
||||
void init() { }
|
||||
|
||||
#endif
|
||||
|
||||
// /* shaders */
|
||||
|
||||
#if CAP_SHADER
|
||||
|
||||
glmatrix projection;
|
||||
|
||||
void new_projection() {
|
||||
projection = id();
|
||||
}
|
||||
|
||||
void projection_multiply(const glmatrix& m) {
|
||||
projection = m * projection;
|
||||
}
|
||||
|
||||
#define glMatrixMode DISABLED
|
||||
#define glLoadIdentity DISABLED
|
||||
#define glMultMatrixf DISABLED
|
||||
#define glScalef DISABLED
|
||||
#define glTranslatef DISABLED
|
||||
#define glPushMatrix DISABLED
|
||||
#define glPopMatrix DISABLED
|
||||
|
||||
void init();
|
||||
|
||||
int compileShader(int type, const char* s) {
|
||||
GLint status;
|
||||
|
||||
GLint shader = glCreateShader(type);
|
||||
glShaderSource(shader, 1, &s, NULL);
|
||||
glCompileShader(shader);
|
||||
|
||||
GLint logLength;
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
|
||||
if (logLength > 0) {
|
||||
char log[logLength];
|
||||
glGetShaderInfoLog(shader, logLength, &logLength, log);
|
||||
if(logLength > 0)
|
||||
printf("compiler log (%d): '%s'\n", logLength, log);
|
||||
}
|
||||
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
|
||||
if (status == 0) {
|
||||
glDeleteShader(shader);
|
||||
printf("failed to compile shader\n");
|
||||
shader = 0;
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
// https://www.opengl.org/sdk/docs/tutorials/ClockworkCoders/attributes.php
|
||||
|
||||
struct GLprogram *current = NULL;
|
||||
|
||||
enum {
|
||||
UNIFORM_MODELVIEWPROJECTION_MATRIX,
|
||||
UNIFORM_NORMAL_MATRIX,
|
||||
NUM_UNIFORMS
|
||||
};
|
||||
|
||||
struct GLprogram {
|
||||
GLuint _program;
|
||||
GLuint vertShader, fragShader;
|
||||
|
||||
GLint uniforms[NUM_UNIFORMS];
|
||||
|
||||
GLprogram(string vsh, string fsh) {
|
||||
_program = glCreateProgram();
|
||||
printf("creating program %d\n", _program);
|
||||
vertShader = compileShader(GL_VERTEX_SHADER, vsh.c_str());
|
||||
fragShader = compileShader(GL_FRAGMENT_SHADER, fsh.c_str());
|
||||
|
||||
// Attach vertex shader to program.
|
||||
glAttachShader(_program, vertShader);
|
||||
|
||||
// Attach fragment shader to program.
|
||||
glAttachShader(_program, fragShader);
|
||||
|
||||
GLint status;
|
||||
glLinkProgram(_program);
|
||||
|
||||
GLint logLength;
|
||||
glGetProgramiv(_program, GL_INFO_LOG_LENGTH, &logLength);
|
||||
if (logLength > 0) {
|
||||
char log[logLength];
|
||||
glGetProgramInfoLog(_program, logLength, &logLength, log);
|
||||
if(logLength > 0)
|
||||
printf("linking log (%d): %s\n", logLength, log);
|
||||
}
|
||||
|
||||
glGetProgramiv(_program, GL_LINK_STATUS, &status);
|
||||
if (status == 0) {
|
||||
printf("failed to link shader\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); ??
|
||||
// glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); ??
|
||||
|
||||
uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(_program, "modelViewProjectionMatrix");
|
||||
uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(_program, "normalMatrix");
|
||||
printf("uniforms: %d %d\n", uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], uniforms[UNIFORM_NORMAL_MATRIX]);
|
||||
}
|
||||
|
||||
~GLprogram() {
|
||||
glDeleteProgram(_program);
|
||||
if(vertShader) glDeleteShader(vertShader), vertShader = 0;
|
||||
if(fragShader) glDeleteShader(fragShader), fragShader = 0;
|
||||
current = NULL;
|
||||
}
|
||||
|
||||
void enable() {
|
||||
if(this != current) {
|
||||
glUseProgram(_program);
|
||||
current = this;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
GLprogram *textured, *nontextured;
|
||||
|
||||
void init() {
|
||||
projection = id();
|
||||
|
||||
for(int i=0; i<2; i++) {
|
||||
auto texture_only = [=] (string s) -> string { if(i) return s; else return ""; };
|
||||
auto not_texture_only = [=] (string s) -> string { if(!i) return s; else return ""; };
|
||||
|
||||
(i==1?textured:nontextured) = new GLprogram(
|
||||
// "attribute vec4 position;"
|
||||
// "attribute vec3 normal;"
|
||||
|
||||
"varying vec4 vColor;"
|
||||
+ texture_only( "varying vec2 vTexCoord;" ) +
|
||||
|
||||
"uniform mat4 modelViewProjectionMatrix;"
|
||||
"uniform mat3 normalMatrix;"
|
||||
|
||||
"void main() {"
|
||||
// "vec3 eyeNormal = normalize(normalMatrix * normal);"
|
||||
// "vec3 lightPosition = vec3(0.0, 0.0, 1.0);"
|
||||
// "vec4 diffuseColor = vec4(0.4, 0.4, 1.0, 1.0);"
|
||||
|
||||
// "float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition)));"
|
||||
|
||||
// "vColor = diffuseColor * nDotVP;"
|
||||
+ texture_only("vTexCoord = gl_MultiTexCoord0.xy;") +
|
||||
"vColor = gl_Color;"
|
||||
|
||||
"gl_Position = modelViewProjectionMatrix * gl_Vertex;"
|
||||
"}",
|
||||
|
||||
"uniform sampler2D myTexture;"
|
||||
"varying vec4 vColor;"
|
||||
+ texture_only( "varying vec2 vTexCoord;" ) +
|
||||
"void main() {"
|
||||
+ texture_only(" gl_FragColor = vColor * texture2D(myTexture, vTexCoord);")
|
||||
+ not_texture_only(" gl_FragColor = vColor;") +
|
||||
" }"
|
||||
);
|
||||
}
|
||||
|
||||
nontextured->enable();
|
||||
}
|
||||
|
||||
void set_modelview(const glmatrix& modelview) {
|
||||
glmatrix mvp = modelview * projection;
|
||||
glUniformMatrix4fv(current->uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, mvp.as_array());
|
||||
// glmatrix nm = modelview;
|
||||
// glUniformMatrix3fv(current->uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, nm[0]);
|
||||
}
|
||||
|
||||
void be_nontextured() { nontextured->enable(); }
|
||||
void be_textured() { textured->enable(); }
|
||||
|
||||
#endif
|
||||
}
|
||||
Reference in New Issue
Block a user