I’m trying to set up a very basic opengl component to visualize a reverb effect but I’m having some trouble with it.
I’ve stripped the openglApp example to a bare minimum but for some reason the fragmentshader is not working. Maybe somebody can point me into the right direction?
Here’s my code which contains a vertex struct (with only a position right now because I couldn’t find my error), a small attributes struct (also only containing position) and small VBO struct and the rendering code:
class ReverbRenderer : public OpenGLRenderer {
public:
struct Vertex {
float position[3];
};
class VBO {
public:
VBO(OpenGLContext &glContext, std::vector<Vertex> vertices) : ctx(glContext), size(vertices.size()) {
ctx.extensions.glGenBuffers(1, &vbo);
ctx.extensions.glBindBuffer(GL_ARRAY_BUFFER, vbo);
ctx.extensions.glBufferData(GL_ARRAY_BUFFER,
static_cast<GLsizeiptr>(static_cast<size_t>(vertices.size()) * sizeof(Vertex)),
vertices.data(),
GL_STATIC_DRAW);
}
void bind() {
ctx.extensions.glBindBuffer(GL_ARRAY_BUFFER, vbo);
}
int getSize() {
return size;
}
private:
GLuint vbo;
OpenGLContext &ctx;
int size;
};
struct Attributes {
Attributes (OpenGLContext& ctx, OpenGLShaderProgram& shaderProgram) {
position = createAttribute(ctx, shaderProgram, "position");
}
void enable (OpenGLContext& ctx) {
if (position != nullptr) {
ctx.extensions.glVertexAttribPointer(position->attributeID, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
ctx.extensions.glEnableVertexAttribArray(position->attributeID);
}
}
void disable (OpenGLContext& ctx) {
if (position != nullptr)
ctx.extensions.glDisableVertexAttribArray(position->attributeID);
}
ScopedPointer<OpenGLShaderProgram::Attribute> position;
private:
static OpenGLShaderProgram::Attribute* createAttribute (OpenGLContext& openGLContext, OpenGLShaderProgram& shader, const char* attributeName) {
if (openGLContext.extensions.glGetAttribLocation (shader.getProgramID(), attributeName) < 0)
return nullptr;
return new OpenGLShaderProgram::Attribute(shader, attributeName);
}
};
ReverbRenderer(OpenGLContext &glContext)
: ctx(glContext)
{
}
~ReverbRenderer() {
ctx.detach();
}
void newOpenGLContextCreated() override {
std::vector<ReverbRenderer::Vertex> vertices;
Vertex v1 = {{-.5f, -.5f, 0}};
Vertex v2 = {{.5f, -.5f, 0}};
Vertex v3 = {{.5f, .5f, 0}};
Vertex v4 = {{.5f, .5f, 0}};
Vertex v5 = {{-.5f, .5f, 0}};
Vertex v6 = {{-.5f, -.5f, 0}};
vertices.push_back(v1);
vertices.push_back(v2);
vertices.push_back(v3);
vertices.push_back(v4);
vertices.push_back(v5);
vertices.push_back(v6);
vbo = std::make_unique<VBO>(ctx, vertices);
createShaders();
}
void createShaders()
{
vertexShader = "attribute vec3 position;\n"
"\n"
"void main()\n"
"{\n"
" gl_Position = vec4(position, 1.0);\n"
"}\n";
fragmentShader = "void main()\n"
"{\n"
" gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
"}\n";
std::unique_ptr<OpenGLShaderProgram> newShader = std::make_unique<OpenGLShaderProgram>(ctx);
String statusText;
if (newShader->addVertexShader(vertexShader) && newShader->addFragmentShader(fragmentShader) && newShader->link()) {
shader.reset(newShader.get());
shader->use();
attributes = std::make_unique<Attributes>(ctx, *shader.get());
statusText = "GLSL: v" + String(OpenGLShaderProgram::getLanguageVersion(), 2);
}
else
statusText = newShader->getLastError();
std::cout << statusText << std::endl;
}
void renderOpenGL() override {
jassert (OpenGLHelpers::isContextActive());
OpenGLHelpers::clear(Colours::black);
shader->use();
vbo->bind();
attributes->enable(ctx);
glDrawArrays(GL_TRIANGLES, 0, vbo->getSize());
attributes->disable(ctx);
// reset buffers for further drawing
ctx.extensions.glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void openGLContextClosing() override {
}
private:
OpenGLContext &ctx;
std::string vertexShader, fragmentShader;
std::unique_ptr<OpenGLShaderProgram> shader;
std::unique_ptr<Attributes> attributes;
std::unique_ptr<VBO> vbo;
};
In the reverbs component I initialize the gl context as follows:
gl.setRenderer(&renderer);
gl.attachTo(*this);
gl.setContinuousRepainting(true);
For some reason the result is always just a white square on a black background. But in the fragment shader the colour should be set differently. The output generated by create shaders says I’m using GLSL 1.20. So the code should be fine.
