Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions examples/rhombo_scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
int main()
{
// Create a scene
mplot::Visual v(1024, 768, "Cylindrical projection of rhombohedrons");
v.ptype = mplot::perspective_type::cylindrical; // compute cyl. projection for this scene
mplot::Visual v(1024, 768, "Rhombohedrons");
//v.coordArrowsInScene (true);
v.fov = 40;
v.lightingEffects(false);
Expand Down
80 changes: 11 additions & 69 deletions mplot/VisualBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,11 @@ namespace mplot
viewFollowsVMRotations,
};

//! Whether to render with perspective or orthographic (or even a cylindrical projection)
//! Whether to render with perspective or orthographic
enum class perspective_type : uint32_t
{
perspective,
orthographic,
cylindrical
orthographic
};

#ifdef __APPLE__
Expand Down Expand Up @@ -359,25 +358,13 @@ namespace mplot
//! one for graphical objects and a text shader program, which uses textures to draw text on
//! quads.
mplot::visgl::visual_shaderprogs shaders;
//! Which shader is active for graphics shading?
//! Which shader is active for graphics shading. In practice, this is always 'projection2d'
mplot::visgl::graphics_shader_type active_gprog = mplot::visgl::graphics_shader_type::none;
//! Stores the info required to load the 2D projection shader
std::vector<mplot::gl::ShaderInfo> proj2d_shader_progs;
//! Stores the info required to load the text shader
std::vector<mplot::gl::ShaderInfo> text_shader_progs;

//! Stores the info required to load the cylindrical projection shader
std::vector<mplot::gl::ShaderInfo> cyl_shader_progs;
//! Passed to the cyl_shader_progs as a uniform to define the location of the cylindrical
//! projection camera
sm::vec<float, 4> cyl_cam_pos = { 0.0f, 0.0f, 0.0f, 1.0f };
//! Default cylindrical camera position
sm::vec<float, 4> cyl_cam_pos_default = { 0.0f, 0.0f, 0.0f, 1.0f };
//! The radius of the 'cylindrical projection screen' around the camera position
float cyl_radius = 0.005f;
//! The height of the 'cylindrical projection screen'
float cyl_height = 0.01f;

// These static functions will be set as callbacks in each VisualModel object.
static mplot::visgl::visual_shaderprogs get_shaderprogs (mplot::VisualBase<glver>* _v) { return _v->shaders; };
static GLuint get_gprog (mplot::VisualBase<glver>* _v) { return _v->shaders.gprog; };
Expand Down Expand Up @@ -818,16 +805,11 @@ namespace mplot
{
sm::mat<float, 4> sv_tr;
sm::mat<float, 4> sv_rot;
if (this->ptype == perspective_type::orthographic || this->ptype == perspective_type::perspective) {
sv_tr.translate (this->scenetrans_delta);
// A rotation delta in world frame about the 'screen centre'
sv_rot.translate (this->rotation_centre);
sv_rot.rotate (this->rotation_delta);
sv_rot.translate (-this->rotation_centre);
} else {
// Only rotate in cyl view
sv_rot.rotate (this->rotation_delta);
}
sv_tr.translate (this->scenetrans_delta);
// A rotation delta in world frame about the 'screen centre'
sv_rot.translate (this->rotation_centre);
sv_rot.rotate (this->rotation_delta);
sv_rot.translate (-this->rotation_centre);

this->sceneview = sv_tr * sv_rot * this->savedSceneview;
this->sceneview_tr = sv_tr * this->savedSceneview_tr;
Expand Down Expand Up @@ -1044,10 +1026,6 @@ namespace mplot
<< "F1-F10: Select model index (with shift: toggle hide)\n"
<< "Shift-Left: Decrease opacity of selected model\n"
<< "Shift-Right: Increase opacity of selected model\n"
<< "Shift-Up: Double cyl proj radius\n"
<< "Shift-Down: Halve cyl proj radius\n"
<< "Ctrl-Up: Double cyl proj height\n"
<< "Ctrl-Down: Halve cyl proj height\n"
<< std::flush;
}

Expand Down Expand Up @@ -1181,33 +1159,10 @@ namespace mplot
if (!this->vm.empty()) { this->vm[this->selectedVisualModel]->incAlpha(); }
}

