Home > Back-end >  Why changing model matrix change size of wrong object in OpenGL?
Why changing model matrix change size of wrong object in OpenGL?

Time:03-16

After scaling model2 matrix. model2 matrix is matrix of grid enter image description here

Before enter image description here

I want to increase size of grid not cube. Why is it happened? Why scale set y of cube to 0? Where is the mistake? All my code below.

Look at draw_canvas.cpp paintGL function, there is scaling matrix with name 'model2'. This line model2.scale(10.0f,0.0f,10.0f). Why this scaling changes my cube?

 QMatrix4x4 model2(1.0f, 0.0f, 0.0f, 0.0f,
                     0.0f, 1.0f, 0.0f, 0.0f,
                     0.0f, 0.0f, 1.0f, 0.0f,
                     0.0f, 0.0f, 0.0f, 1.0f);
    unsigned int modelID2 = gridShaderProgram->uniformLocation("model");
    
    model2.translate(QVector3D(0.0f, 0.0f, 0.0f)); 
    model2.scale(10.0f, 0.0f, 10.0f);

draw_canwas3D.h


#pragma once
#include <QOpenGLWidget>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLBuffer>
#include <QOpenGLShaderProgram>
#include <QOpenGLShader>
#include <list>


class Canvas3D : public QOpenGLWidget
{
public:
    Canvas3D(QWidget *parent = nullptr) : QOpenGLWidget(parent) { };
    ~Canvas3D();
private:
    QOpenGLVertexArrayObject m_vao;
    QOpenGLBuffer m_vbo;
    QOpenGLShaderProgram* m_program;
    QOpenGLShaderProgram* gridShaderProgram;
    QOpenGLShaderProgram* shLightprogram;
        
    QVector3D cameraPos {0.0f, 0.0f, 3.0f};
    QVector3D cameraFront{0.0f, 0.0f, -1.0f};
    QVector3D cameraUp{0.0f, 1.0f, 0.0f};
    float yaw = -90.0f;
    float pitch = 0.0f;
    float lastX = 400, lastY = 300;
    float Zoom = 45.0;
    unsigned int gridVAO;
    unsigned int gridEBO;
    GLuint lenght = 0;
    //std::list<Object*>
protected:
    void initializeGL() override;

    void resizeGL(int w, int h) override;

    void paintGL() override;

    void keyPressEvent(QKeyEvent *ev) override;
    
    bool eventFilter(QObject *obj, QEvent *event);

};

draw_canvas3D.cpp

#include "draw_canvas3D.h"
#include "src/common/geometry/shapes3D/cube.h"
#include <iostream>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QOpenGLExtraFunctions>
#include <QMatrix4x4>
#include <QVector3D>
#include <QtMath>
#include <QKeyEvent>


