czlowiekzgon

Untitled

Dec 17th, 2018
55
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.24 KB | None | 0 0
  1.  
  2. #include "glwidget.h"
  3. #include <QMouseEvent>
  4. #include <QOpenGLShaderProgram>
  5. #include <QCoreApplication>
  6. #include <math.h>
  7. #include <iostream>
  8. using namespace std;
  9.  
  10. //bool GLWidget::m_transparent = false;
  11.  
  12. GLWidget::GLWidget(QWidget *parent)
  13. : QOpenGLWidget(parent),
  14. m_xRot(0),
  15. m_yRot(0),
  16. m_zRot(0),
  17. m_program(0)
  18. {
  19. // OpenGL profile
  20. m_core = QSurfaceFormat::defaultFormat().profile() == QSurfaceFormat::CoreProfile;
  21.  
  22. // GLWidget widget will capture events from keyboard
  23. setFocusPolicy(Qt::StrongFocus);
  24. }
  25.  
  26. GLWidget::~GLWidget()
  27. {
  28. cleanup();
  29. }
  30.  
  31. // returns size of the window
  32. QSize GLWidget::sizeHint() const
  33. {
  34. return QSize(1000, 800);
  35. }
  36.  
  37. // memory clean-up when the apps is finished
  38. void GLWidget::cleanup()
  39. {
  40. if (m_program == nullptr)
  41. return;
  42. makeCurrent();
  43. m_objVbo.destroy();
  44. delete m_program;
  45. m_program = 0;
  46. doneCurrent();
  47. }
  48.  
  49. ////////////////////////////////// object rotation
  50. // normalizes rotation angle
  51. static void qNormalizeAngle(int &angle)
  52. {
  53. while (angle < 0)
  54. angle += 360 * 16;
  55. while (angle > 360 * 16)
  56. angle -= 360 * 16;
  57. }
  58.  
  59. // sets rotation angle
  60. void GLWidget::setXRotation(int angle)
  61. {
  62. qNormalizeAngle(angle); // normalizes rotation angle
  63. if (angle != m_xRot) {
  64. m_xRot = angle;
  65. update(); // forces paintGL() call
  66. }
  67. }
  68.  
  69. // sets rotation angle
  70. void GLWidget::setYRotation(int angle)
  71. {
  72. qNormalizeAngle(angle); // normalizes rotation angle
  73. if (angle != m_yRot) {
  74. m_yRot = angle;
  75. update(); // forces paintGL() call
  76. }
  77. }
  78.  
  79. // sets rotation angle
  80. void GLWidget::setZRotation(int angle)
  81. {
  82. qNormalizeAngle(angle); // normalizes rotation angle
  83. if (angle != m_zRot) {
  84. m_zRot = angle;
  85. update(); // forces paintGL() call
  86. }
  87. }
  88.  
  89.  
  90. /////////////////////////////////////////// vertex shader
  91. static const char *vertexShaderSource =
  92. "attribute vec4 vertex;\n"
  93. "attribute vec3 normal;\n"
  94. "uniform mat4 projMatrix;\n"
  95. "uniform mat4 mvMatrix;\n"
  96. "void main() {\n"
  97. " gl_Position = projMatrix * mvMatrix * vertex;\n"
  98. "}\n";
  99.  
  100. /////////////////////////////////////////// fragment shader
  101. static const char *fragmentShaderSource =
  102. "uniform highp vec3 modelColor;\n"
  103. "void main() {\n"
  104. " gl_FragColor = vec4(modelColor, 0);\n"
  105. "}\n";
  106.  
  107.  
  108. /////////////////////////////////////////////////// OpenGL initialization
  109. void GLWidget::initializeGL()
  110. {
  111. initializeOpenGLFunctions(); // required to call OpenGL functions directly
  112. glClearColor(0.2, 0.2, 0.2, 1); // backgroung clear color
  113.  
  114. // loads, compiles and links shader programs
  115. m_program = new QOpenGLShaderProgram;
  116. m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
  117. m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
  118. m_program->bindAttributeLocation("vertex", 0);
  119. m_program->bindAttributeLocation("normal", 1);
  120. m_program->link();
  121.  
  122. // sets shader variables
  123. m_program->bind();
  124. m_projMatrixLoc = m_program->uniformLocation("projMatrix"); // projection matrix
  125. m_mvMatrixLoc = m_program->uniformLocation("mvMatrix"); // model-view matrix
  126. m_currentColor = m_program->uniformLocation("modelColor");
  127. // builds 3D object based on VAO nad VBO
  128. m_vao.create(); // creates vertex array object
  129. QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao); // binds vertex array object
  130. m_objVbo.create(); // creates vertex buffer object
  131. m_objVbo.bind(); // binds vertex buffer object
  132. m_objVbo.allocate(m_obj.constData(), m_obj.count() * sizeof(GLfloat)); // copies mesh data to vertex buffer object
  133. setupVertexAttribs(); // stores vertex attribute bindings for the program
  134.  
  135. // sets camera position to (0,0,-1), camera looks at (0,0,0)
  136. m_camera.setToIdentity();
  137. m_camera.translate(0, 0, -1);
  138.  
  139. m_program->release();
  140. }
  141.  
  142. // sets VAO attributes
  143. void GLWidget::setupVertexAttribs()
  144. {
  145. m_objVbo.bind();
  146. QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
  147. f->glEnableVertexAttribArray(0);
  148. f->glEnableVertexAttribArray(1);
  149. f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), 0);
  150. f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), reinterpret_cast<void *>(3 * sizeof(GLfloat)));
  151. m_objVbo.release();
  152. }
  153.  
  154.  
  155. /////////////////////////////////////////////////// OpenGL drawing
  156. void GLWidget::paintGL()
  157. {
  158. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clears framebuffer
  159. glEnable(GL_DEPTH_TEST); // enables Z-buffer
  160. glEnable(GL_CULL_FACE); // enables backface culling (back face of triangles is inivisible)
  161.  
  162. QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao); // binds vertex array object
  163.  
  164. m_program->bind(); // binds shaders
  165.  
  166. // rotation of the robot
  167. m_world.setToIdentity();
  168. m_world.rotate(0.0f - (m_xRot / 16.0f), 1, 0, 0);
  169. m_world.rotate(m_yRot / 16.0f, 0, 1, 0);
  170. m_world.rotate(m_zRot / 16.0f, 0, 0, 1);
  171.  
  172. QMatrix4x4 m_world_tmp = m_world; // stores current model-view matrix
  173.  
  174. //PRAWIDŁOWA KONWENCJA
  175. //TRANSLATE => ROTATE => SCALE
  176.  
  177.  
  178. m_world.translate(playerPosition);
  179. //robot head
  180.  
  181. m_program->setUniformValue(m_currentColor, QVector3D(0.7f, 0.8, 0.9));
  182. m_world = m_world_tmp;
  183. m_world.translate(0.0, 0.15, 0.0);
  184. m_world.scale(QVector3D(0.1, 0.1, 0.1));
  185. setTransforms();
  186. glDrawArrays(GL_TRIANGLES, 0, m_obj.vertexCount()); // draws VAO
  187.  
  188. // robot right hand
  189. m_program->setUniformValue(m_currentColor, QVector3D(0.2f, 0.9, 0.3f));
  190. m_world = m_world_tmp;
  191. m_world.translate(0.17, 0, 0.0);
  192. m_world.rotate(-15.0, 0, 0, 1);
  193. m_world.scale(QVector3D(0.16, 0.05, 0.05));
  194. setTransforms();
  195. glDrawArrays(GL_TRIANGLES, 0, m_obj.vertexCount()); // draws VAO
  196.  
  197.  
  198. // robot left hand
  199. m_world = m_world_tmp;
  200. // m_world.translate(-0.17, 0.02, 0.0);
  201. m_world.rotate(sin(timer*(0.1))*(-6.5),0, 0, 1);
  202. m_world.translate(-0.17, 0.02, 0.0);
  203.  
  204. m_world.scale(QVector3D(0.16, 0.05, 0.05));
  205. setTransforms();
  206. glDrawArrays(GL_TRIANGLES, 0, m_obj.vertexCount()); // draws VAO
  207.  
  208. // robot left leg
  209. m_program->setUniformValue(m_currentColor, QVector3D(0.2f, 0.8f, 0.3));
  210. m_world = m_world_tmp;
  211. m_world.translate(-0.1, -0.29, 0.0);
  212. m_world.rotate(60.0, 0, 0, 1);
  213. m_world.scale(QVector3D(0.16, 0.05, 0.05));
  214. setTransforms();
  215. glDrawArrays(GL_TRIANGLES, 0, m_obj.vertexCount()); // draws VAO
  216.  
  217. // robot right leg
  218. m_world = m_world_tmp;
  219. m_world.translate(0.1, -0.29, 0.0);
  220. m_world.rotate(-60.0, 0, 0, 1);
  221. m_world.scale(QVector3D(0.16, 0.05, 0.05));
  222. setTransforms();
  223. glDrawArrays(GL_TRIANGLES, 0, m_obj.vertexCount()); // draws VAO
  224.  
  225. //robot body
  226. m_program->setUniformValue(m_currentColor, QVector3D(0.8f, 0.8f, 0.7));
  227. m_world = m_world_tmp;
  228. m_world.translate(0.0, -0.05, 0.0);
  229. m_world.scale(QVector3D(0.15, 0.25, 0.15));
  230. setTransforms();
  231. glDrawArrays(GL_TRIANGLES, 0, m_obj.vertexCount()); // draws VAO
  232. if(keyState[Qt::Key_W]) playerPosition.setZ(playerPosition.z() - 0.02);
  233. if(keyState[Qt::Key_S]) playerPosition.setZ(playerPosition.z() + 0.02);
  234. if(keyState[Qt::Key_A]){
  235. playerPosition;
  236. playerPosition.setX(playerPosition.x() - 0.02);
  237. }
  238. if(keyState[Qt::Key_D]) playerPosition.setX(playerPosition.x() + 0.02);
  239. m_program->release(); // executes shaders (actual redrawing)
  240.  
  241. timer++; //increments after frame ends
  242. update();
  243. }
  244.  
  245.  
  246. // sends transformation matrices to shaders
  247. void GLWidget::setTransforms(void)
  248. {
  249. m_program->setUniformValue(m_projMatrixLoc, m_proj); // sets projection matrix
  250. m_program->setUniformValue(m_mvMatrixLoc, m_camera * m_world); // sets model-view matrix
  251. }
  252.  
  253.  
  254. /////////////////////////////////////////////////// function called when window size is changed
  255. void GLWidget::resizeGL(int w, int h)
  256. {
  257. // defines perspective projection
  258. m_proj.setToIdentity();
  259. m_proj.perspective(60.0f, GLfloat(w) / h, 0.01f, 100.0f); // sets FOV, aspect, near clipping plane, and far clipping plane
  260. }
  261.  
  262.  
  263.  
  264. /////////////////////////////////////////////////// mouse events
  265. void GLWidget::mousePressEvent(QMouseEvent *event)
  266. {
  267. m_lastPos = event->pos();
  268. }
  269.  
  270. void GLWidget::mouseMoveEvent(QMouseEvent *event)
  271. {
  272. int dx = event->x() - m_lastPos.x();
  273. int dy = event->y() - m_lastPos.y();
  274.  
  275. if (event->buttons() & Qt::LeftButton) {
  276. setXRotation(m_xRot + 8 * dy);
  277. setYRotation(m_yRot + 8 * dx);
  278. } else if (event->buttons() & Qt::RightButton) {
  279. setXRotation(m_xRot + 8 * dy);
  280. setZRotation(m_zRot + 8 * dx);
  281. }
  282. m_lastPos = event->pos();
  283. }
  284.  
  285.  
  286.  
  287. /////////////////////////////////////////////////// keyboard events
  288. void GLWidget::keyPressEvent(QKeyEvent *e)
  289. {
  290. if(e->key()>-0 && e->key()<=255){
  291. keyState[e-key()]=true;
  292. }
  293. if (e->key() == Qt::Key_Escape)
  294. exit(0);
  295. else
  296. if (e->key() == Qt::Key_Q)
  297. exit(0);
  298. else
  299. QWidget::keyPressEvent(e);
  300. }
  301. void GLWidget::keyReleaseEvent(QKeyEvent *event){
  302. if(e->key()>-0 && e->key()<=255){
  303. keyState[e-key()]=false;
  304. }
  305. }
Add Comment
Please, Sign In to add comment