Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "glwidget.h"
- #include <QMouseEvent>
- #include <QOpenGLShaderProgram>
- #include <QCoreApplication>
- #include <math.h>
- #include <iostream>
- using namespace std;
- //bool GLWidget::m_transparent = false;
- GLWidget::GLWidget(QWidget *parent)
- : QOpenGLWidget(parent),
- m_xRot(0),
- m_yRot(0),
- m_zRot(0),
- m_program(0)
- {
- // OpenGL profile
- m_core = QSurfaceFormat::defaultFormat().profile() == QSurfaceFormat::CoreProfile;
- // GLWidget widget will capture events from keyboard
- setFocusPolicy(Qt::StrongFocus);
- }
- GLWidget::~GLWidget()
- {
- cleanup();
- }
- // returns size of the window
- QSize GLWidget::sizeHint() const
- {
- return QSize(1000, 800);
- }
- // memory clean-up when the apps is finished
- void GLWidget::cleanup()
- {
- if (m_program == nullptr)
- return;
- makeCurrent();
- m_objVbo.destroy();
- delete m_program;
- m_program = 0;
- doneCurrent();
- }
- ////////////////////////////////// object rotation
- // normalizes rotation angle
- static void qNormalizeAngle(int &angle)
- {
- while (angle < 0)
- angle += 360 * 16;
- while (angle > 360 * 16)
- angle -= 360 * 16;
- }
- // sets rotation angle
- void GLWidget::setXRotation(int angle)
- {
- qNormalizeAngle(angle); // normalizes rotation angle
- if (angle != m_xRot) {
- m_xRot = angle;
- update(); // forces paintGL() call
- }
- }
- // sets rotation angle
- void GLWidget::setYRotation(int angle)
- {
- qNormalizeAngle(angle); // normalizes rotation angle
- if (angle != m_yRot) {
- m_yRot = angle;
- update(); // forces paintGL() call
- }
- }
- // sets rotation angle
- void GLWidget::setZRotation(int angle)
- {
- qNormalizeAngle(angle); // normalizes rotation angle
- if (angle != m_zRot) {
- m_zRot = angle;
- update(); // forces paintGL() call
- }
- }
- /////////////////////////////////////////// vertex shader
- static const char *vertexShaderSource =
- "attribute vec4 vertex;\n"
- "attribute vec3 normal;\n"
- "uniform mat4 projMatrix;\n"
- "uniform mat4 mvMatrix;\n"
- "void main() {\n"
- " gl_Position = projMatrix * mvMatrix * vertex;\n"
- "}\n";
- /////////////////////////////////////////// fragment shader
- static const char *fragmentShaderSource =
- "uniform highp vec3 modelColor;\n"
- "void main() {\n"
- " gl_FragColor = vec4(modelColor, 0);\n"
- "}\n";
- /////////////////////////////////////////////////// OpenGL initialization
- void GLWidget::initializeGL()
- {
- initializeOpenGLFunctions(); // required to call OpenGL functions directly
- glClearColor(0.2, 0.2, 0.2, 1); // backgroung clear color
- // loads, compiles and links shader programs
- m_program = new QOpenGLShaderProgram;
- m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
- m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
- m_program->bindAttributeLocation("vertex", 0);
- m_program->bindAttributeLocation("normal", 1);
- m_program->link();
- // sets shader variables
- m_program->bind();
- m_projMatrixLoc = m_program->uniformLocation("projMatrix"); // projection matrix
- m_mvMatrixLoc = m_program->uniformLocation("mvMatrix"); // model-view matrix
- m_currentColor = m_program->uniformLocation("modelColor");
- // builds 3D object based on VAO nad VBO
- m_vao.create(); // creates vertex array object
- QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao); // binds vertex array object
- m_objVbo.create(); // creates vertex buffer object
- m_objVbo.bind(); // binds vertex buffer object
- m_objVbo.allocate(m_obj.constData(), m_obj.count() * sizeof(GLfloat)); // copies mesh data to vertex buffer object
- setupVertexAttribs(); // stores vertex attribute bindings for the program
- // sets camera position to (0,0,-1), camera looks at (0,0,0)
- m_camera.setToIdentity();
- m_camera.translate(0, 0, -1);
- m_program->release();
- }
- // sets VAO attributes
- void GLWidget::setupVertexAttribs()
- {
- m_objVbo.bind();
- QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
- f->glEnableVertexAttribArray(0);
- f->glEnableVertexAttribArray(1);
- f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), 0);
- f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), reinterpret_cast<void *>(3 * sizeof(GLfloat)));
- m_objVbo.release();
- }
- /////////////////////////////////////////////////// OpenGL drawing
- void GLWidget::paintGL()
- {
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clears framebuffer
- glEnable(GL_DEPTH_TEST); // enables Z-buffer
- glEnable(GL_CULL_FACE); // enables backface culling (back face of triangles is inivisible)
- QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao); // binds vertex array object
- m_program->bind(); // binds shaders
- // rotation of the robot
- m_world.setToIdentity();
- m_world.rotate(0.0f - (m_xRot / 16.0f), 1, 0, 0);
- m_world.rotate(m_yRot / 16.0f, 0, 1, 0);
- m_world.rotate(m_zRot / 16.0f, 0, 0, 1);
- QMatrix4x4 m_world_tmp = m_world; // stores current model-view matrix
- //PRAWIDŁOWA KONWENCJA
- //TRANSLATE => ROTATE => SCALE
- m_world.translate(playerPosition);
- //robot head
- m_program->setUniformValue(m_currentColor, QVector3D(0.7f, 0.8, 0.9));
- m_world = m_world_tmp;
- m_world.translate(0.0, 0.15, 0.0);
- m_world.scale(QVector3D(0.1, 0.1, 0.1));
- setTransforms();
- glDrawArrays(GL_TRIANGLES, 0, m_obj.vertexCount()); // draws VAO
- // robot right hand
- m_program->setUniformValue(m_currentColor, QVector3D(0.2f, 0.9, 0.3f));
- m_world = m_world_tmp;
- m_world.translate(0.17, 0, 0.0);
- m_world.rotate(-15.0, 0, 0, 1);
- m_world.scale(QVector3D(0.16, 0.05, 0.05));
- setTransforms();
- glDrawArrays(GL_TRIANGLES, 0, m_obj.vertexCount()); // draws VAO
- // robot left hand
- m_world = m_world_tmp;
- // m_world.translate(-0.17, 0.02, 0.0);
- m_world.rotate(sin(timer*(0.1))*(-6.5),0, 0, 1);
- m_world.translate(-0.17, 0.02, 0.0);
- m_world.scale(QVector3D(0.16, 0.05, 0.05));
- setTransforms();
- glDrawArrays(GL_TRIANGLES, 0, m_obj.vertexCount()); // draws VAO
- // robot left leg
- m_program->setUniformValue(m_currentColor, QVector3D(0.2f, 0.8f, 0.3));
- m_world = m_world_tmp;
- m_world.translate(-0.1, -0.29, 0.0);
- m_world.rotate(60.0, 0, 0, 1);
- m_world.scale(QVector3D(0.16, 0.05, 0.05));
- setTransforms();
- glDrawArrays(GL_TRIANGLES, 0, m_obj.vertexCount()); // draws VAO
- // robot right leg
- m_world = m_world_tmp;
- m_world.translate(0.1, -0.29, 0.0);
- m_world.rotate(-60.0, 0, 0, 1);
- m_world.scale(QVector3D(0.16, 0.05, 0.05));
- setTransforms();
- glDrawArrays(GL_TRIANGLES, 0, m_obj.vertexCount()); // draws VAO
- //robot body
- m_program->setUniformValue(m_currentColor, QVector3D(0.8f, 0.8f, 0.7));
- m_world = m_world_tmp;
- m_world.translate(0.0, -0.05, 0.0);
- m_world.scale(QVector3D(0.15, 0.25, 0.15));
- setTransforms();
- glDrawArrays(GL_TRIANGLES, 0, m_obj.vertexCount()); // draws VAO
- if(keyState[Qt::Key_W]) playerPosition.setZ(playerPosition.z() - 0.02);
- if(keyState[Qt::Key_S]) playerPosition.setZ(playerPosition.z() + 0.02);
- if(keyState[Qt::Key_A]){
- playerPosition;
- playerPosition.setX(playerPosition.x() - 0.02);
- }
- if(keyState[Qt::Key_D]) playerPosition.setX(playerPosition.x() + 0.02);
- m_program->release(); // executes shaders (actual redrawing)
- timer++; //increments after frame ends
- update();
- }
- // sends transformation matrices to shaders
- void GLWidget::setTransforms(void)
- {
- m_program->setUniformValue(m_projMatrixLoc, m_proj); // sets projection matrix
- m_program->setUniformValue(m_mvMatrixLoc, m_camera * m_world); // sets model-view matrix
- }
- /////////////////////////////////////////////////// function called when window size is changed
- void GLWidget::resizeGL(int w, int h)
- {
- // defines perspective projection
- m_proj.setToIdentity();
- m_proj.perspective(60.0f, GLfloat(w) / h, 0.01f, 100.0f); // sets FOV, aspect, near clipping plane, and far clipping plane
- }
- /////////////////////////////////////////////////// mouse events
- void GLWidget::mousePressEvent(QMouseEvent *event)
- {
- m_lastPos = event->pos();
- }
- void GLWidget::mouseMoveEvent(QMouseEvent *event)
- {
- int dx = event->x() - m_lastPos.x();
- int dy = event->y() - m_lastPos.y();
- if (event->buttons() & Qt::LeftButton) {
- setXRotation(m_xRot + 8 * dy);
- setYRotation(m_yRot + 8 * dx);
- } else if (event->buttons() & Qt::RightButton) {
- setXRotation(m_xRot + 8 * dy);
- setZRotation(m_zRot + 8 * dx);
- }
- m_lastPos = event->pos();
- }
- /////////////////////////////////////////////////// keyboard events
- void GLWidget::keyPressEvent(QKeyEvent *e)
- {
- if(e->key()>-0 && e->key()<=255){
- keyState[e-key()]=true;
- }
- if (e->key() == Qt::Key_Escape)
- exit(0);
- else
- if (e->key() == Qt::Key_Q)
- exit(0);
- else
- QWidget::keyPressEvent(e);
- }
- void GLWidget::keyReleaseEvent(QKeyEvent *event){
- if(e->key()>-0 && e->key()<=255){
- keyState[e-key()]=false;
- }
- }
Add Comment
Please, Sign In to add comment