diff --git a/src/shaders/basicShader.frag b/src/shaders/basicShader.frag index 108bdb0..463f192 100644 --- a/src/shaders/basicShader.frag +++ b/src/shaders/basicShader.frag @@ -2,6 +2,7 @@ uniform vec3 lDirection; uniform bool isSky; uniform bool isPhong; +uniform bool isPickerColor; uniform sampler2D tex; uniform float skyMult; @@ -16,7 +17,10 @@ void main() { vec4 texColor = texture(tex, texCoords); - if(isSky) { + + if(isPickerColor){ + fColor = ifColor; + } else if(isSky) { fColor = skyMult * normalize(texColor*texColor*texColor*2/1.41)*2; } else if(isPhong) { // Get lighting vectors @@ -40,5 +44,5 @@ main() //fColor = vec4(fNormal, 1); } else { fColor = texColor * ifColor; - } + } } diff --git a/src/shaders/basicShader.vert b/src/shaders/basicShader.vert index 8f741cb..8e745c4 100644 --- a/src/shaders/basicShader.vert +++ b/src/shaders/basicShader.vert @@ -8,6 +8,7 @@ uniform vec4 color; uniform bool isSky; uniform bool isPhong; +uniform bool isPickerColor; in vec4 vPosition; in vec3 vNormal; @@ -30,7 +31,7 @@ main() ifColor = color; - if(!isPhong && !isSky) { + if(!isPickerColor && !isPhong && !isSky) { // Get lighting vectors vec3 LightDirection = normalize(lDirection); vec3 nfNormal = normalize(fNormal); @@ -50,5 +51,6 @@ main() ifColor = vec4(color * (0.1 + diffuse + specular), 1); //ifColor = vec4(fNormal, 1); } + } diff --git a/src/shaders/skyboxShader.vert b/src/shaders/skyboxShader.vert index 8d621b1..2926847 100644 --- a/src/shaders/skyboxShader.vert +++ b/src/shaders/skyboxShader.vert @@ -9,7 +9,7 @@ in vec4 vPosition; void main() { - gl_Position = projMatrix * mvMatrix * vPosition; - texCoords = vUv; + gl_Position = projMatrix * mvMatrix * vPosition; + texCoords = vUv; } diff --git a/src/shaders/skyboxshader.vert b/src/shaders/skyboxshader.vert deleted file mode 100644 index 8d621b1..0000000 --- a/src/shaders/skyboxshader.vert +++ /dev/null @@ -1,15 +0,0 @@ -#version 400 core - -uniform mat4 mvMatrix; -uniform mat4 projMatrix; -out vec2 texCoords; -in vec2 vUv; -in vec4 vPosition; - -void -main() -{ - gl_Position = projMatrix * mvMatrix * vPosition; - texCoords = vUv; -} - diff --git a/src/viewer/simpleViewer.cpp b/src/viewer/simpleViewer.cpp index c2be734..9a9e480 100644 --- a/src/viewer/simpleViewer.cpp +++ b/src/viewer/simpleViewer.cpp @@ -1,589 +1,590 @@ -/**************************************************************************** - - Copyright (C) 2002-2008 Gilles Debunne. All rights reserved. - - This file is part of the QGLViewer library version 2.3.6. - - http://www.libqglviewer.com - contact@libqglviewer.com - - This file may be used under the terms of the GNU General Public License - versions 2.0 or 3.0 as published by the Free Software Foundation and - appearing in the LICENSE file included in the packaging of this file. - In addition, as a special exception, Gilles Debunne gives you certain - additional rights, described in the file GPL_EXCEPTION in this package. - - libQGLViewer uses dual licensing. Commercial/proprietary software must - purchase a libQGLViewer Commercial License. - - This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - -*****************************************************************************/ - -#include "simpleViewer.h" -#include "../interfaces/visitor.h" -#include "../glnodes/scenegroup.h" -#include "../glnodes/shapes.h" -#include - -#include -#include - -#include - -#include -#include -#include -#include -using namespace std; - -#define BUFFER_OFFSET(i) ((char *)NULL + (i)) -#define GRID_SIZE 10; - -namespace -{ - const int numVerticesCube = 12*3; - const double frame_limit = 5; - const double inc_mult = 5; - const double inc_offset = 1.05; - - int m_lDirectionLocation; - int m_normalMatrixLoc; - - QVector3D sun = QVector3D(0,-1,0); - QMatrix4x4 sunRotate; -} - -class SkyboxCamera : public qglviewer::Camera -{ - virtual qreal zNear() const { return 0.01; } - virtual qreal zFar() const { return 100.0; } -}; - -Viewer::Viewer() -{ - activeColor = new QColor(255, 255, 255, 255); - activeCell = nullptr; - activeShape = 0; - angle_mult = 0.1; -} - -Viewer::~Viewer() -{ - cleanup(); -} - -void Viewer::cleanup() -{ - makeCurrent(); - - // Delete shaders - delete m_program; - m_program = 0; - - // Delete buffers - glDeleteBuffers(NumBuffers, m_Buffers); - glDeleteVertexArrays(NumVAOs, m_VAOs); - - doneCurrent(); -} - -void Viewer::drawSkybox() -{ - // Use the Skybox Shaders - //skyboxRenderShaderProgram->bind(); - s_texture->bind(); - - // Get projection and camera transformations - QMatrix4x4 projectionMatrix; - QMatrix4x4 modelViewMatrix; - camera()->getProjectionMatrix(projectionMatrix); - camera()->getModelViewMatrix(modelViewMatrix); - - // Increase size of skybox - - modelViewMatrix.scale(101); - - float colorMult = 0.2 + std::fabs(0.8 * cos(std::fmod(angle_mult * frame + 300, 360) / 360 * M_PI)); - - m_program->setUniformValue(m_skyMultLoc, colorMult); - m_program->setUniformValue(m_mvMatrixLocation, modelViewMatrix); - m_program->setUniformValue(m_isSkyLoc, true); - - int faces = floor(numVerticesCube/6); - for(int i = 0; i < faces; i++){ // 6 vertexes par face - glBindVertexArray(m_VAOs[VAO_Cube]); - - glDrawArrays(GL_TRIANGLES, i*6, 6); - } -} - -void Viewer::draw() -{ - drawSkybox(); - - // Bind our vertex/fragment shaders - m_program->bind(); - - // Get projection and camera transformations - QMatrix4x4 projectionMatrix; - QMatrix4x4 modelViewMatrix; - camera()->getProjectionMatrix(projectionMatrix); - camera()->getModelViewMatrix(modelViewMatrix); - - // Prepare a transformation stack - - // stack modelStack; - - //modelViewMatrix.rotate(45, 0, 1, 0); - // uncomment this and the cube translation in init() - // to see the cube spin - /*rot = QQuaternion::fromAxisAndAngle(1, 0, 1, 90/60 * frame); - modelViewMatrix.rotate(rot); - projectionMatrix.translate(0, -5, 0); - projectionMatrix.rotate(15, 1, 0, 0);//*/ - - modelViewMatrix.rotate(30,0,1,0); - - m_program->setUniformValue(m_projMatrixLocation, projectionMatrix); - m_program->setUniformValue(m_mvMatrixLocation, modelViewMatrix); - - // Adjust sun position - - float rotAngle = std::fmod(angle_mult * frame, 360); - sunRotate.rotate(rotAngle, 1, 0, 0); - - m_program->setUniformValue(m_lDirLoc, (sun * sunRotate)); - - // Traverse the Scene in order to draw its components - - modelStack.push(modelViewMatrix); - root.accept(*this); - frame++; - - sunRotate.setToIdentity(); - //float rotAngle = (frame * angle_mult) % 360; - - update(); -} - -void Viewer::mouseMoveEvent(QMouseEvent* e) { - //cout << "Viewer::mouseMoveEvent(QMouseEvent* e)" << endl; - // Normal QGLViewer behavior. - QGLViewer::mouseMoveEvent(e); -} - -void Viewer::mousePressEvent(QMouseEvent* e) { - // Auto Return, but old code left in as reference - - // TODO: figure out how to get this weird offset ↓↓ frame position maybe? - int x = this->x() + e->x() + 10; - int y = this->parentWidget()->height() - e->y() + 21; - std::cout << "--------------------------------------------------\nPicking shape at " << x << " (" << this->x() << " + " << e->x() << "), " << y << endl; - std::cout << "Window geom: " << this->window()->size().width() << "w, " << this->window()->size().height() << "h" << endl; - Shape* selectedShape = pickGeom(x, y); - // OpenGL coords start at the window's bottom-left, not the frame's. ugh. - - QGLViewer::mousePressEvent(e); -} - -void Viewer::deselect(){ - std::cout << "Deselecting cell " << activeCell << endl; - if(activeCell != nullptr && activeCell->getChildren()->size()){ - std::cout << "Cell has children..." << endl; - Shape* shape = dynamic_cast (activeCell->childAt(0)); - QColor newColor = shape->getColor(); - std::cout << newColor.Rgb << endl; - newColor.setAlpha(180); - shape->setColor(newColor); - }else{ - std::cout << "Cell has no children, moving on" << endl; - } - this->update(); -} - -void Viewer::mouseReleaseEvent(QMouseEvent* e) { - //cout << "Viewer::mouseReleaseEvent(QMouseEvent* e)" << endl; - QGLViewer::mouseReleaseEvent(e); -} - -void Viewer::init() -{ - SkyboxCamera *_cam = new SkyboxCamera(); - setCamera(_cam); - //camera()->setType(qglviewer::Camera::PERSPECTIVE); - //setMouseBinding(Qt::NoModifier, Qt::LeftButton, CAMERA, SCREEN_ROTATE); - //setMouseBinding(Qt::AltModifier, Qt::LeftButton, CAMERA, NO_MOUSE_ACTION); - //setMouseBinding(Qt::NoModifier, Qt::MouseButton(Qt::LeftButton + Qt::MidButton), CAMERA, NO_MOUSE_ACTION); - //setMouseBinding(Qt::ControlModifier, Qt::MouseButton(Qt::LeftButton + Qt::MidButton), CAMERA, NO_MOUSE_ACTION); - //setMouseBinding(Qt::ShiftModifier, Qt::MouseButton(Qt::LeftButton + Qt::MidButton), CAMERA, NO_MOUSE_ACTION); - - // Our scene will be from -5 to 5 in X and Y (the grid will be 10x10). - setSceneRadius(5); - showEntireScene(); - - // Init OpenGL objects - connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &Viewer::cleanup); - initializeOpenGLFunctions(); - - // Init shaders & geometry - initShaders(); - initGeometries(); - - sunRotate.rotate(-15,0,0,1); - sun = sun * sunRotate; - - { - Shape* cube = new Cube(); - cube->setColor(*activeColor); - - // uncomment this and the quaternion transformation in draw() - // to see the cube rotate. This is how we can easily make the sun. - // cube->transform.translate(3, 0, 0); - - SceneGroup *c = new SceneGroup(); - c->addChild(cube); - root.addChild(c); - } -} - -void Viewer::initShaders() -{ - - - // Load vertex and fragment shaders - m_program = new QOpenGLShaderProgram; - colorPickerShaderProgram = m_program; - if (!m_program->addShaderFromSourceFile(QOpenGLShader::Vertex, "src/shaders/basicShader.vert")) { - cerr << "Unable to load Shader" << endl - << "Log file:" << endl; - qDebug() << m_program->log(); - } - if (!m_program->addShaderFromSourceFile(QOpenGLShader::Fragment, "src/shaders/basicShader.frag")) { - cerr << "Unable to load Shader" << endl - << "Log file:" << endl; - qDebug() << m_program->log(); - } - m_program->link(); - m_program->bind(); // Note: This is equivalent to glUseProgram(programId()); - - // Specify shader input paramters - // The strings "vPosition", "mvMatrix", etc. have to match an attribute name in the vertex shader. - if ((m_vPositionLocation = m_program->attributeLocation("vPosition")) < 0) - qDebug() << "Unable to find shader location for " << "vPosition"; - - if ((m_colorLocation = m_program->uniformLocation("color")) < 0) - qDebug() << "Unable to find shader location for " << "color"; - - if ((m_mvMatrixLocation = m_program->uniformLocation("mvMatrix")) < 0) - qDebug() << "Unable to find shader location for " << "mvMatrix"; - - if ((m_projMatrixLocation = m_program->uniformLocation("projMatrix")) < 0) - qDebug() << "Unable to find shader location for " << "projMatrix"; - - if ((m_lDirectionLocation = m_program->uniformLocation("lDirection")) < 0) - qDebug() << "Unable to find m_shader location for" << "lDirection"; - - if ((m_normalMatrixLoc = m_program->uniformLocation("normalMatrix")) < 0) - qDebug() << "Unable to find m_shader location for" << "normalMatrix"; - - if ((m_vNormalLocation = m_program->attributeLocation("vNormal")) < 0) - qDebug() << "Unable to find m_shader location for" << "vNormal"; - - if ((s_vUvLocation = m_program->attributeLocation("vUv")) < 0) - qDebug() << "Unable to find shader location for " << "vUv"; - - if ((m_isSkyLoc = m_program->uniformLocation("isSky")) < 0) - qDebug() << "Unable to find m_shader location for" << "isSky"; - - if ((m_isPhongLoc = m_program->uniformLocation("isPhong")) < 0) - qDebug() << "Unable to find m_shader location for" << "isPhong"; - - if ((m_lDirLoc = m_program->uniformLocation("lDirection")) < 0) - qDebug() << "Unable to find m_shader location for" << "lDirection"; - - if ((m_skyMultLoc = m_program->uniformLocation("skyMult")) < 0) - qDebug() << "Unable to find m_shader location for" << "skyMult"; - - - /* - * Adding Texture Shader - */ - /* - textureRenderShaderprogram = new QOpenGLShaderProgram; - if (!textureRenderShaderprogram->addShaderFromSourceFile(QOpenGLShader::Vertex, "src/shaders/textureShader.vert")) { - cerr << "Unable to load Shader" << endl - << "Log file:" << endl; - qDebug() << textureRenderShaderprogram->log(); - } - if (!textureRenderShaderprogram->addShaderFromSourceFile(QOpenGLShader::Fragment, "src/shaders/textureShader.frag")) { - cerr << "Unable to load Shader" << endl - << "Log file:" << endl; - qDebug() << textureRenderShaderprogram->log(); - } - - textureRenderShaderprogram->link(); -*/ - /* - * Adding Skybox Shaders - * - */ - skyboxRenderShaderProgram = new QOpenGLShaderProgram; - if (!skyboxRenderShaderProgram->addShaderFromSourceFile(QOpenGLShader::Vertex, "src/shaders/skyboxShader.vert")) { - cerr << "Unable to load Shader" << endl - << "Log file:" << endl; - qDebug() << skyboxRenderShaderProgram->log(); - } - if (!skyboxRenderShaderProgram->addShaderFromSourceFile(QOpenGLShader::Fragment, "src/shaders/skyboxShader.frag")) { - cerr << "Unable to load Shader" << endl - << "Log file:" << endl; - qDebug() << skyboxRenderShaderProgram->log(); - } - - skyboxRenderShaderProgram->link(); - -// if ((s_texCoordsLocation = m_program->attributeLocation("texCoords")) < 0) -// qDebug() << "Unable to find shader location for " << "vPosition"; - - if ((s_vPositionLocation = skyboxRenderShaderProgram->attributeLocation("vPosition")) < 0) - qDebug() << "Unable to find shader location for " << "vPosition"; - - - if ((s_projMatrixLocation = skyboxRenderShaderProgram->uniformLocation("projMatrix")) < 0) - qDebug() << "Unable to find shader location for " << "projMatrix"; - - - if ((s_mvMatrixLocation = skyboxRenderShaderProgram->uniformLocation("mvMatrix")) < 0) - qDebug() << "Unable to find shader location for " << "mvMatrix"; - - s_texture = new QOpenGLTexture(QImage("src/data/skybox.jpg"));/*/ - s_texture = new QOpenGLTexture(QImage("src/data/uvLayoutGrid.png"));//*/ - s_texture->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear); - s_texture->setMagnificationFilter(QOpenGLTexture::Linear); -} - -// Creates the basic shapes in memory. We only have 3, so we just prep them all in advance. -void Viewer::initGeometries() -{ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable( GL_BLEND ); - //glEnable( GL_CULL_FACE ); - glFrontFace( GL_CCW ); - //glCullFace( GL_BACK ); - glClearColor(0.0,0.0,0.0,0.0); - - // Create our VertexArrays Objects and VertexBuffer Objects - glGenVertexArrays(NumVAOs, m_VAOs); - glGenBuffers(NumBuffers, m_Buffers); - - // Create our pentagone object, store its vertices on the graphic card, and - // bind the data to the vPosition attribute of the shader - GLfloat verticesCube[numVerticesCube][3] = { // 12 triangles == 6 squares - //Front, if Z is towards us - { -0.5, 0.5, 0.5 }, { -0.5, -0.5, 0.5 }, { 0.5, -0.5, 0.5 }, - { 0.5, -0.5, 0.5 }, { 0.5, 0.5, 0.5 }, { -0.5, 0.5, 0.5 }, - //Back - { -0.5, 0.5, -0.5 }, { 0.5, 0.5, -0.5 }, { 0.5, -0.5, -0.5 }, - { 0.5, -0.5, -0.5 }, { -0.5, -0.5, -0.5 }, { -0.5, 0.5, -0.5 }, - //Right - { -0.5, 0.5, 0.5 }, { -0.5, 0.5, -0.5 }, { -0.5, -0.5, -0.5 }, - { -0.5, -0.5, -0.5 }, { -0.5, -0.5, 0.5 }, { -0.5, 0.5, 0.5 }, - //Left - { 0.5, 0.5, 0.5 }, { 0.5, -0.5, -0.5 }, { 0.5, 0.5, -0.5 }, - { 0.5, -0.5, -0.5 }, { 0.5, 0.5, 0.5 }, { 0.5, -0.5, 0.5 }, - //Top - { -0.5, 0.5, 0.5 }, { 0.5, 0.5, 0.5 }, { 0.5, 0.5, -0.5 }, - { 0.5, 0.5, -0.5 }, { -0.5, 0.5, -0.5 }, { -0.5, 0.5, 0.5 }, - //Bottom - { -0.5, -0.5, 0.5 }, { 0.5, -0.5, -0.5 }, { 0.5, -0.5, 0.5 }, - { 0.5, -0.5, -0.5 }, { -0.5, -0.5, 0.5 }, { -0.5, -0.5, -0.5 } - }; - - GLfloat uvs[numVerticesCube][2] = { - - { 1.0, .25 }, { 1.0, .50 }, { .75, .50 }, - { .75, .50 }, { .75, .25 }, { 1.0, .25 }, - - { .25, .25 }, { .50, .25 }, { .50, .50 }, - { .50, .50 }, { .25, .50 }, { .25, .25 }, - - { .00, .25}, { .25, .25}, { .25, .50}, - { .25, .50}, { .00, .50}, { .00, .25}, - - { .75, .25}, { .50, .50}, { .50, .25}, - { .50, .50}, { .75, .25}, { .75, .50}, - - { .25, .00 }, { .49, .00 }, { .49, .25 }, - { .49, .25 }, { .25, .25 }, { .25, .00 }, - - { .25, .50 }, { .49, .75 }, { .49, .50 }, - { .49, .75 }, { .25, .50 }, { .25, .75 }, - - }; - - GLfloat normals[numVerticesCube][3] = { - { 0.0, 0.0, 1.0 }, {0.0, 0.0, 1.0}, {0.0, 0.0, 1.0}, - { 0.0, 0.0, 1.0 }, {0.0, 0.0, 1.0}, {0.0, 0.0, 1.0}, - - { 0.0, 0.0, -1.0 }, {0.0, 0.0, -1.0}, {0.0, 0.0, -1.0}, - { 0.0, 0.0, -1.0 }, {0.0, 0.0, -1.0}, {0.0, 0.0, -1.0}, - - { -1.0, 0.0, 0.0 }, {-1.0, 0.0, 0.0}, {-1.0, 0.0, 0.0}, - { -1.0, 0.0, 0.0 }, {-1.0, 0.0, 0.0}, {-1.0, 0.0, 0.0}, - - { 1.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, - { 1.0, 0.0, 0.0 }, {1.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, - - { 0.0, 1.0, 0.0 }, {0.0, 1.0, 0.0}, {0.0, 1.0, 0.0}, - { 0.0, 1.0, 0.0 }, {0.0, 1.0, 0.0}, {0.0, 1.0, 0.0}, - - { 0.0, -1.0, 0.0 }, {0.0, -1.0, 0.0}, {0.0, -1.0, 0.0}, - { 0.0, -1.0, 0.0 }, {0.0, -1.0, 0.0}, {0.0, -1.0, 0.0} - }; - - - // Fill vertex VBO - GLsizeiptr offsetVertices = 0; - GLsizeiptr offsetNormals = sizeof(verticesCube); - GLsizeiptr offsetUV = offsetNormals + sizeof(normals); - GLsizeiptr dataSize = offsetUV + sizeof(uvs); - - - glBindVertexArray(m_VAOs[VAO_Cube]); -// glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[VBO_Cube]); - glGenBuffers(NumBuffers, m_Buffers); - glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[VBO_Cube]); - glBufferData(GL_ARRAY_BUFFER, dataSize, - NULL, GL_STATIC_DRAW); - - glBufferSubData(GL_ARRAY_BUFFER, offsetVertices, sizeof(verticesCube), verticesCube); - glBufferSubData(GL_ARRAY_BUFFER, offsetNormals, sizeof(normals), normals); - glBufferSubData(GL_ARRAY_BUFFER, offsetUV, sizeof(uvs), uvs); - - glVertexAttribPointer(m_vPositionLocation, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); - glEnableVertexAttribArray(m_vPositionLocation); - - glVertexAttribPointer(m_vNormalLocation, 3, GL_FLOAT, GL_TRUE, 0, BUFFER_OFFSET(offsetNormals)); - glEnableVertexAttribArray(m_vNormalLocation); - - glVertexAttribPointer(s_vUvLocation, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(offsetUV)); - glEnableVertexAttribArray(s_vUvLocation); - -} - -void Viewer::visit(Cube &s) -{ - QMatrix4x4 modelViewMatrix = modelStack.top() * QMatrix4x4(s.transform); - - int faces = floor(numVerticesCube/6); - for(int i = 0; i < faces; i++){ // 6 vertexes par face - glBindVertexArray(m_VAOs[VAO_Cube]); - m_program->setUniformValue(m_isSkyLoc, false); - m_program->setUniformValue(m_isPhongLoc, true); - m_program->setUniformValue(m_mvMatrixLocation, modelViewMatrix); - m_program->setUniformValue(m_normalMatrixLoc, modelViewMatrix.normalMatrix()); - m_program->setUniformValue(m_colorLocation, s.getColor()); - - glDrawArrays(GL_TRIANGLES, i*6, 6); - } -} - -void Viewer::visit(SceneGroup &s) -{ - // Build compound transformation matrix - QMatrix4x4 currentMatrix = modelStack.top() * QMatrix4x4(s.transform); - modelStack.push(currentMatrix); - - while(s.hasNext()) { - // Get next leaf - GlNode* current = s.getChild(); - - // Draw/Traverse child - current->accept(*this); - } - - // Return model matrix to previous state - modelStack.pop(); -} - -void Viewer::setPhong(bool on) { - m_program->setUniformValue(m_isPhongLoc, on); - if(on) std::cout << "Phong ON\n"; - else std::cout << "Phong OFF\n"; - this->update(); -} - -void Viewer::changeColor(QColor c){ - if(activeCell->getChildren()->size()){ - Shape* shape = dynamic_cast (activeCell->childAt(0)); - shape->setColor(c); - } - activeColor = new QColor(c); - this->update(); -} - -Shape* Viewer::pickGeom(int x, int y){ - QMap mapColorToShape; - QColor c; - QRgb startColor = 0xFF0001; // alpha must be 100%, glReadPixels doesn't resturn alpha - unsigned char pixelData[3]; - // Traverse tree - /* TODO: Make this recurse through SceneGroups, with like "populateMap(map, root, color)" - * Right now it's fine because we have simple Minecraft rules - * but could be important in the future - */ - QOpenGLShaderProgram *lastshader = m_program; - - //colorPickerShaderProgram->bind(); - - std::cout << "Iterating through " << root.getChildren()->size() << "items"<size(); i(root.childAt(i)); - Shape* currentCube; - - if(current->getChildren()->size()) - { - currentCube = dynamic_cast(current->childAt(0)); - } - - if(currentCube) - { - c.setRgb(startColor); - mapColorToShape.insert(c.rgb(), currentCube); - std::cout << "Setting " << currentCube << " to " << c.red() << " " << c.green() << " " << c.blue() << " " << c.alpha() << endl; - currentCube->setColor(c); - startColor+=6; - } - } - - update(); - - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - // for debugging purposes - /*QImage *im = new QImage(128,128, QImage::Format_RGB32); - for(int i = 0; i< 128; i++){ - for(int j = 0; j< 128; j++){ - glReadPixels(x-64+i, y+64-j, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixelData); - QColor* pickedColor = new QColor(pixelData[0], pixelData[1], pixelData[2]); - if(i==64&&j==64) pickedColor->setRgba(0xFFFFFFFF); - im->setPixelColor(i, j, pickedColor->rgb()); - } - } - im->save("./screenshot.bmp");//*/ - - glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixelData); - QColor* pickedColor = new QColor(pixelData[0], pixelData[1], pixelData[2]); - unsigned int pickedInt = pickedColor->rgb(); - Shape* pickedShape = mapColorToShape.value(pickedInt - (pickedInt % 6) + 1); - std::cout << "Picked Color: " << pickedColor->red() << " " << pickedColor->green() << " " << pickedColor->blue() << " " << pickedColor->alpha() << endl; - std::cout << "Picked Shape: " << pickedShape << endl; - - - - //lastshader->bind(); - return pickedShape; -} +/**************************************************************************** + + Copyright (C) 2002-2008 Gilles Debunne. All rights reserved. + + This file is part of the QGLViewer library version 2.3.6. + + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + versions 2.0 or 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + In addition, as a special exception, Gilles Debunne gives you certain + additional rights, described in the file GPL_EXCEPTION in this package. + + libQGLViewer uses dual licensing. Commercial/proprietary software must + purchase a libQGLViewer Commercial License. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ + +#include "simpleViewer.h" +#include "../interfaces/visitor.h" +#include "../glnodes/scenegroup.h" +#include "../glnodes/shapes.h" +#include + +#include +#include + +#include + +#include +#include +#include +#include +using namespace std; + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) +#define GRID_SIZE 10; + +namespace +{ + const int numVerticesCube = 12*3; + const double frame_limit = 5; + const double inc_mult = 5; + const double inc_offset = 1.05; + + int m_lDirectionLocation; + int m_normalMatrixLoc; + + QVector3D sun = QVector3D(0,-1,0); + QMatrix4x4 sunRotate; +} + +class SkyboxCamera : public qglviewer::Camera +{ + virtual qreal zNear() const { return 0.01; } + virtual qreal zFar() const { return 100.0; } +}; + +Viewer::Viewer() +{ + activeColor = new QColor(255, 255, 255, 255); + activeCell = nullptr; + activeShape = 0; + angle_mult = 0.1; +} + +Viewer::~Viewer() +{ + cleanup(); +} + +void Viewer::cleanup() +{ + makeCurrent(); + + // Delete shaders + delete m_program; + m_program = 0; + + // Delete buffers + glDeleteBuffers(NumBuffers, m_Buffers); + glDeleteVertexArrays(NumVAOs, m_VAOs); + + doneCurrent(); +} + +void Viewer::drawSkybox() +{ + // Use the Skybox Shaders + //skyboxRenderShaderProgram->bind(); + s_texture->bind(); + + // Get projection and camera transformations + QMatrix4x4 projectionMatrix; + QMatrix4x4 modelViewMatrix; + camera()->getProjectionMatrix(projectionMatrix); + camera()->getModelViewMatrix(modelViewMatrix); + + // Increase size of skybox + + modelViewMatrix.scale(101); + + float colorMult = 0.2 + std::fabs(0.8 * cos(std::fmod(angle_mult * frame + 300, 360) / 360 * M_PI)); + + m_program->setUniformValue(m_skyMultLoc, colorMult); + m_program->setUniformValue(m_mvMatrixLocation, modelViewMatrix); + m_program->setUniformValue(m_isSkyLoc, true); + + int faces = floor(numVerticesCube/6); + for(int i = 0; i < faces; i++){ // 6 vertexes par face + glBindVertexArray(m_VAOs[VAO_Cube]); + + glDrawArrays(GL_TRIANGLES, i*6, 6); + } +} + +void Viewer::draw() +{ + drawSkybox(); + + // Bind our vertex/fragment shaders + m_program->bind(); + + // Get projection and camera transformations + QMatrix4x4 projectionMatrix; + QMatrix4x4 modelViewMatrix; + camera()->getProjectionMatrix(projectionMatrix); + camera()->getModelViewMatrix(modelViewMatrix); + + // Prepare a transformation stack + + // stack modelStack; + + //modelViewMatrix.rotate(45, 0, 1, 0); + // uncomment this and the cube translation in init() + // to see the cube spin + /*rot = QQuaternion::fromAxisAndAngle(1, 0, 1, 90/60 * frame); + modelViewMatrix.rotate(rot); + projectionMatrix.translate(0, -5, 0); + projectionMatrix.rotate(15, 1, 0, 0);//*/ + + modelViewMatrix.rotate(30,0,1,0); + + m_program->setUniformValue(m_projMatrixLocation, projectionMatrix); + m_program->setUniformValue(m_mvMatrixLocation, modelViewMatrix); + + // Adjust sun position + + float rotAngle = std::fmod(angle_mult * frame, 360); + sunRotate.rotate(rotAngle, 1, 0, 0); + + m_program->setUniformValue(m_lDirLoc, (sun * sunRotate)); + + // Traverse the Scene in order to draw its components + + modelStack.push(modelViewMatrix); + root.accept(*this); + frame++; + + sunRotate.setToIdentity(); + //float rotAngle = (frame * angle_mult) % 360; + + update(); +} + +void Viewer::mouseMoveEvent(QMouseEvent* e) { + //cout << "Viewer::mouseMoveEvent(QMouseEvent* e)" << endl; + // Normal QGLViewer behavior. + QGLViewer::mouseMoveEvent(e); +} + +void Viewer::mousePressEvent(QMouseEvent* e) { + // Auto Return, but old code left in as reference + + // TODO: figure out how to get this weird offset ↓↓ frame position maybe? + int x = this->x() + e->x() + 10; + int y = this->parentWidget()->height() - e->y() + 21; + std::cout << "--------------------------------------------------\nPicking shape at " << x << " (" << this->x() << " + " << e->x() << "), " << y << endl; + std::cout << "Window geom: " << this->window()->size().width() << "w, " << this->window()->size().height() << "h" << endl; + Shape* selectedShape = pickGeom(x, y); + // OpenGL coords start at the window's bottom-left, not the frame's. ugh. + + QGLViewer::mousePressEvent(e); +} + +void Viewer::deselect(){ + std::cout << "Deselecting cell " << activeCell << endl; + if(activeCell != nullptr && activeCell->getChildren()->size()){ + std::cout << "Cell has children..." << endl; + Shape* shape = dynamic_cast (activeCell->childAt(0)); + QColor newColor = shape->getColor(); + std::cout << newColor.Rgb << endl; + newColor.setAlpha(180); + shape->setColor(newColor); + }else{ + std::cout << "Cell has no children, moving on" << endl; + } + this->update(); +} + +void Viewer::mouseReleaseEvent(QMouseEvent* e) { + //cout << "Viewer::mouseReleaseEvent(QMouseEvent* e)" << endl; + QGLViewer::mouseReleaseEvent(e); +} + +void Viewer::init() +{ + SkyboxCamera *_cam = new SkyboxCamera(); + setCamera(_cam); + //camera()->setType(qglviewer::Camera::PERSPECTIVE); + //setMouseBinding(Qt::NoModifier, Qt::LeftButton, CAMERA, SCREEN_ROTATE); + //setMouseBinding(Qt::AltModifier, Qt::LeftButton, CAMERA, NO_MOUSE_ACTION); + //setMouseBinding(Qt::NoModifier, Qt::MouseButton(Qt::LeftButton + Qt::MidButton), CAMERA, NO_MOUSE_ACTION); + //setMouseBinding(Qt::ControlModifier, Qt::MouseButton(Qt::LeftButton + Qt::MidButton), CAMERA, NO_MOUSE_ACTION); + //setMouseBinding(Qt::ShiftModifier, Qt::MouseButton(Qt::LeftButton + Qt::MidButton), CAMERA, NO_MOUSE_ACTION); + + // Our scene will be from -5 to 5 in X and Y (the grid will be 10x10). + setSceneRadius(5); + showEntireScene(); + + // Init OpenGL objects + connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &Viewer::cleanup); + initializeOpenGLFunctions(); + + // Init shaders & geometry + initShaders(); + initGeometries(); + + sunRotate.rotate(-15,0,0,1); + sun = sun * sunRotate; + + { + Shape* cube = new Cube(); + cube->setColor(*activeColor); + + // uncomment this and the quaternion transformation in draw() + // to see the cube rotate. This is how we can easily make the sun. + // cube->transform.translate(3, 0, 0); + + SceneGroup *c = new SceneGroup(); + c->addChild(cube); + root.addChild(c); + } +} + +void Viewer::initShaders() +{ + + + // Load vertex and fragment shaders + m_program = new QOpenGLShaderProgram; + colorPickerShaderProgram = m_program; + if (!m_program->addShaderFromSourceFile(QOpenGLShader::Vertex, "src/shaders/basicShader.vert")) { + cerr << "Unable to load Shader" << endl + << "Log file:" << endl; + qDebug() << m_program->log(); + } + if (!m_program->addShaderFromSourceFile(QOpenGLShader::Fragment, "src/shaders/basicShader.frag")) { + cerr << "Unable to load Shader" << endl + << "Log file:" << endl; + qDebug() << m_program->log(); + } + m_program->link(); + m_program->bind(); // Note: This is equivalent to glUseProgram(programId()); + + // Specify shader input paramters + // The strings "vPosition", "mvMatrix", etc. have to match an attribute name in the vertex shader. + if ((m_vPositionLocation = m_program->attributeLocation("vPosition")) < 0) + qDebug() << "Unable to find shader location for " << "vPosition"; + + if ((m_colorLocation = m_program->uniformLocation("color")) < 0) + qDebug() << "Unable to find shader location for " << "color"; + + if ((m_mvMatrixLocation = m_program->uniformLocation("mvMatrix")) < 0) + qDebug() << "Unable to find shader location for " << "mvMatrix"; + + if ((m_projMatrixLocation = m_program->uniformLocation("projMatrix")) < 0) + qDebug() << "Unable to find shader location for " << "projMatrix"; + + if ((m_lDirectionLocation = m_program->uniformLocation("lDirection")) < 0) + qDebug() << "Unable to find m_shader location for" << "lDirection"; + + if ((m_normalMatrixLoc = m_program->uniformLocation("normalMatrix")) < 0) + qDebug() << "Unable to find m_shader location for" << "normalMatrix"; + + if ((m_vNormalLocation = m_program->attributeLocation("vNormal")) < 0) + qDebug() << "Unable to find m_shader location for" << "vNormal"; + + if ((s_vUvLocation = m_program->attributeLocation("vUv")) < 0) + qDebug() << "Unable to find shader location for " << "vUv"; + + if ((m_isSkyLoc = m_program->uniformLocation("isSky")) < 0) + qDebug() << "Unable to find m_shader location for" << "isSky"; + + if ((m_isPhongLoc = m_program->uniformLocation("isPhong")) < 0) + qDebug() << "Unable to find m_shader location for" << "isPhong"; + + if ((m_lDirLoc = m_program->uniformLocation("lDirection")) < 0) + qDebug() << "Unable to find m_shader location for" << "lDirection"; + + if ((m_skyMultLoc = m_program->uniformLocation("skyMult")) < 0) + qDebug() << "Unable to find m_shader location for" << "skyMult"; + + if ((m_pickerColor = m_program->uniformLocation("isPickerColor")) < 0) + qDebug() << "Unable to find m_shader location for" << "isPickerColor"; + + + /* + * Adding Texture Shader + */ + /* + textureRenderShaderprogram = new QOpenGLShaderProgram; + if (!textureRenderShaderprogram->addShaderFromSourceFile(QOpenGLShader::Vertex, "src/shaders/textureShader.vert")) { + cerr << "Unable to load Shader" << endl + << "Log file:" << endl; + qDebug() << textureRenderShaderprogram->log(); + } + if (!textureRenderShaderprogram->addShaderFromSourceFile(QOpenGLShader::Fragment, "src/shaders/textureShader.frag")) { + cerr << "Unable to load Shader" << endl + << "Log file:" << endl; + qDebug() << textureRenderShaderprogram->log(); + } + + textureRenderShaderprogram->link(); +*/ + /* + * Adding Skybox Shaders + * + */ + skyboxRenderShaderProgram = new QOpenGLShaderProgram; + if (!skyboxRenderShaderProgram->addShaderFromSourceFile(QOpenGLShader::Vertex, "src/shaders/skyboxShader.vert")) { + cerr << "Unable to load Shader" << endl + << "Log file:" << endl; + qDebug() << skyboxRenderShaderProgram->log(); + } + if (!skyboxRenderShaderProgram->addShaderFromSourceFile(QOpenGLShader::Fragment, "src/shaders/skyboxShader.frag")) { + cerr << "Unable to load Shader" << endl + << "Log file:" << endl; + qDebug() << skyboxRenderShaderProgram->log(); + } + + skyboxRenderShaderProgram->link(); + +// if ((s_texCoordsLocation = m_program->attributeLocation("texCoords")) < 0) +// qDebug() << "Unable to find shader location for " << "vPosition"; + + if ((s_vPositionLocation = skyboxRenderShaderProgram->attributeLocation("vPosition")) < 0) + qDebug() << "Unable to find shader location for " << "vPosition"; + + + if ((s_projMatrixLocation = skyboxRenderShaderProgram->uniformLocation("projMatrix")) < 0) + qDebug() << "Unable to find shader location for " << "projMatrix"; + + + if ((s_mvMatrixLocation = skyboxRenderShaderProgram->uniformLocation("mvMatrix")) < 0) + qDebug() << "Unable to find shader location for " << "mvMatrix"; + + s_texture = new QOpenGLTexture(QImage("src/data/skybox.jpg"));/*/ + s_texture = new QOpenGLTexture(QImage("src/data/uvLayoutGrid.png"));//*/ + s_texture->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear); + s_texture->setMagnificationFilter(QOpenGLTexture::Linear); +} + +// Creates the basic shapes in memory. We only have 3, so we just prep them all in advance. +void Viewer::initGeometries() +{ + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable( GL_BLEND ); + //glEnable( GL_CULL_FACE ); + glFrontFace( GL_CCW ); + //glCullFace( GL_BACK ); + glClearColor(0.0,0.0,0.0,0.0); + + // Create our VertexArrays Objects and VertexBuffer Objects + glGenVertexArrays(NumVAOs, m_VAOs); + glGenBuffers(NumBuffers, m_Buffers); + + // Create our pentagone object, store its vertices on the graphic card, and + // bind the data to the vPosition attribute of the shader + GLfloat verticesCube[numVerticesCube][3] = { // 12 triangles == 6 squares + //Front, if Z is towards us + { -0.5, 0.5, 0.5 }, { -0.5, -0.5, 0.5 }, { 0.5, -0.5, 0.5 }, + { 0.5, -0.5, 0.5 }, { 0.5, 0.5, 0.5 }, { -0.5, 0.5, 0.5 }, + //Back + { -0.5, 0.5, -0.5 }, { 0.5, 0.5, -0.5 }, { 0.5, -0.5, -0.5 }, + { 0.5, -0.5, -0.5 }, { -0.5, -0.5, -0.5 }, { -0.5, 0.5, -0.5 }, + //Right + { -0.5, 0.5, 0.5 }, { -0.5, 0.5, -0.5 }, { -0.5, -0.5, -0.5 }, + { -0.5, -0.5, -0.5 }, { -0.5, -0.5, 0.5 }, { -0.5, 0.5, 0.5 }, + //Left + { 0.5, 0.5, 0.5 }, { 0.5, -0.5, -0.5 }, { 0.5, 0.5, -0.5 }, + { 0.5, -0.5, -0.5 }, { 0.5, 0.5, 0.5 }, { 0.5, -0.5, 0.5 }, + //Top + { -0.5, 0.5, 0.5 }, { 0.5, 0.5, 0.5 }, { 0.5, 0.5, -0.5 }, + { 0.5, 0.5, -0.5 }, { -0.5, 0.5, -0.5 }, { -0.5, 0.5, 0.5 }, + //Bottom + { -0.5, -0.5, 0.5 }, { 0.5, -0.5, -0.5 }, { 0.5, -0.5, 0.5 }, + { 0.5, -0.5, -0.5 }, { -0.5, -0.5, 0.5 }, { -0.5, -0.5, -0.5 } + }; + + GLfloat uvs[numVerticesCube][2] = { + + { 1.0, .25 }, { 1.0, .50 }, { .75, .50 }, + { .75, .50 }, { .75, .25 }, { 1.0, .25 }, + + { .25, .25 }, { .50, .25 }, { .50, .50 }, + { .50, .50 }, { .25, .50 }, { .25, .25 }, + + { .00, .25}, { .25, .25}, { .25, .50}, + { .25, .50}, { .00, .50}, { .00, .25}, + + { .75, .25}, { .50, .50}, { .50, .25}, + { .50, .50}, { .75, .25}, { .75, .50}, + + { .25, .00 }, { .49, .00 }, { .49, .25 }, + { .49, .25 }, { .25, .25 }, { .25, .00 }, + + { .25, .50 }, { .49, .75 }, { .49, .50 }, + { .49, .75 }, { .25, .50 }, { .25, .75 }, + + }; + + GLfloat normals[numVerticesCube][3] = { + { 0.0, 0.0, 1.0 }, {0.0, 0.0, 1.0}, {0.0, 0.0, 1.0}, + { 0.0, 0.0, 1.0 }, {0.0, 0.0, 1.0}, {0.0, 0.0, 1.0}, + + { 0.0, 0.0, -1.0 }, {0.0, 0.0, -1.0}, {0.0, 0.0, -1.0}, + { 0.0, 0.0, -1.0 }, {0.0, 0.0, -1.0}, {0.0, 0.0, -1.0}, + + { -1.0, 0.0, 0.0 }, {-1.0, 0.0, 0.0}, {-1.0, 0.0, 0.0}, + { -1.0, 0.0, 0.0 }, {-1.0, 0.0, 0.0}, {-1.0, 0.0, 0.0}, + + { 1.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, + { 1.0, 0.0, 0.0 }, {1.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, + + { 0.0, 1.0, 0.0 }, {0.0, 1.0, 0.0}, {0.0, 1.0, 0.0}, + { 0.0, 1.0, 0.0 }, {0.0, 1.0, 0.0}, {0.0, 1.0, 0.0}, + + { 0.0, -1.0, 0.0 }, {0.0, -1.0, 0.0}, {0.0, -1.0, 0.0}, + { 0.0, -1.0, 0.0 }, {0.0, -1.0, 0.0}, {0.0, -1.0, 0.0} + }; + + + // Fill vertex VBO + GLsizeiptr offsetVertices = 0; + GLsizeiptr offsetNormals = sizeof(verticesCube); + GLsizeiptr offsetUV = offsetNormals + sizeof(normals); + GLsizeiptr dataSize = offsetUV + sizeof(uvs); + + + glBindVertexArray(m_VAOs[VAO_Cube]); +// glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[VBO_Cube]); + glGenBuffers(NumBuffers, m_Buffers); + glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[VBO_Cube]); + glBufferData(GL_ARRAY_BUFFER, dataSize, + NULL, GL_STATIC_DRAW); + + glBufferSubData(GL_ARRAY_BUFFER, offsetVertices, sizeof(verticesCube), verticesCube); + glBufferSubData(GL_ARRAY_BUFFER, offsetNormals, sizeof(normals), normals); + glBufferSubData(GL_ARRAY_BUFFER, offsetUV, sizeof(uvs), uvs); + + glVertexAttribPointer(m_vPositionLocation, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); + glEnableVertexAttribArray(m_vPositionLocation); + + glVertexAttribPointer(m_vNormalLocation, 3, GL_FLOAT, GL_TRUE, 0, BUFFER_OFFSET(offsetNormals)); + glEnableVertexAttribArray(m_vNormalLocation); + + glVertexAttribPointer(s_vUvLocation, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(offsetUV)); + glEnableVertexAttribArray(s_vUvLocation); + +} + +void Viewer::visit(Cube &s) +{ + QMatrix4x4 modelViewMatrix = modelStack.top() * QMatrix4x4(s.transform); + + int faces = floor(numVerticesCube/6); + for(int i = 0; i < faces; i++){ // 6 vertexes par face + glBindVertexArray(m_VAOs[VAO_Cube]); + m_program->setUniformValue(m_isSkyLoc, false); + m_program->setUniformValue(m_isPhongLoc, true); + m_program->setUniformValue(m_pickerColor, true); + m_program->setUniformValue(m_mvMatrixLocation, modelViewMatrix); + m_program->setUniformValue(m_normalMatrixLoc, modelViewMatrix.normalMatrix()); + m_program->setUniformValue(m_colorLocation, s.getColor()); + + glDrawArrays(GL_TRIANGLES, i*6, 6); + } +} + +void Viewer::visit(SceneGroup &s) +{ + // Build compound transformation matrix + QMatrix4x4 currentMatrix = modelStack.top() * QMatrix4x4(s.transform); + modelStack.push(currentMatrix); + + while(s.hasNext()) { + // Get next leaf + GlNode* current = s.getChild(); + + // Draw/Traverse child + current->accept(*this); + } + + // Return model matrix to previous state + modelStack.pop(); +} + +void Viewer::setPhong(bool on) { + m_program->setUniformValue(m_isPhongLoc, on); + if(on) std::cout << "Phong ON\n"; + else std::cout << "Phong OFF\n"; + this->update(); +} + +void Viewer::changeColor(QColor c){ + if(activeCell->getChildren()->size()){ + Shape* shape = dynamic_cast (activeCell->childAt(0)); + shape->setColor(c); + } + activeColor = new QColor(c); + this->update(); +} + +Shape* Viewer::pickGeom(int x, int y){ + QMap mapColorToShape; + QColor c; + QRgb startColor = 0xFF0001; // alpha must be 100%, glReadPixels doesn't resturn alpha + unsigned char pixelData[3]; + // Traverse tree + /* TODO: Make this recurse through SceneGroups, with like "populateMap(map, root, color)" + * Right now it's fine because we have simple Minecraft rules + * but could be important in the future + */ + + m_program->setUniformValue(m_pickerColor, true); + + std::cout << "Iterating through " << root.getChildren()->size() << "items"<size(); i(root.childAt(i)); + Shape* currentCube; + + if(current->getChildren()->size()) + { + currentCube = dynamic_cast(current->childAt(0)); + } + + if(currentCube) + { + c.setRgb(startColor); + mapColorToShape.insert(c.rgb(), currentCube); + std::cout << "Setting " << currentCube << " to " << c.red() << " " << c.green() << " " << c.blue() << " " << c.alpha() << endl; + currentCube->setColor(c); + startColor+=6; + } + } + + root.accept(*this); + update(); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + // for debugging purposes + /*QImage *im = new QImage(128,128, QImage::Format_RGB32); + for(int i = 0; i< 128; i++){ + for(int j = 0; j< 128; j++){ + glReadPixels(x-64+i, y+64-j, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixelData); + QColor* pickedColor = new QColor(pixelData[0], pixelData[1], pixelData[2]); + if(i==64&&j==64) pickedColor->setRgba(0xFFFFFFFF); + im->setPixelColor(i, j, pickedColor->rgb()); + } + } + im->save("./screenshot.bmp");//*/ + + glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixelData); + QColor* pickedColor = new QColor(pixelData[0], pixelData[1], pixelData[2]); + unsigned int pickedInt = pickedColor->rgb(); + Shape* pickedShape = mapColorToShape.value(pickedInt - (pickedInt % 6) + 1); + std::cout << "Picked Color: " << pickedColor->red() << " " << pickedColor->green() << " " << pickedColor->blue() << " " << pickedColor->alpha() << endl; + std::cout << "Picked Shape: " << pickedShape << endl; + + return pickedShape; +} diff --git a/src/viewer/simpleViewer.h b/src/viewer/simpleViewer.h index fc542bd..2b27c43 100644 --- a/src/viewer/simpleViewer.h +++ b/src/viewer/simpleViewer.h @@ -1,122 +1,123 @@ -/**************************************************************************** - - Copyright (C) 2002-2008 Gilles Debunne. All rights reserved. - - This file is part of the QGLViewer library version 2.3.6. - - http://www.libqglviewer.com - contact@libqglviewer.com - - This file may be used under the terms of the GNU General Public License - versions 2.0 or 3.0 as published by the Free Software Foundation and - appearing in the LICENSE file included in the packaging of this file. - In addition, as a special exception, Gilles Debunne gives you certain - additional rights, described in the file GPL_EXCEPTION in this package. - - libQGLViewer uses dual licensing. Commercial/proprietary software must - purchase a libQGLViewer Commercial License. - - This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - -*****************************************************************************/ - -#ifndef SIMPLEVIEWER_H -#define SIMPLEVIEWER_H - -#include -#include -#include -#include -#include -#include -#include "../interfaces/visitor.h" -#include "../glnodes/glnode.h" -#include "../glnodes/scenegroup.h" -#include "../glnodes/shapes.h" -#include - -QT_FORWARD_DECLARE_CLASS(QOpenGLShaderProgram) - -class Viewer : public QGLViewer, - protected QOpenGLFunctions_4_0_Core, - public Visitor -{ -Q_OBJECT -public: - Viewer(); - ~Viewer(); - - virtual void visit(SceneGroup &s); - virtual void visit(Cube &s); - -public slots: - void cleanup(); - void changeColor(QColor); - void setPhong(bool); - -signals: - int shapeSelected(int); - -protected : - virtual void draw(); - virtual void drawSkybox(); - virtual void init(); - - virtual void mouseMoveEvent(QMouseEvent* e); - virtual void mouseReleaseEvent(QMouseEvent* e); - virtual void mousePressEvent(QMouseEvent *e); - - SceneGroup root; - std::stack modelStack; - -private: - void initShaders(); - void initGeometries(); - void deselect(); - Shape* pickGeom(int, int); - - // shader switching variables and constants; - QOpenGLShaderProgram *colorPickerShaderProgram; - QOpenGLShaderProgram *textureRenderShaderprogram; - QOpenGLShaderProgram *skyboxRenderShaderProgram; - QOpenGLShaderProgram *m_program; - int m_vPositionLocation; - int m_colorLocation; - int m_projMatrixLocation; - int m_mvMatrixLocation; - - int s_texCoordsLocation; - int s_vPositionLocation; - int s_mvMatrixLocation; - int s_colorLocation; - int s_projMatrixLocation; - int s_skyboxCubemapLocation; - int s_vUvLocation; - int m_vNormalLocation; - - int m_isPhongLoc; - int m_isSkyLoc; - int m_lDirLoc; - int m_skyMultLoc; - - float angle_mult; - - QOpenGLTexture *s_texture; - - SceneGroup* activeCell; - QColor* activeColor; - int activeShape; - - enum VAO_IDs { VAO_Cube, NumVAOs }; - enum Buffer_IDs { VBO_Cube, NumBuffers }; - - GLuint m_VAOs[NumVAOs]; - GLuint m_Buffers[NumBuffers]; - - Shape* generateShapeFromIndex(int); - - QQuaternion rot; - unsigned int frame; -}; - -#endif // SIMPLEVIEWER_H +/**************************************************************************** + + Copyright (C) 2002-2008 Gilles Debunne. All rights reserved. + + This file is part of the QGLViewer library version 2.3.6. + + http://www.libqglviewer.com - contact@libqglviewer.com + + This file may be used under the terms of the GNU General Public License + versions 2.0 or 3.0 as published by the Free Software Foundation and + appearing in the LICENSE file included in the packaging of this file. + In addition, as a special exception, Gilles Debunne gives you certain + additional rights, described in the file GPL_EXCEPTION in this package. + + libQGLViewer uses dual licensing. Commercial/proprietary software must + purchase a libQGLViewer Commercial License. + + This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +*****************************************************************************/ + +#ifndef SIMPLEVIEWER_H +#define SIMPLEVIEWER_H + +#include +#include +#include +#include +#include +#include +#include "../interfaces/visitor.h" +#include "../glnodes/glnode.h" +#include "../glnodes/scenegroup.h" +#include "../glnodes/shapes.h" +#include + +QT_FORWARD_DECLARE_CLASS(QOpenGLShaderProgram) + +class Viewer : public QGLViewer, + protected QOpenGLFunctions_4_0_Core, + public Visitor +{ +Q_OBJECT +public: + Viewer(); + ~Viewer(); + + virtual void visit(SceneGroup &s); + virtual void visit(Cube &s); + +public slots: + void cleanup(); + void changeColor(QColor); + void setPhong(bool); + +signals: + int shapeSelected(int); + +protected : + virtual void draw(); + virtual void drawSkybox(); + virtual void init(); + + virtual void mouseMoveEvent(QMouseEvent* e); + virtual void mouseReleaseEvent(QMouseEvent* e); + virtual void mousePressEvent(QMouseEvent *e); + + SceneGroup root; + std::stack modelStack; + +private: + void initShaders(); + void initGeometries(); + void deselect(); + Shape* pickGeom(int, int); + + // shader switching variables and constants; + QOpenGLShaderProgram *colorPickerShaderProgram; + QOpenGLShaderProgram *textureRenderShaderprogram; + QOpenGLShaderProgram *skyboxRenderShaderProgram; + QOpenGLShaderProgram *m_program; + int m_vPositionLocation; + int m_colorLocation; + int m_projMatrixLocation; + int m_mvMatrixLocation; + + int s_texCoordsLocation; + int s_vPositionLocation; + int s_mvMatrixLocation; + int s_colorLocation; + int s_projMatrixLocation; + int s_skyboxCubemapLocation; + int s_vUvLocation; + int m_vNormalLocation; + + int m_isPhongLoc; + int m_isSkyLoc; + int m_lDirLoc; + int m_skyMultLoc; + bool m_pickerColor; + + float angle_mult; + + QOpenGLTexture *s_texture; + + SceneGroup* activeCell; + QColor* activeColor; + int activeShape; + + enum VAO_IDs { VAO_Cube, NumVAOs }; + enum Buffer_IDs { VBO_Cube, NumBuffers }; + + GLuint m_VAOs[NumVAOs]; + GLuint m_Buffers[NumBuffers]; + + Shape* generateShapeFromIndex(int); + + QQuaternion rot; + unsigned int frame; +}; + +#endif // SIMPLEVIEWER_H