Skip to content

Instantly share code, notes, and snippets.

@matkatmusic matkatmusic/gl setup.cpp Secret
Last active Mar 19, 2018

Embed
What would you like to do?
//usage: halo is an instance of GradientComponent
MainContentComponent::MainContentComponent() :
halo(Colour{0xff00ffff}, //inner color
Colour{0x000000ff}, //outer color
false, //hallow
0.75f, //xgap
0.75f, //ygap
0.3f, //gradient
0.3f) //radius
{
addAndMakeVisible( halo );
setSize (600, 400);
}
//shader setup:
#define NEW_LINE "\n"
const std::map<OpenGLData::OpenGLUniforms, String> OpenGLData::OpenGLUniformsMap =
{
{ OpenGLUniforms::Bounds, "bounds" },
{ OpenGLUniforms::InnerColor, "innerColor" },
{ OpenGLUniforms::OuterColor, "outerColor" },
{ OpenGLUniforms::Hollow, "hollow" },
{ OpenGLUniforms::RoundedBoxWidth, "roundedBoxWidth" },
{ OpenGLUniforms::RoundedBoxHeight, "roundedBoxHeight" },
{ OpenGLUniforms::Gradient, "gradient" },
{ OpenGLUniforms::Radius, "radius" }
};
String GradientComponent::makeFragmentShaderHeader()
{
return
"uniform vec4 " + OpenGLData::OpenGLUniformsMap.at(OpenGLData::OpenGLUniforms::Bounds) + ";" NEW_LINE
"uniform vec4 " + OpenGLData::OpenGLUniformsMap.at(OpenGLData::OpenGLUniforms::InnerColor) + ";" NEW_LINE
"uniform vec4 " + OpenGLData::OpenGLUniformsMap.at(OpenGLData::OpenGLUniforms::OuterColor) + ";" NEW_LINE
"uniform bool " + OpenGLData::OpenGLUniformsMap.at(OpenGLData::OpenGLUniforms::Hollow) + ";" NEW_LINE
"uniform float " + OpenGLData::OpenGLUniformsMap.at(OpenGLData::OpenGLUniforms::RoundedBoxWidth) + ";" NEW_LINE
"uniform float " + OpenGLData::OpenGLUniformsMap.at(OpenGLData::OpenGLUniforms::RoundedBoxHeight) + ";" NEW_LINE
"uniform float " + OpenGLData::OpenGLUniformsMap.at(OpenGLData::OpenGLUniforms::Gradient) + ";" NEW_LINE
"uniform float " + OpenGLData::OpenGLUniformsMap.at(OpenGLData::OpenGLUniforms::Radius) + ";" NEW_LINE
;
}
void GradientComponent::newOpenGLContextCreated()
{
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;
String fragmentShader = makeFragmentShaderHeader() +
"float roundedBox(vec2 point, vec2 rectBounds, float radius)" NEW_LINE
"{" NEW_LINE
//this returns the distance
" return length(max (abs(point) - rectBounds + radius, 0.0)) - radius;" NEW_LINE
"}" NEW_LINE
"float hsluv_fromLinear(float c) {" NEW_LINE
" return c <= 0.0031308 ? 12.92 * c : 1.055 * pow(c, 1.0 / 2.4) - 0.055;" NEW_LINE
"}" NEW_LINE
"void main(void)" NEW_LINE
"{" NEW_LINE
// Normalized pixel coordinates (from 0 to 1)
" vec2 normalizedFragCoord = gl_FragCoord.xy / bounds.xy;" NEW_LINE
//" float ratio = bounds.y / bounds.x;" NEW_LINE
//change normalized pixel coord range from [0,1] to [-1,1]
" vec2 p = normalizedFragCoord * 2.0 - 1.0;" NEW_LINE
//remove y-axis scaling from normalizing
//" p.y *= ratio;" NEW_LINE
" vec4 col;" NEW_LINE
" float d = roundedBox(p, vec2(roundedBoxWidth, roundedBoxHeight), radius);" NEW_LINE//distance from rounded rect bounds
" if( hollow == false )" NEW_LINE
" {" NEW_LINE
" col = sqrt(mix(innerColor*innerColor, outerColor*outerColor, smoothstep(0., gradient, d ) ));" NEW_LINE
" }" NEW_LINE
" else" NEW_LINE
" {" NEW_LINE
" if( abs(d) < gradient )" NEW_LINE
" {" NEW_LINE
" if( d == 0. )" NEW_LINE
" {" NEW_LINE
" col = innerColor; " NEW_LINE //purple
" }" NEW_LINE
" else" NEW_LINE
" {" NEW_LINE
" col = sqrt(mix(innerColor*innerColor, outerColor*outerColor, smoothstep(0., gradient, abs(d)) ));" NEW_LINE
" }" NEW_LINE
" }" NEW_LINE
" else" NEW_LINE
" {" NEW_LINE
" col = outerColor; //yellow" NEW_LINE
" }" NEW_LINE
" }" NEW_LINE
// "col.x = hsluv_fromLinear(col.x);"
// "col.y = hsluv_fromLinear(col.y);"
// "col.z = hsluv_fromLinear(col.z);"
// "col.w = hsluv_fromLinear(col.w);"
" gl_FragColor = col;" 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 attribute 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() );
uniforms = new Uniforms(*shader);
jassert( uniforms->bounds != nullptr );
jassert( uniforms->innerColor != nullptr );
jassert( uniforms->outerColor != nullptr );
jassert( uniforms->hollow != nullptr );
jassert( uniforms->roundedBoxWidth != nullptr );
jassert( uniforms->roundedBoxHeight != nullptr );
jassert( uniforms->gradient != nullptr );
openGLContext.extensions.glGenBuffers (1, &vertexBuffer); //16. generate a single buffer, store the index in vertexBuffer
openGLContext.extensions.glBindBuffer (GL_ARRAY_BUFFER, vertexBuffer); //17. bind the vertexBuffer object as a GL_ARRAY_BUFFER type
Array<Mesh> meshes = createMeshes();
Array<float> vertices;
for( auto& mesh : meshes )
{
for( auto& vertex : mesh.vertices )
{
vertices.add(vertex.x);
vertices.add(vertex.y);
}
numMeshes += 1;
}
vertexBuffer = createVBO(vertices.getRawDataPointer(),
sizeof(Vertex) * vertices.size());
}
}
//thanks http://www.falloutsoftware.com/tutorials/gl/gl3.htm#vertex_array !!!!
GLuint GradientComponent::createVBO(GLfloat *vertices, int size)
{
GLuint newBuffer;
glGenBuffersARB(1, &newBuffer);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, newBuffer);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, size, vertices, GL_STATIC_DRAW_ARB);
return newBuffer;
}
//render callback:
void GradientComponent::renderOpenGL()
{
jassert (OpenGLHelpers::isContextActive()); //can't draw without a context!
OpenGLHelpers::clear(Colours::white); //white background
//what do all of these do?
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();
shader->use(); //enable use of our shader
openGLContext.extensions.glBindBuffer (GL_ARRAY_BUFFER, vertexBuffer); //48. bind the vertexBuffer to the GL_ARRAY_BUFFER
if (positionAttribute != nullptr)
{
openGLContext.extensions.glVertexAttribPointer(positionAttribute->attributeID,
2,
GL_FLOAT,
GL_FALSE,
sizeof(Vertex),
0);
openGLContext.extensions.glEnableVertexAttribArray (positionAttribute->attributeID); //52. enable reading from the attribute
}
//update bounds uniform
updateShaderUniforms();
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vertexBuffer);
// Activate array-based data
glEnableClientState(GL_VERTEX_ARRAY);
// Stride of 2, floats
glVertexPointer(2, GL_FLOAT, 0, 0);
// Draw triangles
glDrawArrays(GL_TRIANGLES, 0, numMeshes * 3 * sizeof(Vertex));
// Switch off vertex array data
glDisableClientState(GL_VERTEX_ARRAY);
// Bind with 0 to switch back to default pointer operation
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
if (positionAttribute != nullptr)
openGLContext.extensions.glDisableVertexAttribArray (positionAttribute->attributeID);
}
void GradientComponent::updateShaderUniforms()
{
auto desktopScale = (float) openGLContext.getRenderingScale();
auto r = getLocalBounds().toFloat().operator*(desktopScale); //scale up window size
auto& oc = outerColor;
Colour ic = oc.interpolatedWith(innerColor, crossFade);
if( uniforms->bounds != nullptr ) uniforms->bounds->set(r.getWidth(), r.getHeight(), 0.f, 0.f);
else jassertfalse;
if( uniforms->innerColor != nullptr ) uniforms->innerColor->set(ic.getFloatRed(), ic.getFloatGreen(), ic.getFloatBlue(), ic.getFloatAlpha());
else jassertfalse;
if( uniforms->outerColor != nullptr ) uniforms->outerColor->set(oc.getFloatRed(), oc.getFloatGreen(), oc.getFloatBlue(), oc.getFloatAlpha());
else jassertfalse;
if( uniforms->hollow != nullptr ) uniforms->hollow->set(hollow);
else jassertfalse;
if( uniforms->roundedBoxWidth != nullptr ) uniforms->roundedBoxWidth->set(roundedBoxWidth);
else jassertfalse;
if( uniforms->roundedBoxHeight != nullptr ) uniforms->roundedBoxHeight->set(roundedBoxHeight);
else jassertfalse;
if( uniforms->gradient != nullptr ) uniforms->gradient->set(gradient);
else jassertfalse;
if( uniforms->radius != nullptr) uniforms->radius->set(radius);
else jassertfalse;
}
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.