Advertisement
Guest User

Cylinder.cpp

a guest
Mar 1st, 2017
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.30 KB | None | 0 0
  1. // Cylinder.cpp
  2. //
  3.  
  4.  
  5. #include "stdafx.h"
  6. #include "GL/gl3w.h"
  7. #include "Cylinder.h"
  8. #include "Defs.h"
  9. #include "Constants.h"
  10. #include "GLHelpers.h"
  11. #include "glm/glm.hpp"
  12. #include "glm/detail/type_vec3.hpp"
  13. #include "glm/gtc/matrix_transform.hpp"
  14. #include "glm/gtc/type_ptr.hpp"
  15.  
  16. inline float setFov(float fov) {
  17. #ifdef GLM_FORCE_RADIANS
  18. return (float)(fov / 180.0 * M_PI);
  19. #else
  20. // Documentation of glm which I read was not correct here
  21. return (float)(fov / 180.0 * M_PI);
  22. #endif
  23. }
  24.  
  25. /**
  26. * struct that holds all of the object data
  27. */
  28. struct Vertex
  29. {
  30. glm::vec3 position;
  31. glm::vec3 normal;
  32. glm::tvec3<GLubyte> color;
  33. };
  34.  
  35. /**
  36. * Generate the side of a cylinder centered at (0, 0, 0). Allocates vertData,
  37. * the ownership of which passes to the caller (who must dispose it).
  38. *
  39. * @param numFacets the number of flat sides that approximate the cylinder
  40. * @param height the height of the cylinder (spanning -height/2.0f to height/2.0f)
  41. * @param radius the radius of the cylinder
  42. * @param vertData array of Vertex structures that are output
  43. *
  44. * @returns the number of Vertices that have been generated
  45. */
  46. int genCylSide(int numFacets, float height, float radius, Vertex* &vertData)
  47. {
  48. int numVertices = numFacets * 2 + 2;
  49. vertData = new Vertex[numVertices];
  50. for (int i = 0; i < numVertices; i++)
  51. {
  52. float alpha = static_cast<float>(2.0 * M_PI * (i / 2) / numFacets);
  53. vertData[i].position.x = cos(alpha) * radius;
  54. vertData[i].position.y = i % 2 == 0 ? -height / 2.0f : height / 2.0f;
  55. vertData[i].position.z = sin(alpha) * radius;
  56. vertData[i].normal = glm::normalize(glm::vec3(vertData[i].position.x, 0.0, vertData[i].position.z));
  57. glm::vec3 colA, colB;
  58. colA = i % 2 == 0 ? glm::vec3(0.0, 0.0, 1.0) : glm::vec3(1.0, 0.0, 0.0);
  59. colB = i % 2 == 0 ? glm::vec3(1.0, 1.0, 0.0) : glm::vec3(0.0, 1.0, 0.0);
  60. vertData[i].color = glm::mix(colA, colB, 1.0 - abs((alpha / (2.0 * M_PI) * 2.0 - 1.0))) * 255.0f;
  61. }
  62. return numVertices;
  63. }
  64.  
  65. /**
  66. * Generates a disc centered at (0, 0, 0). Allocates vertData,
  67. * the ownership of which passes to the caller (who must dispose it).
  68. *
  69. * @param numFacets the number of sides that approximate the disc
  70. * @param radius the radius of the disc
  71. * @param vertData array of Vertex structures that are output
  72. *
  73. * @returns the number of Vertices that have been generated
  74. */
  75. int genDisc(int numFacets, float radius, Vertex* &vertData)
  76. {
  77. // TODO Vertex daten fuer Zylinderscheibe generieren,
  78. // in vertData ablegen
  79. // und Anzahl der Vertices ausgegen, siehe analog
  80. // genCylSide
  81.  
  82. int numVertices = numFacets * 2 + 2;
  83. vertData = new Vertex[numVertices];
  84. for (int i = 0; i < numVertices; i++)
  85. {
  86. float alpha = static_cast<float>(2.0 * M_PI * (i / 2) / numFacets);
  87. vertData[i].position.x = (i % 2 == 0) ? cos(alpha) * radius : 0;
  88. vertData[i].position.y = 0;
  89. vertData[i].position.z = (i % 2 == 0) ? sin(alpha) * radius : 0;
  90. vertData[i].color = glm::vec3(1.0, 1.0, 1.0) * 255.0f;
  91. }
  92. return numVertices;
  93.  
  94. // END TODO
  95. }
  96.  
  97. Cylinder::Cylinder(COGL4CoreAPI *Api) : RenderPlugin(Api) {
  98. this->myName = "MyPlugins/Cylinder";
  99. this->myDescription = "renders a single triangle";
  100. //draw = true;
  101. }
  102.  
  103. Cylinder::~Cylinder() {
  104.  
  105. }
  106.  
  107. bool Cylinder::Activate(void) {
  108. std::string pathName = this->GetCurrentPluginPath();
  109.  
  110. viewTrafoHandle = this->AddManipulator(
  111. "View",
  112. &this->viewTrafo,
  113. Manipulator::MANIPULATOR_ORBIT_VIEW_3D,
  114. false
  115. );
  116. boxTrafoHandle = this->AddManipulator(
  117. "Object",
  118. &this->boxTrafo,
  119. Manipulator::MANIPULATOR_OBJ_MOVE_SCALE_ROT);
  120.  
  121. this->SelectCurrentManipulator(2);
  122.  
  123. this->boxTrafo = glm::mat4();
  124.  
  125. this->numFacets = 5;
  126. this->numFacets.Set(this, "numFacets", &Cylinder::NumFacetsChanged);
  127. this->numFacets.Register("min=3 step=1 max=90");
  128.  
  129.  
  130.  
  131. vShaderName = pathName + std::string("shader/vert.glsl");
  132. fShaderName = pathName + std::string("shader/frag.glsl");
  133.  
  134. shader.CreateProgramFromFile(
  135. vShaderName.c_str(),
  136. fShaderName.c_str()
  137. );
  138. this->fovY = 37.0f;
  139. this->fovY.Set(this, "fov", nullptr);
  140. this->fovY.Register("min=20 max=70");
  141. this->fNear = 0.001f;
  142.  
  143. InitGeometry();
  144. return true;
  145. }
  146.  
  147. bool Cylinder::Deactivate(void) {
  148. glDisableVertexAttribArray(0);
  149. glBindBuffer(GL_ARRAY_BUFFER, 0);
  150. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  151. glDeleteBuffers(1, &this->cylSideStrip);
  152. glDeleteBuffers(1, &this->cylTopStrip);
  153. glDeleteVertexArrays(1, &this->cylSideArray);
  154. glDeleteVertexArrays(1, &this->cylTopArray);
  155. shader.RemoveAllShaders();
  156. return true;
  157. }
  158.  
  159. bool Cylinder::Init(void) {
  160. if (gl3wInit()) {
  161. fprintf(stderr, "Error: Failed to initialize gl3d.\n");
  162. return false;
  163. }
  164. glClearColor(0.0f, 0.5f, 1.0f, 1.0f);
  165. glClearDepth(1.0f); // min. Tiefe 0.0, max. Tiefe 1.0
  166. glEnable(GL_DEPTH_TEST);
  167. // glEnable(GL_CULL_FACE);
  168. //glDisable(GL_CULL_FACE);
  169. return true;
  170. }
  171.  
  172. bool Cylinder::Render(void) {
  173.  
  174. glClearColor(0.0f, 0.5f, 1.0f, 1.0f);
  175. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  176. glEnable(GL_DEPTH_TEST);
  177.  
  178. projMatrix = glm::perspective(
  179. setFov(this->fovY),
  180. aspectRatio,
  181. this->fNear,
  182. 1000.0f
  183. );
  184.  
  185. shader.Bind();
  186.  
  187.  
  188. // TODO
  189. // Benoetigte Matrizen erzeugen
  190. // ModelView
  191. // ModelViewProjection
  192. // NormalModel
  193. // ViewInverse
  194.  
  195.  
  196. glm::mat4 mv_matrix = viewTrafo* boxTrafo;
  197. glm::mat4 mvp_matrix = projMatrix *mv_matrix;
  198. glm::mat3 normal_model = glm::mat3();
  199. glm::mat4 view_inv = glm::mat4();
  200.  
  201. // Matrizen an passende shader variablen binden
  202.  
  203. glUniformMatrix4fv(shader.GetUniformLocation("modelMatrix"), 1, GL_FALSE, mv_matrix);
  204. glUniformMatrix4fv(shader.GetUniformLocation("mvpMatrix"), 1, GL_FALSE, mvp_matrix);
  205.  
  206. // END TODO
  207.  
  208. glUniform3f(shader.GetUniformLocation("lightPosWCS"), 300.0f, 600.0f, 600.0f);
  209. glUniform3f(shader.GetUniformLocation("lightCol"), 1.0f, 1.0f, 1.0f);
  210.  
  211. (glBindVertexArray(this->cylSideArray));
  212. (glDrawArrays(GL_TRIANGLE_STRIP, 0, this->cylSideLength));
  213.  
  214. // TODO
  215. // Zylinder Boden und Deckel setzen
  216. // Entsprechende Matrizen anpassen und neu an Shader uebergeben
  217. // Nur eine Geometrie benutzen!
  218.  
  219. // END TODO
  220. shader.Release();
  221. return false;
  222. }
  223.  
  224. bool Cylinder::Keyboard(int key, int action, int mods, int x, int y)
  225. {
  226. if (action == OGLC_RELEASE) {
  227. std::cout << "key pressed: " << key << std::endl;
  228. switch (key) {
  229.  
  230. case OGLC_KEY_R:
  231. {
  232. fprintf(stderr, "Reload shaders ...\n");
  233. shader.RemoveAllShaders();
  234. shader.CreateProgramFromFile(vShaderName.c_str(), fShaderName.c_str());
  235. return true;
  236. }
  237. case OGLC_KEY_S:
  238. {
  239. int w, h;
  240. this->GetWindowSize(w, h);
  241. std::cout << "saving frame to test.png" << std::endl;
  242. GrabFramebuffer("test.png", 0, 0, w, h);
  243. return true;
  244. }
  245. };
  246. }
  247.  
  248. return false;
  249. }
  250.  
  251. bool Cylinder::Resize(int width, int height)
  252. {
  253. aspectRatio = width / static_cast<float>(height);
  254. projMatrix = glm::perspective(
  255. setFov(this->fovY),
  256. aspectRatio,
  257. this->fNear,
  258. 1000.0f);
  259.  
  260. this->windowWidth = width;
  261. this->windowHeight = height;
  262. return true;
  263. }
  264.  
  265. bool Cylinder::InitGeometry(void)
  266. {
  267. Vertex *vertices;
  268. glGenVertexArrays(1, &this->cylSideArray);
  269. glGenBuffers(1, &this->cylSideStrip);
  270. glBindVertexArray(this->cylSideArray);
  271.  
  272. glBindBuffer(GL_ARRAY_BUFFER, this->cylSideStrip);
  273. glEnableVertexAttribArray(0);
  274. this->cylSideLength = genCylSide(this->numFacets, 2.0f, 1.0f, vertices);
  275. glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * this->cylSideLength, vertices, GL_STATIC_DRAW);
  276. glEnableVertexAttribArray(0);
  277. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
  278. glEnableVertexAttribArray(1);
  279. glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<const GLvoid*>(sizeof(glm::vec3)));
  280. glEnableVertexAttribArray(2);
  281. glVertexAttribPointer(2, 3, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), reinterpret_cast<const GLvoid*>(2 * sizeof(glm::vec3)));
  282.  
  283. delete[]vertices;
  284.  
  285. // TODO
  286. // Geometry fuer Zylinder Kopf in VertexArray this->cylTopArray
  287. // und Buffer this->cylTopStrip initialisieren
  288. // Funktion genDisc benutzen
  289.  
  290. // END TODO
  291.  
  292.  
  293. return true;
  294. }
  295.  
  296. void Cylinder::NumFacetsChanged(APIVar<Cylinder, IntVarPolicy>& numFacets)
  297. {
  298. InitGeometry();
  299. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement