How to display 2D graphics in pangolin with panel - c++

I can't figure out how to use pangolin to display 2D openGL graphics.
I'm am in internship in the research department of a school.
I am very novice at OpenGl and Pangolin.
I'm trying to add a monitoring window to an open_source program so that it is more user-friendly. This program is ORB_SLAM2, and it already uses pangolin as an openGL display manager. It has already some windows opening with panels and 3d openGL displays like thisby this piece of code
void Viewer::Run()
{
//...
pangolin::CreateWindowAndBind("ORB-SLAM2: Map Viewer",1024,768);
// 3D Mouse handler requires depth testing to be enabled
glEnable(GL_DEPTH_TEST);
// Issue specific OpenGl we might need
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
pangolin::CreatePanel("menu").SetBounds(0.0,1.0,0.0,pangolin::Attach::Pix(175));
// ... define elements of the menu (not important)
// Define Camera Render Object (for view / scene browsing)
pangolin::OpenGlRenderState s_cam(
pangolin::ProjectionMatrix(1024,768,mViewpointF,mViewpointF,512,389,0.1,1000),
pangolin::ModelViewLookAt(mViewpointX,mViewpointY,mViewpointZ, 0,0,0,0.0,-1.0, 0.0));
// Add named OpenGL viewport to window and provide 3D Handler
pangolin::View& d_cam = pangolin::CreateDisplay()
.SetBounds(0.0, 1.0, pangolin::Attach::Pix(175), 1.0, -1024.0f/768.0f)
.SetHandler(new pangolin::Handler3D(s_cam));
pangolin::OpenGlMatrix Twc;
Twc.SetIdentity();
//...
while(1)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
mpMapDrawer->GetCurrentOpenGLCameraMatrix(Twc);
//...
d_cam.Activate(s_cam);
glClearColor(1.0f,1.0f,1.0f,1.0f);
mpMapDrawer->DrawCurrentCamera(Twc);
if(menuShowKeyFrames || menuShowGraph)
mpMapDrawer->DrawKeyFrames(menuShowKeyFrames,menuShowGraph);
if(menuShowPoints)
mpMapDrawer->DrawMapPoints();
pangolin::FinishFrame();
//...
}
So I tried to copy that and remove the 3D handling part of it like this
void Monitor::Run()
{
//...
pangolin::CreateWindowAndBind("ORB-SLAM2: Monitoring",1024,768);
// Issue specific OpenGl we might need
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
pangolin::View& menu = pangolin::CreatePanel("vars").SetBounds(0.0,1.0,0.0,pangolin::Attach::Pix(175));
//...
// Add named OpenGL viewport to window
pangolin::View& graph = pangolin::CreateDisplay()
.SetBounds(0.0, 1.0, pangolin::Attach::Pix(175), 1.0, 1024.0f/768.0f);
while (1){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
graph.Activate();
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// 2D Basic test shape
glBegin(GL_QUADS);
glColor3f(0.4f, 0.05f, 0.05f);
glVertex2f(-0.5, 0.8f);
glVertex2f(-0.8f, -0.8f);
glVertex2f(0.8f, -0.8f);
glVertex2f(0.8f, 0.8f); glEnd();
pangolin::FinishFrame();
}
}
But The 2D Shape isn't apearing, it only shows the background color
I tried the followings:
Removing the Panel: it makes the shape appear but I want to keep the panel.
Changing zorders of the menu and the shape in both orders, didn't change anything
Not enclosing it in an infinite while loop: Both panel and shape appeared but obviously it is a static image. But it appears the render works the first call of FinishFrame() and then it doesn't anymore.
And other stuffs but i can't list it all here.
I'm wandering if it is because I didn't create OpenGlRenderState Object, But I don't understand why I would need it for 2D Rendering from my understanding of OpenGL and Pangolin.
I hope you guys can help me.

Related

Unexpected gluLookAt behavior with a point draw on OpenGL

