Scaled 2d text in OpenGL application - opengl

I have an OpenGL application that displays a 2D grid. I want to be able to label each cell in the grid with a letter.
Right now I am drawing text on each cell using the code based on this answer:
void drawLetter(double x, double y, double win_w, double win_h, char c) {
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0.0, win_w, 0.0, win_h);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glColor3f(1.0, 1.0, 0.0); // Green
glRasterPos2i(x, y);
void * font = GLUT_BITMAP_8_BY_13;
glutBitmapCharacter(font, c);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
}
The problem I have is that the cells in the grid are much bigger than this font. I want the letters to be scaled to fill the entire cell. Ideally, I'd like to specify x, y, width, and height in window units, and scale the character to be those dimensions. However, I don't really know how to accomplish this. I've found some tutorials on the internet but they all seem to rely on external libraries; for various reasons I cannot use any external libraries.
Is there an easy way to accomplish this? I know there are also stroke fonts available but I still don't know how to accomplish the appropriate scaling.

Related

OpenGL depth buffer isn't working

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.

How to determine a full-window rectangle in OpenGL

That's problem: I'm currently in OpenGL eye-space, now I want make a black rectangle to cover all window's area. How can I determine a exactly X, Y, Z position to do this?
Update
Or can someone tell me how can I determine the X, Y (top-left) of window when we have a Z value?
You can try to calculate a rectangle that fits the camera exactly and go from there. To do that, you would need to take into account the projection matrix and calculate an inverse.
However, there is a simpler method. All you have to do is to change the camera temporarily, so that you know exactly how to draw the rectangle. A simple enough camera is the default orthogonal camera, with simple limits(from -1 to 1). The following does that:
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glBegin(GL_QUAD);
glVertex2f(-1.f, -1.f);
glVertex2f(1.f, -1.f);
glVertex2f(1.f, 1.f);
glVertex2f(-1.f, 1.f);
glEnd();
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);

OpenGL frustum, perspective

I have the following code that takes snapshots to the framebuffer. I verified the framebuffer works correctly and the camera is facing the object correctly. I used to get pictures done correctly, but it was based on faulty code, using the wrong frustum. So I decided to start fresh (with the frustums).
The object is centered at the middle and is 32*32 blocks with each block 2*2, so 64 * 64.
My distance is 100 and my viewport is 128x256. My frustum is 1 to 1000.0.
I'm relatively new to Opengl so I'm having trouble understanding the concepts of frustrums and perspectives fully.
I do not get a picture at all.
saveGLState();
const int nrPics = 360 / DEGREES_BETWEEN_PICTURES;
for (int i = 0; i < nrPics; i++) {
catchFbo->bind();
glViewport(0, 0, PICTURE_WIDTH, PICTURE_HEIGHT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float rat = PICTURE_WIDTH / PICTURE_HEIGHT;
glFrustum(- 1.0, + 1.0, - rat, + rat, 1.0, 1000.0);
gluPerspective(90.0f,rat,CAPT_FRUSTRUM_NEAR,CAPT_FRUSTRUM_FAR);
glColorMask(true, true, true, true);
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_MULTISAMPLE);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
drawScreenshot(i);
catchFbo->release();
QImage catchImage = catchFbo->toImage();
catchImage.save("object/test" + QString::number(i) + ".png");
}
glDisable(GL_MULTISAMPLE);
restoreGLState();
void VoxelEditor::saveGLState()
{
glPushAttrib(GL_ALL_ATTRIB_BITS);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
}
void VoxelEditor::restoreGLState()
{
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glPopAttrib();
}
EDIT: I tried using only glFrustum or glPerspective. No luck.
You shouldn't use both glFrustum and gluProjection. They both are operations which setup the projection matrix, and if you use them together you'll multiply them together and get a weird result. Generally you'd just apply glFrustum OR gluProjection on an identity matrix, not both.
If that doesn't solve the problem, what are your values of NEAR, FAR, WIDTH, and HEIGHT?
Also make sure you're not doing integer divide for your screen ratio (a common bug).

OpenGL Camera position and skybox

Been integrating this camera tutorial http://www.swiftless.com/tutorials/opengl/camera2.html and having a bit of trouble centering the camera in the skybox.
Using this code below makes my camera inside the box:
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-1.0, 1.0, -1.0*(GLfloat)h/(GLfloat)w,
1.0*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
else
glOrtho(-1.0*(GLfloat)w/(GLfloat)h,
1.0*(GLfloat)w/(GLfloat)h, -1.0, 1.0, -10.0, 10.0);
glMatrixMode(GL_MODELVIEW);
}
To draw the skybox, I followed this tutorial: http://sidvind.com/wiki/Skybox_tutorial
I've been trying to translate objects closer to the camera, but didn't work as I expected. Now I'm not sure what I need to do.
Appreciate any help.
First: Don'y apply the projection in the reshape handler. Otherwise simple things appear impossible (like doing a skybox). Second: For a skybox to work you must use the very same projection like for the rendering of the rest of the scene. What you should change is the translation of the modelview to 0, yet keeping the camera orientation.
You can do this by setting the last column of the modelview matrix to (0,0,0,1).
So this makes your rendering code like this:
void render_skybox()
{
push_modelview();
set_modelview_column(3, 0, 0, 1);
draw_skybox();
pop_modelview();
}
void render()
{
set_viewport();
set_projection();
apply_camera_transform();
render_skybox();
render_scene();
}

Using GLUT bitmap fonts

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();