The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

404 lines
15KB

  1. /*
  2. ==============================================================================
  3. This file was auto-generated!
  4. ==============================================================================
  5. */
  6. #ifndef MAINCOMPONENT_H_INCLUDED
  7. #define MAINCOMPONENT_H_INCLUDED
  8. #include "../JuceLibraryCode/JuceHeader.h"
  9. #include "WavefrontObjParser.h"
  10. //==============================================================================
  11. /*
  12. This component lives inside our window, and this is where you should put all
  13. your controls and content.
  14. */
  15. class MainContentComponent : public OpenGLAppComponent
  16. {
  17. public:
  18. //==============================================================================
  19. MainContentComponent()
  20. {
  21. setSize (800, 600);
  22. }
  23. ~MainContentComponent()
  24. {
  25. shutdownOpenGL();
  26. }
  27. void initialise() override
  28. {
  29. setShaders();
  30. }
  31. void shutdown() override
  32. {
  33. shader = nullptr;
  34. shape = nullptr;
  35. attributes = nullptr;
  36. uniforms = nullptr;
  37. }
  38. Matrix3D<float> getProjectionMatrix() const
  39. {
  40. float w = 1.0f / (0.5 + 0.1f);
  41. float h = w * getLocalBounds().toFloat().getAspectRatio (false);
  42. return Matrix3D<float>::fromFrustum (-w, w, -h, h, 4.0f, 30.0f);
  43. }
  44. Matrix3D<float> getViewMatrix() const
  45. {
  46. Matrix3D<float> viewMatrix (Vector3D<float> (0.0f, 0.0f, -10.0f));
  47. //viewMatrix *= draggableOrientation.getRotationMatrix();
  48. // Matrix3D<float> rotationMatrix = viewMatrix.rotated (Vector3D<float> (rotation, rotation, -0.3f));
  49. Matrix3D<float> rotationMatrix = viewMatrix.rotated (Vector3D<float> (-0.3f, 5.0f*sin(getFrameCounter()*0.01f), 0.0f));
  50. return viewMatrix * rotationMatrix;
  51. }
  52. void render() override
  53. {
  54. jassert (OpenGLHelpers::isContextActive());
  55. const float desktopScale = (float) openGLContext.getRenderingScale();
  56. OpenGLHelpers::clear (Colour::greyLevel(0.1));
  57. glEnable (GL_DEPTH_TEST);
  58. glDepthFunc (GL_LESS);
  59. glEnable (GL_BLEND);
  60. glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  61. openGLContext.extensions.glActiveTexture (GL_TEXTURE0);
  62. glEnable (GL_TEXTURE_2D);
  63. glViewport (0, 0, roundToInt (desktopScale * getWidth()), roundToInt (desktopScale * getHeight()));
  64. shader->use();
  65. if (uniforms->projectionMatrix != nullptr)
  66. uniforms->projectionMatrix->setMatrix4 (getProjectionMatrix().mat, 1, false);
  67. if (uniforms->viewMatrix != nullptr)
  68. uniforms->viewMatrix->setMatrix4 (getViewMatrix().mat, 1, false);
  69. shape->draw (openGLContext, *attributes);
  70. // Reset the element buffers so child Components draw correctly
  71. openGLContext.extensions.glBindBuffer (GL_ARRAY_BUFFER, 0);
  72. openGLContext.extensions.glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0);
  73. }
  74. void paint (Graphics& g) override
  75. {
  76. // You can add your component specific drawing code here!
  77. // This will draw over the top of the openGL background.
  78. // g.setColour(Colours::white);
  79. // g.drawEllipse (100, 100, 50, 50, 2);
  80. }
  81. void resized() override
  82. {
  83. // This is called when the MainContentComponent is resized.
  84. // If you add any child components, this is where you should
  85. // update their positions.
  86. }
  87. void setShaders()
  88. {
  89. vertexShader = {
  90. "attribute vec4 position;\n"
  91. "attribute vec4 sourceColour;\n"
  92. "attribute vec2 texureCoordIn;\n"
  93. "\n"
  94. "uniform mat4 projectionMatrix;\n"
  95. "uniform mat4 viewMatrix;\n"
  96. "\n"
  97. "varying vec4 destinationColour;\n"
  98. "varying vec2 textureCoordOut;\n"
  99. "\n"
  100. "void main()\n"
  101. "{\n"
  102. " destinationColour = sourceColour;\n"
  103. " textureCoordOut = texureCoordIn;\n"
  104. " gl_Position = projectionMatrix * viewMatrix * position;\n"
  105. "}\n"};
  106. fragmentShader = {
  107. #if JUCE_OPENGL_ES
  108. "varying lowp vec4 destinationColour;\n"
  109. "varying lowp vec2 textureCoordOut;\n"
  110. #else
  111. "varying vec4 destinationColour;\n"
  112. "varying vec2 textureCoordOut;\n"
  113. #endif
  114. "\n"
  115. "void main()\n"
  116. "{\n"
  117. " vec4 colour = vec4(0.95, 0.57, 0.03, 0.8);\n"
  118. " gl_FragColor = colour;\n"
  119. "}\n" };
  120. ScopedPointer<OpenGLShaderProgram> newShader (new OpenGLShaderProgram (openGLContext));
  121. String statusText;
  122. if (newShader->addVertexShader (OpenGLHelpers::translateVertexShaderToV3 (vertexShader))
  123. && newShader->addFragmentShader (OpenGLHelpers::translateFragmentShaderToV3 (fragmentShader))
  124. && newShader->link())
  125. {
  126. shape = nullptr;
  127. attributes = nullptr;
  128. uniforms = nullptr;
  129. shader = newShader;
  130. shader->use();
  131. shape = new Shape (openGLContext);
  132. attributes = new Attributes (openGLContext, *shader);
  133. uniforms = new Uniforms (openGLContext, *shader);
  134. statusText = "GLSL: v" + String (OpenGLShaderProgram::getLanguageVersion(), 2);
  135. }
  136. else
  137. {
  138. statusText = newShader->getLastError();
  139. }
  140. }
  141. private:
  142. //==============================================================================
  143. // private member variables
  144. struct Vertex
  145. {
  146. float position[3];
  147. float normal[3];
  148. float colour[4];
  149. float texCoord[2];
  150. };
  151. //==============================================================================
  152. // This class just manages the attributes that the demo shaders use.
  153. struct Attributes
  154. {
  155. Attributes (OpenGLContext& openGLContext, OpenGLShaderProgram& shader)
  156. {
  157. position = createAttribute (openGLContext, shader, "position");
  158. normal = createAttribute (openGLContext, shader, "normal");
  159. sourceColour = createAttribute (openGLContext, shader, "sourceColour");
  160. texureCoordIn = createAttribute (openGLContext, shader, "texureCoordIn");
  161. }
  162. void enable (OpenGLContext& openGLContext)
  163. {
  164. if (position != nullptr)
  165. {
  166. openGLContext.extensions.glVertexAttribPointer (position->attributeID, 3, GL_FLOAT, GL_FALSE, sizeof (Vertex), 0);
  167. openGLContext.extensions.glEnableVertexAttribArray (position->attributeID);
  168. }
  169. if (normal != nullptr)
  170. {
  171. openGLContext.extensions.glVertexAttribPointer (normal->attributeID, 3, GL_FLOAT, GL_FALSE, sizeof (Vertex), (GLvoid*) (sizeof (float) * 3));
  172. openGLContext.extensions.glEnableVertexAttribArray (normal->attributeID);
  173. }
  174. if (sourceColour != nullptr)
  175. {
  176. openGLContext.extensions.glVertexAttribPointer (sourceColour->attributeID, 4, GL_FLOAT, GL_FALSE, sizeof (Vertex), (GLvoid*) (sizeof (float) * 6));
  177. openGLContext.extensions.glEnableVertexAttribArray (sourceColour->attributeID);
  178. }
  179. if (texureCoordIn != nullptr)
  180. {
  181. openGLContext.extensions.glVertexAttribPointer (texureCoordIn->attributeID, 2, GL_FLOAT, GL_FALSE, sizeof (Vertex), (GLvoid*) (sizeof (float) * 10));
  182. openGLContext.extensions.glEnableVertexAttribArray (texureCoordIn->attributeID);
  183. }
  184. }
  185. void disable (OpenGLContext& openGLContext)
  186. {
  187. if (position != nullptr) openGLContext.extensions.glDisableVertexAttribArray (position->attributeID);
  188. if (normal != nullptr) openGLContext.extensions.glDisableVertexAttribArray (normal->attributeID);
  189. if (sourceColour != nullptr) openGLContext.extensions.glDisableVertexAttribArray (sourceColour->attributeID);
  190. if (texureCoordIn != nullptr) openGLContext.extensions.glDisableVertexAttribArray (texureCoordIn->attributeID);
  191. }
  192. ScopedPointer<OpenGLShaderProgram::Attribute> position, normal, sourceColour, texureCoordIn;
  193. private:
  194. static OpenGLShaderProgram::Attribute* createAttribute (OpenGLContext& openGLContext,
  195. OpenGLShaderProgram& shader,
  196. const char* attributeName)
  197. {
  198. if (openGLContext.extensions.glGetAttribLocation (shader.getProgramID(), attributeName) < 0)
  199. return nullptr;
  200. return new OpenGLShaderProgram::Attribute (shader, attributeName);
  201. }
  202. };
  203. //==============================================================================
  204. // This class just manages the uniform values that the demo shaders use.
  205. struct Uniforms
  206. {
  207. Uniforms (OpenGLContext& openGLContext, OpenGLShaderProgram& shader)
  208. {
  209. projectionMatrix = createUniform (openGLContext, shader, "projectionMatrix");
  210. viewMatrix = createUniform (openGLContext, shader, "viewMatrix");
  211. texture = createUniform (openGLContext, shader, "demoTexture");
  212. lightPosition = createUniform (openGLContext, shader, "lightPosition");
  213. bouncingNumber = createUniform (openGLContext, shader, "bouncingNumber");
  214. }
  215. ScopedPointer<OpenGLShaderProgram::Uniform> projectionMatrix, viewMatrix, texture, lightPosition, bouncingNumber;
  216. private:
  217. static OpenGLShaderProgram::Uniform* createUniform (OpenGLContext& openGLContext,
  218. OpenGLShaderProgram& shader,
  219. const char* uniformName)
  220. {
  221. if (openGLContext.extensions.glGetUniformLocation (shader.getProgramID(), uniformName) < 0)
  222. return nullptr;
  223. return new OpenGLShaderProgram::Uniform (shader, uniformName);
  224. }
  225. };
  226. //==============================================================================
  227. /** This loads a 3D model from an OBJ file and converts it into some vertex buffers
  228. that we can draw.
  229. */
  230. struct Shape
  231. {
  232. Shape (OpenGLContext& openGLContext)
  233. {
  234. if (shapeFile.load (BinaryData::teapot_obj).wasOk())
  235. for (int i = 0; i < shapeFile.shapes.size(); ++i)
  236. vertexBuffers.add (new VertexBuffer (openGLContext, *shapeFile.shapes.getUnchecked(i)));
  237. }
  238. void draw (OpenGLContext& openGLContext, Attributes& attributes)
  239. {
  240. for (int i = 0; i < vertexBuffers.size(); ++i)
  241. {
  242. VertexBuffer& vertexBuffer = *vertexBuffers.getUnchecked (i);
  243. vertexBuffer.bind();
  244. attributes.enable (openGLContext);
  245. glDrawElements (GL_TRIANGLES, vertexBuffer.numIndices, GL_UNSIGNED_INT, 0);
  246. attributes.disable (openGLContext);
  247. }
  248. }
  249. private:
  250. struct VertexBuffer
  251. {
  252. VertexBuffer (OpenGLContext& context, WavefrontObjFile::Shape& shape) : openGLContext (context)
  253. {
  254. numIndices = shape.mesh.indices.size();
  255. openGLContext.extensions.glGenBuffers (1, &vertexBuffer);
  256. openGLContext.extensions.glBindBuffer (GL_ARRAY_BUFFER, vertexBuffer);
  257. Array<Vertex> vertices;
  258. createVertexListFromMesh (shape.mesh, vertices, Colours::green);
  259. openGLContext.extensions.glBufferData (GL_ARRAY_BUFFER, vertices.size() * sizeof (Vertex),
  260. vertices.getRawDataPointer(), GL_STATIC_DRAW);
  261. openGLContext.extensions.glGenBuffers (1, &indexBuffer);
  262. openGLContext.extensions.glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
  263. openGLContext.extensions.glBufferData (GL_ELEMENT_ARRAY_BUFFER, numIndices * sizeof (juce::uint32),
  264. shape.mesh.indices.getRawDataPointer(), GL_STATIC_DRAW);
  265. }
  266. ~VertexBuffer()
  267. {
  268. openGLContext.extensions.glDeleteBuffers (1, &vertexBuffer);
  269. openGLContext.extensions.glDeleteBuffers (1, &indexBuffer);
  270. }
  271. void bind()
  272. {
  273. openGLContext.extensions.glBindBuffer (GL_ARRAY_BUFFER, vertexBuffer);
  274. openGLContext.extensions.glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
  275. }
  276. GLuint vertexBuffer, indexBuffer;
  277. int numIndices;
  278. OpenGLContext& openGLContext;
  279. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VertexBuffer)
  280. };
  281. WavefrontObjFile shapeFile;
  282. OwnedArray<VertexBuffer> vertexBuffers;
  283. static void createVertexListFromMesh (const WavefrontObjFile::Mesh& mesh, Array<Vertex>& list, Colour colour)
  284. {
  285. const float scale = 0.2f;
  286. WavefrontObjFile::TextureCoord defaultTexCoord = { 0.5f, 0.5f };
  287. WavefrontObjFile::Vertex defaultNormal = { 0.5f, 0.5f, 0.5f };
  288. for (int i = 0; i < mesh.vertices.size(); ++i)
  289. {
  290. const WavefrontObjFile::Vertex& v = mesh.vertices.getReference (i);
  291. const WavefrontObjFile::Vertex& n
  292. = i < mesh.normals.size() ? mesh.normals.getReference (i) : defaultNormal;
  293. const WavefrontObjFile::TextureCoord& tc
  294. = i < mesh.textureCoords.size() ? mesh.textureCoords.getReference (i) : defaultTexCoord;
  295. Vertex vert =
  296. {
  297. { scale * v.x, scale * v.y, scale * v.z, },
  298. { scale * n.x, scale * n.y, scale * n.z, },
  299. { colour.getFloatRed(), colour.getFloatGreen(), colour.getFloatBlue(), colour.getFloatAlpha() },
  300. { tc.x, tc.y }
  301. };
  302. list.add (vert);
  303. }
  304. }
  305. };
  306. const char* vertexShader;
  307. const char* fragmentShader;
  308. ScopedPointer<OpenGLShaderProgram> shader;
  309. ScopedPointer<Shape> shape;
  310. ScopedPointer<Attributes> attributes;
  311. ScopedPointer<Uniforms> uniforms;
  312. String newVertexShader, newFragmentShader;
  313. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainContentComponent)
  314. };
  315. // (This function is called by the app startup code to create our main component)
  316. Component* createMainContentComponent() { return new MainContentComponent(); }
  317. #endif // MAINCOMPONENT_H_INCLUDED