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.

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