1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-11-23 21:07:17 +00:00

shaderside projection

This commit is contained in:
Zeno Rogue 2018-11-17 17:59:57 +01:00
parent 51dea031c6
commit 680dca90c8
8 changed files with 127 additions and 52 deletions

View File

@ -174,11 +174,11 @@ void setcameraangle(bool b) {
}
}
bool using_perspective;
bool shaderside_projection;
void start_projection(int ed, bool perspective) {
glhr::new_projection();
using_perspective = perspective;
shaderside_projection = perspective;
if(ed && stereo::mode == stereo::sLR) {
glhr::projection_multiply(glhr::translate(ed, 0, 0));
@ -192,12 +192,19 @@ void eyewidth_translate(int ed) {
if(ed) glhr::projection_multiply(glhr::translate(-ed * stereo::eyewidth(), 0, 0));
}
void stereo::set_projection(int ed) {
void stereo::set_projection(int ed, bool apply_models) {
DEBB(DF_GRAPH, (debugfile,"stereo::set_projection\n"));
start_projection(ed, pmodel == mdDisk && !spherespecial && !(hyperbolic && vid.alpha <= -1));
shaderside_projection = false;
glhr::new_shader_projection = glhr::shader_projection::standard;
if(pmodel == mdDisk && !spherespecial && !(hyperbolic && vid.alpha <= -1))
shaderside_projection = true;
if(pmodel == mdBand && hyperbolic && apply_models && !inHighQual)
shaderside_projection = true, glhr::new_shader_projection = glhr::shader_projection::band;
start_projection(ed, shaderside_projection);
if(!using_perspective) {
if(!shaderside_projection) {
glhr::projection_multiply(glhr::ortho(vid.xres/2, -vid.yres/2, abs(stereo::scrdist) + 30000));
if(ed) {
glhr::glmatrix m = glhr::id;
@ -308,7 +315,7 @@ void setGLProjection(color_t col) {
GLERR("setGLProjection");
stereo::set_projection(0);
stereo::set_projection(0, true);
GLERR("after set_projection");
}

View File

@ -2407,7 +2407,7 @@ void drawaura() {
}
}
glflush();
glhr::switch_mode(glhr::gmVarColored);
glhr::switch_mode(glhr::gmVarColored, glhr::shader_projection::standard);
glhr::id_modelview();
glhr::prepare(auravertices);
glhr::set_depthtest(false);

View File

@ -355,7 +355,7 @@ void drawStats() {
dynamicval<videopar> v(vid, vid);
vid.alpha = vid.scale = 1;
calcparam();
stereo::set_projection(0);
stereo::set_projection(0, false);
if(haveMobileCompass()) {
initquickqueue();
@ -476,7 +476,7 @@ void drawStats() {
}
}
}
calcparam(); stereo::set_projection(0);
calcparam(); stereo::set_projection(0, false);
string s0;
if(!peace::on) {

11
hyper.h
View File

@ -3307,7 +3307,7 @@ namespace stereo {
bool in_anaglyph();
void set_viewport(int ed);
void set_projection(int ed);
void set_projection(int ed, bool apply_models);
void set_mask(int ed);
}
@ -3630,10 +3630,15 @@ namespace glhr {
const GLfloat* as_array() const { return a[0]; }
};
enum class shader_projection { standard, band, MAX };
extern shader_projection new_shader_projection;
void set_depthtest(bool b);
glmatrix translate(ld x, ld y, ld z);
void color2(color_t color, ld part = 1);
void be_textured();
void be_nontextured(shader_projection sp = new_shader_projection);
void be_textured(shader_projection sp = new_shader_projection);
void set_modelview(const glmatrix& m);
hyperpoint gltopoint(const glvertex& t);
glvertex pointtogl(const hyperpoint& t);
@ -4010,7 +4015,7 @@ extern ld hexshift;
extern bool noshadow, bright, nohelp, dont_face_pc;
extern void switchHardcore();
extern bool using_perspective;
extern bool shaderside_projection;
void generateAlts(heptagon *h, int levs = IRREGULAR ? 1 : S3-3, bool link_cdata = true);

View File

@ -439,6 +439,7 @@ void glflush() {
if(isize(text_vertices)) {
// printf("%08X | %d texts, %d vertices\n", text_color, texts_merged, isize(text_vertices));
stereo::set_projection(0, false);
glhr::be_textured();
glBindTexture(GL_TEXTURE_2D, text_texture);
glhr::color2(text_color);
@ -478,6 +479,10 @@ void glapplymatrix(const transmatrix& V) {
mat[15] = 1;
if(vid.stretch != 1) mat[1] *= vid.stretch, mat[5] *= vid.stretch, mat[9] *= vid.stretch, mat[13] *= vid.stretch;
if(conformal::model_has_orientation())
for(int a=0; a<4; a++)
conformal::apply_orientation(mat[a*4], mat[a*4+1]);
glhr::set_modelview(glhr::as_glmatrix(mat));
}
@ -535,10 +540,13 @@ void dqi_poly::gldraw() {
}
for(int ed = stereo::active() ? -1 : 0; ed<2; ed+=2) {
if(ed) stereo::set_projection(ed), stereo::set_viewport(ed);
if(ed) stereo::set_projection(ed, true), stereo::set_viewport(ed);
bool draw = color;
if(using_perspective) glapplymatrix(V);
if(shaderside_projection) {
if(glhr::current_shader_projection == glhr::shader_projection::band && V[2][2] > 1e8) continue;
glapplymatrix(V);
}
if(draw) {
if(true) {
@ -560,7 +568,7 @@ void dqi_poly::gldraw() {
glStencilFunc( GL_NOTEQUAL, 1, 1);
GLfloat xx = vid.xres;
GLfloat yy = vid.yres;
GLfloat dist = using_perspective ? stereo::scrdist : 0;
GLfloat dist = shaderside_projection ? stereo::scrdist : 0;
vector<glvertex> scr = {
make_array<GLfloat>(-xx, -yy, dist),
make_array<GLfloat>(+xx, -yy, dist),
@ -571,7 +579,7 @@ void dqi_poly::gldraw() {
glhr::id_modelview();
glDrawArrays(tinf ? GL_TRIANGLES : GL_TRIANGLE_FAN, 0, 4);
glhr::vertices(v);
if(using_perspective) glapplymatrix(V);
if(shaderside_projection) glapplymatrix(V);
}
else {
glStencilOp( GL_ZERO, GL_ZERO, GL_ZERO);
@ -595,7 +603,7 @@ void dqi_poly::gldraw() {
}
}
if(stereo::active()) stereo::set_projection(0), stereo::set_viewport(0), stereo::set_mask(0);
if(stereo::active()) stereo::set_projection(0, true), stereo::set_viewport(0), stereo::set_mask(0);
}
#endif
@ -946,7 +954,7 @@ void dqi_poly::draw() {
} */
#if CAP_GL
if(vid.usingGL && using_perspective) {
if(vid.usingGL && shaderside_projection) {
glLineWidth(get_width(this));
flags &= ~POLY_INVERSE;
gldraw();
@ -1219,7 +1227,7 @@ int curvestart = 0;
bool keep_curvedata = false;
void queuereset(eModel m, PPR prio) {
queueaction(prio, [m] () { pmodel = m; stereo::set_projection(0); });
queueaction(prio, [m] () { pmodel = m; stereo::set_projection(0, true); });
}
void dqi_line::draw() {
@ -1266,7 +1274,7 @@ void sortquickqueue() {
}
void quickqueue() {
spherespecial = 0; stereo::set_projection(0);
spherespecial = 0; stereo::set_projection(0, true);
int siz = isize(ptds);
setcameraangle(false);
for(int i=0; i<siz; i++) ptds[i]->draw();
@ -1402,7 +1410,7 @@ void drawqueue() {
spherespecial = 0;
spherephase = 0;
stereo::set_projection(0);
stereo::set_projection(0, true);
for(auto& ptd: ptds) if(ptd->prio == PPR::OUTCIRCLE)
ptd->draw();
@ -1418,7 +1426,7 @@ void drawqueue() {
}
spherespecial = sphereflipped() ? 1 : -1;
stereo::set_projection(0);
stereo::set_projection(0, true);
reverse_side_priorities();
for(int i=ptds.size()-1; i>=0; i--)
@ -1429,7 +1437,7 @@ void drawqueue() {
reverse_side_priorities();
spherespecial *= -1;
spherephase = 1;
stereo::set_projection(0);
stereo::set_projection(0, true);
}
for(auto& ptd: ptds) if(ptd->prio != PPR::OUTCIRCLE) {
@ -1440,7 +1448,7 @@ void drawqueue() {
#if CAP_GL
if(vid.usingGL)
stereo::set_projection(0), stereo::set_mask(0), stereo::set_viewport(0);
stereo::set_projection(0, true), stereo::set_mask(0), stereo::set_viewport(0);
#endif
#if CAP_SDL

View File

@ -301,7 +301,7 @@ void bantar_frame() {
cci.second.c->wparam = cci.second.gid;
calcparam();
stereo::set_projection(0);
stereo::set_projection(0, true);
vector<unique_ptr<drawqueueitem>> subscr[4];
@ -407,7 +407,7 @@ void bantar_frame() {
vid.xposition = (!(i&2)) ? xdst : -xdst;
vid.yposition = (!(i&1)) ? ydst : -ydst;
calcparam();
stereo::set_projection(0);
stereo::set_projection(0, true);
drawqueue();
}

View File

@ -1235,7 +1235,7 @@ void prepareTexture() {
glbuf->enable();
stereo::set_viewport(0);
stereo::set_projection(0);
stereo::set_projection(0, true);
stereo::set_mask(0);
glbuf->clear(0);
@ -1283,7 +1283,7 @@ void drawRugScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_BLEND);
glhr::switch_mode(glhr::gmLightFog);
glhr::switch_mode(glhr::gmLightFog, glhr::shader_projection::standard);
glhr::set_depthtest(true);
glDepthFunc(invert_depth ? GL_GREATER : GL_LESS);
@ -1351,7 +1351,7 @@ void drawRugScene() {
glEnable(GL_BLEND);
stereo::set_mask(0), stereo::set_viewport(0);
stereo::set_projection(0);
stereo::set_projection(0, true);
if(rug_failure) {
rug::close();

View File

@ -42,7 +42,9 @@ flagtype flags[gmMAX] = { 0, GF_TEXTURE, GF_VARCOLOR, GF_TEXTURE | GF_LIGHTFOG |
eMode mode;
void switch_mode(eMode m);
shader_projection current_shader_projection, new_shader_projection;
void switch_mode(eMode m, shader_projection sp);
void display(const glmatrix& m) {
for(int i=0; i<4; i++) {
@ -200,7 +202,7 @@ struct GLprogram {
GLuint _program;
GLuint vertShader, fragShader;
GLint uMVP, uFog, uColor, tTexture;
GLint uMVP, uFog, uColor, tTexture, uMV, uProjection;
GLprogram(string vsh, string fsh) {
_program = glCreateProgram();
@ -247,6 +249,8 @@ struct GLprogram {
// glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); ??
// glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); ??
uMV = glGetUniformLocation(_program, "uMV");
uProjection = glGetUniformLocation(_program, "uP");
uMVP = glGetUniformLocation(_program, "uMVP");
uFog = glGetUniformLocation(_program, "uFog");
uColor = glGetUniformLocation(_program, "uColor");
@ -274,7 +278,7 @@ struct GLprogram {
};
GLprogram *programs[gmMAX];
GLprogram *programs[gmMAX][int(shader_projection::MAX)];
string stringbuilder() { return ""; }
@ -287,7 +291,7 @@ template<class... T> string stringbuilder(bool i, const string& s, T... t) {
else return stringbuilder(t...);
}
glmatrix current_matrix;
glmatrix current_matrix, current_modelview, current_projection;
bool operator == (const glmatrix& m1, const glmatrix& m2) {
for(int i=0; i<4; i++)
@ -296,18 +300,35 @@ bool operator == (const glmatrix& m1, const glmatrix& m2) {
return true;
}
bool operator != (const glmatrix& m1, const glmatrix& m2) {
return !(m1 == m2);
}
void set_modelview(const glmatrix& modelview) {
glmatrix mvp = modelview * projection;
#if MINIMIZE_GL_CALLS
if(mvp == current_matrix) return;
current_matrix = mvp;
#endif
glUniformMatrix4fv(current->uMVP, 1, 0, mvp.as_array());
if(current_shader_projection != shader_projection::standard) {
if(modelview != current_modelview) {
current_modelview = modelview;
glUniformMatrix4fv(current->uMV, 1, 0, modelview.as_array());
}
if(projection != current_projection) {
current_projection = projection;
glUniformMatrix4fv(current->uProjection, 1, 0, projection.as_array());
}
}
else {
glmatrix mvp = modelview * projection;
#if MINIMIZE_GL_CALLS
if(mvp == current_matrix) return;
current_matrix = mvp;
#endif
glUniformMatrix4fv(current->uMVP, 1, 0, mvp.as_array());
}
// glmatrix nm = modelview;
// glUniformMatrix3fv(current->uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, nm[0]);
}
void id_modelview() {
if(current_shader_projection != shader_projection::standard) { set_modelview(id); return; }
#if MINIMIZE_GL_CALLS
if(projection == current_matrix) return;
current_matrix = projection;
@ -334,14 +355,14 @@ void colorClear(color_t color) {
glClearColor(c[3] / 255.0, c[2] / 255.0, c[1]/255.0, c[0] / 255.0);
}
void be_nontextured() { switch_mode(gmColored); }
void be_textured() { switch_mode(gmTextured); }
void be_nontextured(shader_projection sp) { switch_mode(gmColored, sp); }
void be_textured(shader_projection sp) { switch_mode(gmTextured, sp); }
void switch_mode(eMode m) {
if(m == mode) return;
void switch_mode(eMode m, shader_projection sp) {
if(m == mode && current_shader_projection == sp) return;
GLERR("pre_switch_mode");
#if CAP_SHADER
programs[m]->enable();
programs[m][int(sp)]->enable();
GLERR("after_enable");
#endif
flagtype newflags = flags[m] &~ flags[mode];
@ -421,9 +442,12 @@ void switch_mode(eMode m) {
#endif
}
mode = m;
current_shader_projection = sp;
GLERR("after_switch_mode");
current_vertices = NULL;
current_matrix[0][0] = -1e8; // invalid
current_modelview[0][0] = -1e8;
current_projection[0][0] = -1e8;
id_modelview();
}
@ -452,14 +476,20 @@ void init() {
#if CAP_SHADER
projection = id;
for(int i=0; i<4; i++) {
for(int i=0; i<gmMAX; i++)
for(int j=0; j<int(shader_projection::MAX); j++) {
flagtype f = flags[i];
bool texture = f & GF_TEXTURE;
bool lfog = f & GF_LIGHTFOG;
bool varcol = f & GF_VARCOLOR;
programs[i] = new GLprogram(stringbuilder(
shader_projection sp = shader_projection(j);
bool mps = j != 0;
bool band = (sp == shader_projection::band);
programs[i][j] = new GLprogram(stringbuilder(
1, "attribute mediump vec4 aPosition;",
texture, "attribute mediump vec2 aTexture;",
@ -469,16 +499,41 @@ void init() {
1, "varying mediump vec4 vColor;",
texture, "varying mediump vec2 vTexCoord;",
1, "uniform mediump mat4 uMVP;",
!mps, "uniform mediump mat4 uMVP;",
mps, "uniform mediump mat4 uMV;",
mps, "uniform mediump mat4 uP;",
1, "uniform mediump float uFog;",
!varcol, "uniform mediump vec4 uColor;",
1, "float sinh(float x) {",
1, " return (exp(x) - exp(-x)) / 2.0;",
1, " }",
1, "float cosh(float x) {",
1, " return (exp(x) + exp(-x)) / 2.0;",
1, " }",
1, "float tanh(float x) {",
1, " return sinh(x) / cosh(x);",
1, " }",
1, "float asinh(float x) {",
1, " return log(sqrt(1.0 + x*x) + x);",
1, " }",
1, "void main() {",
texture, "vTexCoord = aTexture;",
varcol, "vColor = aColor;",
!varcol, "vColor = uColor;",
lfog, "vColor = vColor * clamp(1.0 + aPosition.z * uFog, 0.0, 1.0);",
1, "gl_Position = uMVP * aPosition;",
!mps, "gl_Position = uMVP * aPosition;",
mps&&!band,"gl_Position = uP * (uMV * aPosition);",
band, "vec4 t = uMV * aPosition;",
band, "float ty = asinh(t.y);",
band, "float tx = asinh(t.x / cosh(ty));",
band, "ty = 2.0 * atan(tanh(ty/2.0));",
band, "t[0] = tx; t[1] = ty; t[2] = 1.0; t[3] = 1.0;",
band, "gl_Position = uP * t;",
1, "}"),
stringbuilder(
@ -490,15 +545,15 @@ void init() {
texture, "gl_FragColor = vColor * texture2D(tTexture, vTexCoord);",
!texture, "gl_FragColor = vColor;",
1, "}"
));
));
}
switch_mode(gmColored);
programs[gmColored]->enable();
switch_mode(gmColored, shader_projection::standard);
programs[gmColored][0]->enable();
#endif
#if !CAP_SHADER
switch_mode(gmColored);
switch_mode(gmColored, 0);
#endif
#if CAP_SHADER