void Canvas3D::initializeGL()
{
    connect(this, SIGNAL(frameSwapped()), this, SLOT(update()));
    auto functions = this->context()->functions();
    functions->glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    this->setGeometry(100, 100, 800, 600);
    functions->glViewport(this->geometry().x(),
                  this->geometry().y(),
                  this->geometry().width(),
                  this->geometry().height());

    m_program = new QOpenGLShaderProgram(this);
    QOpenGLShader vxShader(QOpenGLShader::Vertex);
    vxShader.compileSourceFile("/main/stage/home/andreyp/fork_invar/invar/shaders/shader.vs");
    QOpenGLShader frShader(QOpenGLShader::Fragment);
    frShader.compileSourceFile("/main/stage/home/andreyp/fork_invar/invar/shaders/shader.fs");
    m_program->addShader(&vxShader);
    m_program->addShader(&frShader);
    m_program->link();
    functions->glEnable(GL_DEPTH_TEST);
    this->installEventFilter(this);
    
    functions->glEnable(GL_POLYGON_SMOOTH);
    functions->glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
    functions->glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
    
    /*GRID*/ //Create Class
   auto additionalFunctions = this->context()->extraFunctions(); 
   unsigned int gridVBO;

   std::vector<QVector3D> vertices;
  std::vector<unsigned int> indices;
  int slices = 10;
  for(int j=0; j<=slices;   j) {
    for(int i=0; i<=slices;   i) {
      float x = (float)i/(float)slices;
      float y = 0;
      float z = (float)j/(float)slices;
      vertices.push_back(QVector3D(x, y, z));
    }
  }

  for(int j=0; j<slices;   j) {
    for(int i=0; i<slices;   i) {

      int row1 =  j * (slices 1);
      int row2 = (j 1) * (slices 1);

      indices.push_back(row1 i); indices.push_back(row1 i 1); indices.push_back(row1 i 1); indices.push_back(row2 i 1);
      indices.push_back(row2 i 1); indices.push_back(row2 i); indices.push_back(row2 i); indices.push_back(row1 i);

    }
  }
  lenght = (GLuint)indices.size()*4;
   /*std::vector<QVector3D> vecLines;
   std::vector<unsigned int> vecLinesIdx;*/
   /*for(unsigned int nHorizontalLines = 0; nHorizontalLines < 10;   nHorizontalLines)
   {
       vecLines.push_back(QVector3D(0.0f, 0.0, -(float)nHorizontalLines));
       vecLines.push_back(QVector3D(9.0f, 0.0, -(float)nHorizontalLines));
   }
   
  
   for(unsigned int nVerticalLines = 0; nVerticalLines < 10;   nVerticalLines)
   {
       vecLines.push_back(QVector3D((float)nVerticalLines, 0.0f, 0.0f));
       vecLines.push_back(QVector3D((float)nVerticalLines, 0.0f, -9.0f));
   }
   for(unsigned int j = 0; j < 39; j =2)
   {
       vecLinesIdx.push_back(j);
       vecLinesIdx.push_back(j 1);
   }*/
   

   functions->glGenBuffers(1, &gridEBO);
   functions->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gridEBO);
   functions->glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size()*sizeof(unsigned int), indices.data(), GL_STATIC_DRAW);
  
   functions->glGenBuffers(1, &gridVBO);
   additionalFunctions->glGenVertexArrays(1, &gridVAO);
   additionalFunctions->glBindVertexArray(gridVAO);
   functions->glBindBuffer(GL_ARRAY_BUFFER, gridVBO);
   functions->glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(QVector3D), vertices.data(), GL_STATIC_DRAW);
   
   functions->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), nullptr);
   functions->glEnableVertexAttribArray(0);
   gridShaderProgram = new QOpenGLShaderProgram(this);
   QOpenGLShader vxShader2(QOpenGLShader::Vertex);
   vxShader2.compileSourceFile("/main/stage/home/andreyp/fork_invar/invar/shaders/shaderGrid.vs");
   QOpenGLShader frShader2(QOpenGLShader::Fragment);
   frShader2.compileSourceFile("/main/stage/home/andreyp/fork_invar/invar/shaders/shaderGrid.fs");
   gridShaderProgram->addShader(&vxShader2);
   gridShaderProgram->addShader(&frShader2);
   gridShaderProgram->link();
    /*GRID END*/
   
   
}


void Canvas3D::resizeGL(int w, int h)
{
    auto functions = this->context()->functions();
    functions->glViewport(0,
                  0,
                  this->geometry().width(),
                  this->geometry().height());
    
}

void Canvas3D::paintGL()
{
    auto functions = this->context()->functions();
    //auto additionalFunctions = this->context()->extraFunctions();
    functions->glClearColor(0.0f / 255.0f, 25.0f / 255.0f, 53.0f / 255.0f, 1.0f);
    functions->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    QMatrix4x4 projection;
    projection.perspective(Zoom, 800.0f / 600.0f, 0.1f, 100.0f);

    QMatrix4x4 view; 
    view.lookAt(cameraPos,
                cameraPos   cameraFront,
                cameraUp);
   
    unsigned int viewID = m_program->uniformLocation("view");
    functions->glUniformMatrix4fv(viewID, 1, GL_FALSE, view.constData());
    
    unsigned int projectionID = m_program->uniformLocation("projection");
    functions->glUniformMatrix4fv(projectionID, 1, GL_FALSE, projection.constData());
    
    QVector3D cubePositions[] = {
        QVector3D(0.0f, 0.0, 0.0),
        QVector3D( 0.5f, 0.0f, 0.5f),
        QVector3D( 2.0f, 0.0f, 3.0f),
        QVector3D(-1.5f, -2.2f, -2.5f),
        QVector3D(-3.8f, -2.0f, -12.3f),
        QVector3D( 2.4f, -0.4f, -3.5f),
        QVector3D(-1.7f, 3.0f, -7.5f),
        QVector3D( 1.3f, -2.0f, -2.5f),
        QVector3D( 1.5f, 2.0f, -2.5f),
        QVector3D( 1.5f, 0.2f, -1.5f),
        QVector3D(-1.3f, 1.0f, -1.5f)
    };
    

    for(unsigned int i = 0; i < 2; i  )
    {
       
        QMatrix4x4 model(1.0f, 0.0f, 0.0f, 0.0f,
                         0.0f, 1.0f, 0.0f, 0.0f,
                         0.0f, 0.0f, 1.0f, 0.0f,
                         0.0f, 0.0f, 0.0f, 1.0f);
        unsigned int modelID = m_program->uniformLocation("model");
        
        model.translate(cubePositions[i]);
        functions->glUniformMatrix4fv(modelID, 1, GL_FALSE, model.constData());
        
        auto cube3d = new invar::geometry3D::Cube(cubePositions[i], 1*qSqrt(3), m_program);
  

        cube3d->Draw();
    }
    auto additionalFunctions = this->context()->extraFunctions();
    additionalFunctions->glBindVertexArray(0);
    /*GRID*/
    unsigned int viewID2 = gridShaderProgram->uniformLocation("view");
    functions->glUniformMatrix4fv(viewID2, 1, GL_FALSE, view.constData());
    
    unsigned int projectionID2 = gridShaderProgram->uniformLocation("projection");
    functions->glUniformMatrix4fv(projectionID2, 1, GL_FALSE, projection.constData());
    
    QMatrix4x4 model2(1.0f, 0.0f, 0.0f, 0.0f,
                     0.0f, 1.0f, 0.0f, 0.0f,
                     0.0f, 0.0f, 1.0f, 0.0f,
                     0.0f, 0.0f, 0.0f, 1.0f);
    unsigned int modelID2 = gridShaderProgram->uniformLocation("model");
    //model2.scale(10.0f, 0.0f, 10.0f); ------ THIS SCALING
    model2.translate(QVector3D(0.0f, 0.0f, 0.0f)); 
    
    functions->glUniformMatrix4fv(modelID2, 1, GL_FALSE, model2.constData());
    gridShaderProgram->bind();
    
    additionalFunctions->glBindVertexArray(gridVAO);
    functions->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gridEBO);
    functions->glDrawElements(GL_LINES, lenght, GL_UNSIGNED_INT, 0);

    /*GRID END*/
}

void Canvas3D::keyPressEvent(QKeyEvent *ev)
{
    const float cameraSpeed = 0.25f;
    if(ev->key() == Qt::Key_W)
        cameraPos  = cameraSpeed * cameraFront;
    else if(ev->key() == Qt::Key_S)
        cameraPos -= cameraSpeed * cameraFront;
    else if(ev->key() == Qt::Key_A)
        cameraPos -= QVector3D(QVector3D::crossProduct(cameraFront, cameraUp)) * cameraSpeed;
    else if(ev->key() == Qt::Key_D)
        cameraPos  = QVector3D(QVector3D::crossProduct(cameraFront, cameraUp)) * cameraSpeed;
    else if(ev->key() == Qt::Key_Q)
    {
        /*Rotate camera*/
    }
    else if(ev->key() == Qt::Key_E)
    {
        /*Rotate camera*/
    }

}   

bool Canvas3D::eventFilter(QObject *obj, QEvent *event)
{
    
  if (event->type() == QEvent::MouseButtonPress)
  {
    QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
    lastX = mouseEvent->pos().x();
    lastY = mouseEvent->pos().y();
  }
  if (event->type() == QEvent::MouseMove)
  {
    QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event); 
    float xoffset = mouseEvent->pos().x() - lastX;
    float yoffset = lastY - mouseEvent->pos().y();
    lastX = mouseEvent->pos().x();
    lastY = mouseEvent->pos().y();
    float sensitivity = 0.1f;
    xoffset *= sensitivity;
    yoffset *= sensitivity;
    yaw  = xoffset;
    pitch  = yoffset;
    if(pitch > 89.0f)
        pitch = 89.0f;
    if(pitch < -89.0f)
        pitch = -89.0f;
    QVector3D direction;
    direction.setX(qCos(qDegreesToRadians(yaw)) * qCos(qDegreesToRadians(pitch)));
    direction.setY(qSin(qDegreesToRadians(pitch)));
    direction.setZ(qSin(qDegreesToRadians(yaw)) * qCos(qDegreesToRadians(pitch)));
    cameraFront = direction.normalized();
  }
  else if (event->type() == QEvent::Wheel)
  {
    QWheelEvent *wheelEvent = static_cast<QWheelEvent*>(event);
    QPoint numDegrees = wheelEvent->angleDelta();
    if (numDegrees.y() < 0 && Zoom < 45.0f)
        Zoom  = 1.0f;
    if (numDegrees.y() > 0 && Zoom > 1.0f)  
        Zoom -= 1.0f;
  }
  return false;
}

Canvas3D::~Canvas3D()
{
    //delete f;
}

cube.cpp


#include "src/common/geometry/shapes3D/cube.h"
#include <QOpenGLExtraFunctions>
#include <QOpenGLWidget>
#include <QOpenGLContext>
#include <QtMath>
#include <iostream>

