| namespace OpenGLData | |
| { | |
| struct Vertex | |
| { | |
| float position[2]; | |
| }; | |
| struct Triangle | |
| { | |
| Vertex a; | |
| Vertex b; | |
| Vertex c; | |
| }; | |
| } | |
| void GradientComponent::newOpenGLContextCreated() | |
| { | |
| #define NEW_LINE "\n" | |
| String vertexShader = "attribute vec4 position;" NEW_LINE | |
| "void main(void)" NEW_LINE | |
| "{" NEW_LINE | |
| " gl_Position = position;"// * vec4(2.0, 2.0, 0.0, 1.0);" NEW_LINE | |
| "}" NEW_LINE; | |
| //This is a linear gradient along the y axis. Color1 is the bottom color. color2 is the top color | |
| String fragmentShader = "uniform vec4 bounds;" NEW_LINE | |
| "uniform vec4 color1;" NEW_LINE | |
| "uniform vec4 color2;" NEW_LINE | |
| "void main()" NEW_LINE | |
| "{" NEW_LINE | |
| "vec2 pos = gl_FragCoord.xy / bounds.xy;" NEW_LINE | |
| "gl_FragColor = vec4(mix(color1, color2, pos.y));" NEW_LINE | |
| "}" NEW_LINE | |
| ; | |
| shader = new OpenGLShaderProgram(openGLContext); | |
| //make sure the shader is valid and compilable | |
| if(shader->addVertexShader(vertexShader) && | |
| shader->addFragmentShader(fragmentShader) && | |
| shader->link()) | |
| { | |
| //find our uniform in the context | |
| if( openGLContext.extensions.glGetAttribLocation(shader->getProgramID(), "position") < 0 ) | |
| { | |
| jassertfalse; //attribute not found | |
| } | |
| positionAttribute = new OpenGLShaderProgram::Attribute(*shader, OpenGLData::OpenGLAttributesMap.at(OpenGLData::OpenGLAttributes::Position).toRawUTF8() ); | |
| if(shader->getUniformIDFromName("bounds" ) < 0 || | |
| shader->getUniformIDFromName("color1" ) < 0 || | |
| shader->getUniformIDFromName("color2" ) < 0 | |
| ) | |
| { | |
| jassertfalse; //couldn't find uniform! | |
| } | |
| boundsUniform = new OpenGLShaderProgram::Uniform(*shader, "bounds" ); | |
| color1Uniform = new OpenGLShaderProgram::Uniform(*shader, "color1" ); | |
| color2Uniform = new OpenGLShaderProgram::Uniform(*shader, "color2" ); | |
| Point<float> LL(-1, -1); | |
| Point<float> LR(1, -1); | |
| Point<float> UL(-1, 1); | |
| Point<float> UR(1, 1); | |
| /* | |
| this triangle looks like this: | |
| |\ | |
| |_\ | |
| */ | |
| OpenGLData::Triangle* triangle = new OpenGLData::Triangle | |
| { | |
| OpenGLData::Vertex{LL.x, LL.y}, | |
| OpenGLData::Vertex{UL.x, UL.y}, | |
| OpenGLData::Vertex{LR.x, LR.y}, | |
| }; | |
| triangles.add( triangle ); | |
| /* | |
| this triangle looks like this: | |
| __ | |
| \ | | |
| \| | |
| */ | |
| triangle = new OpenGLData::Triangle | |
| { | |
| OpenGLData::Vertex{LR.x, LR.y}, | |
| OpenGLData::Vertex{UL.x, UL.y}, | |
| OpenGLData::Vertex{UR.x, UR.y}, | |
| }; | |
| triangles.add( triangle ); | |
| //request a single buffer, store the index of the buffer in trianglesBufferID | |
| openGLContext.extensions.glGenBuffers (1, &trianglesBufferID); | |
| //this buffer is of type GL_ARRAY_BUFFER | |
| openGLContext.extensions.glBindBuffer (GL_ARRAY_BUFFER, trianglesBufferID); | |
| // fill the vertexBuffer with the triangle data | |
| openGLContext.extensions.glBufferData (GL_ARRAY_BUFFER, | |
| static_cast<GLsizeiptr> (static_cast<size_t> (triangles.size()) * sizeof (OpenGLData::Triangle)), // size of data being loaded into buffer | |
| triangles.getRawDataPointer(), | |
| GL_STATIC_DRAW); | |
| } | |
| } | |
| void GradientComponent::renderOpenGL() | |
| { | |
| jassert (OpenGLHelpers::isContextActive()); //can't draw without a context! | |
| OpenGLHelpers::clear(Colours::white); | |
| //what do all of these do? | |
| glEnableClientState(GL_VERTEX_ARRAY); | |
| glEnable (GL_DEPTH_TEST); | |
| glDepthFunc (GL_LESS); | |
| glEnable (GL_BLEND); | |
| glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
| glEnable (GL_TEXTURE_2D); | |
| // Draw the gradient for the background fill | |
| glMatrixMode(GL_PROJECTION); | |
| glLoadIdentity(); | |
| glMatrixMode(GL_MODELVIEW); | |
| glLoadIdentity(); | |
| auto desktopScale = (float) openGLContext.getRenderingScale(); | |
| shader->use(); //enable use of our shader | |
| DBG( "sizeof triangle: " + String( sizeof(OpenGLData::Triangle) ) ); | |
| // update attribute values | |
| glVertexAttribPointer(positionAttribute->attributeID, | |
| 3, | |
| GL_FLOAT, | |
| GL_FALSE, | |
| sizeof(OpenGLData::Vertex), | |
| triangles.getRawDataPointer()); | |
| glEnableVertexAttribArray(positionAttribute->attributeID); //enable openGL to read from squareVertices | |
| //update bounds uniform | |
| auto r = getLocalBounds().toFloat().operator*(desktopScale); //scale up window size | |
| shader->setUniform(OpenGLData::OpenGLUniformsMap.at(OpenGLData::OpenGLUniforms::Bounds).toRawUTF8(), | |
| r.getWidth(), | |
| r.getHeight(), | |
| 0.f, | |
| 0.f); | |
| //update color1 uniform | |
| shader->setUniform(OpenGLData::OpenGLUniformsMap.at(OpenGLData::OpenGLUniforms::Color1).toRawUTF8(), | |
| color1.getFloatRed(), | |
| color1.getFloatGreen(), | |
| color1.getFloatBlue(), | |
| color1.getFloatAlpha()); | |
| //update color2 uniform | |
| shader->setUniform(OpenGLData::OpenGLUniformsMap.at(OpenGLData::OpenGLUniforms::Color2).toRawUTF8(), | |
| color2.getFloatRed(), | |
| color2.getFloatGreen(), | |
| color2.getFloatBlue(), | |
| color2.getFloatAlpha()); | |
| glDrawElements(GL_TRIANGLES, | |
| triangles.size(), | |
| GL_FLOAT, | |
| 0); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment