Alternative to glRotatef and glutBitmapCharacter? - opengl

This is what my code is currently. However, for the life of me I cannot get the text to rotate. Do I need to use something other than glutBitmapCharacter?
Just to clarify, this is only a 2D program
main.cpp
#include "bookshelf.h"
void Initialize()
{
glClearColor (1.0, 1.0, 1.0, 0.0 );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho(0,799,799,0,0.0,1.0);
}
void main( int argc, char *argv[] )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_SINGLE | GLUT_RGB );
glutInitWindowSize( 800, 800 );
glutInitWindowPosition( 200, 50 );
glutCreateWindow("Bookshelf - Ankit Ahuja");
Initialize();
glutDisplayFunc(Bookshelf);
glutMainLoop();
}
bookshelf.h
#include <GL/glut.h>
void Bookshelf()
{
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glColor3f( 0.0, 0.0, 0.0 );
glRasterPos2f(170,90);
glRotatef(0,0.0,0.0,0.0);
char text1[50]="Apple Recipe Book";
for(int i=0; i<50; i++) glutBitmapCharacter(GLUT_BITMAP_8_BY_13,text1[i]);
glRasterPos2f(190,110);
glRotatef(0,0.0,0.0,0.0);
char text2[50]="Banana Recipe Book";
for(int i=0; i<50; i++) glutBitmapCharacter(GLUT_BITMAP_8_BY_13,text2[i]);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}

Yep.
glutBitmapCharacter() is just going to splat a char on the screen (note the call to glRasterPos2f()).
There's no built-in support for 3D fonts in OpenGL, but a lot of 3rd party APIs. See this link for a summary:OpenGL Fonts
I don't like just pasting in a link, but I do use the FreeType2 library listed, and I've had good success with it.

Give glutStrokeCharacter() a shot.
Or use glutBitmapCharacter() and your choice of render-to-texture method. Then render a quad with your texture in whatever orientation you want.

Related

My OpenGL triangle doesen't show

The triangle doesn't appear on the screen.
I am using Dev c++ 4.9.9.2(i know that you don't like it, but for me it's still the best :) with free glut.
Here's the code:
#include <GL/glut.h>
void display(){
glClear ( GL_COLOR_BUFFER_BIT );
glutSwapBuffers();
glBegin ( GL_TRIANGLES );
glColor3f ( 0.0, 1.0, 0.0);
glVertex2f (-0.5,-0.5);
glVertex2f (0.5,-0.5);
glVertex2f (0.0, 0.5);
glEnd();
}
void reshape ( int width, int height ){
glViewport ( 0, 0, width, height );
}
void initOpenGL(){
glClearColor ( 1.0, 0.1, 0.0, 1.0 );
}
int main (int argc, char **argv){
glutInit ( &argc , argv );
glutInitDisplayMode ( GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH );
glutInitWindowSize ( 500, 500 );
glutInitWindowPosition ( 100, 100 );
glutCreateWindow ( "OpenGl" );
initOpenGL();
glutDisplayFunc ( display );
glutIdleFunc ( display );
glutReshapeFunc ( reshape );
glutMainLoop ();
return 0;
}
Let's take a closer look at your display function:
display()
{
glClear();
glutSwapBuffers();
drawTriangle();
}
glClear() clears the backbuffer to a constant color. glutSwapBuffers() swaps frontbuffer and backbuffer. This will show the current content of the backbuffer (which is just the clear color) on the screen. The content of the new backbuffer will be undefined. Every draw call will draw to the backbuffer.
As you see, the program has never a chance to display something other than the clear color on screen. Just move glutSwapBuffers() to the end of the function:
display()
{
glClear();
drawTriangle();
glutSwapBuffers();
}
And please pick a more recent tutorial. You are using the fixed function pipeline, which has been deprecated for about 10 years. You can recognize it by calls like glBegin() or glVertex3f(). There is no reason to learn something that is dying (or already dead on some platforms).

GLUT mouse Tracking and Drawing

