OpenGL newbie question


#1

Hi. I’m trying to build very a simple thing using OpenGL but I’m banging my head against the walls with various issues. I have some basic understanding of OpenGL but I guess I do not understand exactly how a renderer works when contained inside a Juce component. I have been able to run my code, interacting a bit, but sooner or later it crashes, due to some glReadPixels call inside my mouseDown function. Off course glReadPixels returns 0.5 for no apparent reason. Another weird thing is that the viewport reading inside the same function sometimes (but very rarely) returns garbage data. But why ? Should I have a lock on the render and mouse function ? I have to add that in a separate project I was able to work out everything as expected by scratch, without using Juce, just plain GLUT handlers. Could anyone give me some help here please?


#2

I managed somehow to run this without issues, using some locks, but still not sure why I need to do this. I thought I post my solution here maybe someone can provide me a hint what’s going on here :? Why do I need the lock here, should the render method lock the messaging queue? Can this be improved somehow?


void OpenGLCanvas::mouseDown(const MouseEvent& e)
{
    
    ScopedLock l(lock);
    
// set flag for mouse down
    mouseIsDown = true;
    mouseX = e.getMouseDownX();
    mouseY = e.getMouseDownY();    
    
 
}

void OpenGLCanvas::mouseUp(const MouseEvent& e) {
    ScopedLock l(lock);
    mouseIsDown = false;
    
}

void OpenGLCanvas::renderOpenGL()
{
   glEnable(GL_DEPTH_TEST);
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    
  // skipped code for drawing models    

    {
        ScopedLock l (lock);
        // check if mouse button flag was set
        if (mouseIsDown) {
            mouseIsDown = false;
            
            GLint viewp[4];
            glGetIntegerv (GL_VIEWPORT,viewp);            
            
            std::cout << " wxh: " << viewp[2] << " " << viewp[3] << "\n";
            
            GLfloat z;
            glReadPixels(mouseX , viewp[3]-mouseY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z);
            std::cout << "  z:" << z << "\n";
        }
    }
    
  
    
}

#3

Sorry, not enough info to be able to guess what’s happening.


#4

Sorry if I my post is a bit confusing. Let me post the code which is not working


void OpenGLCanvas::mouseDown(const MouseEvent& e)
{
    
    const int mouseX = e.getMouseDownX();
    const int mouseY = e.getMouseDownY();
    
    GLint viewp[4];
    glGetIntegerv (GL_VIEWPORT,viewp);   
    
    std::cout << " WxH: " << viewp[2] << " " << viewp[3] << "\n";
 
    GLfloat z;
    glReadPixels(mouseX , viewp[3]-mouseY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z);
    std::cout << "  z:" << z << "\n";
    
}

void OpenGLCanvas::renderOpenGL()
{
    glEnable(GL_DEPTH_TEST);
    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(50.f, getContextWidth()/getContextHeight(), 1.f, 1000.f);
    glMatrixMode(GL_MODELVIEW);
    
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
	glTranslatef(-1,0,-5);
	glRotatef(15,1,0,0);
	glRotatef(3,0,1,0);
    
 
    glColor3f(0.2,0.4,1.0);
    glPushMatrix();
    glTranslatef(1,1,1);
    glutSolidSphere(1,25,25);
    glPopMatrix();

}

// meanwhile in the header:
class OpenGLCanvas  : public Component, public OpenGLRenderer

Now if I use the above version wherever I click glReadPixels returns 0.5, thus the depth is wrong - should have different value depending on region of the the sphere reading from.
But this is not the worst thing that happens because it also freezes after a couple of mouse clicks.
On the other hand sometimes even the WxH reading is wrong (I get garbage).
Bellow is an output:

JUCE v2.0.40
 WxH: 1042 566
  z:0.5
 WxH: 1042 566
  z:0.5
 WxH: 1042 566
  z:0.5
 WxH: 1042 566
  z:0.5
 WxH: -1073745528 75964416
  z:3.17677e-36
 WxH: 1042 566
  z:0.5

If I read only in the render method, just as in the first post, by using a locked signal flag when mouse was clicked, everything works fine.


#5

You can’t call GL functions on the message thread! GL function only work when a context is active.


#6

Uh… sorry, now that you’re saying this I realize how stupid I was :oops:
Just one further question tough: do you think switching the context in the mouse handler or using the flag with lock should be the appropriate solution?


#7

No! That’d be bonkers. If you need to get pixels from the context, then you need to get them while it’s actually being drawn.


#8

I tought so… 8) Thanks very much for the help!