namespace invar::geometry3D
{
void Cube::Draw()
{
    auto context = QOpenGLContext::currentContext();
    auto functions = context->functions();
    auto additionalFunctions = context->extraFunctions();
    m_program->bind();
    additionalFunctions->glBindVertexArray(VAO);
    functions->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    int size;    
    functions->glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
    functions->glDrawElements(GL_TRIANGLES, size/sizeof(float), GL_UNSIGNED_INT, 0);
    
}

void Cube::setupShape()
{
    auto context = QOpenGLContext::currentContext();
    auto functions = context->functions();
    auto additionalFunctions = context->extraFunctions();
    
    float vertices[] = {
 
        -0.5f,0.5f,-0.5f,   0.0f, 0.0f, 0.0f,//Point A 0
        -0.5f,0.5f,0.5f,    0.0f, 0.0f, 1.0f,//Point B 1
        0.5f,0.5f,-0.5f,    0.0f, 1.0f, 0.0f,//Point C 2
        0.5f,0.5f,0.5f,     0.0f, 1.0f, 1.0f,//Point D 3
         
        -0.5f,-0.5f,-0.5f,  1.0f, 0.0f, 0.0f,//Point E 4
        -0.5f,-0.5f,0.5f,   1.0f, 0.0f, 1.0f,//Point F 5
        0.5f,-0.5f,-0.5f,   1.0f, 1.0f, 0.0f,//Point G 6
        0.5f,-0.5f,0.5f,    1.0f, 1.0f, 1.0f//Point H 7
 
    };
    
    unsigned int indices[] = {
        0,1,2,
        1,2,3,
 
        4,5,6,
        5,6,7,
        
        0,1,5,
        0,4,5,
        
        2,3,7,
        2,6,7,
    
        0,2,6,
        0,4,6,
       
        1,5,7,
        1,3,7
    };
   functions->glGenBuffers(1, &EBO);
   functions->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
   functions->glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
   
   unsigned int VBO;
   functions->glGenBuffers(1, &VBO);
   additionalFunctions->glGenVertexArrays(1, &VAO);
   additionalFunctions->glBindVertexArray(VAO);
   functions->glBindBuffer(GL_ARRAY_BUFFER, VBO);
   functions->glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
   
   functions->glEnableVertexAttribArray(0);/*Check if need to normilize*/
   functions->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float),(void*)0);
   
   functions->glEnableVertexAttribArray(1);
   functions->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float),
                                       (void*)(3*sizeof(float)));
   
   additionalFunctions->glBindVertexArray(0);
   
}

Cube::Cube(QVector3D pos, float diagonal, QOpenGLShaderProgram* m_program):
           pos(pos), diagonal(diagonal), m_program(m_program)
{
    this->setupShape();
}

}

cube.h

#pragma once
#include "shape3D.h"
#include <QOpenGLContext>
#include <QVector3D>
#include <QOpenGLShaderProgram>

namespace invar::geometry3D
{
class Cube
{

public:
    Cube(QVector3D pos, float diagonal, QOpenGLShaderProgram* program);
    void Draw();
private:
    unsigned int VAO;
    unsigned int EBO;
    QVector3D pos;
    float diagonal;
    QOpenGLShaderProgram* m_program;
    void setupShape();
};
}

Shaders is simple

shaderGrid.fs


#version 130
out vec4 FragColor;

void main()
{
FragColor = vec4(0, 1.0, 1.0, 1.0);
}

shaderGrid.vs

#version 130

in vec3 aPos;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
    gl_Position = projection * view * model * vec4(aPos, 1.0);
}

shader.fs //--- CUBE FRAGMENT SHADER

#version 130
out vec4 FragColor;
in vec3 ourColor;
void main()
{
FragColor = vec4(ourColor, 1.0);
}

shader.vs //--- CUBE VERTEX SHADER


#version 130

in vec3 aPos;
in vec3 aColor;
out vec3 ourColor;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0);
ourColor = aColor;
}

CodePudding user response:

glUniform* changes a uniform of the currently installed shader program. Therefore, you must install (bind) the program before setting the uniforms:

gridShaderProgram->bind();    // <--- INSERT

unsigned int viewID2 = gridShaderProgram->uniformLocation("view");
functions->glUniformMatrix4fv(viewID2, 1, GL_FALSE, view.constData());

unsigned int projectionID2 = gridShaderProgram->uniformLocation("projection");
functions->glUniformMatrix4fv(projectionID2, 1, GL_FALSE, projection.constData());

QMatrix4x4 model2(1.0f, 0.0f, 0.0f, 0.0f,
                    0.0f, 1.0f, 0.0f, 0.0f,
                    0.0f, 0.0f, 1.0f, 0.0f,
                    0.0f, 0.0f, 0.0f, 1.0f);
unsigned int modelID2 = gridShaderProgram->uniformLocation("model");
//model2.scale(10.0f, 0.0f, 10.0f); ------ THIS SCALING
model2.translate(QVector3D(0.0f, 0.0f, 0.0f)); 

functions->glUniformMatrix4fv(modelID2, 1, GL_FALSE, model2.constData());

// gridShaderProgram->bind();     <--- DELETE
  • Related