I am making a simple GLUT program which tracks the mouse and put points on the path.
Well This is my code:
void init()
{
glClearColor( 0.0, 0.0, 1.0, 1.0);
glMatrixMode( GL_PROJECTION);
gluOrtho2D( 0.0, 400.0, 0.0, 400.0);
for(int i=0;i<5000;i++)
{
arr[i][0]=0;
arr[i][1]=0;
}
glPointSize(10.0);
}
void drawPoints()
{
glBegin( GL_POINTS );
glColor3f( 0.0,0.0,0.0 );
for ( int i = 0; i < z; i++ )
{
glVertex2f( arr[i][0], arr[i][1]);
}
glEnd();
}
void myDisplay()
{
glClear( GL_COLOR_BUFFER_BIT);
drawPoints();
glutSwapBuffers();
glutPostRedisplay();
}
void myMouseMove( int x, int y)
{
arr[z][0]=x;
arr[z++][1]=y;
}
int main( int argc, char ** argv)
{
glutInit( &argc, argv);
glutInitDisplayMode( GLUT_DOUBLE| GLUT_RGB);
glutInitWindowPosition( 100, 100);
glutInitWindowSize(600,600);
glutCreateWindow( "Testing");
init();
glutDisplayFunc( myDisplay);
glutPassiveMotionFunc( myMouseMove);
glutMainLoop();
return 0;
}
However I am having few problems:
Y coordinate runs in opposite direction.
Draws point ahead of cursor position(while moving in a direction).
Is there any better way to do this?
The Y coordinate being flipped is actually expected behavior. Simply correct for it in your code and you should be fine.
If you want to make sure that your rendered image and mouse cursor are completely synchronized, simply have glut hide the mouse cursor, and then render it yourself using OpenGL.
You should be aware that when using a traditional projection matrix in OpenGL: (0,0) is the lower-left corner. Most window systems will map (0,0) to the top-left corner.
In some circumstances, you can make them match up simply by swapping the bottom/top fields in your call to glOrtho (...) or gluOrtho2D (...) - this has other consequences like reversing polygon winding, so it is not always the best approach.
As for "drawing points ahead of the cursor," I think you may be describing input latency (particularly if you are using VSYNC).
When you use a software cursor vs. hardware cursor the position of the mouse may be off by one or more frames. There is a somewhat technical discussion here (see: Idiosyncrasies) on the effect of buffer swap intervals (OpenGL's mechanism for VSYNC) on input latency.
To fix the inversion do 600 - y for setting arr element. Also your gluOrtho2D is on a scale of 400 by 400 while your windows is 600 by 600 so change your gluOrtho2D scale to the same as the window size and you'll be fine.

Corrupt-looking Accumulation Buffer output

I am in the process of building a simple 3D game engine that is built on top of OpenGL, and for windowing and I/O, GLUT. I have run into a problem with the OpenGL accumulation buffer when trying to build a motion-blur option into the engine. Essentially, here is the small block of code that is supposed to do this for me:
glAccum(GL_MULT, 0.99f);
glAccum(GL_ACCUM, 1.0f - 0.99f);
glAccum(GL_RETURN, 1.0f);
I first tried this block of code by planting it in my Render() method, but it showed a corrupt-looking view where only a select few pixels were visible. So, I then tried it with the rest of the source from the website from which I found the code. I still got the same issue. Below is an image of the issue:
Then, I just took out the accumulation buffer portion (the three lines that are supposed to achieve the motion blur), and here is what I got:
Of course, there would be no motion blur since I removed the glAccum() lines, but that at least told me there is either a problem with my graphics card (it doesn't like accumulation buffers?) or those lines of code don't work.
I don't know if it matters, but I am running the code through NetBeans 7.2 (C++) on a MacBook Pro from 2011. Also, I did request an accumulation buffer in the following line:
glutInitDisplayMode(GLUT_DEPTH | GLUT_ACCUM | GLUT_DOUBLE | GLUT_RGBA);
Here is a sample piece of code I just threw together. I'm not sure if something is wrong in the code, and I know I probably didn't use best practices either, but it gets the point across. I still experienced the error with this code:
#include <iostream>
#include <GLUT/GLUT.h>
using namespace std;
float Rotation = 0.0f;
void Reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1, 1, -1.0f * ((float)height / (float)width), 1.0f * ((float)height / (float)width), 0.1f, 200.0f);
glMatrixMode(GL_MODELVIEW);
}
void Update(int value)
{
Rotation++;
glutPostRedisplay();
glutTimerFunc(17, Update, 0);
}
void InitGL()
{
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glEnable(GL_COLOR_MATERIAL);
glClearDepth(100.0f);
}
void Render(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0, 0, 5.0f, 0, 0, 0, 0, 1, 0);
glPushMatrix();
{
glRotatef(Rotation, 0.0, 1.0, 0.0);
/* Render Icosahedron */
glColor3f(0.5f, 0.5f, 0.5f);
glutSolidIcosahedron();
/* Render wireframe */
glColor4f(1.0, 1.0, 1.0, 1.0);
glLineWidth(2.0);
glutWireIcosahedron();
}
glPopMatrix();
/* Blur */
glAccum(GL_MULT, 0.99);
glAccum(GL_ACCUM, 0.01);
glAccum(GL_RETURN, 1.0);
glFlush();
glutSwapBuffers();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA | GLUT_ACCUM);
glutInitWindowSize(400, 400);
glutCreateWindow("Test");
glutDisplayFunc(Render);
glutReshapeFunc(Reshape);
InitGL();
Reshape(400, 400);
glutTimerFunc(17, Update, 0);
glutMainLoop();
return 0;
}

Calling glRasterPos2i and glutBitmapString in the presence of ModelView transforms

I'm trying to display a text-overlay (basically a help screen which shows my keyboard shortcuts) on top of a 3D Texture I'm rendering. The texture works great and I've got some east-to-use rotations and translations for the user.
My thought was to use
const unsigned char tmp[100] = "text to render";
glRasterPos2i(x, y);
glColor4b(255, 255, 255, 255);
glutBitmapString(GLUT_BITMAP_HELVETICA_18, tmp);
As recommended in How do I use glutBitmapString() in C++ to draw text to the screen? .
This works great except that the text now rotates with the object instead of remaining in a static location on the screen. I read some documentation and found that the glRasterPos functions are manipulated when you manipulate the model view matrix:
The object coordinates presented by glRasterPos are treated just like those of a glVertex command: They are transformed by the current modelview and projection matrices and passed to the clipping stage.
-Source
I then found via another post that you could push and pop the current matrix with glPushMatrix and glPopMatrix.
-Source
When I do this, the text disappears all together. At first I thought I might have had the coordinates wrong for the text, but I tried x=y=0 through x=y=25 in intervals of .01 and never saw the text. It's still possible I'm misunderstanding where this should be drawn, but I'm not sure what to try next.
My drawing function is calling something akin to:
glLoadIdentity();
glPushMatrix();
glTranslatef(0,0,-sdepth);
glRotatef(-stheta, 1.0, 0.0, 0.0);
glRotatef(sphi, 0.0, 0.0, 1.0);
glRotatef(rotateX,0,1,1);
glRotatef(rotateY,1,0,0);
glTranslatef(-0.5,-0.5,-0.5);
glPopMatrix();
glRasterPos2i(2, 2);
glColor4b(255, 255, 255, 255);
glutBitmapString(GLUT_BITMAP_HELVETICA_18, tmp);
Anyone have any recommendations for debug/troubleshooting steps to try to get this text to display in a single, static location on the screen?
Well, if glRasterPos is treated the same way as glVertex, then you need to set up proper projection (GL_PROJECTION) matrix (using gluOrtho2D) before calling glRasterPos.
Give this a shot:
#include <GL/glut.h>
#include <string>
using namespace std;
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glColor3ub(255,0,0);
glPushMatrix();
glScalef(5,5,5);
glBegin(GL_QUADS);
glVertex2f(-1,-1);
glVertex2f(1,-1);
glVertex2f(1,1);
glVertex2f(-1,1);
glEnd();
glPopMatrix();
glColor3ub(0,255,0); // A
glRasterPos2i(0,0); // B
string tmp( "wha-hey!" );
for( size_t i = 0; i < tmp.size(); ++i )
{
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, tmp[i]);
}
glutSwapBuffers();
}
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
double aspect_ratio = (double)w / (double)h;
glOrtho(-10*aspect_ratio, 10*aspect_ratio, -10, 10, -1, 1);
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(800,600);
glutCreateWindow("Text");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return EXIT_SUCCESS;
}
Oddly enough swapping lines A and B causes the glColor3ub() call to not take effect. I think that's what you were running into with the code sequence you posted.
As an aside glColor4b() takes chars which max out at 127. You should switch to glColor4ub() if you want to persist in passing in 255.
Documented here ("The sequence of glRasterPos(), glColor(), glBitmap() doesn't result in the desired bitmap color"), but no explanation given :(
EDIT: Ah ha! The current raster position contains its own color state, which is only updated during a glRasterPos() call.

OpenGL particle system

I'm trying to simulate a particle system using OpenGl but I can't get it to work, this is what I have so far:
#include <GL/glut.h>
int main (int argc, char **argv){
// data allocation, various non opengl stuff
............
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE );
glutInitWindowPosition(100,100);
glutInitWindowSize(size, size);
glPointSize (4);
glutCreateWindow("test gl");
............
// initial state, not opengl
............
glViewport(0,0,size,size);
glutDisplayFunc(display);
glutIdleFunc(compute);
glutMainLoop();
}
void compute (void) {
// change state not opengl
glutPostRedisplay();
}
void display (void) {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POINTS);
for(i = 0; i<nparticles; i++) {
// two types of particles
if (TYPE(particle[i]) == 1) glColor3f(1,0,0);
else glColor3f(0,0,1);
glVertex2f(X(particle[i]),Y(particle[i]));
}
glEnd();
glFlush();
glutSwapBuffers();
}
I get a black window after a couple of seconds (the window has just the title bar before that). Where do I go wrong?
LE: the x and y coordinates of each particle are within the interval (0,size)
Try to make these changes in your code:
move the Main function at the end of the file
glPoinSize call belongs to the Display function
then you should provide a function to handle resizing of the window glutReshapeFunc(reshape), something like this
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h);
}
glFlush is called from glutSwapBuffers function so you don't need it there
insert this code (after glutCreateWindow call) to set the initial position for the projection
glClearColor(0.2, 0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 10, 0.0, 10, -1.0, 1.0);