| const std::map<OpenGLData::OpenGLAttributes, String> OpenGLData::OpenGLAttributesMap = | |
| { | |
| {OpenGLAttributes::Position, "position"} | |
| }; | |
| const std::map<OpenGLData::OpenGLUniforms, String> OpenGLData::OpenGLUniformsMap = | |
| { | |
| { OpenGLUniforms::Bounds, "bounds" }, | |
| { OpenGLUniforms::Color1, "color1" }, | |
| { OpenGLUniforms::Color2, "color2" } | |
| }; | |
| GradientComponent::GradientComponent(Colour a, Colour b) : | |
| color1(a), color2(b) | |
| { | |
| openGLContext.setRenderer(this); | |
| openGLContext.attachTo(*this); | |
| openGLContext.setContinuousRepainting(false); | |
| } | |
| GradientComponent::~GradientComponent() | |
| { | |
| openGLContext.detach(); | |
| } | |
| void GradientComponent::newOpenGLContextCreated() | |
| { | |
| #define NEW_LINE "\n" | |
| String vertexShader = "attribute vec4 " + OpenGLData::OpenGLAttributesMap.at(OpenGLData::OpenGLAttributes::Position) + ";" NEW_LINE | |
| "void main(void)" NEW_LINE | |
| "{" NEW_LINE | |
| " gl_Position = " + OpenGLData::OpenGLAttributesMap.at(OpenGLData::OpenGLAttributes::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 " + OpenGLData::OpenGLUniformsMap.at(OpenGLData::OpenGLUniforms::Bounds) + ";" NEW_LINE | |
| "uniform vec4 " + OpenGLData::OpenGLUniformsMap.at(OpenGLData::OpenGLUniforms::Color1) + ";" NEW_LINE | |
| "uniform vec4 " + OpenGLData::OpenGLUniformsMap.at(OpenGLData::OpenGLUniforms::Color2) + ";" NEW_LINE | |
| "void main()" NEW_LINE | |
| "{" NEW_LINE | |
| "vec2 pos = gl_FragCoord.xy / " + OpenGLData::OpenGLUniformsMap.at(OpenGLData::OpenGLUniforms::Bounds) + ".xy;" NEW_LINE | |
| "gl_FragColor = vec4(mix(" + OpenGLData::OpenGLUniformsMap.at(OpenGLData::OpenGLUniforms::Color1) + ", " + OpenGLData::OpenGLUniformsMap.at(OpenGLData::OpenGLUniforms::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(), OpenGLData::OpenGLAttributesMap.at(OpenGLData::OpenGLAttributes::Position).toRawUTF8()) < 0 ) | |
| { | |
| jassertfalse; //attribute not found | |
| } | |
| positionAttribute = new OpenGLShaderProgram::Attribute(*shader, OpenGLData::OpenGLAttributesMap.at(OpenGLData::OpenGLAttributes::Position).toRawUTF8() ); | |
| if(shader->getUniformIDFromName(OpenGLData::OpenGLUniformsMap.at(OpenGLData::OpenGLUniforms::Bounds).toRawUTF8() ) < 0 || | |
| shader->getUniformIDFromName(OpenGLData::OpenGLUniformsMap.at(OpenGLData::OpenGLUniforms::Color1).toRawUTF8() ) < 0 || | |
| shader->getUniformIDFromName(OpenGLData::OpenGLUniformsMap.at(OpenGLData::OpenGLUniforms::Color2).toRawUTF8() ) < 0 | |
| ) | |
| { | |
| jassertfalse; //couldn't find uniform! | |
| } | |
| boundsUniform = new OpenGLShaderProgram::Uniform(*shader, OpenGLData::OpenGLUniformsMap.at(OpenGLData::OpenGLUniforms::Bounds).toRawUTF8() ); | |
| color1Uniform = new OpenGLShaderProgram::Uniform(*shader, OpenGLData::OpenGLUniformsMap.at(OpenGLData::OpenGLUniforms::Color1).toRawUTF8() ); | |
| color2Uniform = new OpenGLShaderProgram::Uniform(*shader, OpenGLData::OpenGLUniformsMap.at(OpenGLData::OpenGLUniforms::Color2).toRawUTF8() ); | |
| } | |
| } | |
| void GradientComponent::openGLContextClosing() | |
| { | |
| //release any thing allocated in newOpenGLContextCreated() here | |
| shader = nullptr; | |
| positionAttribute = nullptr; | |
| boundsUniform = nullptr; | |
| color1Uniform = nullptr; | |
| color2Uniform = nullptr; | |
| } | |
| 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 | |
| //TODO: make this full window size ((-1,-1) to (1,1)) | |
| const GLfloat squareVertices[] = { | |
| -0.5f, -0.5f, //LL | |
| 0.5f, -0.5f, //LR | |
| -0.5f, 0.5f, //UL | |
| 0.5f, 0.5f, //UR | |
| }; | |
| // update attribute values | |
| glVertexAttribPointer(positionAttribute->attributeID, //ID of attribute | |
| 2, //number of components per generic vertex attribute | |
| GL_FLOAT, //data type of each component in the array | |
| GL_FALSE, //data should not be normalized, because data type is float | |
| 0, //the byte offset between consecutive generic vertex attributes. 0 means bytes are tightly packed | |
| squareVertices); //the data source for the attribute | |
| glEnableVertexAttribArray(positionAttribute->attributeID); //enable openGL to read from squareVertices | |
| //update bounds uniform | |
| auto r = getLocalBounds().toFloat().operator*(desktopScale); | |
| 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()); | |
| //draw it | |
| glDrawArrays(GL_TRIANGLE_STRIP, // | |
| 0, // | |
| 4); // | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment