I'm writing a simple OpenGL application that uses GLUT. I don't want to roll my own font rendering code, instead I want to use the simple bitmap fonts that ship with GLUT. What are the steps to get them working?
Simple text display is easy to do in OpenGL using GLUT bitmap fonts. These are simple 2D fonts and are not suitable for display inside your 3D environment. However, they're perfect for text that needs to be overlayed on the display window.
Here are the sample steps to display Eric Cartman's favorite quote colored in green on a GLUT window:
We'll be setting the raster position in screen coordinates. So, setup the projection and modelview matrices for 2D rendering:
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0.0, WIN_WIDTH, 0.0, WIN_HEIGHT);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
Set the font color. (Set this now, not later.)
glColor3f(0.0, 1.0, 0.0); // Green
Set the window location where the text should be displayed. This is done by setting the raster position in screen coordinates. Lower left corner of the window is (0, 0).
glRasterPos2i(10, 10);
Set the font and display the string characters using glutBitmapCharacter.
string s = "Respect mah authoritah!";
void * font = GLUT_BITMAP_9_BY_15;
for (string::iterator i = s.begin(); i != s.end(); ++i)
{
char c = *i;
glutBitmapCharacter(font, c);
}
Restore back the matrices.
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
Related
I'm using qWidget which inherits QGLWidget and below the widget I have 2 buttons.
button1: +
button2: -
this is my code:
void GLWidget::paintGL() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,_w,0,_h,-1,1);
glViewport(_camera_pos_x,0,_w,_h);
glBegin(GL_LINES);
glVertex2i(50,50);
glVertex2i(200,200);
glEnd();
update();
}
I want each time I'm pressing the + button, the screen will move 10 pixels to the right which means the line should move to the left by 10 pixels.
This is the code when im pressing the button:
void right() {_camera_pos_x += 10;}
_camera_pos_X is just a member int which is initialized to 0.
When I'm pressing the button another line is rendered 10 pixels to the right and I see 2 lines
What's wrong with my code?
By the way, I think im using old code of OpenGL, is there a better way to render a line?
First of all note, that drawing with glBegin/glEnd sequences is deprecated since more than 10 years.
Read about Fixed Function Pipeline and see Vertex Specification for a state of the art way of rendering.
glViewport specifies the transformation from normalized device coordinates to window coordinates. If you want to change the position of the line, then you have to draw the line at a different position, but that doesn't change the size of the viewport. Keep your viewport as large as the window:
glViewport(0, 0, _w, _h);
The default frame buffer is never cleared, so the rendering is always drawn on the rendering of the previous frames. Because of that, you can "see 2 lines". Use glClear to clear the framebuffer at the begine of the rendering:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Change the model view matrix to set the positon of the line:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,_w,0,_h,-1,1);
glViewport(0, 0, _w, _h);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(_camera_pos_x, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_LINES);
glVertex2i(50,50);
glVertex2i(200,200);
glEnd();
You must clear the old contents of the framebuffer, before drawing the new image. Put a glClear(GL_COLOR_BUFFER_BIT) at the beginning of paintGL().
I currently have some heat-map data in a database. I was successful in creating painting a heat-map using the same data [using some vertex shading] onto a plane. Example:
Heat-Map Image example for openGL
Name: Capture.jpg
Views: 0
Size: 8.5 KB
ID: 2667
Now, the problem is that I am currently using something like :
glBegin(GL_QUADS);
glColor4ub(point1.color.red(), point1.color.green(), point1.color.blue(), transparency);
glVertex3d(point1.xCood - 750, point1.yCood - 750, 0);
glColor4ub(point2.color.red(), point2.color.green(), point2.color.blue(), transparency);
glVertex3d(point2.xCood - 750, point2.yCood - 750, 0);
glColor4ub(point3.color.red(), point3.color.green(), point3.color.blue(), transparency);
glVertex3d(point3.xCood - 750, point3.yCood - 750, 0);
glColor4ub(point4.color.red(), point4.color.green(), point4.color.blue(), transparency);
glVertex3d(point4.xCood - 750, point4.yCood - 750, 0);
glEnd();
And what this does [at least in my theory] is that it creates another layer over the existing plane. This causes code on clicking the plane below to be rendered useless. Changing the existing code too much is not an option right now as I do not have access to edit it. I found that if I draw a texture (rather than color a plane) on the old plane, the code stays working.
Example(texture tile just defines number of repetitions required, value is 1 in this case):
glBegin(GL_QUADS);
glTexCoord2d(0.0, textureTile);
glVertex3d(gridRect.left(), gridRect.top(), 0.0);
glTexCoord2d(0.0, 0.0);
glVertex3d(gridRect.left(), gridRect.bottom(), 0.0);
glTexCoord2d(textureTile, 0.0);
glVertex3d(gridRect.right(), gridRect.bottom(), 0.0);
glTexCoord2d(textureTile, textureTile);
glVertex3d(gridRect.right(), gridRect.top(), 0.0);
glEnd();
That said, I was only successful in loading a texture from an image I made. Since the image is suppose to be calculated and painted during run time, I tried making an image from the data to load as a texture.
I used the Qt API functionality for achieving the same. I failed to recreate the same image. Might I be suggested a way to create a texture image from data owned.
Thanks
Sorry for the late answering(in case someone else wanted the answer).
I found the answer to be the use of QOpenGLFramebufferObject.
Final code looks something like:
glViewport(0, 0, VIEW_PORT_SIZE, VIEW_PORT_SIZE);
QOpenGLFramebufferObject fbObject(VIEW_PORT_SIZE, VIEW_PORT_SIZE);
fbObject.bind();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
//Switch to Ortho Mode
glMatrixMode(GL_PROJECTION); // Select Projection
glPushMatrix(); // Push The Matrix
glLoadIdentity(); // Reset The Matrix
glOrtho(left, right, bottom, top, -100, 100); // Select Ortho Mode
glMatrixMode(GL_MODELVIEW); // Select Modelview Matrix
glPushMatrix(); // Push The Matrix
glLoadIdentity(); // Reset The Matrix
//Initialize variables
SPointData point1, point2, point3, point4;
//Paint on buffer
//.................<some painting task>................
//Switch to perspective mode
glMatrixMode(GL_PROJECTION); // Select Projection
glPopMatrix(); // Pop The Matrix
glMatrixMode(GL_MODELVIEW); // Select Modelview
glPopMatrix(); // Pop The Matrix
fbObject.release();
return fbObject.toImage();
I would like to know how to draw the length of a line with respect to the the dimensions of the enclosing window. Note that I am using the combination of GLUT and OpenGL.
For example, say I wanted to draw a line from the bottom center of the screen (I assume this would be at coordinate (WINDOW_LENGTH/2, 0) to the center of the window (WINDOW_LENGTH/2, WINDOW_HEIGHT/2)
How do I do this in OpenGL? Right now I have the following:
//Initializes 3D rendering
void initRendering() {
//Makes 3D drawing work when something is in front of something else
glEnable(GL_DEPTH_TEST);
}
//Called when the window is resized
void handleResize(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION); //Switch to setting the camera perspective
//Set the camera perspective
glLoadIdentity(); //
gluPerspective(45.0, (double)w / (double)h, 1.0, 200.0);
}
//Draws the 3D scene
void drawScene() {
//Clear information from last draw
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
glLoadIdentity(); //Reset the drawing perspective
glTranslatef(0, 0, -1);
glBegin(GL_LINES);
//lines
glVertex2f(0, 0);
glVertex2f(0, .25);
glEnd();
glutSwapBuffers(); //Send the 3D scene to the screen
}
int main(int argc, char** argv) {
//Initialize GLUT
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(400, 400); //Set the window size
//Create the window
glutCreateWindow("Basic Shapes - videotutorialsrock.com");
initRendering(); //Initialize rendering
//Set handler functions for drawing, keypresses, and window resizes
glutDisplayFunc(drawScene);
//glutKeyboardFunc(handleKeypress);
glutReshapeFunc(handleResize);
cout << "GLUT_WINDOW_X: " << GLUT_WINDOW_X << endl;
cout << "GlUT_WINDOW_Y: " << GLUT_WINDOW_Y << endl;
glutMainLoop(); //Start the main loop. glutMainLoop doesn't return.
return 0; //This line is never reached
}
This gives me the following result:
What does not make sense to me is that my window has dimension 400 X 400 but the coordinates: glVertex2f(0, 0) and glVertex2f(0, .25). draw a line from about the center of the window to about 80% of the height of the window. I have a few speculations:
I know that my call to glTranslatef(0, 0, -1); sets the origin to the global coordinate (0, 0, -1) What is puzzling to me:
How does the -1 correspond to moving the image that far over?
Does the .25 in the second coordinate correspond to 25% of the height?
What would the code look like to draw a line from (WINDOW_LENGTH/2, 0) to (WINDOW_LENGTH/2, WINDOW_HEIGHT/2) That is the line from the bottom center of the window to the center of the window.
If you need more information let me know.
Let me try answer your questions:
You are working in a model-view (world to view) system. So you start modelling in world coordinates and transform it to the view coordinates. Therefore, glTranslatef is moving your world 1 coordinates points away from de camera.
What you do in openGL is weakly related to your windows coordinates. So, 0.25 really means 0.25 to openGL and nothing more. This means that you can stablish any semantics to points, like meters, kilometres, milimeters and so on. The correlation between openGL buffer and windows coordinates is stablished in the function gluPerspective, in which it says, basically, the region of your world that must be mapped to your windows coordinate system. The second function, glViewport only says how this map will be translated to you windows coordinates. In your case, you are telling to use all the windows.
As I said before, you need to manipulate your gluPerspective to control how much the openGL world will be mapped to your windows coordinates. To do that, you change the angle of the perspective. Greater angles, more openGL regions will be mapped, and you get an effect of zoom out. Lesser angles, less openGL regions will be mapped, and you get an effect of zoom in
I am attempting to make a simple drawing using openGL. However, the depth buffer doesn't appear to be working.
Other people with a similar problem are typically doing one of two things wrong:
Not including glEnable(GL_DEPTH_TEST)
Bad clipping values
However, my code does not have either of these problems.
...
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
gluPerspective(25.0,1.0,10.0,200.0);
// Set the camera location
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(20.0, 10.0, 50.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
// Enable depth test
glEnable(GL_DEPTH_TEST);
// Cull backfacing polygons
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE)
drawCoordinateAxis();
drawBox(5.0,2.0,5.0,0.8,0.0,0.0);
glTranslated(1.0,-1.0,1.0); //The box is 5x2x5, it is shifted 1 unit down and 1 in the x and z directions
drawBox(5.0,2.0,5.0,0.0,1.0,1.0);
...
When I execute my code, this is drawn. http://imgur.com/G9y41O1
Note that the blue box and the red box collide, so the red box should be covering part of the blue box.
The functions drawCoordinateAxis() and drawBox() just draw a few primitives, nothing fancy inside.
I am running this on Debian squeeze.
void reshape(GLint width, GLint height)
{
g_Width = width;
g_Height = height;
glViewport(0, 0, g_Width, g_Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(65.0, (float)g_Width / g_Height, g_nearPlane, g_farPlane);
glMatrixMode(GL_MODELVIEW);
}
So set Matrix Mode to GL_PROJECTION first, then gluPerspective.... and then back to MODELVIEW mode.
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.