diff --git a/basegraph.cpp b/basegraph.cpp index b84f5e19..000fbfa4 100644 --- a/basegraph.cpp +++ b/basegraph.cpp @@ -199,31 +199,16 @@ void stereo::set_projection(int ed) { if(pmodel && !stereo::active()) { - // simulate glOrtho - GLfloat ortho[16] = { - GLfloat(2. / vid.xres), 0, 0, 0, - 0, GLfloat(-2. / vid.yres), 0, 0, - 0, 0, GLfloat(.4 / stereo::scrdist), 0, - 0, 0, 0, 1}; - - glhr::projection_multiply(glhr::as_glmatrix(ortho)); + glhr::projection_multiply(glhr::ortho(vid.xres/2, -vid.yres/2, stereo::scrdist/.4)); } else if(pmodel) { - float lowdepth = .1, hidepth = 1e9; - - ld right = vid.xres/2 * lowdepth / stereo::scrdist; + ld right = vid.xres/2 / stereo::scrdist; ld left = -right; - ld top = -vid.yres/2 * lowdepth / stereo::scrdist; + ld top = -vid.yres/2 / stereo::scrdist; ld bottom = -top; - GLfloat frustum[16] = { - GLfloat(2 * lowdepth / (right-left)), 0, 0, 0, - 0, GLfloat(2 * lowdepth / (top-bottom)), 0, 0, - 0, 0, -(hidepth+lowdepth)/(hidepth-lowdepth), -1, - 0, 0, -2*lowdepth*hidepth/(hidepth-lowdepth), 0}; - - glhr::projection_multiply(glhr::as_glmatrix(frustum)); + glhr::projection_multiply(glhr::frustum((right-left)/2, (top-bottom)/2)); if(ed) glhr::projection_multiply(glhr::translate(stereo::ipd * vid.radius * ed/2, 0, 0)); @@ -233,22 +218,11 @@ void stereo::set_projection(int ed) { stereo::scrdist_text = 0; } else { - float lowdepth = .1; - float hidepth = 1e9; - - // simulate glFrustum - GLfloat frustum[16] = { - GLfloat(vid.yres * 1./vid.xres), 0, 0, 0, - 0, 1, 0, 0, - 0, 0, -(hidepth+lowdepth)/(hidepth-lowdepth), -1, - 0, 0, -2*lowdepth*hidepth/(hidepth-lowdepth), 0}; - - glhr::projection_multiply(glhr::as_glmatrix(frustum)); + glhr::projection_multiply(glhr::frustum(vid.xres * 1. / vid.yres, 1)); 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}; - glhr::projection_multiply(glhr::as_glmatrix(mat)); + glhr::projection_multiply(glhr::scale(sc, -sc, -1)); if(ed) glhr::projection_multiply(glhr::translate(stereo::ipd * ed/2, 0, 0)); @@ -328,13 +302,6 @@ inline int next_p2 (int a ) return rval; } -void glError(const char* GLcall, const char* file, const int line) { - GLenum errCode = glGetError(); - if(errCode!=GL_NO_ERROR) { - fprintf(stderr, "OPENGL ERROR #%i: in file %s on line %i :: %s\n",errCode,file, line, GLcall); - } - } - #if CAP_GLFONT struct glfont_t { diff --git a/rug.cpp b/rug.cpp index cfeb74ff..920e035a 100644 --- a/rug.cpp +++ b/rug.cpp @@ -995,7 +995,7 @@ bool project_ods(hyperpoint azeq, hyperpoint& h1, hyperpoint& h2, bool eye) { } #endif -vector vertex_array, tvertex_array; +vector vertex_array, tvertex_array, color_array; void drawTriangle(triangle& t) { using namespace hyperpoint_vec; @@ -1013,6 +1013,7 @@ void drawTriangle(triangle& t) { hyperpoint hc = (pts[1] - pts[0]) ^ (pts[2] - pts[0]); double hch = hypot3(hc); + glNormal3f(hc[0]/hch,hc[1]/hch,hc[2]/hch); bool ok = true; @@ -1067,13 +1068,22 @@ void drawTriangle(triangle& t) { hyperpoint hc = (h[1] - h[0]) ^ (h[2] - h[0]); double hch = hypot3(hc); + ld col = (2 + hc[0]/hch) / 3; + + #if !CAP_SHADER glNormal3f(hc[0]/hch,hc[1]/hch,hc[2]/hch); + #endif for(int i: {0,1,2}) { tvertex_array.push_back(t.m[i]->x1); tvertex_array.push_back(t.m[i]->y1); for(int j: {0,1,2}) vertex_array.push_back(h[i][j]); + + #if CAP_SHADER + for(int a=0; a<3; a++) color_array.push_back(col); + color_array.push_back(1); + #endif } } @@ -1123,7 +1133,7 @@ void drawRugScene() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDisable(GL_BLEND); - glhr::switch_mode(glhr::gmVarColored); + glhr::switch_mode(glhr::gmLightFog); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); @@ -1131,32 +1141,22 @@ void drawRugScene() { use_precompute = false; vertex_array.clear(); tvertex_array.clear(); + color_array.clear(); stereo::set_mask(ed), stereo::set_viewport(ed); if(ed == 1 && stereo::mode == stereo::sAnaglyph) glClear(GL_DEPTH_BUFFER_BIT); start_projection(ed); if(stereo::mode == stereo::sODS) { -#ifndef GLES_ONLY - glOrtho(-M_PI, M_PI, -M_PI, M_PI, 0, -M_PI * 2); -#endif + glhr::projection_multiply(glhr::ortho(M_PI, M_PI, 2*M_PI)); } else if(rug_perspective || stereo::active()) { - ld vnear = .001; - ld vfar = 1000; - ld sca = vnear * stereo::tanfov / vid.xres; xview = stereo::tanfov; yview = stereo::tanfov * vid.yres / vid.xres; - //glFrustum(-sca * vid.xres, sca * vid.xres, -sca * vid.yres, sca * vid.yres, vnear, vfar); - - GLfloat frustum[16] = { - GLfloat(vnear / sca / vid.xres), 0, 0, 0, - 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}; - glhr::projection_multiply(glhr::as_glmatrix(frustum)); + glhr::projection_multiply(glhr::frustum(xview, yview, .01, 100)); + xview = -xview; yview = -yview; if(!rug_perspective) glhr::projection_multiply(glhr::translate(0, 0, -model_distance)); @@ -1177,28 +1177,26 @@ void drawRugScene() { yview = stereo::tanfov * model_distance * vid.yres / vid.xres; // glOrtho(-xview, xview, yview, -yview, -1000, 1000); - GLfloat ortho[16] = { - GLfloat(1/xview), 0, 0, 0, - 0, GLfloat(1/yview), 0, 0, - 0, 0, GLfloat(.001), 0, - 0, 0, 0, 1}; - glhr::projection_multiply(glhr::as_glmatrix(ortho)); + glhr::projection_multiply(glhr::ortho(xview, yview, -1000)); } glColor4f(1.f, 1.f, 1.f, 1.f); - fog_max( - gwhere == gSphere ? 10 : - gwhere == gElliptic ? 4 : + glhr::fog_max( + gwhere == gSphere && rug_perspective ? 10 : + gwhere == gElliptic && rug_perspective ? 4 : 100 ); glhr::set_modelview(glhr::id()); - + for(int t=0; t string stringbuilder(bool i, bool j, T... t) { return stringbuilder(j, t...); } +template string stringbuilder(bool i, const string& s, T... t) { + if(i) return s + stringbuilder(i, t...); + else return stringbuilder(i, t...); + } */ + 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 ""; }; - + for(int i=0; i<4; i++) { + flagtype f = flags[i]; + flagtype nf = ~f; + auto texture_only = [=] (string s) -> string { if(f & GF_TEXTURE) return s; else return ""; }; + auto not_texture_only = [=] (string s) -> string { if(nf & GF_TEXTURE) return s; else return ""; }; + programs[i] = new GLprogram( // "attribute vec4 position;" // "attribute vec3 normal;" @@ -237,7 +285,7 @@ void init() { + texture_only( "varying vec2 vTexCoord;" ) + "uniform mat4 modelViewProjectionMatrix;" - "uniform mat3 normalMatrix;" + "uniform float fogfactor;" "void main() {" // "vec3 eyeNormal = normalize(normalMatrix * normal);" @@ -248,7 +296,9 @@ void init() { // "vColor = diffuseColor * nDotVP;" + texture_only("vTexCoord = gl_MultiTexCoord0.xy;") + - "vColor = gl_Color;" + + ((f & GF_LIGHTFOG) ? + "vColor = gl_Color * clamp(1.0 + gl_Vertex.z * fogfactor, 0.0, 1.0);" + : "vColor = gl_Color;") + "gl_Position = modelViewProjectionMatrix * gl_Vertex;" "}", @@ -263,9 +313,6 @@ void init() { ); } - programs[2] = programs[0]; - programs[3] = programs[1]; - glEnableClientState(GL_VERTEX_ARRAY); switch_mode(gmColored); programs[gmColored]->enable(); @@ -300,6 +347,11 @@ void color2(int color) { glColor4f(c[3] / 255.0, c[2] / 255.0, c[1]/255.0, c[0] / 255.0); } +void color2(int color, ld part) { + unsigned char *c = (unsigned char*) (&color); + glColor4f(c[3] / 255.0 * part, c[2] / 255.0 * part, c[1]/255.0 * part, c[0] / 255.0); + } + void colorClear(int color) { unsigned char *c = (unsigned char*) (&color); glClearColor(c[3] / 255.0, c[2] / 255.0, c[1]/255.0, c[0] / 255.0); @@ -328,6 +380,7 @@ void switch_mode(eMode m) { if(oldflags & GF_VARCOLOR) glDisableClientState(GL_COLOR_ARRAY); if(newflags & GF_LIGHTFOG) { +#if !CAP_SHADER GLfloat light_ambient[] = { 3.5, 3.5, 3.5, 1.0 }; GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light_position[] = { 0.0, 0.0, 0.0, 1.0 }; @@ -345,16 +398,23 @@ void switch_mode(eMode m) { glEnable(GL_FOG); glFogi(GL_FOG_MODE, GL_LINEAR); glFogf(GL_FOG_START, 0); +#endif } if(oldflags & GF_LIGHTFOG) { +#if !CAP_SHADER glDisable(GL_FOG); glDisable(GL_LIGHTING); +#endif } mode = m; } void fog_max(ld fogmax) { + #if CAP_SHADER + glUniform1f(current->uniforms[UNIFORM_FOGFACTOR], 1 / fogmax); + #else glFogf(GL_FOG_END, fogmax); + #endif } }