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

3d:: four-phase drawing of sphere

This commit is contained in:
? 2019-02-25 13:17:10 +01:00 committed by Zeno Rogue
parent 3b030471b0
commit 259e376909
4 changed files with 89 additions and 43 deletions

View File

@ -222,8 +222,13 @@ void display_data::set_projection(int ed, bool apply_models) {
shaderside_projection = true, glhr::new_shader_projection = glhr::shader_projection::standardH3;
if(DIM == 3 && euclid)
shaderside_projection = true, glhr::new_shader_projection = glhr::shader_projection::standardR3;
if(DIM == 3 && sphere)
shaderside_projection = true, glhr::new_shader_projection = glhr::shader_projection::standardS3;
if(DIM == 3 && sphere) {
shaderside_projection = true;
if(spherephase == 0) glhr::new_shader_projection = glhr::shader_projection::standardS30;
if(spherephase == 1) glhr::new_shader_projection = glhr::shader_projection::standardS31;
if(spherephase == 2) glhr::new_shader_projection = glhr::shader_projection::standardS32;
if(spherephase == 3) glhr::new_shader_projection = glhr::shader_projection::standardS33;
}
}
start_projection(ed, shaderside_projection);

View File

@ -3801,7 +3801,9 @@ namespace glhr {
const GLfloat* as_array() const { return a[0]; }
};
enum class shader_projection { standard, band, halfplane, standardH3, standardR3, standardS3, MAX };
enum class shader_projection { standard, band, halfplane, standardH3, standardR3,
standardS30, standardS31, standardS32, standardS33, MAX
};
extern shader_projection new_shader_projection;

View File