// Cyl (and possibly spherical) projection radius
if (_key == key::up && (action == keyaction::press || action == keyaction::repeat) && (mods & keymod::shift)) {
this->cyl_radius *= 2.0f;
std::cout << "cyl_radius is now " << this->cyl_radius << std::endl;
}
if (_key == key::down && (action == keyaction::press || action == keyaction::repeat) && (mods & keymod::shift)) {
this->cyl_radius *= 0.5f;
std::cout << "cyl_radius is now " << this->cyl_radius << std::endl;
}

// Cyl projection view height
if (_key == key::up && (action == keyaction::press || action == keyaction::repeat) && (mods & keymod::control)) {
this->cyl_height *= 2.0f;
std::cout << "cyl_height is now " << this->cyl_height << std::endl;
}
if (_key == key::down && (action == keyaction::press || action == keyaction::repeat) && (mods & keymod::control)) {
this->cyl_height *= 0.5f;
std::cout << "cyl_height is now " << this->cyl_height << std::endl;
}

// Reset view to default
if (this->state.test (visual_state::sceneLocked) == false
&& _key == key::a && (mods & keymod::control) && action == keyaction::press) {
std::cout << "Reset to default view\n";
// Reset translation
this->cyl_cam_pos = this->cyl_cam_pos_default;

this->sceneview.set_identity();
this->sceneview_tr.set_identity();
this->sceneview.translate (this->scenetrans_default);
Expand All @@ -1216,7 +1171,6 @@ namespace mplot
this->scenetrans_delta.zero();
this->rotation_delta.reset();
this->d_to_rotation_centre = -this->scenetrans_default[2];

needs_render = true;
}

Expand Down Expand Up @@ -1274,8 +1228,6 @@ namespace mplot
if (this->ptype == mplot::perspective_type::perspective) {
this->ptype = mplot::perspective_type::orthographic;
} else if (this->ptype == mplot::perspective_type::orthographic) {
this->ptype = mplot::perspective_type::cylindrical;
} else {
this->ptype = mplot::perspective_type::perspective;
}
needs_render = true;
Expand Down Expand Up @@ -1499,14 +1451,10 @@ namespace mplot
mouseMoveWorld[1] = (v1[1] / v1[3]) - (v0[1] / v0[3]);
// Note: mouseMoveWorld[2] is unmodified

// We "translate the whole scene" - used by 2D projection shaders (ignored by cyl shader)
// We "translate the whole scene" - used by 2D projection shaders
this->scenetrans_delta[0] += mouseMoveWorld[0];
this->scenetrans_delta[1] -= mouseMoveWorld[1];

// Also translate our cylindrical camera position (used in cyl shader, ignored in proj. shader)
this->cyl_cam_pos[0] -= mouseMoveWorld[0];
this->cyl_cam_pos[2] += mouseMoveWorld[1];

needs_render = true; // updates viewproj; uses this->scenetrans
}

Expand Down Expand Up @@ -1571,8 +1519,7 @@ namespace mplot
}
}

//! When user scrolls, we translate the scene (applies to orthographic/projection) and the
//! cyl_cam_pos (applies to cylindrical projection).
//! When user scrolls, we translate the scene
virtual bool scroll_callback (double xoffset, double yoffset)
{
// yoffset non-zero indicates that the most common scroll wheel is changing. If there's
Expand All @@ -1595,11 +1542,10 @@ namespace mplot
this->ortho_rt = _rt;
}

} else { // perspective_type::perspective or perspective_type::cylindrical
} else { // perspective_type::perspective

// xoffset does what mouse drag left/right in rotateModMode does (L/R scene trans)
this->scenetrans_delta[0] -= xoffset * this->scenetrans_stepsize;
this->cyl_cam_pos[0] += xoffset * this->scenetrans_stepsize;

// yoffset does the 'in-out zooming'

Expand All @@ -1616,10 +1562,6 @@ namespace mplot
}

this->d_to_rotation_centre -= this->scenetrans_delta[2];

// Translate scroll_move_y then add it to cyl_cam_pos here
sm::mat<float, 4> sceneview_rotn (this->sceneview.linear());
this->cyl_cam_pos += sceneview_rotn * scroll_move_y;
}
return true; // needs_render
}
Expand Down
2 changes: 1 addition & 1 deletion mplot/VisualCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ namespace mplot::visgl
{
none, // Unset/unknown graphics shader type
projection2d, // both orthographic and perspective projections to a 2D surface
cylindrical, // A cylindrical projection
cylindrical, // cylindrical projections. Used to be implemented, but removed for code simplicity
spherical // not implemented, but we could have a spherical projection
};

