From e57d54f861029256dcf1e8f9ee9ef04b834089ba Mon Sep 17 00:00:00 2001 From: Dmitri K Date: Fri, 11 Nov 2016 21:40:26 -0500 Subject: [PATCH] AAAAWWWW YYYEEEAAAAHHHH --- src/glnodes/shapes.cpp | 2 + src/shaders/basicShader.frag | 45 +++++----- src/viewer/simpleViewer.cpp | 162 +++++++++++++++++++++-------------- src/viewer/simpleViewer.h | 18 +++- 4 files changed, 139 insertions(+), 88 deletions(-) diff --git a/src/glnodes/shapes.cpp b/src/glnodes/shapes.cpp index 9fa80e2..22c57fd 100644 --- a/src/glnodes/shapes.cpp +++ b/src/glnodes/shapes.cpp @@ -1,6 +1,7 @@ #include "shapes.h" #include #include +#include void Cube::accept(Visitor &v) { v.visit(*this); @@ -13,6 +14,7 @@ void Sphere::accept(Visitor &v) { // *** void Cube::setColor(QColor& c) { + std::cout << "Setting cubr color! " << c.rgb() << endl; color = QColor(c); } diff --git a/src/shaders/basicShader.frag b/src/shaders/basicShader.frag index e54f05e..76e5388 100644 --- a/src/shaders/basicShader.frag +++ b/src/shaders/basicShader.frag @@ -66,29 +66,32 @@ main() { vec4 texColor; - if(drawTextures) { - texColor = texture(tex, texCoords); - } else { - texColor = ifColor; - } if(isPickingMode){ fColor = ifColor; - } else if(isLightSource) { - fColor = texColor; - } else if(isSky) { - fColor = skyMult * normalize(texColor*texColor*texColor*2/1.41)*2; - } else if(isPhong) { - // Get lighting vectors - vec3 LightDirection = normalize(lDirection); - vec3 nfNormal = normalize(fNormal); - vec3 nviewDirection = normalize(fPosition); + }else{ + if(drawTextures) { + texColor = texture(tex, texCoords); + } else { + texColor = ifColor; + } - fColor = calcDirLight(texColor, fPosition, fNormal) - + calcPointLight(texColor, fPosition, fNormal, 0)/4 - + calcPointLight(texColor, fPosition, fNormal, 1)/4 - + calcPointLight(texColor, fPosition, fNormal, 2)/4; - } else { - fColor = texColor * ifColor; - } + if(isLightSource) { + fColor = texColor; + } else if(isSky) { + fColor = skyMult * normalize(texColor*texColor*texColor*2/1.41)*2; + } else if(isPhong) { + // Get lighting vectors + vec3 LightDirection = normalize(lDirection); + vec3 nfNormal = normalize(fNormal); + vec3 nviewDirection = normalize(fPosition); + + fColor = calcDirLight(texColor, fPosition, fNormal) + + calcPointLight(texColor, fPosition, fNormal, 0)/4 + + calcPointLight(texColor, fPosition, fNormal, 1)/4 + + calcPointLight(texColor, fPosition, fNormal, 2)/4; + } else { + fColor = texColor * ifColor; + } + } } diff --git a/src/viewer/simpleViewer.cpp b/src/viewer/simpleViewer.cpp index 819d1b7..2f2fb92 100644 --- a/src/viewer/simpleViewer.cpp +++ b/src/viewer/simpleViewer.cpp @@ -35,6 +35,8 @@ #include #include #include +#include + using namespace std; #define BUFFER_OFFSET(i) ((char *)NULL + (i)) @@ -65,8 +67,8 @@ namespace class SkyboxCamera : public qglviewer::Camera { - virtual qreal zNear() const { return 0.01; } - virtual qreal zFar() const { return 100.0; } + virtual qreal zNear() const { return 0.001; } + virtual qreal zFar() const { return 1000.0; } }; Viewer::Viewer() @@ -128,19 +130,23 @@ void Viewer::drawSkybox() void Viewer::draw() { - drawSkybox(); - glCullFace( GL_BACK ); - // Bind our vertex/fragment shaders m_program->bind(); + glClear(GL_COLOR_BUFFER_BIT); + + if(!isPickingActivated) + drawSkybox(); + glCullFace( GL_BACK ); + + // Get projection and camera transformations QMatrix4x4 projectionMatrix; QMatrix4x4 modelViewMatrix; camera()->getProjectionMatrix(projectionMatrix); camera()->getModelViewMatrix(modelViewMatrix); - modelViewMatrix.rotate(30,0,1,0); + //modelViewMatrix.rotate(30,0,1,0); m_program->setUniformValue(m_projMatrixLocation, projectionMatrix); m_program->setUniformValue(m_mvMatrixLocation, modelViewMatrix); @@ -174,34 +180,22 @@ void Viewer::mouseMoveEvent(QMouseEvent* e) { void Viewer::mousePressEvent(QMouseEvent* e) { // 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; + int x = this->x() + e->x() - 10; + int y = this->parentWidget()->height() - e->y() - 23; 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); + 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; //m_program->setUniformValue(m_isPickingModeLoc, false); + m_program->bind(); + m_program->setUniformValue(m_isPickingModeLoc, false); + isPickingActivated = false; QGLViewer::mouseReleaseEvent(e); } @@ -227,13 +221,13 @@ void Viewer::init() // Init shaders & geometry initShaders(); initGeometries(); + initBuffers(); sunRotate.rotate(-15,0,0,1); sun = sunRotate * sun; + { - Shape* cube = new Cube(); - cube->setColor(*activeColor); QColor* c1 = new QColor(255, 0, 255, 255); QColor* c2 = new QColor(0, 255, 255, 255); @@ -243,6 +237,15 @@ void Viewer::init() Shape* s2 = new Sphere(); Shape* s3 = new Sphere(); + Shape* cube1 = new Cube(); + Shape* cube2 = new Cube(); + Shape* cube3 = new Cube(); + cube1->setColor(*c1); + cube2->setColor(*c2); + cube3->setColor(*c3); + cube2->transform.translate(1, 0, 0); + cube3->transform.translate(0, 0, 1); + s1->transform.rotate(360 * 1/3,0,1,0); s1->transform.translate(1,0,0); s1->transform.scale(0.05); @@ -265,10 +268,16 @@ void Viewer::init() selection->addChild(s2); selection->addChild(s3); - SceneGroup *c = new SceneGroup(); - c->addChild(cube); - c->addChild(selection); - root.addChild(c); + SceneGroup *sc1 = new SceneGroup(); + SceneGroup *sc2 = new SceneGroup(); + SceneGroup *sc3 = new SceneGroup(); + sc1->addChild(cube1); + sc1->addChild(selection); + sc2->addChild(cube2); + sc3->addChild(cube3); + root.addChild(sc1); + root.addChild(sc2); + root.addChild(sc3); } } @@ -589,6 +598,15 @@ void Viewer::initGeometries() glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(sphereIndices), sphereIndices, GL_STATIC_DRAW); } +void Viewer::initBuffers(){ + + glGenRenderbuffers(1, m_RenderBuffers); + glBindRenderbuffer(GL_RENDERBUFFER, m_RenderBuffers[RenderBuffer_Main]); + glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB565, 1920, 1080); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_RenderBuffers[RenderBuffer_Main]); + +} + void Viewer::visit(Cube &s) { @@ -597,24 +615,29 @@ void Viewer::visit(Cube &s) int faces = floor(numVerticesCube/6); glBindVertexArray(m_VAOs[VAO_Cube]); - for(int i =0; isetRgb(s.getColor().rgb() + i); + m_program->bind(); m_program->setUniformValue(m_isSkyLoc, false); m_program->setUniformValue(m_mvMatrixLocation, modelViewMatrix); m_program->setUniformValue(m_normalMatrixLoc, modelViewMatrix.normalMatrix()); - m_program->setUniformValue(m_colorLocation, *(new QColor(s.getColor().rgb()+i))); + m_program->setUniformValue(m_colorLocation, *faceColor); m_program->setUniformValue(m_drawTextLoc, true); m_program->setUniformValue(m_isLightLoc, false); glDrawArrays(GL_TRIANGLES, i*6, 6); + glFinish(); + delete faceColor; } //glDrawArrays(GL_TRIANGLES, 0, 36); } - void Viewer::visit(Sphere &s) { // std::cout << "Sphere found"; - QMatrix4x4 modelViewMatrix = modelStack.top() * QMatrix4x4(s.transform); + QMatrix4x4 modelViewMatrix = modelStack.top() * QMatrix4x4(s.transform); if(!isPickingActivated){ glBindVertexArray(m_VAOs[VAO_Sphere]); @@ -664,7 +687,9 @@ void Viewer::visit(SceneGroup &s) modelStack.pop(); } + void Viewer::setPhong(bool on) { + m_program->bind(); m_program->setUniformValue(m_isPhongLoc, on); if(on) std::cout << "Phong ON\n"; else std::cout << "Phong OFF\n"; @@ -682,28 +707,30 @@ void Viewer::changeColor(QColor c){ Shape* Viewer::pickGeom(int x, int y){ + makeCurrent(); + m_program->bind(); m_program->setUniformValue(m_isPickingModeLoc, true); + //glReadBuffer(GL_COLOR_ATTACHMENT0); + //glBindFramebuffer(GL_FRAMEBUFFER, m_RenderBuffers[RenderBuffer_Main]); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + + isPickingActivated = true; 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; + QRgb startColor = 0x1; // alpha must be 100%, glReadPixels doesn't resturn alpha + unsigned char pixelData[3]; - std::cout << "Iterating through " << root.getChildren()->size() << "items"<size(); isize() << " items"<(root.childAt(i)); + SceneGroup* current = dynamic_cast(root.getChild()); Shape* currentCube; if(current->getChildren()->size()) @@ -711,42 +738,49 @@ Shape* Viewer::pickGeom(int x, int y){ currentCube = dynamic_cast(current->childAt(0)); } - if(currentCube) + currentCube->setColor(c); + if(currentCube) for (int j = 0; j<6; j++) { c.setRgb(startColor); - mapColorToShape.insert(c.rgb(), currentCube); +// QMatrix4x4 direction; direction.translate(0, 1, 0); + mapColorToShape.insert(c.rgb(), currentCube/*->transform * direction*/); std::cout << "Setting " << currentCube << " to " << c.red() << " " << c.green() << " " << c.blue() << " " << c.alpha() << endl; - currentCube->setColor(c); - startColor+=6; + startColor++; } } - - draw(); - glFinish(); - + root.accept(*this); 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); + /*unsigned char pdata[512][512][4]; + glReadPixels(x-256, y-256, 512, 512, GL_RGBA, GL_UNSIGNED_BYTE, pdata); + QImage *im = new QImage(512, 512, QImage::Format_RGB32); + for(int i = 0; i< 512; i++){ + for(int j = 0; j< 512; j++){ + QColor* pickedColor = new QColor(); + + pickedColor->setRgb(pdata[512-j][i][0], pdata[512-j][i][1], pdata[512-j][i][2]); + if(i==256 && j == 256) pickedColor->setRgba(0x88FFFFFF); + if(i==256 && j == 256) + std::cout<<"--- Color under cursor: " << (int)pdata[j][i][0] <<" "<< (int)pdata[j][i][1] <<" "<< (int)pdata[j][i][2] << endl; + pickedColor->setAlpha(255); 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; + std::cout << "Picked Color: " << pickedColor->red() << " " << pickedColor->green() << " " << pickedColor->blue() << " " << pickedColor->alpha() << endl; + std::cout << "Picked Shape: " << pickedShape << endl; + m_program->setUniformValue(m_isPickingModeLoc, false); isPickingActivated = false; - update(); - return pickedShape; + doneCurrent(); + + return pickedShape; } diff --git a/src/viewer/simpleViewer.h b/src/viewer/simpleViewer.h index f458f6d..e7129c1 100644 --- a/src/viewer/simpleViewer.h +++ b/src/viewer/simpleViewer.h @@ -72,7 +72,8 @@ protected : private: void initShaders(); - void initGeometries(); + void initGeometries(); + void initBuffers(); void deselect(); Shape* pickGeom(int, int); @@ -121,11 +122,13 @@ private: QColor* activeColor; int activeShape; - enum VAO_IDs { VAO_Cube, VAO_Sphere, NumVAOs }; - enum Buffer_IDs { VBO_Cube, VBO_Sphere, EBO_Sphere, NumBuffers }; + enum VAO_IDs { VAO_Cube, VAO_Sphere, NumVAOs }; + enum Buffer_IDs { VBO_Cube, VBO_Sphere, EBO_Sphere, NumBuffers }; + enum RenderBuffer_IDs { RenderBuffer_Main, NumRenderBuffers }; GLuint m_VAOs[NumVAOs]; GLuint m_Buffers[NumBuffers]; + GLuint m_RenderBuffers[NumRenderBuffers]; Shape* generateShapeFromIndex(int); @@ -149,6 +152,15 @@ private: "src/data/wood_floor.jpg" }; + int sideColors[6] = { + 0xFF0000, + 0x00FF00, + 0x0000FF, + 0x00FFFF, + 0xFF00FF, + 0xFFFF00, + }; + QOpenGLTexture *TexturePrograms[TEX_LENGTH];