I’m trying to do my first OpenGL Programm with JUCE. The openGLContext is not active, for this reason it exits when I come into the render() method. I don’t exactly how I have to activate the OpenGL context, my shaders are right, they are very easy. I’m working with core profile 3.3. The Code is the following:
class CursorGL : public OpenGLAppComponent {
public:
CursorGL(std::shared_ptr<coord> _coords, glm::mat4& _projection, glm::mat4& _model) {
coords = _coords->shared_from_this();
setSize (600, 300);
setVisible(true);
position.x = coords->x1;
position.y = coords->y1;
target.x = coords->x2;
target.y = coords->y2;
thickness = 75.f;
projection = _projection;
model = _model;
coordTemp = coords->x1;
openGLContext.makeActive();
openGLContext.setMultisamplingEnabled(true);
if(!openGLContext.isActive())
std::cout<<"Could not activate OpenGl Context:"<<openGLContext.isActive()<<std::endl;
}
~CursorGL() {
shutdownOpenGL();
}
void initialise() override {
GLfloat colors[] = {0.5f, 0.5f, 0.5f, 0.5f};
//openGLContext.setOpenGLVersionRequired(openGLContext.openGL3_2);
createShader();
openGLContext.extensions.glUseProgram(shaderProgram);
glViewport(0,0, 300, 600);
openGLContext.extensions.glUniformMatrix4fv(openGLContext.extensions.glGetUniformLocation(shaderProgram, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
openGLContext.extensions.glUniformMatrix4fv(openGLContext.extensions.glGetUniformLocation(shaderProgram, "model"), 1, GL_FALSE, glm::value_ptr(model));
openGLContext.extensions.glUniform1fv(openGLContext.extensions.glGetUniformLocation(shaderProgram, "position"), 1, glm::value_ptr(position)); openGLContext.extensions.glUniform1fv(openGLContext.extensions.glGetUniformLocation(shaderProgram, "target"), 1, glm::value_ptr(target));
openGLContext.extensions.glUniform1f(openGLContext.extensions.glGetUniformLocation(shaderProgram, "thickness"), thickness);
openGLContext.extensions.glGenBuffers(1, &VBO);
openGLContext.extensions.glGenVertexArrays(1, &VAO);
openGLContext.extensions.glBindVertexArray(VAO);
openGLContext.extensions.glBindBuffer(GL_ARRAY_BUFFER, VBO);
openGLContext.extensions.glBufferData(GL_ARRAY_BUFFER, sizeof(colors), &colors, GL_STATIC_DRAW);
openGLContext.extensions.glEnableVertexAttribArray(0);
openGLContext.extensions.glVertexAttribPointer(0,4, GL_FLOAT, GL_FALSE, 4* sizeof(GL_FLOAT), 0);
openGLContext.extensions.glBindVertexArray(0);
openGLContext.extensions.glDeleteBuffers(1, &VBO);
}
void shutdown() override {
openGLContext.extensions.glUseProgram(0);
openGLContext.extensions.glDeleteShader(fragmentShader);
openGLContext.extensions.glDeleteShader(geomShader);
openGLContext.extensions.glDeleteShader(vertexShader);
openGLContext.extensions.glDeleteProgram(shaderProgram);
openGLContext.extensions.glDeleteVertexArrays(1, &VAO);
}
void render() override {
//openGLContext.makeActive();
jassert (OpenGLHelpers::isContextActive());
//OpenGLHelpers::clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
OpenGLHelpers::clear (juce::Colours::white);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
if(coords->isPlaying && coordTemp != coords->x1) {
openGLContext.extensions.glUseProgram(shaderProgram);
coordTemp = coords->x1;
position.x = coords->x1;
position.y = coords->y1;
target.x = coords->x2;
target.y = coords->y2;
openGLContext.extensions.glUniform1fv(openGLContext.extensions.glGetUniformLocation(shaderProgram, "position"), 1, glm::value_ptr(position));
openGLContext.extensions.glUniform1fv(openGLContext.extensions.glGetUniformLocation(shaderProgram, "target"), 1, glm::value_ptr(target));
}
openGLContext.extensions.glBindVertexArray(VAO);
glDrawArrays(GL_POINTS, 0, 1);
openGLContext.extensions.glBindVertexArray(0);
}
void paint(Graphics& g) override {
}
void resized() override {
}
void createShader() {
vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec4 color\n"
"uniform vec2 position\n"
"out VS_OUT {\n"
" vec2 pos;\n"
" vec4 color;\n"
"} vs_out;\n"
"void main() {\n"
" vs_out.pos = position;\n"
" vs_out.color = color;\n"
"}\n";
fragmentShaderSource = "#version 330 core\n"
"in vec4 fColor;\n"
"out vec4 outColor;\n"
"void main() {\n"
" outColor = fColor;\n"
"}\n";
geomShaderSource = "#version 330 core\n"
"uniform float thickness;\n"
"uniform vec2 win_scale;\n"
"in VS_OUT {\n"
" vec2 pos;\n"
" vec4 color;\n"
"} gs_in[]\n"
"uniform mat4 projection;\n"
"uniform mat4 model;\n"
"out vec4 fColor\n"
"vec2 screen_space(vec4 vertex) {\n"
" return vec2(vertex.xy/vertex.w) * win_scale;\n"
"}\n"
"void main() {\n"
" fColor = gs_in[0].color;\n"
" vec2 p0 = gs_in[0].pos;\n"
" vec2 p1 = target;\n"
" vec2 v0 = normalize(p1-p0);\n"
" vec2 n0 = vec2(-v0.y, v0.x);\n"
" gl_Position = projection * model * vec4(p0 - thickness * n0, 0.0, 1.0);\n"
" EmitVertex();\n"
" gl_Position = projection * model * vec4(p0 + thickness * n0, 0.0, 1.0);\n"
" EmitVertex();\n"
" gl_Position = projection * model * vec4(p1 - thickness * n0, 0.0, 1.0);\n"
" EmitVertex();\n"
" gl_Position = projection * model * vec4(p1 + thickness * n0, 0.0, 1.0);\n"
" EmitVertex();\n"
" EndPrimitive();\n"
"}\n";
vertexShader = openGLContext.extensions.glCreateShader(GL_VERTEX_SHADER);
openGLContext.extensions.glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
openGLContext.extensions.glCompileShader(vertexShader);
if (!checkShaderCompileStatus(vertexShader)) {
std::cout<< "Vertex shader did not compile"<<std::endl;
//exit(EXIT_FAILURE);
}
fragmentShader = openGLContext.extensions.glCreateShader(GL_FRAGMENT_SHADER);
openGLContext.extensions.glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
openGLContext.extensions.glCompileShader(fragmentShader);
if (!checkShaderCompileStatus(fragmentShader)) {
std::cout<< "Fragment shader did not compile"<<std::endl;
}
geomShader = openGLContext.extensions.glCreateShader(GL_GEOMETRY_SHADER);
openGLContext.extensions.glShaderSource(geomShader, 1, &geomShaderSource, NULL);
openGLContext.extensions.glCompileShader(geomShader);
if (!checkShaderCompileStatus(geomShader)) {
std::cout<< "Geometry shader did not compile"<<std::endl;
//exit(EXIT_FAILURE);
}
shaderProgram = openGLContext.extensions.glCreateProgram();
openGLContext.extensions.glAttachShader(shaderProgram, vertexShader);
openGLContext.extensions.glAttachShader(shaderProgram, fragmentShader);
openGLContext.extensions.glAttachShader(shaderProgram, geomShader);
openGLContext.extensions.glLinkProgram(shaderProgram);
if (!checkShaderProgramLinkStatus(shaderProgram)) {
std::cout<< "Shader did not link"<<std::endl;
//exit(EXIT_FAILURE);
}
openGLContext.extensions.glUseProgram(shaderProgram);
}
bool checkShaderCompileStatus(GLuint shaderID) {
GLint status;
openGLContext.extensions.glGetShaderiv(shaderID, GL_COMPILE_STATUS, &status);
if(status == GL_FALSE) {
GLint length;
openGLContext.extensions.glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &length);
GLchar* log = new char[length + 1];
openGLContext.extensions.glGetShaderInfoLog(shaderID, length, &length, &log[0]);
std::cout<<"Error by shader compilation:"<<log;
return false;
}
return true;
}
bool checkShaderProgramLinkStatus(GLuint programID){
GLint status;
openGLContext.extensions.glGetProgramiv(programID, GL_LINK_STATUS, &status);
if(status == GL_FALSE) {
GLint length;
openGLContext.extensions.glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &length);
GLchar* log = new char[length + 1];
openGLContext.extensions.glGetProgramInfoLog(programID, length, &length, &log[0]);
std::cout<<"Error by shader linking:"<<log;
return false;
}
return true;
}
private:
const char* vertexShaderSource;
const char* fragmentShaderSource;
const char* geomShaderSource;
std::shared_ptr<coord> coords;
juce::String statusText;
glm::mat4 projection, model;
glm::vec2 position, target;
float coordTemp;
GLfloat thickness;
GLuint VBO, VAO;
GLuint shaderProgram;
GLuint vertexShader, fragmentShader, geomShader;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CursorGL)
};
I could see Juce don’t have the extension
glUniform2fv
available, only glUniform1fv.
I’m instantiating and stoping the class inside another, in the following way:
void JuceDevice::startCursorGL() {
cursorGL = std::make_unique<CursorGL>(coords,projection, model);
cursorGL->initialise();
cursorGL->render();
}
void JuceDevice::stopCursorGL() {
cursorGL->shutdown();
cursorGL.reset();
}
The Programm exits when I call the method render(), at the assertion jassert (OpenGLHelpers::isContextActive()); , how should I activate the OpenGL Context?
Regards