Expand Down
56 changes: 0 additions & 56 deletions mplot/VisualDefaultShaders.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,60 +163,4 @@ namespace mplot
return shdr;
}

// Cylindrical projection
const char* defaultCylShader = "uniform mat4 m_matrix;\n"
"uniform mat4 v_matrix;\n"
"uniform mat4 p_matrix;\n"
"uniform float alpha;\n"
"uniform float cyl_radius = 0.005;\n"
"uniform float cyl_height = 0.01;\n"
"uniform vec4 cyl_cam_pos = vec4(0);\n"
"layout(location = 0) in vec4 position;\n"
"layout(location = 1) in vec4 normalin;\n"
"layout(location = 2) in vec3 color;\n"
"out VERTEX\n"
"{\n"
" vec4 normal;\n"
" vec4 color;\n"
" vec3 fragpos;\n"
"} vertex;\n"
"void main()\n"
"{\n"
" const float pi = 3.1415927;\n"
" const float two_pi = 6.283185307;\n"
" const float heading_offset = 1.570796327;\n"
" vec4 pv = (v_matrix * m_matrix * position);\n"
" vec4 ray = pv - (v_matrix * cyl_cam_pos);\n"
" vec3 rho_phi_z;\n"
" rho_phi_z[0] = sqrt (ray.x * ray.x + ray.y * ray.y);\n"
" rho_phi_z[1] = atan (ray.y, ray.x) - heading_offset;\n"
" if (rho_phi_z[1] > pi) { rho_phi_z[1] = rho_phi_z[1] - two_pi; }\n"
" if (rho_phi_z[1] < -pi) { rho_phi_z[1] = rho_phi_z[1] + two_pi; }\n"
" rho_phi_z[2] = ray.z;\n"
" float x_s = -rho_phi_z[1] / pi;\n"
" float y_s = 0.0;\n"
" if (x_s != 0.0) {\n"
" float theta = asin (rho_phi_z[2] / rho_phi_z[0]);\n"
" y_s = (cyl_radius * tan (theta)) / cyl_height;\n"
" gl_PointSize = 1;\n"
" gl_Position = vec4(x_s, y_s, -1.0, 1.0);\n"
" vertex.color = vec4(color, alpha);\n"
" vertex.fragpos = vec3(m_matrix * position);\n"
" vertex.normal = normalin;\n"
" } else {\n"
" gl_Position = vec4(0.0, 0.0, -100.0, 1.0);\n"
" vertex.color = vec4(color, 0.0);\n"
" vertex.fragpos = vec3(m_matrix * position);\n"
" vertex.normal = normalin;\n"
" }\n"
"}\n";

std::string getDefaultCylVtxShader (const int glver)
{
std::string shdr;
shdr += mplot::gl::version::shaderpreamble (glver);
shdr += defaultCylShader;
return shdr;
}

} // namespace mplot
22 changes: 1 addition & 21 deletions mplot/VisualOwnableMX.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,13 +175,7 @@ namespace mplot
this->shaders.gprog = mplot::gl::LoadShadersMX (this->proj2d_shader_progs, this->glfn);
this->active_gprog = mplot::visgl::graphics_shader_type::projection2d;
}
} else if (this->ptype == perspective_type::cylindrical) {
if (this->active_gprog != mplot::visgl::graphics_shader_type::cylindrical) {
if (this->shaders.gprog) { this->glfn->DeleteProgram (this->shaders.gprog); }
this->shaders.gprog = mplot::gl::LoadShadersMX (this->cyl_shader_progs, this->glfn);
this->active_gprog = mplot::visgl::graphics_shader_type::cylindrical;
}
}
} // else do nothing (all current shaders are 2D perspective)

