mirror of
https://github.com/ConjureETS/LOG750-LAB2.git
synced 2026-03-24 03:21:19 +00:00
553 lines
19 KiB
C++
553 lines
19 KiB
C++
/****************************************************************************
|
|
|
|
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 <qopengl.h>
|
|
#include <QOpenGLShaderProgram>
|
|
|
|
#include <qopengl.h>
|
|
|
|
#include <iostream>
|
|
#include <stack>
|
|
#include <QMouseEvent>
|
|
#include <typeinfo>
|
|
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;
|
|
|
|
enum Buffer_IDs { ArrayBuffer, NumBuffers };
|
|
int vUVLocation;
|
|
|
|
GLuint Buffers[NumBuffers];
|
|
|
|
int m_lDirectionLocation;
|
|
int m_vNormalLocation;
|
|
int m_normalMatrixLoc;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
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(100);
|
|
|
|
skyboxRenderShaderProgram->setUniformValue(s_projMatrixLocation, projectionMatrix);
|
|
skyboxRenderShaderProgram->setUniformValue(s_mvMatrixLocation, modelViewMatrix);
|
|
// skyboxRenderShaderProgram->setAttributeValue(s_colorLocation, );
|
|
|
|
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<QMatrix4x4> 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);//*/
|
|
|
|
m_program->setUniformValue(m_projMatrixLocation, projectionMatrix);
|
|
m_program->setUniformValue(m_mvMatrixLocation, modelViewMatrix);
|
|
|
|
// Traverse the Scene in order to draw its components
|
|
|
|
modelStack.push(modelViewMatrix);
|
|
root.accept(*this);
|
|
frame++;
|
|
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<Shape*> (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();
|
|
|
|
{
|
|
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";
|
|
|
|
|
|
/*
|
|
* 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();
|
|
skyboxRenderShaderProgram->bind();
|
|
|
|
// 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";
|
|
|
|
if ((s_vUvLocation = skyboxRenderShaderProgram->attributeLocation("vUv")) < 0)
|
|
qDebug() << "Unable to find shader location for " << "vUv";
|
|
|
|
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, 1 }, {0, 0, 1}, {0, 0, 1},
|
|
{ 0, 0, 1 }, {0, 0, 1}, {0, 0, 1},
|
|
|
|
{ 0, 0, -1 }, {0, 0, -1}, {0, 0, -1},
|
|
{ 0, 0, -1 }, {0, 0, -1}, {0, 0, -1},
|
|
|
|
{ 1, 0, 0 }, {1, 0, 0}, {1, 0, 0},
|
|
{ 1, 0, 0 }, {1, 0, 0}, {1, 0, 0},
|
|
|
|
{ -1, 0, 0 }, {-1, 0, 0}, {-1, 0, 0},
|
|
{ -1, 0, 0 }, {-1, 0, 0}, {-1, 0, 0},
|
|
|
|
{ 0, 1, 0 }, {0, 1, 0}, {0, 1, 0},
|
|
{ 0, 1, 0 }, {0, 1, 0}, {0, 1, 0},
|
|
|
|
{ 0, -1, 0 }, {0, -1, 0}, {0, -1, 0},
|
|
{ 0, -1, 0 }, {0, -1, 0}, {0, -1, 0},
|
|
};
|
|
|
|
|
|
glBindVertexArray(m_VAOs[VAO_Cube]);
|
|
glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[VBO_Cube]);
|
|
glGenBuffers(NumBuffers, Buffers);
|
|
glBindBuffer(GL_ARRAY_BUFFER, Buffers[ArrayBuffer]);
|
|
glBufferData(GL_ARRAY_BUFFER, sizeof(verticesCube) + sizeof(uvs) + sizeof(normals),
|
|
NULL, GL_STATIC_DRAW);
|
|
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(verticesCube), verticesCube);
|
|
glBufferSubData(GL_ARRAY_BUFFER, sizeof(verticesCube), sizeof(uvs), uvs);
|
|
glBufferSubData(GL_ARRAY_BUFFER, sizeof(verticesCube)+sizeof(uvs), sizeof(normals), normals);
|
|
|
|
// glBindVertexArray(m_VAOs[VAO_Cube]);
|
|
// glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[VBO_Cube]);
|
|
// glBufferData(GL_ARRAY_BUFFER, sizeof(verticesCube), verticesCube, GL_STATIC_DRAW);
|
|
|
|
glVertexAttribPointer(m_vPositionLocation, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
|
|
glEnableVertexAttribArray(m_vPositionLocation);
|
|
|
|
glVertexAttribPointer(s_vUvLocation, 2, GL_FLOAT,
|
|
GL_FALSE, 0, BUFFER_OFFSET(sizeof(verticesCube)));
|
|
glEnableVertexAttribArray(s_vUvLocation);
|
|
|
|
glVertexAttribPointer(m_vNormalLocation, 3, GL_FLOAT,
|
|
GL_FALSE, 0, BUFFER_OFFSET(sizeof(verticesCube) + sizeof(uvs)));
|
|
glEnableVertexAttribArray(m_vNormalLocation);
|
|
}
|
|
|
|
void Viewer::visit(Cube &s)
|
|
{
|
|
QMatrix4x4 modelViewMatrix = modelStack.top() * QMatrix4x4(s.transform);
|
|
QMatrix4x4 lookAt;
|
|
|
|
camera()->getProjectionMatrix(lookAt);
|
|
|
|
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_mvMatrixLocation, modelViewMatrix);
|
|
m_program->setUniformValue(m_normalMatrixLoc, lookAt.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::changeColor(QColor c){
|
|
if(activeCell->getChildren()->size()){
|
|
Shape* shape = dynamic_cast<Shape*> (activeCell->childAt(0));
|
|
shape->setColor(c);
|
|
}
|
|
activeColor = new QColor(c);
|
|
this->update();
|
|
}
|
|
|
|
Shape* Viewer::pickGeom(int x, int y){
|
|
QMap<QRgb, Shape*> 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"<<endl;
|
|
|
|
for(int i = 0, l = root.getChildren()->size(); i<l; i++)
|
|
{
|
|
std::cout << " iterating... " << i << endl;
|
|
SceneGroup* current = dynamic_cast<SceneGroup*>(root.childAt(i));
|
|
Shape* currentCube;
|
|
|
|
if(current->getChildren()->size())
|
|
{
|
|
currentCube = dynamic_cast<Shape*>(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;
|
|
}
|