From 4966bde3d4103bb38b5d10df42b773c19f07d816 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Fri, 9 Feb 2018 00:29:20 +0100 Subject: [PATCH] started work on shaders.cpp --- basegraph.cpp | 97 +++++------------- compileunits.h | 1 + graph.cpp | 9 +- init.cpp | 3 + polygons.cpp | 39 ++------ rug.cpp | 14 +-- shaders.cpp | 267 +++++++++++++++++++++++++++++++++++++++++++++++++ textures.cpp | 9 +- 8 files changed, 317 insertions(+), 122 deletions(-) create mode 100644 shaders.cpp diff --git a/basegraph.cpp b/basegraph.cpp index 81bd8ead..abf6f54a 100644 --- a/basegraph.cpp +++ b/basegraph.cpp @@ -157,7 +157,6 @@ bool cameraangle_on; void setcameraangle(bool b) { if(cameraangle_on != b) { - glMatrixMode(GL_PROJECTION); cameraangle_on = b; ld cam = vid.camera_angle * M_PI / 180; @@ -170,24 +169,22 @@ void setcameraangle(bool b) { 0, -ss, cc, 0, 0, 0, 0, 1 }; - - glMultMatrixf(yzspin); + + glhr::projection_multiply(glhr::as_glmatrix(yzspin)); } } void start_projection(int ed) { - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - glTranslatef((vid.xcenter*2.)/vid.xres - 1, 1 - (vid.ycenter*2.)/vid.yres, 0); + glhr::new_projection(); + glhr::projection_multiply(glhr::translate((vid.xcenter*2.)/vid.xres - 1, 1 - (vid.ycenter*2.)/vid.yres, 0)); if(ed) { - if(stereo::mode == stereo::sLR) { - glTranslatef(ed * (stereo::eyewidth() - .5) * 4, 0, 0); - glScalef(2, 1, 1); + if(stereo::mode == stereo::sLR) { + glhr::projection_multiply(glhr::translate(ed * (stereo::eyewidth() - .5) * 4, 0, 0)); + glhr::projection_multiply(glhr::scale(2, 1, 1)); } else { - glTranslatef(-ed * stereo::eyewidth(), 0, 0); + glhr::projection_multiply(glhr::translate(-ed * stereo::eyewidth(), 0, 0)); } } } @@ -205,11 +202,8 @@ void stereo::set_projection(int ed) { 0, GLfloat(-2. / vid.yres), 0, 0, 0, 0, GLfloat(.4 / stereo::scrdist), 0, 0, 0, 0, 1}; - - glMultMatrixf(ortho); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); + + glhr::projection_multiply(glhr::as_glmatrix(ortho)); } else if(pmodel) { @@ -226,15 +220,12 @@ void stereo::set_projection(int ed) { 0, 0, -(hidepth+lowdepth)/(hidepth-lowdepth), -1, 0, 0, -2*lowdepth*hidepth/(hidepth-lowdepth), 0}; - glMultMatrixf(frustum); + glhr::projection_multiply(glhr::as_glmatrix(frustum)); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); + if(ed) glhr::projection_multiply(glhr::translate(stereo::ipd * vid.radius * ed/2, 0, 0)); - if(ed) glTranslatef(stereo::ipd * vid.radius * ed/2, 0, 0); - - glScalef(1, 1, -1); - glTranslatef(0, 0, stereo::scrdist); + glhr::projection_multiply(glhr::scale(1, 1, -1)); + glhr::projection_multiply(glhr::translate(0, 0, stereo::scrdist)); stereo::scrdist_text = 0; } @@ -249,17 +240,14 @@ void stereo::set_projection(int ed) { 0, 0, -(hidepth+lowdepth)/(hidepth-lowdepth), -1, 0, 0, -2*lowdepth*hidepth/(hidepth-lowdepth), 0}; - glMultMatrixf(frustum); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); + glhr::projection_multiply(glhr::as_glmatrix(frustum)); GLfloat sc = vid.radius / (vid.yres/2.); GLfloat mat[16] = {sc,0,0,0, 0,-sc,0,0, 0,0,-1,0, 0,0, 0,1}; - glMultMatrixf(mat); + glhr::projection_multiply(glhr::as_glmatrix(mat)); - if(ed) glTranslatef(stereo::ipd*ed/2, 0, 0); + if(ed) glhr::projection_multiply(glhr::translate(stereo::ipd * ed/2, 0, 0)); stereo::scrdist_text = vid.yres * sc / 2; } @@ -291,9 +279,6 @@ void stereo::set_viewport(int ed) { void setGLProjection(int col) { DEBB(DF_GRAPH, (debugfile,"setGLProjection\n")); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - unsigned char *c = (unsigned char*) (&col); glClearColor(c[2] / 255.0, c[1] / 255.0, c[0]/255.0, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -516,9 +501,8 @@ bool gl_print(int x, int y, int shift, int size, const char *s, int color, int a glDisable(GL_LIGHTING); glEnable(GL_TEXTURE_2D); + glhr::be_textured(); - glMatrixMode(GL_MODELVIEW); - glcolor2((color << 8) | 0xFF); int tsize = 0; @@ -533,22 +517,8 @@ bool gl_print(int x, int y, int shift, int size, const char *s, int color, int a bool clicked = (mousex >= x && mousey <= y && mousex <= x+tsize && mousey >= y-ysiz); - /* extern bool markcorner; - if(clicked && markcorner) { - markcorner = false; - int w = tsize, h = -ysiz; - displaystr(x, y, 1, 10, "X", 0xFFFFFF, 8); - displaystr(x+w, y, 1, 10, "X", 0xFFFFFF, 8); - displaystr(x, y+h, 1, 10, "X", 0xFFFFFF, 8); - displaystr(x+w, y+h, 1, 10, "X", 0xFFFFFF, 8); - markcorner = true; - } */ - for(int i=0; s[i];) { - // glListBase(f.list_base); - // glCallList(s[i]); // s[i]); - int tabid = getnext(s,i); float fx=f.tx[tabid]; float fy=f.ty[tabid]; @@ -558,12 +528,10 @@ bool gl_print(int x, int y, int shift, int size, const char *s, int color, int a GLERR("pre-print"); for(int ed = (stereo::active() && shift)?-1:0; ed<2; ed+=2) { - glPushMatrix(); - glTranslatef(x-ed*shift-vid.xcenter,y-vid.ycenter, stereo::scrdist_text); + glhr::set_modelview(glhr::translate(x-ed*shift-vid.xcenter,y-vid.ycenter, stereo::scrdist_text)); stereo::set_mask(ed); glBindTexture(GL_TEXTURE_2D, f.textures[tabid]); -#if 1 tver[1] = tver[10] = -hi; tver[6] = tver[9] = wi; tver[12+4] = tver[12+7] = fy; @@ -573,30 +541,13 @@ bool gl_print(int x, int y, int shift, int size, const char *s, int color, int a glTexCoordPointer(3, GL_FLOAT, 0, &tver[12]); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDisableClientState(GL_TEXTURE_COORD_ARRAY); -#else - glBegin(GL_QUADS); - glTexCoord2d(0,0); glVertex2f(0, -hi); - glTexCoord2d(0,fy); glVertex2f(0, 0); - glTexCoord2d(fx,fy); glVertex2f(wi, 0); - glTexCoord2d(fx,0); glVertex2f(wi, -hi); - glEnd(); -#endif - glPopMatrix(); } if(stereo::active() && shift) stereo::set_mask(0); GLERR("print"); - // int tabid = s[i]; - x += wi; - -/* - printf("point %d,%d\n", x, y); - glBegin(GL_POINTS); - glVertex3f(rand() % 100 - rand() % 100, rand() % 100 - rand() % 100, 100); - glEnd(); */ - + x += wi; } glDisable(GL_TEXTURE_2D); @@ -943,6 +894,8 @@ void drawCircle(int x, int y, int size, int color) { if(size < 0) size = -size; #if CAP_GL if(vid.usingGL) { + glhr::be_nontextured(); + glhr::set_modelview(glhr::id()); qglcoords = 0; glcolor2(color); x -= vid.xcenter; y -= vid.ycenter; @@ -1029,11 +982,6 @@ hookset *hooks_hqshot; #if CAP_SDL void saveHighQualityShot(const char *fname, const char *caption, int fade) { -#if !CAP_SDLGFX - addMessage(XLAT("High quality shots not available on this platform")); - return; -#endif - int maxrange = getDistLimit() * 3/2; dynamicval v3(sightrange, (cheater && sightrange < maxrange) ? maxrange : sightrange); @@ -1168,6 +1116,7 @@ void setvideomode() { glDisable(GL_MULTISAMPLE); glViewport(0, 0, vid.xres, vid.yres); + glhr::init(); resetGL(); } #endif diff --git a/compileunits.h b/compileunits.h index cfdc125f..d87df004 100644 --- a/compileunits.h +++ b/compileunits.h @@ -22,6 +22,7 @@ #endif #if IN_CU(0) +#include "shaders.cpp" #include "util.cpp" #include "hyperpoint.cpp" #include "patterns.cpp" diff --git a/graph.cpp b/graph.cpp index d8d43448..fd1c3b28 100644 --- a/graph.cpp +++ b/graph.cpp @@ -2268,6 +2268,8 @@ void drawaura() { #endif #if CAP_GL + glhr::be_nontextured(); + glhr::set_modelview(glhr::id()); setcameraangle(true); glEnableClientState(GL_COLOR_ARRAY); @@ -2287,6 +2289,7 @@ void drawaura() { facs[d] = .99999 + .00001 * exp(dd); } facs[10] = 10; + cmul[1] = cmul[0]; for(int r=0; r<=AURA; r++) for(int z=0; z<11; z++) { float rr = (M_PI * 2 * r) / AURA; @@ -2307,9 +2310,9 @@ void drawaura() { int bz = (c == 3 || c == 2) ? z+1 : z; glcoords[c][0] = cx[br][bz][0]; glcoords[c][1] = cx[br][bz][1]; - coltab[c][0] = cx[br][bz][2]; - coltab[c][1] = cx[br][bz][3]; - coltab[c][2] = cx[br][bz][4]; + coltab[c][0] = min(cx[br][bz][2], 1); + coltab[c][1] = min(cx[br][bz][3], 1); + coltab[c][2] = min(cx[br][bz][4], 1); } glDrawArrays(GL_TRIANGLE_FAN, 0, 4); diff --git a/init.cpp b/init.cpp index 27195245..5d1e3891 100644 --- a/init.cpp +++ b/init.cpp @@ -17,6 +17,9 @@ #define VER "10.3g" #define VERNUM 10307 + +#define CAP_SHADER CAP_GL + #define VERNUM_HEX 0xA0A7 #define GEN_M 0 diff --git a/polygons.cpp b/polygons.cpp index afc01be8..29d1d9b6 100644 --- a/polygons.cpp +++ b/polygons.cpp @@ -312,7 +312,7 @@ void glapplymatrix(const transmatrix& V) { mat[j+i] = -mat[j+i]; } - glMultMatrixf(mat); + glhr::set_modelview(glhr::as_glmatrix(mat)); } int tinfshift; @@ -321,10 +321,12 @@ void gldraw(int useV, const transmatrix& V, int ps, int pq, int col, int outline if(tinf) { glEnable(GL_TEXTURE_2D); + glhr::be_textured(); glBindTexture(GL_TEXTURE_2D, tinf->texture_id); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(3, GL_FLOAT, 0, &tinf->tvertices[tinfshift]); } + else glhr::be_nontextured(); for(int ed = stereo::active() ? -1 : 0; ed<2; ed+=2) { if(ed) stereo::set_projection(ed), stereo::set_viewport(ed); @@ -332,38 +334,11 @@ void gldraw(int useV, const transmatrix& V, int ps, int pq, int col, int outline again: if(useV == 1) { - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); glapplymatrix(V); } + else + glhr::set_modelview(glhr::id()); -/* - if(useV == 2) { - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - GLfloat mat[16] = { - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 - }; - // EYETODO mat[8] += ed * vid.eye; - glMultMatrixf(mat); - } - - if(useV == 3) { - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - GLfloat mat[16] = { - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 0, 0, - 0, 0, stereo::scrdist, 1 - }; - // EYETODO mat[8] += ed * vid.eye; - glMultMatrixf(mat); - } */ - if(draw) { glEnable(GL_STENCIL_TEST); @@ -386,7 +361,7 @@ void gldraw(int useV, const transmatrix& V, int ps, int pq, int col, int outline }; GLfloat *cur = currentvertices; activateVertexArray(scr, 4); - if(useV) glPopMatrix(); + glhr::set_modelview(glhr::id()); glDrawArrays(tinf ? GL_TRIANGLES : GL_TRIANGLE_FAN, 0, 4); activateVertexArray(cur, 0); draw = false; goto again; @@ -406,8 +381,6 @@ void gldraw(int useV, const transmatrix& V, int ps, int pq, int col, int outline glcolor2(outline); glDrawArrays(GL_LINE_STRIP, ps, pq); } - - if(useV) glPopMatrix(); } if(stereo::active()) stereo::set_projection(0), stereo::set_viewport(0), stereo::set_mask(0); diff --git a/rug.cpp b/rug.cpp index eec60ec6..ce17053a 100644 --- a/rug.cpp +++ b/rug.cpp @@ -1147,6 +1147,7 @@ void drawRugScene() { glDisable(GL_BLEND); glEnable(GL_TEXTURE_2D); + glhr::be_textured(); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); @@ -1179,14 +1180,13 @@ void drawRugScene() { 0, GLfloat(vnear / sca / vid.yres), 0, 0, 0, 0, GLfloat(-(vnear+vfar)/(vfar-vnear)), -1, 0, 0, GLfloat(-2*vnear*vfar/(vfar-vnear)), 1}; - glMultMatrixf(frustum); + glhr::projection_multiply(glhr::as_glmatrix(frustum)); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - if(!rug_perspective) glTranslatef(0, 0, -model_distance); + if(!rug_perspective) + glhr::projection_multiply(glhr::translate(0, 0, -model_distance)); if(ed) { if(gwhere == gEuclid) - glTranslatef(stereo::ipd*ed/2, 0, 0); + glhr::projection_multiply(glhr::translate(stereo::ipd*ed/2, 0, 0)); else { use_precompute = true; for(auto p: points) { @@ -1206,7 +1206,7 @@ void drawRugScene() { 0, GLfloat(1/yview), 0, 0, 0, 0, GLfloat(.001), 0, 0, 0, 0, 1}; - glMultMatrixf(ortho); + glhr::projection_multiply(glhr::as_glmatrix(ortho)); } glColor4f(1.f, 1.f, 1.f, 1.f); @@ -1221,6 +1221,8 @@ void drawRugScene() { glFogf(GL_FOG_END, gwhere == gSphere ? 10 : 4); } + glhr::set_modelview(glhr::id()); + for(int t=0; t 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 +} diff --git a/textures.cpp b/textures.cpp index be5561a0..05a56198 100644 --- a/textures.cpp +++ b/textures.cpp @@ -462,12 +462,10 @@ void saveFullTexture() { bool newmove = false; void drawRawTexture() { - glDisable(GL_LIGHTING); glEnable(GL_TEXTURE_2D); - glMatrixMode(GL_MODELVIEW); + glhr::be_textured(); glcolor2(0xFFFFFF20); - glPushMatrix(); - glTranslatef(0, 0, stereo::scrdist); + glhr::set_modelview(glhr::translate(0, 0, stereo::scrdist)); glBindTexture(GL_TEXTURE_2D, textureid); vector tver, sver; for(int i=0; i<4; i++) { @@ -489,8 +487,7 @@ void drawRawTexture() { glTexCoordPointer(3, GL_FLOAT, 0, &tver[0]); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glPopMatrix(); - glDisable(GL_TEXTURE_2D); + glDisable(GL_TEXTURE_2D); } struct magicmapper_point {