Advertisement
Guest User

MyGLWidget.cpp

a guest
May 1st, 2016
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <GL/glew.h>
  2. #include "MyGLWidget.h"
  3.  
  4. #include <iostream>
  5.  
  6. MyGLWidget::MyGLWidget (QGLFormat &f, QWidget* parent) : QGLWidget(f, parent)
  7. {
  8.   setFocusPolicy(Qt::ClickFocus);  // per rebre events de teclat
  9.   xClick = yClick = 0;
  10.   angleY = 0.0;
  11.   angleX = 0.0;
  12.   colFocus = glm::vec3(1, 1, 1);
  13.   posFocus = glm::vec3(1, 1, 1);
  14.   posFocX = 1;
  15.   posFocZ = 1;
  16.   DoingInteractive = NONE;
  17.   radiEsc = sqrt(4);
  18. }
  19.  
  20. void MyGLWidget::initializeGL ()
  21. {
  22.   // glew és necessari per cridar funcions de les darreres versions d'OpenGL
  23.   glewExperimental = GL_TRUE;
  24.   glewInit();
  25.   glGetError();  // Reinicia la variable d'error d'OpenGL
  26.  
  27.   glClearColor (0.5, 0.7, 1.0, 1.0);  // defineix color de fons (d'esborrat)
  28.   glEnable(GL_DEPTH_TEST);
  29.   carregaShaders ();
  30.   createBuffers ();
  31.   projectTransform ();
  32.   viewTransform ();
  33. }
  34.  
  35. void MyGLWidget::paintGL ()
  36. {
  37.   // Esborrem el frame-buffer i el depth-buffer
  38.   glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  39.  
  40.   // Activem el VAO per a pintar el terra
  41.   glBindVertexArray (VAO_Terra);
  42.  
  43.   modelTransformTerra ();
  44.  
  45.   // pintem
  46.   glDrawArrays(GL_TRIANGLES, 0, 12);
  47.  
  48.   // Activem el VAO per a pintar el Patricio
  49.   glBindVertexArray (VAO_Patr);
  50.  
  51.   modelTransformPatricio ();
  52.  
  53.   // Pintem l'escena
  54.   glDrawArrays(GL_TRIANGLES, 0, patr.faces().size()*3);
  55.  
  56.  
  57.   glBindVertexArray(VAO_Patr2);
  58.  
  59.   modelTransformPatricio2();
  60.  
  61.   glDrawArrays(GL_TRIANGLES, 0, patr.faces().size()*3);
  62.  
  63.  
  64.   glBindVertexArray(0);
  65. }
  66.  
  67. void MyGLWidget::resizeGL (int w, int h)
  68. {
  69.   glViewport (0, 0, w, h);
  70. }
  71.  
  72. void MyGLWidget::createBuffers ()
  73. {
  74.   // Carreguem el model de l'OBJ - Atenció! Abans de crear els buffers!
  75.   //patr.load("/assig/idi/models/Patricio.obj");
  76.   patr.load("Patricio.obj");
  77.  
  78.   // Calculem la capsa contenidora del model
  79.   calculaCapsaModel ();
  80.  
  81.   // Creació del Vertex Array Object del Patricio
  82.   glGenVertexArrays(1, &VAO_Patr);
  83.   glBindVertexArray(VAO_Patr);
  84.  
  85.   // Creació dels buffers del model patr
  86.   // Buffer de posicions
  87.   glGenBuffers(1, &VBO_PatrPos);
  88.   glBindBuffer(GL_ARRAY_BUFFER, VBO_PatrPos);
  89.   glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*patr.faces().size()*3*3, patr.VBO_vertices(), GL_STATIC_DRAW);
  90.  
  91.   // Activem l'atribut vertexLoc
  92.   glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
  93.   glEnableVertexAttribArray(vertexLoc);
  94.  
  95.   // Buffer de normals
  96.   glGenBuffers(1, &VBO_PatrNorm);
  97.   glBindBuffer(GL_ARRAY_BUFFER, VBO_PatrNorm);
  98.   glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*patr.faces().size()*3*3, patr.VBO_normals(), GL_STATIC_DRAW);
  99.  
  100.   glVertexAttribPointer(normalLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
  101.   glEnableVertexAttribArray(normalLoc);
  102.  
  103.   // En lloc del color, ara passem tots els paràmetres dels materials
  104.   // Buffer de component ambient
  105.   glGenBuffers(1, &VBO_PatrMatamb);
  106.   glBindBuffer(GL_ARRAY_BUFFER, VBO_PatrMatamb);
  107.   glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*patr.faces().size()*3*3, patr.VBO_matamb(), GL_STATIC_DRAW);
  108.  
  109.   glVertexAttribPointer(matambLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
  110.   glEnableVertexAttribArray(matambLoc);
  111.  
  112.   // Buffer de component difusa
  113.   glGenBuffers(1, &VBO_PatrMatdiff);
  114.   glBindBuffer(GL_ARRAY_BUFFER, VBO_PatrMatdiff);
  115.   glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*patr.faces().size()*3*3, patr.VBO_matdiff(), GL_STATIC_DRAW);
  116.  
  117.   glVertexAttribPointer(matdiffLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
  118.   glEnableVertexAttribArray(matdiffLoc);
  119.  
  120.   // Buffer de component especular
  121.   glGenBuffers(1, &VBO_PatrMatspec);
  122.   glBindBuffer(GL_ARRAY_BUFFER, VBO_PatrMatspec);
  123.   glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*patr.faces().size()*3*3, patr.VBO_matspec(), GL_STATIC_DRAW);
  124.  
  125.   glVertexAttribPointer(matspecLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
  126.   glEnableVertexAttribArray(matspecLoc);
  127.  
  128.   // Buffer de component shininness
  129.   glGenBuffers(1, &VBO_PatrMatshin);
  130.   glBindBuffer(GL_ARRAY_BUFFER, VBO_PatrMatshin);
  131.   glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*patr.faces().size()*3, patr.VBO_matshin(), GL_STATIC_DRAW);
  132.  
  133.   glVertexAttribPointer(matshinLoc, 1, GL_FLOAT, GL_FALSE, 0, 0);
  134.   glEnableVertexAttribArray(matshinLoc);
  135.  
  136.   //////////////////////////////////////////////////////
  137.   ////////////////////SEGON PATRICIO////////////////////
  138.   //////////////////////////////////////////////////////
  139.  
  140.   // Creació del Vertex Array Object del Patricio
  141.   glGenVertexArrays(1, &VAO_Patr2);
  142.   glBindVertexArray(VAO_Patr2);
  143.  
  144.   // Creació dels buffers del model patr
  145.   // Buffer de posicions
  146.   glGenBuffers(1, &VBO_PatrPos2);
  147.   glBindBuffer(GL_ARRAY_BUFFER, VBO_PatrPos2);
  148.   glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*patr.faces().size()*3*3, patr.VBO_vertices(), GL_STATIC_DRAW);
  149.  
  150.   // Activem l'atribut vertexLoc
  151.   glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
  152.   glEnableVertexAttribArray(vertexLoc);
  153.  
  154.   // Buffer de normals
  155.   glGenBuffers(1, &VBO_PatrNorm2);
  156.   glBindBuffer(GL_ARRAY_BUFFER, VBO_PatrNorm2);
  157.   glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*patr.faces().size()*3*3, patr.VBO_normals(), GL_STATIC_DRAW);
  158.  
  159.   glVertexAttribPointer(normalLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
  160.   glEnableVertexAttribArray(normalLoc);
  161.  
  162.   // En lloc del color, ara passem tots els paràmetres dels materials
  163.   // Buffer de component ambient
  164.   glGenBuffers(1, &VBO_PatrMatamb2);
  165.   glBindBuffer(GL_ARRAY_BUFFER, VBO_PatrMatamb2);
  166.   glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*patr.faces().size()*3*3, patr.VBO_matamb(), GL_STATIC_DRAW);
  167.  
  168.   glVertexAttribPointer(matambLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
  169.   glEnableVertexAttribArray(matambLoc);
  170.  
  171.   // Buffer de component difusa
  172.   glGenBuffers(1, &VBO_PatrMatdiff2);
  173.   glBindBuffer(GL_ARRAY_BUFFER, VBO_PatrMatdiff2);
  174.   glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*patr.faces().size()*3*3, patr.VBO_matdiff(), GL_STATIC_DRAW);
  175.  
  176.   glVertexAttribPointer(matdiffLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
  177.   glEnableVertexAttribArray(matdiffLoc);
  178.  
  179.   // Buffer de component especular
  180.   glGenBuffers(1, &VBO_PatrMatspec2);
  181.   glBindBuffer(GL_ARRAY_BUFFER, VBO_PatrMatspec2);
  182.   glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*patr.faces().size()*3*3, patr.VBO_matspec(), GL_STATIC_DRAW);
  183.  
  184.   glVertexAttribPointer(matspecLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
  185.   glEnableVertexAttribArray(matspecLoc);
  186.  
  187.   // Buffer de component shininness
  188.   glGenBuffers(1, &VBO_PatrMatshin2);
  189.   glBindBuffer(GL_ARRAY_BUFFER, VBO_PatrMatshin2);
  190.   glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*patr.faces().size()*3, patr.VBO_matshin(), GL_STATIC_DRAW);
  191.  
  192.   glVertexAttribPointer(matshinLoc, 1, GL_FLOAT, GL_FALSE, 0, 0);
  193.   glEnableVertexAttribArray(matshinLoc);
  194.  
  195.   ////////////////////////////////////////////
  196.   ///////////////////TERRA////////////////////
  197.   ////////////////////////////////////////////
  198.  
  199.   // Dades del terra
  200.   // VBO amb la posició dels vèrtexs
  201.   glm::vec3 posterra[6] = {
  202.     glm::vec3(-2.0, -0.5, 2.0),
  203.     glm::vec3(2.0, -0.5, 2.0),
  204.     glm::vec3(-2.0, -0.5, -2.0),
  205.     glm::vec3(-2.0, -0.5, -2.0),
  206.     glm::vec3(2.0, -0.5, 2.0),
  207.     glm::vec3(2.0, -0.5, -2.0),
  208.   };
  209.  
  210.   // VBO amb la normal de cada vèrtex
  211.   glm::vec3 norm1 (0,1,0);
  212.   glm::vec3 normterra[6] = {
  213.     norm1, norm1, norm1, norm1, norm1, norm1  // la normal (0,0,1) per als dos últims triangles
  214.   };
  215.  
  216.   // Definim el material del terra
  217.   glm::vec3 amb(0.2,0,0.2);
  218.   glm::vec3 diff(0,0,1);
  219.   glm::vec3 spec(0.8,0.8,0.8);
  220.   float shin = 100;
  221.  
  222.   // Fem que aquest material afecti a tots els vèrtexs per igual
  223.   glm::vec3 matambterra[6] = {
  224.     amb, amb, amb, amb, amb, amb,
  225.   };
  226.   glm::vec3 matdiffterra[6] = {
  227.     diff, diff, diff, diff, diff, diff,
  228.   };
  229.   glm::vec3 matspecterra[6] = {
  230.     spec, spec, spec, spec, spec, spec,
  231.   };
  232.   float matshinterra[6] = {
  233.     shin, shin, shin, shin, shin, shin,
  234.   };
  235.  
  236. // Creació del Vertex Array Object del terra
  237.   glGenVertexArrays(1, &VAO_Terra);
  238.   glBindVertexArray(VAO_Terra);
  239.  
  240.   glGenBuffers(1, &VBO_TerraPos);
  241.   glBindBuffer(GL_ARRAY_BUFFER, VBO_TerraPos);
  242.   glBufferData(GL_ARRAY_BUFFER, sizeof(posterra), posterra, GL_STATIC_DRAW);
  243.  
  244.   // Activem l'atribut vertexLoc
  245.   glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
  246.   glEnableVertexAttribArray(vertexLoc);
  247.  
  248.   glGenBuffers(1, &VBO_TerraNorm);
  249.   glBindBuffer(GL_ARRAY_BUFFER, VBO_TerraNorm);
  250.   glBufferData(GL_ARRAY_BUFFER, sizeof(normterra), normterra, GL_STATIC_DRAW);
  251.  
  252.   // Activem l'atribut normalLoc
  253.   glVertexAttribPointer(normalLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
  254.   glEnableVertexAttribArray(normalLoc);
  255.  
  256.   // En lloc del color, ara passem tots els paràmetres dels materials
  257.   // Buffer de component ambient
  258.   glGenBuffers(1, &VBO_TerraMatamb);
  259.   glBindBuffer(GL_ARRAY_BUFFER, VBO_TerraMatamb);
  260.   glBufferData(GL_ARRAY_BUFFER, sizeof(matambterra), matambterra, GL_STATIC_DRAW);
  261.  
  262.   glVertexAttribPointer(matambLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
  263.   glEnableVertexAttribArray(matambLoc);
  264.  
  265.   // Buffer de component difusa
  266.   glGenBuffers(1, &VBO_TerraMatdiff);
  267.   glBindBuffer(GL_ARRAY_BUFFER, VBO_TerraMatdiff);
  268.   glBufferData(GL_ARRAY_BUFFER, sizeof(matdiffterra), matdiffterra, GL_STATIC_DRAW);
  269.  
  270.   glVertexAttribPointer(matdiffLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
  271.   glEnableVertexAttribArray(matdiffLoc);
  272.  
  273.   // Buffer de component especular
  274.   glGenBuffers(1, &VBO_TerraMatspec);
  275.   glBindBuffer(GL_ARRAY_BUFFER, VBO_TerraMatspec);
  276.   glBufferData(GL_ARRAY_BUFFER, sizeof(matspecterra), matspecterra, GL_STATIC_DRAW);
  277.  
  278.   glVertexAttribPointer(matspecLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
  279.   glEnableVertexAttribArray(matspecLoc);
  280.  
  281.   // Buffer de component shininness
  282.   glGenBuffers(1, &VBO_TerraMatshin);
  283.   glBindBuffer(GL_ARRAY_BUFFER, VBO_TerraMatshin);
  284.   glBufferData(GL_ARRAY_BUFFER, sizeof(matshinterra), matshinterra, GL_STATIC_DRAW);
  285.  
  286.   glVertexAttribPointer(matshinLoc, 1, GL_FLOAT, GL_FALSE, 0, 0);
  287.   glEnableVertexAttribArray(matshinLoc);
  288.  
  289.   glBindVertexArray(0);
  290. }
  291.  
  292. void MyGLWidget::carregaShaders ()
  293. {
  294.   // Creem els shaders per al fragment i vertex shader
  295.   QGLShader fs(QGLShader::Fragment, this);
  296.   QGLShader vs(QGLShader::Vertex, this);
  297.   // Carreguem el codi dels fitxers i els compilem
  298.   fs.compileSourceFile("./shaders/fragshad.frag");
  299.   vs.compileSourceFile("./shaders/vertshad.vert");
  300.  
  301.   // Creem el program
  302.   program = new QGLShaderProgram(this);
  303.   // Li afegim els shaders corresponents
  304.   program->addShader(&fs);
  305.   program->addShader(&vs);
  306.  
  307.   // Linkem el program
  308.   program->link();
  309.  
  310.   // Indiquem que aquest és el program que volem usar
  311.   program->bind();
  312.  
  313.   // Obtenim identificador per a l'atribut “vertex” del vertex shader
  314.   vertexLoc = glGetAttribLocation (program->programId(), "vertex");
  315.   // Obtenim identificador per a l'atribut “normal” del vertex shader
  316.   normalLoc = glGetAttribLocation (program->programId(), "normal");
  317.   // Obtenim identificador per a l'atribut “matamb” del vertex shader
  318.   matambLoc = glGetAttribLocation (program->programId(), "matamb");
  319.   // Obtenim identificador per a l'atribut “matdiff” del vertex shader
  320.   matdiffLoc = glGetAttribLocation (program->programId(), "matdiff");
  321.   // Obtenim identificador per a l'atribut “matspec” del vertex shader
  322.   matspecLoc = glGetAttribLocation (program->programId(), "matspec");
  323.   // Obtenim identificador per a l'atribut “matshin” del vertex shader
  324.   matshinLoc = glGetAttribLocation (program->programId(), "matshin");
  325.  
  326.  
  327.   // Identificador per al color del focus de llum
  328.   colFocLoc = glGetUniformLocation (program->programId(), "colFocus");
  329.   // Identificador per a la posició del focus de llum
  330.   posFocLoc = glGetUniformLocation (program->programId(), "posFocus");
  331.  
  332.   // Demanem identificadors per als uniforms del vertex shader
  333.   transLoc = glGetUniformLocation (program->programId(), "TG");
  334.   projLoc = glGetUniformLocation (program->programId(), "proj");
  335.   viewLoc = glGetUniformLocation (program->programId(), "view");
  336.  
  337. }
  338.  
  339. void MyGLWidget::modelTransformPatricio ()
  340. {
  341.   glm::mat4 TG(1.f);  // Matriu de transformació
  342.   TG = glm::translate(TG, glm::vec3(1,0,1));
  343.   TG = glm::scale(TG, glm::vec3(escala, escala, escala));
  344.   TG = glm::translate(TG, -centrePatr);
  345.  
  346.   glUniformMatrix4fv (transLoc, 1, GL_FALSE, &TG[0][0]);
  347. }
  348.  
  349. void MyGLWidget::modelTransformPatricio2 ()
  350. {
  351.   glm::mat4 TG(1.f);  // Matriu de transformació
  352.   TG = glm::translate(TG, glm::vec3(-1,0,-1));
  353.   TG = glm::rotate(TG, (float) M_PI, glm::vec3(0,1,0));
  354.   TG = glm::scale(TG, glm::vec3(escala, escala, escala));
  355.   TG = glm::translate(TG, -centrePatr);
  356.  
  357.   glUniformMatrix4fv (transLoc, 1, GL_FALSE, &TG[0][0]);
  358. }
  359.  
  360. void MyGLWidget::modelTransformTerra ()
  361. {
  362.   glm::mat4 TG(1.f);  // Matriu de transformació
  363.   glUniformMatrix4fv (transLoc, 1, GL_FALSE, &TG[0][0]);
  364. }
  365.  
  366. void MyGLWidget::projectTransform ()
  367. {
  368.   //sempre mantenim la aspect ratio de la pantalla per evitar deformacions
  369.   glm::mat4 Proj;  // Matriu de projecció
  370.   Proj = glm::perspective(float(M_PI/3.0), 1.0f, 1.0f, 3.0f*radiEsc+1);
  371.   //Per a optica axonometrica:
  372.   //Proj = glm::ortho(letf,right,bottom,top,zNear,zFar);
  373.  
  374.   glUniformMatrix4fv (projLoc, 1, GL_FALSE, &Proj[0][0]);
  375. }
  376.  
  377. void MyGLWidget::viewTransform ()
  378. {
  379.   glm::mat4 View;  // Matriu de posició i orientació
  380.   View = glm::translate(glm::mat4(1.f), glm::vec3(0, 0, -2*radiEsc));
  381.   View = glm::rotate(View, -angleY, glm::vec3(0, 1, 0));
  382.   View = glm::rotate(View, -angleX, glm::vec3(1,0,0));
  383.  
  384.   posFocus = glm::vec3(posFocX, 1, 1);
  385.   glUniform3fv (posFocLoc, 1, &posFocus[0]);
  386.   glUniform3fv (colFocLoc, 1, &colFocus[0]);
  387.  
  388.   glUniformMatrix4fv (viewLoc, 1, GL_FALSE, &View[0][0]);
  389. }
  390.  
  391. void MyGLWidget::calculaCapsaModel ()
  392. {
  393.   // Càlcul capsa contenidora i valors transformacions inicials
  394.   float minx, miny, minz, maxx, maxy, maxz;
  395.   minx = maxx = patr.vertices()[0];
  396.   miny = maxy = patr.vertices()[1];
  397.   minz = maxz = patr.vertices()[2];
  398.   for (unsigned int i = 3; i < patr.vertices().size(); i+=3)
  399.   {
  400.     if (patr.vertices()[i+0] < minx)
  401.       minx = patr.vertices()[i+0];
  402.     if (patr.vertices()[i+0] > maxx)
  403.       maxx = patr.vertices()[i+0];
  404.     if (patr.vertices()[i+1] < miny)
  405.       miny = patr.vertices()[i+1];
  406.     if (patr.vertices()[i+1] > maxy)
  407.       maxy = patr.vertices()[i+1];
  408.     if (patr.vertices()[i+2] < minz)
  409.       minz = patr.vertices()[i+2];
  410.     if (patr.vertices()[i+2] > maxz)
  411.       maxz = patr.vertices()[i+2];
  412.   }
  413.   escala = 1.0/(maxy-miny);
  414.   centrePatr[0] = (minx+maxx)/2.0; centrePatr[1] = (miny+maxy)/2.0; centrePatr[2] = (minz+maxz)/2.0;
  415. }
  416.  
  417. void MyGLWidget::keyPressEvent (QKeyEvent *e)
  418. {
  419.   switch (e->key())
  420.   {
  421.     case Qt::Key_Escape:
  422.         exit(0);
  423.     case Qt::Key_K:
  424.         posFocX += 0.1;
  425.         viewTransform();
  426.         break;
  427.     case Qt::Key_L:
  428.         posFocX -= 0.1;
  429.         viewTransform();
  430.         break;
  431.     default: e->ignore(); break;
  432.   }
  433.  
  434.   updateGL();
  435. }
  436.  
  437. void MyGLWidget::mousePressEvent (QMouseEvent *e)
  438. {
  439.   xClick = e->x();
  440.   yClick = e->y();
  441.  
  442.   if (e->button() & Qt::LeftButton &&
  443.       ! (e->modifiers() & (Qt::ShiftModifier|Qt::AltModifier|Qt::ControlModifier)))
  444.   {
  445.     DoingInteractive = ROTATE;
  446.   }
  447. }
  448.  
  449. void MyGLWidget::mouseReleaseEvent( QMouseEvent *)
  450. {
  451.   DoingInteractive = NONE;
  452. }
  453.  
  454. void MyGLWidget::mouseMoveEvent(QMouseEvent *e)
  455. {
  456.   // Aqui cal que es calculi i s'apliqui la rotacio o el zoom com s'escaigui...
  457.   if (DoingInteractive == ROTATE)
  458.   {
  459.     // Fem la rotació
  460.     angleY += (e->x() - xClick) * M_PI / 180.0;
  461.     angleX += (e->y() - yClick) * M_PI / 180.0;
  462.     viewTransform ();
  463.   }
  464.  
  465.   xClick = e->x();
  466.   yClick = e->y();
  467.  
  468.   updateGL ();
  469. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement