Skip to content

Instantly share code, notes, and snippets.

@matkatmusic matkatmusic/opengl.cpp Secret
Created Mar 17, 2018

Embed
What would you like to do?
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
You can’t perform that action at this time.