diff --git a/Common/Common.h b/Common/Common.h index 425f0233..e1eae7c5 100644 --- a/Common/Common.h +++ b/Common/Common.h @@ -36,10 +36,14 @@ using Matrix2r = Eigen::Matrix; using Matrix3r = Eigen::Matrix; using Matrix4r = Eigen::Matrix; using Vector2i = Eigen::Matrix; +using Vector3f = Eigen::Matrix; +using Matrix4f = Eigen::Matrix; using AlignedBox2r = Eigen::AlignedBox; using AlignedBox3r = Eigen::AlignedBox; using AngleAxisr = Eigen::AngleAxis; using Quaternionr = Eigen::Quaternion; +using VectorXr = Eigen::Matrix; +using VectorXf = Eigen::Matrix; #if defined(WIN32) || defined(_WIN32) || defined(WIN64) // Enable memory leak detection diff --git a/Demos/Common/DemoBase.cpp b/Demos/Common/DemoBase.cpp index 162cdf7c..f5f5fb1e 100644 --- a/Demos/Common/DemoBase.cpp +++ b/Demos/Common/DemoBase.cpp @@ -217,8 +217,7 @@ void DemoBase::init(int argc, char **argv, const char *demoName) MiniGL::setViewport(40.0, 0.1f, 500.0, Vector3r(0.0, 3.0, 8.0), Vector3r(0.0, 0.0, 0.0)); MiniGL::setSelectionFunc(selection, this); - if (MiniGL::checkOpenGLVersion(3, 3)) - initShaders(); + initShaders(); m_gui->initImgui(); } @@ -237,6 +236,8 @@ void DemoBase::readScene() void DemoBase::initShaders() { + MiniGL::initShaders(m_exePath + "/resources/shaders"); + std::string vertFile = m_exePath + "/resources/shaders/vs_smooth.glsl"; std::string fragFile = m_exePath + "/resources/shaders/fs_smooth.glsl"; m_shader.compileShaderFile(GL_VERTEX_SHADER, vertFile); @@ -279,6 +280,13 @@ void DemoBase::initShaders() m_shaderFlat.end(); } +void DemoBase::destroyShaders() +{ + m_shader.destroy(); + m_shaderTex.destroy(); + m_shaderFlat.destroy(); + MiniGL::destroyShaders(); +} void DemoBase::shaderTexBegin(const float *col) { @@ -286,12 +294,10 @@ void DemoBase::shaderTexBegin(const float *col) glUniform1f(m_shaderTex.getUniform("shininess"), 5.0f); glUniform1f(m_shaderTex.getUniform("specular_factor"), 0.2f); - GLfloat matrix[16]; - glGetFloatv(GL_MODELVIEW_MATRIX, matrix); - glUniformMatrix4fv(m_shaderTex.getUniform("modelview_matrix"), 1, GL_FALSE, matrix); - GLfloat pmatrix[16]; - glGetFloatv(GL_PROJECTION_MATRIX, pmatrix); - glUniformMatrix4fv(m_shaderTex.getUniform("projection_matrix"), 1, GL_FALSE, pmatrix); + const Matrix4f matrix(MiniGL::getModelviewMatrix().cast()); + glUniformMatrix4fv(m_shaderTex.getUniform("modelview_matrix"), 1, GL_FALSE, &matrix(0,0)); + const Matrix4f pmatrix(MiniGL::getProjectionMatrix().cast()); + glUniformMatrix4fv(m_shaderTex.getUniform("projection_matrix"), 1, GL_FALSE, &pmatrix(0,0)); glUniform3fv(m_shaderTex.getUniform("surface_color"), 1, col); } @@ -306,12 +312,10 @@ void DemoBase::shaderBegin(const float *col) glUniform1f(m_shader.getUniform("shininess"), 5.0f); glUniform1f(m_shader.getUniform("specular_factor"), 0.2f); - GLfloat matrix[16]; - glGetFloatv(GL_MODELVIEW_MATRIX, matrix); - glUniformMatrix4fv(m_shader.getUniform("modelview_matrix"), 1, GL_FALSE, matrix); - GLfloat pmatrix[16]; - glGetFloatv(GL_PROJECTION_MATRIX, pmatrix); - glUniformMatrix4fv(m_shader.getUniform("projection_matrix"), 1, GL_FALSE, pmatrix); + const Matrix4f matrix(MiniGL::getModelviewMatrix().cast()); + glUniformMatrix4fv(m_shader.getUniform("modelview_matrix"), 1, GL_FALSE, &matrix(0,0)); + const Matrix4f pmatrix(MiniGL::getProjectionMatrix().cast()); + glUniformMatrix4fv(m_shader.getUniform("projection_matrix"), 1, GL_FALSE, &pmatrix(0,0)); glUniform3fv(m_shader.getUniform("surface_color"), 1, col); } @@ -326,12 +330,10 @@ void DemoBase::shaderFlatBegin(const float* col) glUniform1f(m_shaderFlat.getUniform("shininess"), 5.0f); glUniform1f(m_shaderFlat.getUniform("specular_factor"), 0.2f); - GLfloat matrix[16]; - glGetFloatv(GL_MODELVIEW_MATRIX, matrix); - glUniformMatrix4fv(m_shaderFlat.getUniform("modelview_matrix"), 1, GL_FALSE, matrix); - GLfloat pmatrix[16]; - glGetFloatv(GL_PROJECTION_MATRIX, pmatrix); - glUniformMatrix4fv(m_shaderFlat.getUniform("projection_matrix"), 1, GL_FALSE, pmatrix); + const Matrix4f matrix(MiniGL::getModelviewMatrix().cast()); + glUniformMatrix4fv(m_shaderFlat.getUniform("modelview_matrix"), 1, GL_FALSE, &matrix(0,0)); + const Matrix4f pmatrix(MiniGL::getProjectionMatrix().cast()); + glUniformMatrix4fv(m_shaderFlat.getUniform("projection_matrix"), 1, GL_FALSE, &pmatrix(0,0)); glUniform3fv(m_shaderFlat.getUniform("surface_color"), 1, col); } @@ -652,15 +654,14 @@ void DemoBase::renderTetModels() void DemoBase::renderAABB(AABB &aabb) { + float color[4] = { 0.5f, 0.5f, 0.5f, 0.3f }; + Vector3r p1, p2; - glBegin(GL_LINES); for (unsigned char i = 0; i < 12; i++) { AABB::getEdge(aabb, i, p1, p2); - glVertex3d(p1[0], p1[1], p1[2]); - glVertex3d(p2[0], p2[1], p2[2]); + MiniGL::drawVector(p1, p2, 1.0f, color); } - glEnd(); } void DemoBase::renderSDF(CollisionDetection::CollisionObject* co) diff --git a/Demos/Common/DemoBase.h b/Demos/Common/DemoBase.h index f9ae14ce..389817d6 100644 --- a/Demos/Common/DemoBase.h +++ b/Demos/Common/DemoBase.h @@ -122,6 +122,7 @@ namespace PBD Shader& getShader() { return m_shader; } Shader& getShaderTex() { return m_shaderTex; } Shader& getShaderFlat() { return m_shaderFlat; } + void destroyShaders(); void shaderTexBegin(const float *col); void shaderTexEnd(); void shaderBegin(const float *col); diff --git a/Demos/Common/Simulator_GUI_imgui.cpp b/Demos/Common/Simulator_GUI_imgui.cpp index 1680a32e..c6db7326 100644 --- a/Demos/Common/Simulator_GUI_imgui.cpp +++ b/Demos/Common/Simulator_GUI_imgui.cpp @@ -410,6 +410,7 @@ void Simulator_GUI_imgui::destroy() ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplGlfw_Shutdown(); ImGui::DestroyContext(); + m_base->destroyShaders(); } void Simulator_GUI_imgui::switchPause() diff --git a/Demos/FluidDemo/main.cpp b/Demos/FluidDemo/main.cpp index 21aed274..fc328ff3 100644 --- a/Demos/FluidDemo/main.cpp +++ b/Demos/FluidDemo/main.cpp @@ -34,9 +34,6 @@ void render (); void cleanup(); void reset(); void selection(const Vector2i &start, const Vector2i &end, void *clientData); -void createSphereBuffers(Real radius, int resolution); -void renderSphere(const Vector3r &x, const float color[]); -void releaseSphereBuffers(); FluidModel model; @@ -53,12 +50,6 @@ const Real containerHeight = 4.0; bool doPause = true; std::vector selectedParticles; Vector3r oldMousePos; -// initiate buffers -GLuint elementbuffer; -GLuint normalbuffer; -GLuint vertexbuffer; -int vertexBufferSize = 0; -GLint context_major_version, context_minor_version; string exePath; string dataPath; @@ -102,10 +93,6 @@ int main( int argc, char **argv ) param->setFct = [&](Real v) -> void { model.setViscosity(v); }; imguiParameters::addParam("Simulation", "PBD", param); - MiniGL::getOpenGLVersion(context_major_version, context_minor_version); - if (context_major_version >= 3) - createSphereBuffers((Real)particleRadius, 8); - MiniGL::mainLoop(); cleanup (); @@ -122,8 +109,6 @@ int main( int argc, char **argv ) void cleanup() { delete TimeManager::getCurrent(); - if (context_major_version >= 3) - releaseSphereBuffers(); } void reset() @@ -202,64 +187,23 @@ void render () const ParticleData &pd = model.getParticles(); const unsigned int nParticles = pd.size(); - float surfaceColor[4] = { 0.2f, 0.6f, 0.8f, 1 }; - float speccolor[4] = { 1.0, 1.0, 1.0, 1.0 }; - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, surfaceColor); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, surfaceColor); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, speccolor); - glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 100.0); - glColor3fv(surfaceColor); - - glPointSize(4.0); - const Real supportRadius = model.getSupportRadius(); Real vmax = static_cast(0.4*2.0)*supportRadius / TimeManager::getCurrent()->getTimeStepSize(); Real vmin = 0.0; - if (context_major_version > 3) - { - for (unsigned int i = 0; i < nParticles; i++) - { - Real v = pd.getVelocity(i).norm(); - v = static_cast(0.5)*((v - vmin) / (vmax - vmin)); - v = min(static_cast(128.0)*v*v, static_cast(0.5)); - float fluidColor[4] = { 0.2f, 0.2f, 0.2f, 1.0 }; - MiniGL::hsvToRgb(0.55f, 1.0f, 0.5f + (float)v, fluidColor); - renderSphere(pd.getPosition(i), fluidColor); - } - -// for (unsigned int i = 0; i < model.numBoundaryParticles(); i++) -// renderSphere(model.getBoundaryX(i), surfaceColor); - } - else + for (unsigned int i = 0; i < nParticles; i++) { - glDisable(GL_LIGHTING); - glBegin(GL_POINTS); - for (unsigned int i = 0; i < nParticles; i++) - { - Real v = pd.getVelocity(i).norm(); - v = static_cast(0.5)*((v - vmin) / (vmax - vmin)); - v = min(static_cast(128.0)*v*v, static_cast(0.5)); - float fluidColor[4] = { 0.2f, 0.2f, 0.2f, 1.0 }; - MiniGL::hsvToRgb(0.55f, 1.0f, 0.5f + (float)v, fluidColor); - - glColor3fv(fluidColor); - glVertex3v(&pd.getPosition(i)[0]); - } - glEnd(); - - // glBegin(GL_POINTS); - // for (unsigned int i = 0; i < model.numBoundaryParticles(); i++) - // { - // glColor3fv(surfaceColor); - // glVertex3fv(&model.getBoundaryX(i)[0]); - // } - // glEnd(); - - glEnable(GL_LIGHTING); + Real v = pd.getVelocity(i).norm(); + v = static_cast(0.5)*((v - vmin) / (vmax - vmin)); + v = min(static_cast(128.0)*v*v, static_cast(0.5)); + float fluidColor[4] = { 0.2f, 0.2f, 0.2f, 1.0 }; + MiniGL::hsvToRgb(0.55f, 1.0f, 0.5f + (float)v, fluidColor); + MiniGL::drawSphere(pd.getPosition(i), particleRadius, fluidColor, 8); } - +// float surfaceColor[4] = { 0.2f, 0.6f, 0.8f, 1 }; +// for (unsigned int i = 0; i < model.numBoundaryParticles(); i++) +// MiniGL::drawSphere(model.getBoundaryX(i), particleRadius, surfaceColor, 8); float red[4] = { 0.8f, 0.0f, 0.0f, 1 }; for (unsigned int j = 0; j < selectedParticles.size(); j++) @@ -365,141 +309,3 @@ void initBoundaryData(std::vector &boundaryParticles) // Front addWall(Vector3r(x1, y1, z2), Vector3r(x2, y2, z2), boundaryParticles); } - - -void createSphereBuffers(Real radius, int resolution) -{ - Real PI = static_cast(M_PI); - // vectors to hold our data - // vertice positions - std::vector v; - // normals - std::vector n; - std::vector indices; - - // initiate the variable we are going to use - Real X1, Y1, X2, Y2, Z1, Z2; - Real inc1, inc2, inc3, inc4, radius1, radius2; - - for (int w = 0; w < resolution; w++) - { - for (int h = (-resolution / 2); h < (resolution / 2); h++) - { - inc1 = (w / (Real)resolution) * 2 * PI; - inc2 = ((w + 1) / (Real)resolution) * 2 * PI; - inc3 = (h / (Real)resolution)*PI; - inc4 = ((h + 1) / (Real)resolution)*PI; - - X1 = sin(inc1); - Y1 = cos(inc1); - X2 = sin(inc2); - Y2 = cos(inc2); - - // store the upper and lower radius, remember everything is going to be drawn as triangles - radius1 = radius*cos(inc3); - radius2 = radius*cos(inc4); - - Z1 = radius*sin(inc3); - Z2 = radius*sin(inc4); - - // insert the triangle coordinates - v.push_back(Vector3r(radius1*X1, Z1, radius1*Y1)); - v.push_back(Vector3r(radius1*X2, Z1, radius1*Y2)); - v.push_back(Vector3r(radius2*X2, Z2, radius2*Y2)); - - indices.push_back((unsigned short)v.size() - 3); - indices.push_back((unsigned short)v.size() - 2); - indices.push_back((unsigned short)v.size() - 1); - - v.push_back(Vector3r(radius1*X1, Z1, radius1*Y1)); - v.push_back(Vector3r(radius2*X2, Z2, radius2*Y2)); - v.push_back(Vector3r(radius2*X1, Z2, radius2*Y1)); - - indices.push_back((unsigned short)v.size() - 3); - indices.push_back((unsigned short)v.size() - 2); - indices.push_back((unsigned short)v.size() - 1); - - // insert the normal data - n.push_back(Vector3r(X1, Z1, Y1)); - n.push_back(Vector3r(X2, Z1, Y2)); - n.push_back(Vector3r(X2, Z2, Y2)); - n.push_back(Vector3r(X1, Z1, Y1)); - n.push_back(Vector3r(X2, Z2, Y2)); - n.push_back(Vector3r(X1, Z2, Y1)); - } - } - - for (unsigned int i = 0; i < n.size(); i++) - n[i].normalize(); - - - glGenBuffers(1, &vertexbuffer); - glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); - glBufferData(GL_ARRAY_BUFFER, v.size() * sizeof(Vector3r), &v[0], GL_STATIC_DRAW); - - glGenBuffers(1, &normalbuffer); - glBindBuffer(GL_ARRAY_BUFFER, normalbuffer); - glBufferData(GL_ARRAY_BUFFER, n.size() * sizeof(Vector3r), &n[0], GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); - - // Generate a buffer for the indices as well - glGenBuffers(1, &elementbuffer); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned short), &indices[0], GL_STATIC_DRAW); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - - // store the number of indices for later use - vertexBufferSize = (unsigned int)indices.size(); - - // clean up after us - indices.clear(); - n.clear(); - v.clear(); -} - -void renderSphere(const Vector3r &x, const float color[]) -{ - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color); - - - glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); - glVertexPointer(3, GL_REAL, 0, 0); - - glBindBuffer(GL_ARRAY_BUFFER, normalbuffer); - glNormalPointer(GL_REAL, 0, 0); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer); - - glPushMatrix(); - glTranslated(x[0], x[1], x[2]); - glDrawElements(GL_TRIANGLES, (GLsizei)vertexBufferSize, GL_UNSIGNED_SHORT, 0); - glPopMatrix(); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); -} - -void releaseSphereBuffers() -{ - if (elementbuffer != 0) - { - glDeleteBuffers(1, &elementbuffer); - elementbuffer = 0; - } - if (normalbuffer != 0) - { - glDeleteBuffers(1, &normalbuffer); - normalbuffer = 0; - } - if (vertexbuffer != 0) - { - glDeleteBuffers(1, &vertexbuffer); - vertexbuffer = 0; - } -} diff --git a/Demos/Visualization/MiniGL.cpp b/Demos/Visualization/MiniGL.cpp index 46b7ac6e..add0e1dd 100644 --- a/Demos/Visualization/MiniGL.cpp +++ b/Demos/Visualization/MiniGL.cpp @@ -13,10 +13,8 @@ #ifdef __APPLE__ #include -#include #else #include "GL/gl.h" -#include "GL/glu.h" #endif #define _USE_MATH_DEFINES @@ -36,6 +34,9 @@ MiniGL::DestroyFct MiniGL::destroyfunc = nullptr; void (*MiniGL::exitfunc)(void) = NULL; int MiniGL::m_width = 0; int MiniGL::m_height = 0; +int MiniGL::m_windowWidth = 0; +int MiniGL::m_windowHeight = 0; +Real MiniGL::m_devicePixelRatio = 1.0; Quaternionr MiniGL::m_rotation; Real MiniGL::m_zoom = 1.0; Vector3r MiniGL::m_translation; @@ -60,7 +61,6 @@ GLint MiniGL::m_context_minor_version = 0; GLint MiniGL::m_context_profile = 0; bool MiniGL::m_breakPointActive = true; bool MiniGL::m_breakPointLoop = false; -GLUquadricObj* MiniGL::m_sphereQuadric = nullptr; std::vector MiniGL::m_reshapeFct; std::vector MiniGL::m_keyboardFct; std::vector MiniGL::m_charFct; @@ -73,6 +73,20 @@ std::vector MiniGL::m_drawLines; std::vector MiniGL::m_drawPoints; bool MiniGL::m_vsync = false; double MiniGL::m_lastTime; +Shader MiniGL::m_shader; +Shader MiniGL::m_shader_screen; +Matrix4r MiniGL::m_modelview_matrix; +Matrix4r MiniGL::m_projection_matrix; +Vector3f MiniGL::m_ambientIntensity; +unsigned int MiniGL::m_numLights = 0; +VectorXf MiniGL::m_diffuseIntensity; +VectorXf MiniGL::m_specularIntensity; +VectorXf MiniGL::m_lightPosition; +GLuint MiniGL::m_vao = 0; +GLuint MiniGL::m_vbo_vertices = 0; +GLuint MiniGL::m_vbo_normals = 0; +GLuint MiniGL::m_vbo_texcoords = 0; +GLuint MiniGL::m_vbo_faces = 0; void MiniGL::bindTexture() @@ -93,222 +107,207 @@ void MiniGL::getOpenGLVersion(int &major_version, int &minor_version) void MiniGL::coordinateSystem() { - Eigen::Vector3f a(0,0,0); - Eigen::Vector3f b(2,0,0); - Eigen::Vector3f c(0,2,0); - Eigen::Vector3f d(0,0,2); - - float diffcolor [4] = {1,0,0,1}; - float speccolor [4] = {1,1,1,1}; - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, diffcolor); - glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, diffcolor); - glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, speccolor); - glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 100.0); - glLineWidth (2); - - glBegin (GL_LINES); - glVertex3fv (&a[0]); - glVertex3fv (&b[0]); - glEnd (); - - float diffcolor2[4] = { 0, 1, 0, 1 }; - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, diffcolor2); - glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, diffcolor2); - - glBegin (GL_LINES); - glVertex3fv (&a[0]); - glVertex3fv (&c[0]); - glEnd (); - - float diffcolor3[4] = { 0, 0, 1, 1 }; - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, diffcolor3); - glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, diffcolor3); - - glBegin (GL_LINES); - glVertex3fv (&a[0]); - glVertex3fv (&d[0]); - glEnd (); - glLineWidth (1); + Vector3r a(0,0,0); + Vector3r b(2,0,0); + Vector3r c(0,2,0); + Vector3r d(0,0,2); + float lineWidth = 3.0; + Vector3f color; + + color << 1,0,0; + drawVector(a, b, lineWidth, &color(0)); + color << 0,1,0; + drawVector(a, c, lineWidth, &color(0)); + color << 0,0,1; + drawVector(a, d, lineWidth, &color(0)); } void MiniGL::drawVector(const Vector3r &a, const Vector3r &b, const float w, float *color) { - float speccolor [4] = {1.0, 1.0, 1.0, 1.0}; - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, color); - glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, color); - glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, speccolor); - glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 100.0); - glColor3fv(color); + float thickness = 0.005f * w; - glLineWidth (w); + // Draw a thick line as a cylinder with constant color. + drawCylinder(a, b, color, thickness, 32, false); +} - glBegin (GL_LINES); - glVertex3v(&a[0]); - glVertex3v(&b[0]); - glEnd (); - - glLineWidth (1); -} - -void MiniGL::drawCylinder(const Vector3r &a, const Vector3r &b, const float *color, const float radius, const unsigned int subdivisions) -{ - float speccolor[4] = { 1.0, 1.0, 1.0, 1.0 }; - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, speccolor); - glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 100.0); - glColor3fv(color); - - Real vx = (b.x() - a.x()); - Real vy = (b.y() - a.y()); - Real vz = (b.z() - a.z()); - //handle the degenerate case with an approximation - if (vz == 0) - vz = .00000001; - Real v = sqrt(vx*vx + vy*vy + vz*vz); - Real ax = static_cast(57.2957795)*acos(vz / v); - if (vz < 0.0) - ax = -ax; - Real rx = -vy*vz; - Real ry = vx*vz; - - GLUquadricObj *quadric = gluNewQuadric(); - gluQuadricNormals(quadric, GLU_SMOOTH); - - glPushMatrix(); - glTranslatef((float)a.x(), (float)a.y(), (float)a.z()); - glRotatef((float)ax, (float)rx, (float)ry, 0.0f); - //draw the cylinder - gluCylinder(quadric, radius, radius, v, subdivisions, 1); - gluQuadricOrientation(quadric, GLU_INSIDE); - //draw the first cap - gluDisk(quadric, 0.0, radius, subdivisions, 1); - glTranslatef(0, 0, (float)v); - //draw the second cap - gluQuadricOrientation(quadric, GLU_OUTSIDE); - gluDisk(quadric, 0.0, radius, subdivisions, 1); - glPopMatrix(); - - gluDeleteQuadric(quadric); +void MiniGL::drawCylinder(const Vector3r &a, const Vector3r &b, const float *color, const float radius, const unsigned int subdivisions, const bool lighting) +{ + Vector3f diffcolor(color); + Vector3f speccolor(1.0, 1.0, 1.0); + + // To simplify computations, the cylinder of height v is generated + // along the z axis from z=0 to z=v and then transformed to the axis ab. + Vector3r ab = b - a; + Real v = ab.norm(); + Eigen::Transform transform = + Eigen::Translation(a) * + Quaternionr::FromTwoVectors(Vector3r(0.0, 0.0, v), ab); + Vector3r xMid = transform * Vector3r(0.0, 0.0, 0.5 * v); + + // Both the lateral surface and the base disks are subdivided into n slices (cf. gluCylinder & gluDisk). + // For this purpose, the base circle is parametrized as a function of the angle theta. + // The lateral slices are again subdivided into two triangles each for rendering. + // Smooth normals are obtained by going outward from the midpoint. + unsigned int n = subdivisions; + VectorXr vertices((n+1) * 2 * 3); + VectorXr normals((n+1) * 2 * 3); + std::vector faces; + unsigned int iMidBottom = 2 * n; + unsigned int iMidTop = 2 * n + 1; + for (unsigned int i = 0; i < n; i++) + { + Real theta = (Real)i / (Real)n * 2.0 * M_PI; + Vector3r x(radius * cos(theta), radius * sin(theta), 0.0); + Vector3r xBottom = transform * x; + x(2) = v; + Vector3r xTop = transform * x; + vertices.segment<3>(2 * 3 * i) = xBottom; + vertices.segment<3>(2 * 3 * i + 3) = xTop; + normals.segment<3>(2 * 3 * i) = (xBottom - xMid).normalized(); + normals.segment<3>(2 * 3 * i + 3) = (xTop - xMid).normalized(); + + // [TESSELLATION] + // iMidTop + // / \ + // iTop ---- iNextTop + // | \ | + // | \ | + // iBottom - iNextBottom + // \ / + // iMidBottom + unsigned int iBottom = 2 * i; + unsigned int iTop = 2 * i + 1; + unsigned int iNextBottom = (2 * (i+1)) % (2 * n); + unsigned int iNextTop = (2 * (i+1) + 1) % (2 * n); + faces.insert(faces.end(), {iTop, iNextTop, iMidTop}); + faces.insert(faces.end(), {iBottom, iNextBottom, iTop}); + faces.insert(faces.end(), {iTop, iNextBottom, iNextTop}); + faces.insert(faces.end(), {iBottom, iMidBottom, iNextBottom}); + } + Vector3r xMidBottom = transform * Vector3r(0.0, 0.0, 0.0); + Vector3r xMidTop = transform * Vector3r(0.0, 0.0, v); + vertices.segment<3>(3 * iMidBottom) = xMidBottom; + vertices.segment<3>(3 * iMidTop) = xMidTop; + normals.segment<3>(3 * iMidBottom) = (xMidBottom - xMid).normalized(); + normals.segment<3>(3 * iMidTop) = (xMidTop - xMid).normalized(); + + enableShader(diffcolor, diffcolor, speccolor, 100.0); + if (!lighting) glUniform1i(m_shader.getUniform("lighting"), GL_FALSE); + supplyVertices(0, (n+1) * 2, &vertices(0)); + supplyNormals(1, (n+1) * 2, &normals(0)); + supplyFaces(faces.size(), &faces[0]); + glDrawElements(GL_TRIANGLES, faces.size(), GL_UNSIGNED_INT, (void*)0); + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); + disableShader(); } void MiniGL::drawSphere(const Vector3r &translation, float radius, float *color, const unsigned int subDivision) { - float speccolor [4] = {1.0, 1.0, 1.0, 1.0}; - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, color); - glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, color); - glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, speccolor); - glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 100.0); - glColor3fv(color); - - if (m_sphereQuadric == nullptr) + Vector3f diffcolor(color); + Vector3f speccolor(1.0, 1.0, 1.0); + + // The surface of the sphere is subdivided into n slices and stacks (cf. gluSphere). + // For this purpose, it is parametrized as a function of the longitude theta and the colatitude phi. + // The slices and stacks are again subdivided into two triangles each for rendering. + // Smooth normals are obtained by going outward from the midpoint. + unsigned int n = subDivision; + VectorXr vertices((n+1) * n * 3); + VectorXr normals((n+1) * n * 3); + std::vector faces; + for (unsigned int i = 0; i <= n; i++) { - m_sphereQuadric = gluNewQuadric(); - gluQuadricNormals(m_sphereQuadric, GLU_SMOOTH); - } + Real phi = (Real)i / (Real)n * M_PI; + Real xy = radius * sin(phi); + Vector3r x(xy, xy, radius * cos(phi)); + for (unsigned int j = 0; j < n; j++) + { + Real theta = (Real)j / (Real)n * 2.0 * M_PI; + x(0) = xy * cos(theta); + x(1) = xy * sin(theta); + vertices.segment<3>(n * 3 * i + 3 * j) = x + translation; + normals.segment<3>(n * 3 * i + 3 * j) = x.normalized(); - glPushMatrix (); - glTranslated ((translation)[0], (translation)[1], (translation)[2]); + if (i < n) + { + // [TESSELATION] + // iTop ---- iNextTop + // | \ | + // | \ | + // iBottom - iNextBottom + unsigned int iBottom = n * i + j; + unsigned int iTop = n * (i+1) + j; + unsigned int iNextBottom = n * i + ((j+1) % n); + unsigned int iNextTop = n * (i+1) + ((j+1) % n); + faces.insert(faces.end(), {iBottom, iNextBottom, iTop}); + faces.insert(faces.end(), {iTop, iNextBottom, iNextTop}); + } + } + } - gluSphere(m_sphereQuadric, radius, subDivision, subDivision); - glPopMatrix(); + enableShader(diffcolor, diffcolor, speccolor, 100.0); + supplyVertices(0, (n+1) * n, &vertices(0)); + supplyNormals(1, (n+1) * n, &normals(0)); + supplyFaces(faces.size(), &faces[0]); + glDrawElements(GL_TRIANGLES, faces.size(), GL_UNSIGNED_INT, (void*)0); + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); + disableShader(); } void MiniGL::drawPoint(const Vector3r &translation, const float pointSize, const float * const color) { - float speccolor [4] = {1.0, 1.0, 1.0, 1.0}; - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, color); - glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, color); - glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, speccolor); - glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 100.0); - glColor3fv(color); - - glPointSize(pointSize); - - glBegin (GL_POINTS); - glVertex3v(&translation[0]); - glEnd (); - - glPointSize(1); + Vector3f diffcolor(color); + Vector3f speccolor(1.0, 1.0, 1.0); + + enableShader(diffcolor, diffcolor, speccolor, 100.0, pointSize); + supplyVertices(0, 1, &translation(0)); + glDrawArrays(GL_POINTS, 0, 1); + glDisableVertexAttribArray(0); + disableShader(); } void MiniGL::drawMesh(const std::vector &vertices, const std::vector &faces, const std::vector &vertexNormals, const float * const color) { // draw mesh - if (MiniGL::checkOpenGLVersion(3, 3)) + supplyVertices(0, vertices.size(), &vertices[0][0]); + if (vertexNormals.size() > 0) { - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_REAL, GL_FALSE, 0, &vertices[0][0]); - if (vertexNormals.size() > 0) - { - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 3, GL_REAL, GL_FALSE, 0, &vertexNormals[0][0]); - } - } - else - { - float speccolor[4] = { 1.0, 1.0, 1.0, 1.0 }; - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, speccolor); - glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 100.0f); - glColor3fv(color); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_REAL, 0, &vertices[0][0]); - if (vertexNormals.size() > 0) - { - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_REAL, 0, &vertexNormals[0][0]); - } + supplyNormals(2, vertexNormals.size(), &vertexNormals[0][0]); } + supplyFaces(faces.size(), faces.data()); - glDrawElements(GL_TRIANGLES, (GLsizei) faces.size(), GL_UNSIGNED_INT, faces.data()); + glDrawElements(GL_TRIANGLES, (GLsizei) faces.size(), GL_UNSIGNED_INT, (void*)0); - if (MiniGL::checkOpenGLVersion(3, 3)) - { - glDisableVertexAttribArray(0); - glDisableVertexAttribArray(2); - } - else - { - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - } + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(2); } void MiniGL::drawQuad(const Vector3r &a, const Vector3r &b, const Vector3r &c, const Vector3r &d, const Vector3r &norm, float *color) { - float speccolor[4] = { 1.0, 1.0, 1.0, 1.0 }; - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, color); - glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, color); - glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, speccolor); - glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 100.0); - - glBegin (GL_QUADS); - glNormal3v(&norm[0]); - glVertex3v(&a[0]); - glVertex3v(&b[0]); - glVertex3v(&c[0]); - glVertex3v(&d[0]); - glEnd (); + // The quad is subdivided into two triangles for rendering. + drawTriangle(a, b, c, norm, color); + drawTriangle(a, c, d, norm, color); } void MiniGL::drawTriangle (const Vector3r &a, const Vector3r &b, const Vector3r &c, const Vector3r &norm, float *color) { - float speccolor[4] = { 1.0, 1.0, 1.0, 1.0 }; - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, color); - glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, color); - glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, speccolor); - glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 100.0); + VectorXr triangle(3 * 3); + triangle << a, b, c; - glBegin (GL_TRIANGLES); - glNormal3v(&norm[0]); - glVertex3v(&a[0]); - glVertex3v(&b[0]); - glVertex3v(&c[0]); - glEnd (); + Vector3f diffcolor(color); + Vector3f speccolor(1.0, 1.0, 1.0); + + glVertexAttrib3rv(1, &norm(0)); + + enableShader(diffcolor, diffcolor, speccolor, 100.0); + supplyVertices(0, 3, &triangle(0)); + glDrawArrays(GL_TRIANGLES, 0, 3); + glDisableVertexAttribArray(0); + disableShader(); + + glVertexAttrib3r(1, 0.0, 0.0, 1.0); } void MiniGL::drawTetrahedron(const Vector3r &a, const Vector3r &b, const Vector3r &c, const Vector3r &d, float *color) @@ -325,60 +324,62 @@ void MiniGL::drawTetrahedron(const Vector3r &a, const Vector3r &b, const Vector3 void MiniGL::drawGrid_xz(float *color) { - float speccolor[4] = { 1.0, 1.0, 1.0, 1.0 }; - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, speccolor); - glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 100.0); + Vector3f diffcolor(color); + Vector3f speccolor(1.0, 1.0, 1.0); const int size = 5; - glBegin(GL_LINES); + VectorXr grid((2*size + 1) * 4 * 3); for (int i = -size; i <= size; i++) { - glVertex3f((float) i, 0.0f, (float) -size); - glVertex3f((float) i, 0.0f, (float) size); - glVertex3f((float) -size, 0.0f, (float) i); - glVertex3f((float) size, 0.0f, (float) i); + grid.segment<12>((i+size) * 12) << (float) i, 0.0f, (float) -size, + (float) i, 0.0f, (float) size, + (float) -size, 0.0f, (float) i, + (float) size, 0.0f, (float) i; } - glEnd(); - - glLineWidth(3.0f); - glBegin(GL_LINES); - glVertex3f((float)-size, 0.0f, 0.0f); - glVertex3f((float)size, 0.0f, 0.0f); - glVertex3f(0.0f, 0.0f, (float) -size); - glVertex3f(0.0f, 0.0f, (float) size); - glEnd(); + enableShader(diffcolor, diffcolor, speccolor, 100.0); + glUniform1i(m_shader.getUniform("lighting"), GL_FALSE); + supplyVertices(0, (2*size + 1) * 4, &grid(0)); + glDrawArrays(GL_LINES, 0, (2*size + 1) * 4); + glDisableVertexAttribArray(0); + disableShader(); + + float lineWidth = 3.0; + + drawVector(Vector3r(-size, 0.0, 0.0), Vector3r(0.0, 0.0, 0.0), lineWidth, color); + drawVector(Vector3r(2.0, 0.0, 0.0), Vector3r(size, 0.0, 0.0), lineWidth, color); + drawVector(Vector3r(0.0, 0.0, -size), Vector3r(0.0, 0.0, 0.0), lineWidth, color); + drawVector(Vector3r(0.0, 0.0, 2.0), Vector3r(0.0, 0.0, size), lineWidth, color); } void MiniGL::drawGrid_xy(float *color) { - float speccolor[4] = { 1.0, 1.0, 1.0, 1.0 }; - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, speccolor); - glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 100.0); + Vector3f diffcolor(color); + Vector3f speccolor(1.0, 1.0, 1.0); const int size = 5; - glBegin(GL_LINES); + VectorXr grid((2*size + 1) * 4 * 3); for (int i = -size; i <= size; i++) { - glVertex3f((float)i, (float)-size, 0.0f ); - glVertex3f((float)i, (float)size, 0.0f); - glVertex3f((float)-size, (float)i, 0.0f); - glVertex3f((float)size, (float)i, 0.0f); + grid.segment<12>((i+size) * 12) << (float)i, (float)-size, 0.0f, + (float)i, (float)size, 0.0f, + (float)-size, (float)i, 0.0f, + (float)size, (float)i, 0.0f; } - glEnd(); - - glLineWidth(3.0f); - glBegin(GL_LINES); - glVertex3f((float)-size, 0.0f, 0.0f); - glVertex3f((float)size, 0.0f, 0.0f); - glVertex3f(0.0f, (float)-size, 0.0f); - glVertex3f(0.0f, (float)size, 0.0f); - glEnd(); + enableShader(diffcolor, diffcolor, speccolor, 100.0); + glUniform1i(m_shader.getUniform("lighting"), GL_FALSE); + supplyVertices(0, (2*size + 1) * 4, &grid(0)); + glDrawArrays(GL_LINES, 0, (2*size + 1) * 4); + glDisableVertexAttribArray(0); + disableShader(); + + float lineWidth = 3.0; + + drawVector(Vector3r(-size, 0.0, 0.0), Vector3r(0.0, 0.0, 0.0), lineWidth, color); + drawVector(Vector3r(2.0, 0.0, 0.0), Vector3r(size, 0.0, 0.0), lineWidth, color); + drawVector(Vector3r(0.0, -size, 0.0), Vector3r(0.0, 0.0, 0.0), lineWidth, color); + drawVector(Vector3r(0.0, 2.0, 0.0), Vector3r(0.0, size, 0.0), lineWidth, color); } void MiniGL::setViewport(float pfovy, float pznear, float pzfar, const Vector3r &peyepoint, const Vector3r &plookat) @@ -387,13 +388,20 @@ void MiniGL::setViewport(float pfovy, float pznear, float pzfar, const Vector3r znear = pznear; zfar = pzfar; - glLoadIdentity (); - gluLookAt (peyepoint [0], peyepoint [1], peyepoint [2], plookat[0], plookat[1], plookat[2], 0, 1, 0); - - Matrix4r transformation; - Real *lookAtMatrix = transformation.data(); - glGetRealv(GL_MODELVIEW_MATRIX, &lookAtMatrix[0]); + // Compute the lookAt modelview matrix (cf. gluLookAt). + Vector3r f = (plookat - peyepoint).normalized(); + Vector3r up(0.0, 1.0, 0.0); + Vector3r s = f.cross(up); + Vector3r u = s.normalized().cross(f); + m_modelview_matrix.setIdentity(); + m_modelview_matrix.block<1,3>(0,0) = s; + m_modelview_matrix.block<1,3>(1,0) = u; + m_modelview_matrix.block<1,3>(2,0) = -f; + m_modelview_matrix(0,3) = -s.dot(peyepoint); + m_modelview_matrix(1,3) = -u.dot(peyepoint); + m_modelview_matrix(2,3) = f.dot(peyepoint); + const Matrix4r& transformation = m_modelview_matrix; Matrix3r rot; Vector3r scale; @@ -411,8 +419,6 @@ void MiniGL::setViewport(float pfovy, float pznear, float pzfar, const Vector3r m_zoom = scale[0]; m_rotation = Quaternionr(rot); - - glLoadIdentity (); } void MiniGL::setViewport(float pfovy, float pznear, float pzfar) @@ -444,10 +450,11 @@ void MiniGL::init(int argc, char **argv, const int width, const int height, cons if (!glfwInit()) exit(EXIT_FAILURE); - glfwWindowHint(GLFW_COCOA_RETINA_FRAMEBUFFER, GL_FALSE); - //glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - //glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - //glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_SAMPLES, 4); if (maximized) glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE); @@ -478,9 +485,8 @@ void MiniGL::init(int argc, char **argv, const int width, const int height, cons LOG_INFO << "Renderer: " << glGetString(GL_RENDERER); LOG_INFO << "Version: " << glGetString(GL_VERSION); + glEnable(GL_MULTISAMPLE); glEnable (GL_DEPTH_TEST); - glEnable (GL_NORMALIZE); - glShadeModel (GL_SMOOTH); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -492,11 +498,17 @@ void MiniGL::init(int argc, char **argv, const int width, const int height, cons glfwSetCursorPosCallback(m_glfw_window, mouseMove); glfwSetScrollCallback(m_glfw_window, mouseWheel); - int w, h; - glfwGetWindowSize(m_glfw_window, &w, &h); - glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + glGenVertexArrays(1, &m_vao); + glBindVertexArray(m_vao); + glGenBuffers(1, &m_vbo_vertices); + glGenBuffers(1, &m_vbo_normals); + glGenBuffers(1, &m_vbo_texcoords); + glGenBuffers(1, &m_vbo_faces); + // Set the default normal (cf. glNormal). + glVertexAttrib3r(1, 0.0, 0.0, 1.0); + m_lastTime = glfwGetTime(); } @@ -521,18 +533,13 @@ void MiniGL::initTexture() glGenTextures(1, &m_texId); glBindTexture(GL_TEXTURE_2D, m_texId); - glTexImage2D(GL_TEXTURE_2D, 0, 3, IMAGE_COLS, IMAGE_ROWS, 0, GL_RGB, + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_COLS, IMAGE_ROWS, 0, GL_RGB, GL_UNSIGNED_BYTE, texData); // Create texture from image data glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glEnable(GL_TEXTURE_2D); // Enable 2D texture - - // Correct texture distortion in perpective projection - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); - glBindTexture(GL_TEXTURE_2D, 0); } @@ -551,7 +558,11 @@ void MiniGL::setSelectionFunc(void(*func) (const Vector2i&, const Vector2i&, voi void MiniGL::destroy () { - gluDeleteQuadric(m_sphereQuadric); + glDeleteBuffers(1, &m_vbo_vertices); + glDeleteBuffers(1, &m_vbo_normals); + glDeleteBuffers(1, &m_vbo_texcoords); + glDeleteBuffers(1, &m_vbo_faces); + glDeleteVertexArrays(1, &m_vao); } void MiniGL::reshape (GLFWwindow* glfw_window, int w, int h) @@ -646,77 +657,165 @@ void MiniGL::char_callback(GLFWwindow* window, unsigned int codepoint) } void MiniGL::setProjectionMatrix (int width, int height) -{ - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(fovy, (Real)width / (Real)height, znear, zfar); +{ + // Compute the perspective projection matrix (cf. gluPerspective). + Real aspect = (Real)width / (Real)height; + Real fovy_rad = fovy * M_PI / 180.0; + Real f = cos(0.5 * fovy_rad) / sin(0.5 * fovy_rad); + m_projection_matrix.setZero(); + m_projection_matrix(0,0) = f / aspect; + m_projection_matrix(1,1) = f; + m_projection_matrix(2,2) = (zfar + znear) / (znear - zfar); + m_projection_matrix(2,3) = 2.0 * zfar * znear / (znear - zfar); + m_projection_matrix(3,2) = -1.0; } void MiniGL::viewport () { glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glRenderMode (GL_RENDER); glfwGetFramebufferSize(m_glfw_window, &m_width, &m_height); + getWindowSize(m_windowWidth, m_windowHeight); + m_devicePixelRatio = static_cast(m_width) / static_cast(m_windowWidth); glViewport (0, 0, m_width, m_height); - glMatrixMode (GL_PROJECTION); - glLoadIdentity (); setProjectionMatrix (m_width, m_height); - glMatrixMode (GL_MODELVIEW); - glTranslatef((float)m_translation[0], (float)m_translation[1], (float)m_translation[2]); Matrix3r rot; rot = m_rotation.toRotationMatrix(); - Matrix4r transform(Matrix4r::Identity()); + Matrix4r& transform = m_modelview_matrix; + transform.setIdentity(); Vector3r scale(m_zoom, m_zoom, m_zoom); transform.block<3,3>(0,0) = rot; transform.block<3,1>(0,3) = m_translation; transform(0,0) *= scale[0]; transform(1,1) *= scale[1]; transform(2,2) *= scale[2]; - Real *transformMatrix = transform.data(); - glLoadMatrix(&transformMatrix[0]); } void MiniGL::initLights () { - float t = 0.9f; - float a = 0.2f; - float amb0 [4] = {a,a,a,1}; - float diff0 [4] = {t,0,0,1}; - float spec0 [4] = {1,1,1,1}; - float pos0 [4] = {-10,10,10,1}; - glLightfv(GL_LIGHT0, GL_AMBIENT, amb0); - glLightfv(GL_LIGHT0, GL_DIFFUSE, diff0); - glLightfv(GL_LIGHT0, GL_SPECULAR, spec0); - glLightfv(GL_LIGHT0, GL_POSITION, pos0); - glEnable(GL_LIGHT0); - - float amb1 [4] = {a,a,a,1}; - float diff1 [4] = {0,0,t,1}; - float spec1 [4] = {1,1,1,1}; - float pos1 [4] = {10,10,10,1}; - glLightfv(GL_LIGHT1, GL_AMBIENT, amb1); - glLightfv(GL_LIGHT1, GL_DIFFUSE, diff1); - glLightfv(GL_LIGHT1, GL_SPECULAR, spec1); - glLightfv(GL_LIGHT1, GL_POSITION, pos1); - glEnable(GL_LIGHT1); - - float amb2 [4] = {a,a,a,1}; - float diff2 [4] = {0,t,0,1}; - float spec2 [4] = {1,1,1,1}; - float pos2 [4] = {0,10,10,1}; - glLightfv(GL_LIGHT2, GL_AMBIENT, amb2); - glLightfv(GL_LIGHT2, GL_DIFFUSE, diff2); - glLightfv(GL_LIGHT2, GL_SPECULAR, spec2); - glLightfv(GL_LIGHT2, GL_POSITION, pos2); - glEnable(GL_LIGHT2); - - - glEnable(GL_LIGHTING); - glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); - glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); + m_ambientIntensity << 0.2f, 0.2f, 0.2f; + + m_numLights = 3; + m_diffuseIntensity.resize(m_numLights * 3); + m_specularIntensity.resize(m_numLights * 3); + m_lightPosition.resize(m_numLights * 3); + + m_diffuseIntensity.segment<3>(0) << 0.9f, 0.0f, 0.0f; + m_specularIntensity.segment<3>(0) << 1.0f, 1.0f, 1.0f; + m_lightPosition.segment<3>(0) << -10.0f, 10.0f, 10.0f; + + m_diffuseIntensity.segment<3>(1 * 3) << 0.0f, 0.0f, 0.9f; + m_specularIntensity.segment<3>(1 * 3) << 1.0f, 1.0f, 1.0f; + m_lightPosition.segment<3>(1 * 3) << 10.0f, 10.0f, 10.0f; + + m_diffuseIntensity.segment<3>(2 * 3) << 0.0f, 0.9f, 0.0f; + m_specularIntensity.segment<3>(2 * 3) << 1.0f, 1.0f, 1.0f; + m_lightPosition.segment<3>(2 * 3) << 0.0f, 10.0f, 10.0f; +} + +void MiniGL::initShaders(const std::string& shaderPath) +{ + Shader& shader = m_shader; + shader.compileShaderFile(GL_VERTEX_SHADER, shaderPath + "/mini.vert"); + shader.compileShaderFile(GL_FRAGMENT_SHADER, shaderPath + "/mini.frag"); + shader.createAndLinkProgram(); + shader.begin(); + shader.addUniform("modelview_matrix"); + shader.addUniform("projection_matrix"); + shader.addUniform("pointSize"); + shader.addUniform("lighting"); + shader.addUniform("ambientIntensity"); + shader.addUniform("diffuseIntensity"); + shader.addUniform("specularIntensity"); + shader.addUniform("lightPosition"); + shader.addUniform("ambientReflectance"); + shader.addUniform("diffuseReflectance"); + shader.addUniform("specularReflectance"); + shader.addUniform("shininess"); + shader.end(); + + Shader& screenShader = m_shader_screen; + screenShader.compileShaderFile(GL_VERTEX_SHADER, shaderPath + "/mini_screen.vert"); + screenShader.compileShaderFile(GL_FRAGMENT_SHADER, shaderPath + "/mini_screen.frag"); + screenShader.createAndLinkProgram(); + screenShader.begin(); + screenShader.addUniform("width"); + screenShader.addUniform("height"); + screenShader.addUniform("color"); + screenShader.end(); +} + +void MiniGL::destroyShaders() +{ + m_shader.destroy(); + m_shader_screen.destroy(); +} + +void MiniGL::enableShader(const Vector3f& ambientReflectance, const Vector3f& diffuseReflectance, const Vector3f& specularReflectance, const float shininess, const float pointSize) +{ + Shader& shader = m_shader; + shader.begin(); + const Matrix4f modelview_matrix(m_modelview_matrix.cast()); + glUniformMatrix4fv(shader.getUniform("modelview_matrix"), 1, GL_FALSE, &modelview_matrix(0,0)); + const Matrix4f projection_matrix(m_projection_matrix.cast()); + glUniformMatrix4fv(shader.getUniform("projection_matrix"), 1, GL_FALSE, &projection_matrix(0,0)); + glUniform1f(shader.getUniform("pointSize"), pointSize); + glUniform1i(shader.getUniform("lighting"), GL_TRUE); + glUniform3fv(shader.getUniform("ambientIntensity"), 1, &m_ambientIntensity(0)); + glUniform3fv(shader.getUniform("diffuseIntensity"), m_numLights, &m_diffuseIntensity(0)); + glUniform3fv(shader.getUniform("specularIntensity"), m_numLights, &m_specularIntensity(0)); + glUniform3fv(shader.getUniform("lightPosition"), m_numLights, &m_lightPosition(0)); + glUniform3fv(shader.getUniform("ambientReflectance"), 1, &ambientReflectance(0)); + glUniform3fv(shader.getUniform("diffuseReflectance"), 1, &diffuseReflectance(0)); + glUniform3fv(shader.getUniform("specularReflectance"), 1, &specularReflectance(0)); + glUniform1f(shader.getUniform("shininess"), shininess); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_PROGRAM_POINT_SIZE); +} + +void MiniGL::disableShader() +{ + Shader& shader = m_shader; + shader.end(); +} + +void MiniGL::enableScreenShader(const Vector3f& color) +{ + Shader& shader = m_shader_screen; + shader.begin(); + glUniform1f(shader.getUniform("width"), static_cast(m_windowWidth)); + glUniform1f(shader.getUniform("height"), static_cast(m_windowHeight)); + glUniform3fv(shader.getUniform("color"), 1, &color(0)); +} + +void MiniGL::disableScreenShader() +{ + Shader& shader = m_shader_screen; + shader.end(); +} +void MiniGL::supplyVectors(GLuint index, GLuint vbo, unsigned int dim, unsigned int n, const float* data) +{ + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, n * dim * sizeof(float), data, GL_STREAM_DRAW); + glVertexAttribPointer(index, dim, GL_FLOAT, GL_FALSE, 0, (void*)0); + glEnableVertexAttribArray(index); +} + +void MiniGL::supplyVectors(GLuint index, GLuint vbo, unsigned int dim, unsigned int n, const double* data) +{ + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, n * dim * sizeof(double), data, GL_STREAM_DRAW); + glVertexAttribPointer(index, dim, GL_DOUBLE, GL_FALSE, 0, (void*)0); + glEnableVertexAttribArray(index); +} + +void MiniGL::supplyIndices(GLuint vbo, unsigned int n, const unsigned int* data) +{ + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, n * sizeof(unsigned int), data, GL_STREAM_DRAW); } void MiniGL::move(Real x, Real y, Real z) @@ -841,16 +940,34 @@ void MiniGL::mouseMove (GLFWwindow* window, double x, double y) void MiniGL::unproject(const int x, const int y, Vector3r &pos) { GLint viewport[4]; - GLdouble mv[16], pm[16]; glGetIntegerv(GL_VIEWPORT, viewport); - glGetDoublev(GL_MODELVIEW_MATRIX, mv); - glGetDoublev(GL_PROJECTION_MATRIX, pm); - GLdouble resx, resy, resz; - gluUnProject(x, viewport[3] - y, znear, mv, pm, viewport, &resx, &resy, &resz); - pos[0] = (Real) resx; - pos[1] = (Real) resy; - pos[2] = (Real) resz; + unproject( + Vector3r( + static_cast(x) * m_devicePixelRatio, + static_cast(viewport[3]) - static_cast(y) * m_devicePixelRatio, + static_cast(znear) + ), + pos + ); +} + +void MiniGL::unproject(const Vector3r& win, Vector3r& pos) +{ + GLint viewport[4]; + glGetIntegerv(GL_VIEWPORT, viewport); + + // Map the specified window coordinates to object coordinates (cf. gluUnProject). + Vector4r ndc; + ndc(0) = static_cast(2.0) * (win(0) - static_cast(viewport[0])) / static_cast(viewport[2]) - static_cast(1.0); + ndc(1) = static_cast(2.0) * (win(1) - static_cast(viewport[1])) / static_cast(viewport[3]) - static_cast(1.0); + ndc(2) = static_cast(2.0) * win(2) - static_cast(1.0); + ndc(3) = static_cast(1.0); + Vector4r obj = (m_projection_matrix * m_modelview_matrix).inverse() * ndc; + if (obj(3) == static_cast(0.0)) obj.setZero(); + else obj /= obj(3); + + pos = obj.segment<3>(0); } float MiniGL::getZNear() @@ -892,20 +1009,16 @@ bool MiniGL::checkOpenGLVersion(const int major_version, const int minor_version Shader *MiniGL::createShader(const std::string &vertexShader, const std::string &geometryShader, const std::string &fragmentShader) { - if (checkOpenGLVersion(3,3)) - { - Shader *shader = new Shader(); - - if (vertexShader != "") - shader->compileShaderFile(GL_VERTEX_SHADER, vertexShader); - if (geometryShader != "") - shader->compileShaderFile(GL_GEOMETRY_SHADER, geometryShader); - if (fragmentShader != "") - shader->compileShaderFile(GL_FRAGMENT_SHADER, fragmentShader); - shader->createAndLinkProgram(); - return shader; - } - return NULL; + Shader *shader = new Shader(); + + if (vertexShader != "") + shader->compileShaderFile(GL_VERTEX_SHADER, vertexShader); + if (geometryShader != "") + shader->compileShaderFile(GL_GEOMETRY_SHADER, geometryShader); + if (fragmentShader != "") + shader->compileShaderFile(GL_FRAGMENT_SHADER, fragmentShader); + shader->createAndLinkProgram(); + return shader; } void MiniGL::drawElements() @@ -975,11 +1088,11 @@ void MiniGL::mainLoop() if (destroyfunc != nullptr) destroyfunc(); + destroy(); + glfwDestroyWindow(m_glfw_window); glfwTerminate(); - - destroy(); } void MiniGL::leaveMainLoop() diff --git a/Demos/Visualization/MiniGL.h b/Demos/Visualization/MiniGL.h index 4907ab6b..752a1ff5 100644 --- a/Demos/Visualization/MiniGL.h +++ b/Demos/Visualization/MiniGL.h @@ -7,31 +7,16 @@ #include #ifdef USE_DOUBLE -#define glNormal3v glNormal3dv -#define glVertex3v glVertex3dv -#define glVertex3 glVertex3d -#define glMultMatrix glMultMatrixd -#define glGetRealv glGetDoublev -#define glLoadMatrix glLoadMatrixd -#define glTranslate glTranslated #define GL_REAL GL_DOUBLE -#define TW_TYPE_REAL TW_TYPE_DOUBLE -#define TW_TYPE_DIR3R TW_TYPE_DIR3D +#define glVertexAttrib3r glVertexAttrib3d +#define glVertexAttrib3rv glVertexAttrib3dv #else -#define glNormal3v glNormal3fv -#define glVertex3v glVertex3fv -#define glVertex3 glVertex3f -#define glMultMatrix glMultMatrixf -#define glGetRealv glGetFloatv -#define glLoadMatrix glLoadMatrixf -#define glTranslate glTranslatef #define GL_REAL GL_FLOAT -#define TW_TYPE_REAL TW_TYPE_FLOAT -#define TW_TYPE_DIR3R TW_TYPE_DIR3F +#define glVertexAttrib3r glVertexAttrib3f +#define glVertexAttrib3rv glVertexAttrib3fv #endif struct GLFWwindow; -typedef class GLUquadric GLUquadricObj; namespace PBD { @@ -96,6 +81,9 @@ namespace PBD static std::vector m_mouseWheelFct; static int m_width; static int m_height; + static int m_windowWidth; + static int m_windowHeight; + static Real m_devicePixelRatio; static Vector3r m_translation; static Quaternionr m_rotation; static Real m_zoom; @@ -122,10 +110,23 @@ namespace PBD static std::vector m_drawPoints; static std::vector m_drawLines; static std::vector m_drawTriangle; - static GLUquadricObj* m_sphereQuadric; static GLFWwindow* m_glfw_window; static bool m_vsync; static double m_lastTime; + static Shader m_shader; + static Shader m_shader_screen; + static Matrix4r m_modelview_matrix; + static Matrix4r m_projection_matrix; + static Vector3f m_ambientIntensity; + static unsigned int m_numLights; + static VectorXf m_diffuseIntensity; + static VectorXf m_specularIntensity; + static VectorXf m_lightPosition; + static GLuint m_vao; + static GLuint m_vbo_vertices; + static GLuint m_vbo_normals; + static GLuint m_vbo_texcoords; + static GLuint m_vbo_faces; static void reshape (GLFWwindow* glfw_window, int w, int h); static void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods); @@ -143,7 +144,7 @@ namespace PBD static void drawVector(const Vector3r &a, const Vector3r &b, const float w, float *color); /** Renders a closed cylinder between two points. */ - static void drawCylinder(const Vector3r &a, const Vector3r &b, const float *color, const float radius = 0.02, const unsigned int subdivisions = 8); + static void drawCylinder(const Vector3r &a, const Vector3r &b, const float *color, const float radius = 0.02, const unsigned int subdivisions = 8, const bool lighting = true); static void drawSphere(const Vector3r &translation, float radius, float *color, const unsigned int subDivision = 16); static void drawQuad (const Vector3r &a, const Vector3r &b, const Vector3r &c, const Vector3r &d, const Vector3r &norm, float *color); /** Draw a tetrahedron. @@ -177,6 +178,7 @@ namespace PBD static void setSelectionFunc(void(*func) (const Vector2i&, const Vector2i&, void*), void *clientData); static void setMouseMoveFunc(int button, void(*func) (int, int, void*)); static void unproject(const int x, const int y, Vector3r &pos); + static void unproject(const Vector3r& win, Vector3r& pos); static float getZNear(); static float getZFar(); static void hsvToRgb(float h, float s, float v, float *rgb); @@ -201,6 +203,7 @@ namespace PBD static int getWidth() { return m_width; } static int getHeight() { return m_height; } + static Real getDevicePixelRatio() { return m_devicePixelRatio; } static int getDrawMode() { return drawMode; } static void setDrawMode(int val) { drawMode = val; } @@ -218,7 +221,52 @@ namespace PBD static void setWindowPos(int x, int y); static void setWindowSize(int w, int h); static bool getWindowMaximized(); - static void setWindowMaximized(const bool b); + static void setWindowMaximized(const bool b); + + static const Matrix4r& getModelviewMatrix() { return m_modelview_matrix; } + static const Matrix4r& getProjectionMatrix() { return m_projection_matrix; } + + static void initShaders(const std::string& shaderPath); + static void destroyShaders(); + static void enableShader(const Vector3f& ambientReflectance, const Vector3f& diffuseReflectance, const Vector3f& specularReflectance, const float shininess, const float pointSize=1.0); + static void disableShader(); + static void enableScreenShader(const Vector3f& color); + static void disableScreenShader(); + + static const GLuint getVao() { return m_vao; } + static const GLuint getVboVertices() { return m_vbo_vertices; } + static const GLuint getVboNormals() { return m_vbo_normals; } + static const GLuint getVboTexcoords() { return m_vbo_texcoords; } + static const GLuint getVboFaces() { return m_vbo_faces; } + + // Fill a VBO with vector data and map to the VAO attribute at the specified index. + static void supplyVectors(GLuint index, GLuint vbo, unsigned int dim, unsigned int n, const float* data); + static void supplyVectors(GLuint index, GLuint vbo, unsigned int dim, unsigned int n, const double* data); + // Fill the dedicated VBO with 3D vertex data and map to the VAO attribute at the specified index. + template + static void supplyVertices(GLuint index, unsigned int numVectors, const T* data) + { + supplyVectors(index, m_vbo_vertices, 3, numVectors, data); + } + // Fill the dedicated VBO with 3D normal data and map to the VAO attribute at the specified index. + template + static void supplyNormals(GLuint index, unsigned int numVectors, const T* data) + { + supplyVectors(index, m_vbo_normals, 3, numVectors, data); + } + // Fill the dedicated VBO with 2D texcoord data and map to the VAO attribute at the specified index. + template + static void supplyTexcoords(GLuint index, unsigned int numVectors, const T* data) + { + supplyVectors(index, m_vbo_texcoords, 2, numVectors, data); + } + // Fill a VBO with index data. + static void supplyIndices(GLuint vbo, unsigned int n, const unsigned int* data); + // Fill the dedicated VBO with face index data. + static void supplyFaces(unsigned int numIndices, const unsigned int* data) + { + supplyIndices(m_vbo_faces, numIndices, data); + } }; } diff --git a/Demos/Visualization/Selection.h b/Demos/Visualization/Selection.h index facc890e..09f4c72e 100644 --- a/Demos/Visualization/Selection.h +++ b/Demos/Visualization/Selection.h @@ -10,10 +10,8 @@ #ifdef __APPLE__ #include -#include #else #include "GL/gl.h" -#include "GL/glu.h" #endif #include @@ -43,34 +41,25 @@ namespace PBD int itop = ip1y > ip2y ? ip1y : ip2y; int ibottom = ip1y < ip2y ? ip1y : ip2y; - float left = (float)ileft; - float right = (float)iright; - float top = (float)itop; - float bottom = (float)ibottom; + float left = (float)ileft * MiniGL::getDevicePixelRatio(); + float right = (float)iright * MiniGL::getDevicePixelRatio(); + float top = (float)itop * MiniGL::getDevicePixelRatio(); + float bottom = (float)ibottom * MiniGL::getDevicePixelRatio(); if (left != right && top != bottom) { GLint viewport[4]; - GLdouble mv[16],pm[16]; glGetIntegerv(GL_VIEWPORT, viewport); - glGetDoublev(GL_MODELVIEW_MATRIX, mv); - glGetDoublev(GL_PROJECTION_MATRIX, pm); - GLdouble resx,resy,resz; float zNear = MiniGL::getZNear(); float zFar = MiniGL::getZFar(); - gluUnProject(left, viewport[3] - top, zNear , mv, pm, viewport, &resx, &resy, &resz); - const Vector3r vector0((Real)resx, (Real)resy, (Real)resz); - gluUnProject(left, viewport[3] - top, zFar , mv, pm, viewport, &resx, &resy, &resz); - const Vector3r vector1((Real)resx, (Real)resy, (Real)resz); - gluUnProject(left, viewport[3] - bottom, zNear , mv, pm, viewport, &resx, &resy, &resz); - const Vector3r vector2((Real)resx, (Real)resy, (Real)resz); - gluUnProject(right, viewport[3] - top, zNear , mv, pm, viewport, &resx, &resy, &resz); - const Vector3r vector3((Real)resx, (Real)resy, (Real)resz); - gluUnProject(right, viewport[3] - bottom, zNear , mv, pm, viewport, &resx, &resy, &resz); - const Vector3r vector4((Real)resx, (Real)resy, (Real)resz); - gluUnProject(right, viewport[3] - bottom, zFar , mv, pm, viewport, &resx, &resy, &resz); - const Vector3r vector5((Real)resx, (Real)resy, (Real)resz); + Vector3r vector0, vector1, vector2, vector3, vector4, vector5; + MiniGL::unproject(Vector3r(left, viewport[3] - top, zNear), vector0); + MiniGL::unproject(Vector3r(left, viewport[3] - top, zFar), vector1); + MiniGL::unproject(Vector3r(left, viewport[3] - bottom, zNear), vector2); + MiniGL::unproject(Vector3r(right, viewport[3] - top, zNear), vector3); + MiniGL::unproject(Vector3r(right, viewport[3] - bottom, zNear), vector4); + MiniGL::unproject(Vector3r(right, viewport[3] - bottom, zFar), vector5); SelectionPlane plane[4]; plane[0].normal = (vector3-vector0).cross(vector1-vector0); diff --git a/Demos/Visualization/Shader.cpp b/Demos/Visualization/Shader.cpp index 46518ec8..4ff080c2 100644 --- a/Demos/Visualization/Shader.cpp +++ b/Demos/Visualization/Shader.cpp @@ -17,11 +17,7 @@ Shader::Shader(void) Shader::~Shader(void) { - m_initialized = false; - m_attributes.clear(); - m_uniforms.clear(); - if (m_program) - glDeleteProgram(m_program); + destroy(); } void Shader::compileShaderString(GLenum type, const std::string &source) @@ -85,6 +81,18 @@ void Shader::createAndLinkProgram() glDeleteShader(m_shaders[i]); } +void Shader::destroy() +{ + m_initialized = false; + m_attributes.clear(); + m_uniforms.clear(); + if (m_program) + { + glDeleteProgram(m_program); + m_program = 0; + } +} + void Shader::begin() { if (m_initialized) diff --git a/Demos/Visualization/Shader.h b/Demos/Visualization/Shader.h index 4011f436..5fc4d75c 100644 --- a/Demos/Visualization/Shader.h +++ b/Demos/Visualization/Shader.h @@ -16,6 +16,7 @@ namespace PBD void compileShaderString(GLenum whichShader, const std::string &source); void compileShaderFile(GLenum whichShader, const std::string &filename); void createAndLinkProgram(); + void destroy(); void addAttribute(const std::string &attribute); void addUniform(const std::string &uniform); bool isInitialized(); diff --git a/Demos/Visualization/Visualization.h b/Demos/Visualization/Visualization.h index 373ac99b..75718c08 100644 --- a/Demos/Visualization/Visualization.h +++ b/Demos/Visualization/Visualization.h @@ -3,6 +3,7 @@ #include "Common/Common.h" #include "MiniGL.h" +#include "Utils/IndexedFaceMesh.h" namespace PBD { @@ -23,40 +24,14 @@ namespace PBD const unsigned int nFaces = mesh.numFaces(); const Vector3r *vertexNormals = mesh.getVertexNormals().data(); - if (MiniGL::checkOpenGLVersion(3, 3)) - { - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_REAL, GL_FALSE, 0, &pd.getPosition(offset)[0]); - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 3, GL_REAL, GL_FALSE, 0, &vertexNormals[0][0]); - } - else - { - float speccolor[4] = { 1.0, 1.0, 1.0, 1.0 }; - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, speccolor); - glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 100.0f); - glColor3fv(color); + MiniGL::supplyVertices(0, mesh.numVertices(), &pd.getPosition(offset)[0]); + MiniGL::supplyNormals(2, mesh.numVertices(), &vertexNormals[0][0]); + MiniGL::supplyFaces(3 * nFaces, faces); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - glVertexPointer(3, GL_REAL, 0, &pd.getPosition(0)[0]); - glNormalPointer(GL_REAL, 0, &vertexNormals[0][0]); - } + glDrawElements(GL_TRIANGLES, (GLsizei)3 * nFaces, GL_UNSIGNED_INT, (void*)0); - glDrawElements(GL_TRIANGLES, (GLsizei)3 * mesh.numFaces(), GL_UNSIGNED_INT, mesh.getFaces().data()); - - if (MiniGL::checkOpenGLVersion(3, 3)) - { - glDisableVertexAttribArray(0); - glDisableVertexAttribArray(2); - } - else - { - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - } + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(2); } template @@ -70,46 +45,16 @@ namespace PBD MiniGL::bindTexture(); - if (MiniGL::checkOpenGLVersion(3,3)) - { - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_REAL, GL_FALSE, 0, &pd.getPosition(offset)[0]); - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 2, GL_REAL, GL_FALSE, 0, &uvs[0][0]); - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 3, GL_REAL, GL_FALSE, 0, &vertexNormals[0][0]); - } - else - { - float speccolor[4] = { 1.0, 1.0, 1.0, 1.0 }; - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, speccolor); - glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 100.0); - glColor3fv(color); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glVertexPointer(3, GL_REAL, 0, &pd.getPosition(0)[0]); - glTexCoordPointer(2, GL_REAL, 0, &uvs[0][0]); - glNormalPointer(GL_REAL, 0, &vertexNormals[0][0]); - } + MiniGL::supplyVertices(0, mesh.numVertices(), &pd.getPosition(offset)[0]); + MiniGL::supplyTexcoords(1, mesh.numUVs(), &uvs[0][0]); + MiniGL::supplyNormals(2, mesh.numVertices(), &vertexNormals[0][0]); + MiniGL::supplyFaces(3 * nFaces, faces); - glDrawElements(GL_TRIANGLES, (GLsizei)3 * mesh.numFaces(), GL_UNSIGNED_INT, mesh.getFaces().data()); + glDrawElements(GL_TRIANGLES, (GLsizei)3 * nFaces, GL_UNSIGNED_INT, (void*)0); - if (MiniGL::checkOpenGLVersion(3, 3)) - { - glDisableVertexAttribArray(0); - glDisableVertexAttribArray(1); - glDisableVertexAttribArray(2); - } - else - { - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); + glDisableVertexAttribArray(2); MiniGL::unbindTexture(); } diff --git a/data/shaders/fs_flatTex.glsl b/data/shaders/fs_flatTex.glsl index 265beec8..59f309e1 100644 --- a/data/shaders/fs_flatTex.glsl +++ b/data/shaders/fs_flatTex.glsl @@ -36,7 +36,7 @@ void main() float cos_nh = max(dot(eye_n, h), 0.0); vec3 color = surface_color * (ambient + diffuse * cos_ln + specular_factor * specular * pow(cos_nh, shininess)); - vec4 color2 = texture2D(tex, inData.texCoord) * vec4(color, 1.0); + vec4 color2 = texture(tex, inData.texCoord) * vec4(color, 1.0); frag_color = color2; } diff --git a/data/shaders/fs_smoothTex.glsl b/data/shaders/fs_smoothTex.glsl index 7bcb3a95..17625363 100644 --- a/data/shaders/fs_smoothTex.glsl +++ b/data/shaders/fs_smoothTex.glsl @@ -36,7 +36,7 @@ void main() float cos_nh = max(dot(eye_n, h), 0.0); vec3 color = surface_color * (ambient + diffuse * cos_ln + specular_factor * specular * pow(cos_nh, shininess)); - vec4 color2 = texture2D(tex, inData.texCoord) * vec4(color, 1.0); + vec4 color2 = texture(tex, inData.texCoord) * vec4(color, 1.0); frag_color = color2; } diff --git a/data/shaders/mini.frag b/data/shaders/mini.frag new file mode 100644 index 00000000..95ee4f6d --- /dev/null +++ b/data/shaders/mini.frag @@ -0,0 +1,52 @@ +#version 330 + +#define NUM_LIGHTS 3 + +uniform bool lighting; +uniform vec3 ambientIntensity; +uniform vec3 diffuseIntensity[NUM_LIGHTS]; +uniform vec3 specularIntensity[NUM_LIGHTS]; +uniform vec3 lightPosition[NUM_LIGHTS]; +uniform vec3 ambientReflectance; +uniform vec3 diffuseReflectance; +uniform vec3 specularReflectance; +uniform float shininess; + +in VertexData { + vec3 position; + vec3 normal; +} IN; + +out vec4 outColor; + +void main() +{ + if (lighting) + { + vec3 view = normalize(-IN.position); + vec3 normal = normalize(IN.normal); + + // Compute the ambient lighting. + vec3 color = ambientReflectance * ambientIntensity; + + for (int i = 0; i < NUM_LIGHTS; i++) + { + vec3 light = normalize(lightPosition[i] - IN.position); + float diffuseFactor = max(dot(normal, light), 0.0); + if (diffuseFactor > 0.0) + { + // Compute the diffuse lighting using the Lambertian model. + color += diffuseFactor * diffuseReflectance * diffuseIntensity[i]; + + vec3 halfway = normalize(light + view); + float specularFactor = pow(max(dot(halfway, normal), 0.0), shininess); + + // Compute the specular lighting using the Blinn-Phong model. + color += specularFactor * specularReflectance * specularIntensity[i]; + } + } + + outColor = vec4(color, 1.0); + } + else outColor = vec4(diffuseReflectance, 1.0); +} \ No newline at end of file diff --git a/data/shaders/mini.vert b/data/shaders/mini.vert new file mode 100644 index 00000000..dc80d99d --- /dev/null +++ b/data/shaders/mini.vert @@ -0,0 +1,22 @@ +#version 330 + +uniform mat4 modelview_matrix; +uniform mat4 projection_matrix; +uniform float pointSize; + +layout(location = 0) in vec3 position; +layout(location = 1) in vec3 normal; + +out VertexData { + vec3 position; + vec3 normal; +} OUT; + +void main() +{ + vec4 vertexPosition = modelview_matrix * vec4(position, 1.0); + OUT.position = vertexPosition.xyz / vertexPosition.w; + OUT.normal = mat3(modelview_matrix) * normal; + gl_Position = projection_matrix * vertexPosition; + gl_PointSize = pointSize; +} \ No newline at end of file diff --git a/data/shaders/mini_screen.frag b/data/shaders/mini_screen.frag new file mode 100644 index 00000000..1b4d9e41 --- /dev/null +++ b/data/shaders/mini_screen.frag @@ -0,0 +1,10 @@ +#version 330 + +uniform vec3 color; + +out vec4 outColor; + +void main() +{ + outColor = vec4(color, 1.0); +} \ No newline at end of file diff --git a/data/shaders/mini_screen.vert b/data/shaders/mini_screen.vert new file mode 100644 index 00000000..6a098bd8 --- /dev/null +++ b/data/shaders/mini_screen.vert @@ -0,0 +1,12 @@ +#version 330 + +uniform float width; +uniform float height; + +layout(location = 0) in vec2 position; + +void main() +{ + // Project the screen position to NDC (cf. glOrtho). + gl_Position = vec4(2.0 * (position.x / width) - 1.0, -2.0 * (position.y / height) + 1.0, -1.0, 1.0); +} \ No newline at end of file