this->glfn->UseProgram (this->shaders.gprog);
this->glfn->Viewport (0, 0, this->window_w * mplot::retinaScale, this->window_h * mplot::retinaScale);
Expand All @@ -191,14 +185,6 @@ namespace mplot
this->setOrthographic();
} else if (this->ptype == perspective_type::perspective) {
this->setPerspective();
} else if (this->ptype == perspective_type::cylindrical) {
// Set cylindrical-specific uniforms
GLint loc_campos = this->glfn->GetUniformLocation (this->shaders.gprog, static_cast<const GLchar*>("cyl_cam_pos"));
if (loc_campos != -1) { this->glfn->Uniform4fv (loc_campos, 1, this->cyl_cam_pos.data()); }
GLint loc_cyl_radius = this->glfn->GetUniformLocation (this->shaders.gprog, static_cast<const GLchar*>("cyl_radius"));
if (loc_cyl_radius != -1) { this->glfn->Uniform1f (loc_cyl_radius, this->cyl_radius); }
GLint loc_cyl_height = this->glfn->GetUniformLocation (this->shaders.gprog, static_cast<const GLchar*>("cyl_height"));
if (loc_cyl_height != -1) { this->glfn->Uniform1f (loc_cyl_height, this->cyl_height); }
} else {
// unknown projection
return;
Expand Down Expand Up @@ -445,12 +431,6 @@ namespace mplot
this->shaders.gprog = mplot::gl::LoadShadersMX (this->proj2d_shader_progs, this->glfn);
this->active_gprog = mplot::visgl::graphics_shader_type::projection2d;

// Alternative cylindrical shader for possible later use. (NB: not loaded immediately)
this->cyl_shader_progs = {
{GL_VERTEX_SHADER, "VisCyl.vert.glsl", mplot::getDefaultCylVtxShader(glver), 0 },
{GL_FRAGMENT_SHADER, "Visual.frag.glsl", mplot::getDefaultFragShader(glver), 0 }
};

// A specific text shader is loaded for text rendering
this->text_shader_progs = {
{GL_VERTEX_SHADER, "VisText.vert.glsl", mplot::getDefaultTextVtxShader(glver), 0 },
Expand Down
22 changes: 1 addition & 21 deletions mplot/VisualOwnableNoMX.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,13 +169,7 @@ namespace mplot
this->shaders.gprog = mplot::gl::LoadShaders (this->proj2d_shader_progs);
this->active_gprog = mplot::visgl::graphics_shader_type::projection2d;
}
} else if (this->ptype == perspective_type::cylindrical) {
if (this->active_gprog != mplot::visgl::graphics_shader_type::cylindrical) {
if (this->shaders.gprog) { glDeleteProgram (this->shaders.gprog); }
this->shaders.gprog = mplot::gl::LoadShaders (this->cyl_shader_progs);
this->active_gprog = mplot::visgl::graphics_shader_type::cylindrical;
}
}
} // else do nothing (all current shaders are 2D perspective)

glUseProgram (this->shaders.gprog);
glViewport (0, 0, this->window_w * mplot::retinaScale, this->window_h * mplot::retinaScale);
Expand All @@ -185,14 +179,6 @@ namespace mplot
this->setOrthographic();
} else if (this->ptype == perspective_type::perspective) {
this->setPerspective();
} else if (this->ptype == perspective_type::cylindrical) {
// Set cylindrical-specific uniforms
GLint loc_campos = glGetUniformLocation (this->shaders.gprog, static_cast<const GLchar*>("cyl_cam_pos"));
if (loc_campos != -1) { glUniform4fv (loc_campos, 1, this->cyl_cam_pos.data()); }
GLint loc_cyl_radius = glGetUniformLocation (this->shaders.gprog, static_cast<const GLchar*>("cyl_radius"));
if (loc_cyl_radius != -1) { glUniform1f (loc_cyl_radius, this->cyl_radius); }
GLint loc_cyl_height = glGetUniformLocation (this->shaders.gprog, static_cast<const GLchar*>("cyl_height"));
if (loc_cyl_height != -1) { glUniform1f (loc_cyl_height, this->cyl_height); }
} else {
// unknown projection
return;
Expand Down Expand Up @@ -397,12 +383,6 @@ namespace mplot
this->shaders.gprog = mplot::gl::LoadShaders (this->proj2d_shader_progs);
this->active_gprog = mplot::visgl::graphics_shader_type::projection2d;

// Alternative cylindrical shader for possible later use. (NB: not loaded immediately)
this->cyl_shader_progs = {
{GL_VERTEX_SHADER, "VisCyl.vert.glsl", mplot::getDefaultCylVtxShader(glver), 0 },
{GL_FRAGMENT_SHADER, "Visual.frag.glsl", mplot::getDefaultFragShader(glver), 0 }
};

// A specific text shader is loaded for text rendering
this->text_shader_progs = {
{GL_VERTEX_SHADER, "VisText.vert.glsl", mplot::getDefaultTextVtxShader(glver), 0 },
Expand Down