I am currently working on the printing loop of my software that reads 3D obj file.
I have stored my obj file read in the variable tie. This variable contain an OpenGL list. My objective is to be able to move around the read object by using keyboard. The keyboard reading is implemented correctly (i can see in through the logs).
Issue
When i compile the following code loop, the gluLookAt exucute properly and I am able to move around my object by changing the value of the parameters.
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) ;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
light();
gluPerspective (60.0, 250/(float)250, 0.1, 500.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(eyeX,eyeY,eyeZ,eyeX+directionX,eyeY+directionY,eyeZ+directionZ,upX,upY,upZ);
glPushMatrix();
glRotated(45,0,0,1);
glTranslated(0,0,50);
glBindTexture(GL_TEXTURE_2D,texture1);
//glCallList(xwing); //ICI
glEnd();
glPopMatrix();
glColor3d(1,1,1);
glDisable(GL_LIGHTING);
glBindTexture(GL_TEXTURE_2D,texture2);
GLUquadric* params = gluNewQuadric();
gluQuadricDrawStyle(params,GLU_FILL);
gluQuadricTexture(params,GL_TRUE);
gluSphere(params,100,20,20);
gluDeleteQuadric(params);
glEnable(GL_LIGHTING);
glBindTexture(GL_TEXTURE_2D,texture1);
glCallList(tie); //ICI
glPointSize(5.0);
glBegin(GL_POINTS);
glColor3f(1.0f,0.0f,0.0f);
glVertex3f(-1.0f,0.0f,0.0f);
glEnd();
SwapBuffers(hDC);
//} //else
Sleep(1);
But when i comment these 4 lines:
glBegin(GL_POINTS);
glColor3f(1.0f,0.0f,0.0f);
glVertex3f(-1.0f,0.0f,0.0f);
glEnd();
My object doesn't move anymore. As if gluLookAt didn't succeed to execute.
Do you have any idea why is this happening. Did I forget something in my code?
glBegin and glEnd delimit the vertices that define a primitive or a group of like primitives. You have to ensure, the each glBegin is followed by a glEnd.
This means, if your Display Lists contains a glBegin then it should contain a glEnd, too. I strongly recommend to do it this way. The other possibility would be to do it manually after glCallList:
glCallList(tie);
glEnd();
glPushMatrix and glPopMatrix are used to push matrices on and pop matrices from the matrix stack. If you want to add a model matrix to the view matrix, then you have to do the following steps.
Push the view matrix glPushMatrix. This pushs a copy of the view matrix on the stack.
Add the model matrix to the current view matrix (glRotated, glTranslated, ... )
Draw the model. (glCallList, gluSphere, ... )
Restore the original view matrix (glPopMatrix).
Adapt your code somehow like this:
// set up view matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(eyeX,eyeY,eyeZ,eyeX+directionX,eyeY+directionY,eyeZ+directionZ,upX,upY,upZ);
// save view matrix
glPushMatrix();
// add model matrix
glRotated(45,0,0,1);
glTranslated(0,0,50);
// do the drawing
glColor3d(1,1,1);
glDisable(GL_LIGHTING);
glBindTexture(GL_TEXTURE_2D,texture2);
GLUquadric* params = gluNewQuadric();
gluQuadricDrawStyle(params,GLU_FILL);
gluQuadricTexture(params,GL_TRUE);
gluSphere(params,100,20,20);
gluDeleteQuadric(params);
glEnable(GL_LIGHTING);
glBindTexture(GL_TEXTURE_2D,texture1);
glCallList(tie);
glEnd(); // <-- maybe this could be done in "tie"
// restore the view matrix
glPopMatrix();

Adding gluPerspective and gluLookAt made my drawing disappear

I'm currently working on a basic GUI that create and draw a robot in a 3d space, I'm using OpenGL and freeglut to deal with the 3d part.
Until last week, I was ignoring all the perspective stuff like 'gluLookAt' or 'gluPerspective' ...
Now, I would like to add those things in order to get basic camera movement (rotation, zoom, translation) with user input.
But i'm stuck cause whenever I try to add the perspective part to my code, I'm not able to get my beautiful robot anymore.
here's my current code :
void drawScene(void) {
glClearColor(1.0f,1.0f,1.0f,0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glMatrixMode(GL_MODELVIEW);
glColor3f(0.0f, 0.0f, 0.0f);
ortho();
robot.draw(); // only sone basic lines and quads
glLoadIdentity();
sprintf(title, "robot creation link:%i/joint:%i", robot.linkNumber, robot.jointNumber);
glutSetWindowTitle(title);
glFlush();
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA|GLUT_SINGLE|GLUT_MULTISAMPLE);
glutInitWindowPosition(0,0);
glutInitWindowSize(1360,768);
glEnable(GL_MULTISAMPLE_ARB | GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
id = glutCreateWindow("robot creation");
glutDisplayFunc (drawScene);
glutKeyboardFunc(keyboardHandler);
glutSpecialFunc (specialKeyHandler);
glutMouseFunc (mouseHandler);
glutReshapeFunc (reshapeHandler);
glutMainLoop();
return 0;
}
I wonder if my code need to be completly re-done to work properly with such things or if I'm not using them properly.
Atm I've tried to add this after the window creation :
glViewport(0, 0, 1360, 768);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(180.0f,1360.0f/768.0f,0.1f,1000.0f);
and this in the drawScene function after the drawing part :
gluLookAt(
10.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f
);
I know I'm facing the object because I can see a dot in the center of the screen that came from the robot.
You have both matrix modes (model view and projection. It is better to activate one. For gmu perspective try something like gluPerspective(170, 1.33, 0.00001, 1000); or put the camera closer to check if you can see a difference in the object. If you are not able to see the object your matrices are overwriting each other. You can check their values by:Gl.glGetDoublev(Gl.GL_MODELVIEW_MATRIX, modelMatrix);
Gl.glGetDoublev(Gl.GL_PROJECTION_MATRIX, projMatrix);.
Another option is also gluunproject which is easier to work than look at function (in my opinion)

Why is my HUD not rendering in OpenGL?

I'm new to OpenGL, and I've been going through NeHe's tutorials and various other web sources, and I'm testing some things to render text as a HUD of sorts over everything else.
After a very long night, I can't get this to work and I can't find any solutions here that work, so I thought I'd ask.
My code:
GLvoid glLoadHUD(GLvoid)
{
glPushAttrib(GL_LIGHTING_BIT |
GL_DEPTH_BUFFER_BIT |
GL_TEXTURE_BIT);
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
glRasterPos2f(0.1f, 0.6f);
glColor3f(1.0f,1.0f,1.0f);
glPrint("Test.");
glRasterPos2f(0.0f, 0.0f);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopAttrib();
glEnable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
}
Which is the code to render the text, and this is the code for drawing the scene:
int DrawGLScene(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clears buffers
glLoadIdentity();
// If I put glLoadHUD(); here, it renders but the models render over it,
// which is useless.
for (xloop = 0; xloop < 3;)
{
glLoadIdentity();
glTranslatef(-4.0f+(float(xloop)*4.0f),0.0f,-12.0f);
glCallList(dlstBox); // This is the call to create a box.
xloop++;
}
glLoadHUD(); // If I put it here though, it doesn't render at all.
return TRUE;
}
Thank you in advance for any help you could give, I know I'm pretty green and I'm sure it's staring me right in the face, but this is driving me mad and I'm not sure how to make it work.
With glLoadHud after the rest of the scene, your MODELVIEW matrix is still on the stack, and you do not clear it as part of glLoadHud. Thus all of the glTranslatef translations that you accumulate during the scene are still active when you're drawing the hud, which translates it right out of your viewable window.
Clear the MODELVIEW matrix as part of the start of glLoadHud and see if that makes a difference.
It might be printing inside your z-clipping so it will not show up on your screen. So, move out of the screen a little bit and see if it shows up.

Untextured Quads appear dark

I just started working with OpenGL, but I ran into a problem after implementing a Font system.
My plan is to simply visualize several Pathfinding Algorithms.
Currently OpenGL gets set up like this (OnSize gets called once on window creation manually):
void GLWindow::OnSize(GLsizei width, GLsizei height)
{
// set size
glViewport(0,0,width,height);
// orthographic projection
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0,width,height,0.0,-1.0,1.0);
glMatrixMode(GL_MODELVIEW);
m_uiWidth = width;
m_uiHeight = height;
}
void GLWindow::InitGL()
{
// enable 2D texturing
glEnable(GL_TEXTURE_2D);
// choose a smooth shading model
glShadeModel(GL_SMOOTH);
// set the clear color to black
glClearColor(0.0, 0.0, 0.0, 0.0);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.0f);
}
In theory I don't need blending, because I will only use untextured Quads to visualize obstacles and line etc to draw paths... So everything will be untextured, except the fonts...
The Font Class has a push and pop function, that look like this (if I remember right my Font system is based on a NeHe Tutorial that I was following quite a while ago):
inline void GLFont::pushScreenMatrix()
{
glPushAttrib(GL_TRANSFORM_BIT);
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(viewport[0],viewport[2],viewport[1],viewport[3], -1.0, 1.0);
glPopAttrib();
}
inline void GLFont::popProjectionMatrix()
{
glPushAttrib(GL_TRANSFORM_BIT);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glPopAttrib();
}
So the Problem:
If I don't draw a Text I can see the Quads I want to draw, but they are quite dark, so there must be something wrong with my general OpenGL Matrix Properties.
If I draw Text (so the font related push and pop functions get called) I can't see any Quads.
The question:
How do I solve this problem and some background information why this happened would also be nice, because I am still a beginner/student, who just started.
If your quads are untextured, you will run into undefined behaviour. What will probably happen is that any previous texture will be used, and the colour at point (0,0) will be used, which could be what is causing them to be invisible.
Really, you need to disable texturing before trying to draw untextured quads using glDisable(GL_TEXTURE_2D). Again, if you don't, it'll just use the previous texture and texture co-ordinates, which without seeing your draw() loop, I'm assuming to be undefined.

Drawing the alpha channel correctly in OpenGl

After loading an image, I have the individual bytes for each channel loaded into an array of unsigned characters. It's passed to a function that projects it as a texture onto a quad. Everything seems to work properly other than the alpha channel, which shows up as the background color. I'm using OpenGL to draw the image. Would I benefit by adding a layering mechanism? Also, how can I achieve the transparent effect that I want?
Note: This is the code that I have a feeling needs changed:
void SetUpView()
{
// Set color and depth clear value
glClearDepth(1.f);
glClearColor(1.f, 0.f, 0.f, 0.f);
// Enable Z-buffer read and write
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glDepthMask(GL_TRUE);
glEnable (GL_BLEND);
glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
// Setup a perspective projection
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90.f, 1.f, 1.f, 500.f);
};
Also, here's the code to render the quad.
void DrawTexturedRect(RectBounds *Verts, Image *Texture)
{
glBindTexture(GL_TEXTURE_2D, GetTextureID(Texture));
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glPixelZoom(1, -1);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 1.0);
glVertex3f(Verts->corners[0].x, Verts->corners[0].y, Verts->corners[0].z);
glTexCoord2f(1.0, 1.0);
glVertex3f(Verts->corners[1].x, Verts->corners[1].y, Verts->corners[1].z);
glTexCoord2f(1.0, 0.0);
glVertex3f(Verts->corners[2].x, Verts->corners[2].y, Verts->corners[2].z);
glTexCoord2f(0.0, 0.0);
glVertex3f(Verts->corners[3].x, Verts->corners[3].y, Verts->corners[3].z);
glEnd();
};
The Image class holds an array of unsigned chars, obtained using OpenIL.
Relevant code:
loaded = ilLoadImage(filename.c_str());
ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE);
unsigned char *bytes = ilGetData();
//NewImage is an instance of an Image. This is returned and passed to the above function.
NewImage->data = bytes;
Before drawing anything transparent you should call:
glDepthMask(false);
And then afterwards:
glDepthMask(true);
Also, all transparent objects must be drawn after all opaque ones.
glClearColor(1.f, 0.f, 0.f, 0.f);
I'd assume that's at the RGBA default, and you're setting red to 1.0.
How about a better explanation of what you're trying to accomplish?
Try:
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Edit: I know what that looks like. It looks like you are drawing the blue square (Which has a Z-order position placing it behind the cursor) AFTER the cursor. You have to draw things in the correct, back-to-front Z-Order when alpha blending or you see errors like you are seeing.