@ -1396,6 +1396,41 @@ void reverse_side_priorities() {
PPR::LAKEWALL, PPR::INLAKEWALL, PPR::BELOWBOTTOM})
reverse_priority(p);
}
// on the sphere, parts on the back are drawn first
void draw_backside() {
if(pmodel == mdHyperboloid && hyperbolic) {
dynamicval<eModel> dv (pmodel, mdHyperboloidFlat);
for(auto& ptd: ptds)
if(!among(ptd->prio, PPR::MOBILE_ARROW, PPR::OUTCIRCLE, PPR::CIRCLE))
ptd->draw();
}
spherespecial = sphereflipped() ? 1 : -1;
current_display->set_projection(0, true);
if(pmodel == mdRotatedHyperboles) {
for(auto& ptd: ptds)
if(!among(ptd->prio, PPR::MOBILE_ARROW, PPR::OUTCIRCLE, PPR::CIRCLE))
ptd->draw();
glflush();
}
else {
reverse_side_priorities();
for(int i=ptds.size()-1; i>=0; i--)
if(!among(ptds[i]->prio, PPR::MOBILE_ARROW, PPR::OUTCIRCLE, PPR::CIRCLE))
ptds[i]->draw_back();
glflush();
reverse_side_priorities();
}
spherespecial *= -1;
spherephase = 1;
current_display->set_projection(0, true);
}
extern bool lshiftclick, lctrlclick;
void drawqueue() {
callhooks(hook_drawqueue);
@ -1445,48 +1480,44 @@ void drawqueue() {
current_display->set_projection(0, true);
setcameraangle(true);
for(auto& ptd: ptds) if(ptd->prio == PPR::OUTCIRCLE)
ptd->draw();
// on the sphere, parts on the back are drawn first
if(two_sided_model()) {
if(pmodel == mdHyperboloid && hyperbolic) {
dynamicval<eModel> dv (pmodel, mdHyperboloidFlat);
for(auto& ptd: ptds)
if(!among(ptd->prio, PPR::MOBILE_ARROW, PPR::OUTCIRCLE, PPR::CIRCLE))
ptd->draw();
if(sphere && DIM == 3) {
for(int p: {0, 1, 2, 3}) {
if(p == 1 || p == 3) {
#ifdef GL_ES
glClearDepthf(1.0f);
#else
glClearDepth(1.0f);
#endif
glDepthFunc(GL_LEQUAL);
}
else {
#ifdef GL_ES
glClearDepthf(0.0f);
#else
glClearDepth(0.0f);
#endif
glDepthFunc(GL_GEQUAL);
}
glClear(GL_DEPTH_BUFFER_BIT);
glhr::be_nontextured();
spherephase = p;
current_display->set_projection(0, true);
for(auto& ptd: ptds) ptd->draw();
// glflush();
}
spherespecial = sphereflipped() ? 1 : -1;
current_display->set_projection(0, true);
if(pmodel == mdRotatedHyperboles) {
for(auto& ptd: ptds)
if(!among(ptd->prio, PPR::MOBILE_ARROW, PPR::OUTCIRCLE, PPR::CIRCLE))
ptd->draw();
glflush();
}
else {
reverse_side_priorities();
for(int i=ptds.size()-1; i>=0; i--)
if(!among(ptds[i]->prio, PPR::MOBILE_ARROW, PPR::OUTCIRCLE, PPR::CIRCLE))
ptds[i]->draw_back();
glflush();
reverse_side_priorities();
}
spherespecial *= -1;
spherephase = 1;
current_display->set_projection(0, true);
}
else {
for(auto& ptd: ptds) if(ptd->prio == PPR::OUTCIRCLE)
ptd->draw();
if(two_sided_model()) draw_backside();
for(auto& ptd: ptds) if(ptd->prio != PPR::OUTCIRCLE) {
dynamicval<int> ss(spherespecial, among(ptd->prio, PPR::MOBILE_ARROW, PPR::OUTCIRCLE, PPR::CIRCLE) ? 0 : spherespecial);
ptd->draw();
for(auto& ptd: ptds) if(ptd->prio != PPR::OUTCIRCLE) {
dynamicval<int> ss(spherespecial, among(ptd->prio, PPR::MOBILE_ARROW, PPR::OUTCIRCLE, PPR::CIRCLE) ? 0 : spherespecial);
ptd->draw();
}
glflush();
}
glflush();
#if CAP_GL
if(vid.usingGL)

View File

@ -493,7 +493,11 @@ void init() {
bool hp = (sp == shader_projection::halfplane);
bool sh3 = (sp == shader_projection::standardH3);
bool sr3 = (sp == shader_projection::standardR3);
bool ss3 = (sp == shader_projection::standardS3);
bool ss30 = (sp == shader_projection::standardS30);
bool ss31 = (sp == shader_projection::standardS31);
bool ss32 = (sp == shader_projection::standardS32);
bool ss33 = (sp == shader_projection::standardS33);
bool ss3 = ss30 || ss31 || ss32 || ss33;
bool s3 = (sh3 || sr3 || ss3);
@ -561,7 +565,11 @@ void init() {
s3, "vec4 t = uMV * aPosition;",
sh3, "vColor.xyz = vColor.xyz * (1.0 - acosh(t[3]) / uFog);",
sr3, "vColor.xyz = vColor.xyz * (1.0 - sqrt(t[0]*t[0] + t[1]*t[1] + t[2]*t[2]) / 7.);",
ss3, "vColor.xyz = vColor.xyz * (1.0 - acos(t[3]) / 1.6);",
ss30, "vColor.xyz = vColor.xyz * (acos(t[3]) / 6.3); t = -t; ",
ss31, "vColor.xyz = vColor.xyz * (acos(t[3]) / 6.3); t.xyz = -t.xyz; ",
ss32, "vColor.xyz = vColor.xyz * (1.0 - acos(t[3]) / 6.3); t.w = -t.w; ",
ss33, "vColor.xyz = vColor.xyz * (1.0 - acos(t[3]) / 6.3); ",
sh3 || sr3,"t[3] = 1.0;",
band || hp || s3,"gl_Position = uP * t;",