opengl tiny rendering glitch, need help & tips - c++

here is my code:
#include <stdlib.h>
#include <iostream>
#include <gl/glew.h>
#include <gl/freeglut.h>
#include <gl/GL.h>
#include <gl/GLU.h>
#include <SDL.h>
using namespace std;
typedef unsigned short us;
typedef unsigned char uc;
bool *keystates = new bool[256];
bool *skeystates= new bool[256];
uc dir_m[8][2]={
{ 0, 1 },
{ 0,-1 },
{ -1,0 },
{ 1,0 },
{ 1,1},
{ 1,-1 },
{ -1,-1 },
{ -1,1 }
};
us totalbots=15;
float zoomlvl=-70.f;
float camx=0.f,camy=0.f;
struct bot_data{
float x,y,z;
float r,g,b;
float size; // "radius" of the square
us coold;
us age;
us trans:5;
us dir:3,fac:2;
bot_data(void);
void move(void);
void deliver(us bot);
};
struct bool_data{
bool ch:1,ch2:1;
};
bot_data::bot_data(void){
size=0.25f;
fac=rand()%4;
switch(fac){
case 0:x=10.f,y=10.f,z=0.f;
r=1.0f,g=0.f,b=0.f;
break;
case 1:x=-10.f,y=-10.f,z=0.f;
r=0.0f,g=0.f,b=1.f;
break;
case 2:x=-10.f,y=10.f,z=0.f;
r=1.0f,g=1.f,b=0.f;
break;
case 3:x=10.f,y=-10.f,z=0.f;
r=0.0f,g=1.f,b=0.f;
break;
}
coold=0;
trans=0;
age=0;
dir=rand()%8;
}
bot_data *cubers=new bot_data[65536];
bool_data *bools=new bool_data;
void bot_data::move(void){
float move=size/10.f;
switch(dir){
case 0:y+=move;
break;
case 1:y-=move;
break;
case 2:x-=move;
break;
case 3:x+=move;
break;
case 4:x+=move;
y+=move;
break;
case 5:x+=move;
y-=move;
break;
case 6:y-=move;
x-=move;
break;
case 7:y+=move;
x-=move;
break;
}
}
void bot_data::deliver(us bot){
age=-10;
totalbots+=3;
float tmp=size-(size/4.f);
size=0.25f;
x-=size;
y+=size;
for(uc i=1;i<=3;i++){
cubers[totalbots-i].fac=fac;
switch(fac){
case 0:cubers[totalbots-i].r=1.0f,cubers[totalbots-i].g=0.f,cubers[totalbots-i].b=0.f;
break;
case 1:cubers[totalbots-i].r=0.0f,cubers[totalbots-i].g=0.f,cubers[totalbots-i].b=1.f;
break;
case 2:cubers[totalbots-i].r=1.0f,cubers[totalbots-i].g=1.f,cubers[totalbots-i].b=0.f;
break;
case 3:cubers[totalbots-i].r=0.0f,cubers[totalbots-i].g=1.f,cubers[totalbots-i].b=0.f;
break;
}
cubers[totalbots-i].coold=coold;
cubers[totalbots-i].size=size;
switch(i){
case 1:cubers[totalbots-i].x=x;
cubers[totalbots-i].y=y-size*2;
break;
case 2:cubers[totalbots-i].x=x+size*2;
cubers[totalbots-i].y=y;
break;
case 3:cubers[totalbots-i].x=x+size*2;
cubers[totalbots-i].y=y-size*2;
break;
}
}
}
void initkeys(void){
for(uc i=0;i<255;i++){
keystates[i]=false;
skeystates[i]=false;
}
}
void p_keys(unsigned char key, int x, int y){
keystates[key]=true;
}
void keyup(unsigned char key, int x, int y){
keystates[key]=false;
}
void sp_keys(int key, int x, int y){
skeystates[key]=true;
}
void skeyup(int key, int x, int y){
skeystates[key]=false;
}
void key_func(void){
if (keystates['z']){
if(skeystates[GLUT_KEY_UP])zoomlvl+=1.f;
else if (skeystates[GLUT_KEY_DOWN])zoomlvl-=1.f;
if(zoomlvl<-100.0f)zoomlvl=-100.f;
else if(zoomlvl>-5.f)zoomlvl=-5.f;
}
else{
if(skeystates[GLUT_KEY_UP])camy-=1.f;
else if(skeystates[GLUT_KEY_DOWN])camy+=1.f;
}
if(skeystates[GLUT_KEY_LEFT])camx+=1.f;
else if(skeystates[GLUT_KEY_RIGHT])camx-=1.f;
}
void render_p(us bot){
glColor3f(cubers[bot].r,cubers[bot].g,cubers[bot].b);
glBegin(GL_QUADS);
glVertex2f(cubers[bot].size,cubers[bot].size);
glVertex2f(cubers[bot].size,-cubers[bot].size);
glVertex2f(-cubers[bot].size,-cubers[bot].size);
glVertex2f(-cubers[bot].size,cubers[bot].size);
glEnd();
}
void process_cubers(void){
for(us i=0;i<totalbots;i++){
//glPushMatrix();
glLoadIdentity();
glTranslatef(cubers[i].x,cubers[i].y,cubers[i].z);
if(cubers[i].coold==0){
cubers[i].move();
cubers[i].trans++;
if(cubers[i].trans==20){
cubers[i].trans=0;
cubers[i].coold=50;
if(cubers[i].age<100){
cubers[i].size+=0.025f;
}
else if(cubers[i].age==150){
cubers[i].deliver(i);
}
cubers[i].dir=rand()%8;
cubers[i].age+=10;
}
}
else cubers[i].coold--;
render_p(i);
//glPopMatrix();
}
}
void display(void){
key_func();
glClearColor(0.6f,0.6f,0.6f,1.f);
glClear (GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glTranslatef(camx,camy,zoomlvl);
process_cubers();
glutSwapBuffers();
SDL_Delay(1000/30);
glutPostRedisplay();
}
void resize(int width,int height){
glViewport(0,0,(GLsizei)width,(GLsizei)height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60,(GLfloat)width/(GLfloat)height,1.f,100.f);
glMatrixMode(GL_MODELVIEW);
}
int main (int argc, char **argv) {
initkeys();
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE);
glutInitWindowSize (640, 480);
glutInitWindowPosition (0, 0);
glutCreateWindow ("opengl 1");
glutDisplayFunc(display);
glutIdleFunc(display);
glutReshapeFunc(resize);
glutKeyboardFunc(p_keys);
glutKeyboardUpFunc(keyup);
glutSpecialFunc(sp_keys);
glutSpecialUpFunc(skeyup);
glutMainLoop();
return 0;
}
it renders a certain amount of said squares that move each certain intervals. their move distance is their size. each time they move they grow in size until they reach the size limit (1.f in radius in this case) after a certain amount of moves (15 in this case) the square will split into 4 smaller squares and FILLING OUT THE EXACT SPACE its precursor occupied, that means it is supposed to look completely seamless..the problem is instead, i get this split second tear & glitch-looking rendering after the square splits, but other than that i found no other problems.
what i suspect is perhaps i missed some gl function i was supposed to call around the time i am rendering the new 3 squares (the splitting occurs by adding 3 new squares, and shrinking the current one to a quarter of its size, then adjusting all the squres.)

Try this:
#include <GL/glew.h>
#include <GL/glut.h>
typedef unsigned short us;
typedef unsigned char uc;
bool *keystates = new bool[256];
bool *skeystates= new bool[256];
uc dir_m[8][2]=
{
{ 0, 1 },
{ 0,-1 },
{ -1,0 },
{ 1,0 },
{ 1,1},
{ 1,-1 },
{ -1,-1 },
{ -1,1 }
};
us totalbots=15;
float zoomlvl=-70.f;
float camx=0.f,camy=0.f;
struct bot_data
{
float x,y,z;
float r,g,b;
float size; // "radius" of the square
us coold;
us age;
us trans:5;
us dir:3,fac:2;
bot_data(void);
void move(void);
void deliver(us bot);
};
struct bool_data
{
bool ch:1,ch2:1;
};
bot_data::bot_data(void)
{
size=0.25f;
fac=rand()%4;
switch(fac){
case 0:x=10.f,y=10.f,z=0.f;
r=1.0f,g=0.f,b=0.f;
break;
case 1:x=-10.f,y=-10.f,z=0.f;
r=0.0f,g=0.f,b=1.f;
break;
case 2:x=-10.f,y=10.f,z=0.f;
r=1.0f,g=1.f,b=0.f;
break;
case 3:x=10.f,y=-10.f,z=0.f;
r=0.0f,g=1.f,b=0.f;
break;
}
coold=0;
trans=0;
age=0;
dir=rand()%8;
}
bot_data *cubers=new bot_data[65536];
bool_data *bools=new bool_data;
void bot_data::move(void)
{
float move=size/10.f;
switch(dir){
case 0:y+=move;
break;
case 1:y-=move;
break;
case 2:x-=move;
break;
case 3:x+=move;
break;
case 4:x+=move;
y+=move;
break;
case 5:x+=move;
y-=move;
break;
case 6:y-=move;
x-=move;
break;
case 7:y+=move;
x-=move;
break;
}
}
void bot_data::deliver(us bot)
{
age=-10;
totalbots+=3;
float tmp=size-(size/4.f);
size=0.25f;
x-=size;
y+=size;
for(uc i=1;i<=3;i++){
cubers[totalbots-i].fac=fac;
switch(fac){
case 0:cubers[totalbots-i].r=1.0f,cubers[totalbots-i].g=0.f,cubers[totalbots-i].b=0.f;
break;
case 1:cubers[totalbots-i].r=0.0f,cubers[totalbots-i].g=0.f,cubers[totalbots-i].b=1.f;
break;
case 2:cubers[totalbots-i].r=1.0f,cubers[totalbots-i].g=1.f,cubers[totalbots-i].b=0.f;
break;
case 3:cubers[totalbots-i].r=0.0f,cubers[totalbots-i].g=1.f,cubers[totalbots-i].b=0.f;
break;
}
cubers[totalbots-i].coold=coold;
cubers[totalbots-i].size=size;
switch(i){
case 1:cubers[totalbots-i].x=x;
cubers[totalbots-i].y=y-size*2;
break;
case 2:cubers[totalbots-i].x=x+size*2;
cubers[totalbots-i].y=y;
break;
case 3:cubers[totalbots-i].x=x+size*2;
cubers[totalbots-i].y=y-size*2;
break;
}
}
}
void initkeys(void)
{
for(uc i=0;i<255;i++){
keystates[i]=false;
skeystates[i]=false;
}
}
void p_keys(unsigned char key, int x, int y)
{
keystates[key]=true;
}
void keyup(unsigned char key, int x, int y)
{
keystates[key]=false;
}
void sp_keys(int key, int x, int y)
{
skeystates[key]=true;
}
void skeyup(int key, int x, int y)
{
skeystates[key]=false;
}
void key_func(void)
{
if (keystates['z'])
{
if(skeystates[GLUT_KEY_UP])zoomlvl+=1.f;
if(skeystates[GLUT_KEY_DOWN])zoomlvl-=1.f;
if(zoomlvl<-100.0f)zoomlvl=-100.f;
if(zoomlvl>-5.f)zoomlvl=-5.f;
}
else
{
if(skeystates[GLUT_KEY_UP])camy-=1.f;
if(skeystates[GLUT_KEY_DOWN])camy+=1.f;
if(skeystates[GLUT_KEY_LEFT])camx+=1.f;
if(skeystates[GLUT_KEY_RIGHT])camx-=1.f;
}
}
void render_p(us bot)
{
glColor3f(cubers[bot].r,cubers[bot].g,cubers[bot].b);
glBegin(GL_QUADS);
glVertex2f(cubers[bot].size,cubers[bot].size);
glVertex2f(cubers[bot].size,-cubers[bot].size);
glVertex2f(-cubers[bot].size,-cubers[bot].size);
glVertex2f(-cubers[bot].size,cubers[bot].size);
glEnd();
}
void process_cubers(void)
{
for(us i=0;i<totalbots;i++){
if(cubers[i].coold==0){
cubers[i].move();
cubers[i].trans++;
if(cubers[i].trans==20){
cubers[i].trans=0;
cubers[i].coold=50;
if(cubers[i].age<100){
cubers[i].size+=0.025f;
}
else if(cubers[i].age==150){
cubers[i].deliver(i);
}
cubers[i].dir=rand()%8;
cubers[i].age+=10;
}
}
else cubers[i].coold--;
}
for(us i=0;i<totalbots;i++)
{
glPushMatrix();
glTranslatef(cubers[i].x,cubers[i].y,cubers[i].z);
render_p(i);
glPopMatrix();
}
}
void display(void)
{
key_func();
glClearColor(0.6f,0.6f,0.6f,1.f);
glClear (GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
double w = glutGet( GLUT_WINDOW_WIDTH );
double h = glutGet( GLUT_WINDOW_HEIGHT );
gluPerspective(60, w / h,1.f,100.f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(camx,camy,zoomlvl);
process_cubers();
glutSwapBuffers();
}
void timer(int extra)
{
glutPostRedisplay();
glutTimerFunc(33, timer, 0);
}
int main (int argc, char **argv)
{
initkeys();
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize (640, 480);
glutInitWindowPosition (0, 0);
glutCreateWindow ("opengl 1");
glutDisplayFunc(display);
glutKeyboardFunc(p_keys);
glutKeyboardUpFunc(keyup);
glutSpecialFunc(sp_keys);
glutSpecialUpFunc(skeyup);
glutTimerFunc(0, timer, 0);
glutMainLoop();
return 0;
}
You were drawing in your simulation loop. This splits that into two loops, sim then draw.

The way graphics rendering works (OpenGL or otherwise) is that it only guarantees a "nice" seam between two triangles that are "exactly" aligned along some edge if you render them as part of the same triangle strip, the same (vertex buffer, index buffer) model pair, or some other construct that groups triangles into a single render unit.
When you render a "quad," you are really rendering a 2-triangle triangle strip, so the seam between the two triangles looks nice.
When you render two seperate quads that are aligned along some edge, the edge can look bad. Anti-aliasing can help to fix the problem a little bit, but ultimately you need to use a single render unit if you want to get rid of the tearing along seams.
The figure shows four quads (eight triangles) being rendered in a grid. The diagonals are within quads so there isn't any tearing, but the since the quads are all rendered separately there is tearing along their seams.

Related

How do I move a polygon's vertices in the direction of the front face based on its present rotation?

I want the user to have the ability to use the arrow keys to manipulate the polygon. The top arrow key is supposed to move all of the vertices in the direction of the top face.
The left arrow key does this - > angleOfRotation += 5. The right arrow key does this - > angleOfRotation -= 5.
In this image you will find my polygon. There is a box and arrow pointing out the top face. Also, you will notice an arrow pointing away from the polygon illustrating the direction I want it to move with its current angleOfRotation.
game.cpp
#include <iostream>
#include <GL/freeglut.h>
int i;
static int r = 25;
static int screen[] = {640, 480};
static float angleOfRotation = 0.0;
int pos[] = {15, 1};
struct Box {
GLint x = -1; GLint y = -1;
int rx = 2.5, ry = 5;
GLfloat pos[4][2] = {
{x, y}, {x, y-ry}, {x+rx, y-ry}, {x+rx, y}
};
};
Box box;
void reshape(GLint w, GLint h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-r,r,-r,r);
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef((box.pos[0][0]+box.pos[1][0])/2, (box.pos[0][1]+box.pos[1][1])/2, 0.0);
glRotatef(angleOfRotation, 0.0, 0.0, 1.0);
glTranslatef((-box.pos[0][0]+-box.pos[1][0])/2, (-box.pos[0][1]+-box.pos[1][1])/2, 0.0);
glBegin(GL_POLYGON);
for (i=0;i<4;i++)
glVertex2f(box.pos[i][0], box.pos[i][1]);
glEnd();
glutSwapBuffers();
}
void timer(int v)
{
glutTimerFunc(1000/60, timer, v);
glutPostRedisplay();
}
void special(int key, int, int)
{
switch (key)
{
case GLUT_KEY_LEFT:
angleOfRotation += 5;
break;
case GLUT_KEY_RIGHT:
angleOfRotation -= 5;
break;
case GLUT_KEY_UP:
for (i=0;i<4;i++)
box.pos[i][1] += 0.36;
break;
case GLUT_KEY_DOWN:
for (i=0;i<4;i++)
box.pos[i][1] -= 0.36;
break;
default: return;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowPosition(100, 100);
glutInitWindowSize(screen[0], screen[1]);
glutCreateWindow("game");
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutSpecialFunc(special);
glutTimerFunc(0,timer,0);
glutMainLoop();
}

How to declare function in other function?

So I'm making quiz in opengl with c++. The problem is that I don't know how to declare function inside other function, so I have an error.
void main_menu_display()
{
glClear(GL_COLOR_BUFFER_BIT);
// code to draw main menu
glutSwapBuffers();
}
void main_menu_key(unsigned char key, int x, int y)
{
I also tried this, to solve errors: //void first_screen_display();
//void first_screen_key();
switch(key)
{
case 27: //< escape -> quit
exit(0);
case 13: //< enter -> goto first display
glutDisplayFunc(first_screen_display);
glutKeyboardFunc(first_screen_key);
break;
and there's error: 'first_screen_display' was not declared in this scope
and same happens with first screen key.
}
glutPostRedisplay();
}
void first_screen_display()
{
glClear(GL_COLOR_BUFFER_BIT);
// code to draw first screen of game
glutSwapBuffers();
}
void first_screen_key(unsigned char key, int x, int y)
{
switch(key)
{
case 27: //< escape -> return to main menu
glutDisplayFunc(first_screen_display);
glutKeyboardFunc(first_screen_key);
break;
/* other stuff */
default:
break;
}
glutPostRedisplay();
}
int main(int argc, char* argv[]) //argument count, argument variables
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);
glutInitWindowSize(600,600);
glutInitWindowPosition(100,100);
glutCreateWindow("Quiz");
glutDisplayFunc(main_menu_display);
glutKeyboardFunc(main_menu_key);
//glutDisplayFunc(first_screen_display);
//glutKeyboardFunc(first_screen_key);
Init();
glutMainLoop();
return 0;
}

In openGL: how to move an object( cube) on a plane surface with keep the surface static?

#include<gl/glut.h>
#include<stdio.h>
GLfloat vertices[][3]={
{0.0,0.0,0.0},{0.0,0.4,0.0},{0.4,0.4,0.0},{0.4,0.0,0.0} };
GLfloat color[2][3]={ {1.0,0.0,0.0},{0.0,1.0,0.0}};
void board()
{
glColor3f(0.0,0.0,1.0);
glBegin(GL_LINE_LOOP);
glVertex3f(-0.8,-0.8,0.0);
glVertex3f(-0.8,0.80,0.0);
glVertex3f(0.80,0.80,0.0);
glVertex3f(0.8,-0.80,0.0);
glEnd();
}
void cube()
{
glBegin(GL_LINE_LOOP);
glColor3f(1.0,0.0,0.0);
glVertex3fv(vertices[0]);
glVertex3fv(vertices[1]);
glVertex3fv(vertices[2]);
glVertex3fv(vertices[3]);
glEnd();
}
void display()
{
glClearColor(1.0,1.0,1.0,1.0);
glViewport(0,0,600,600);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
cube();
board();
glFlush();
}
void mykey(int key,int x,int y)
{
switch(key){
case GLUT_KEY_LEFT: glTranslatef(-0.4,0.0,0.0); break;
case GLUT_KEY_RIGHT: glTranslatef(0.4,0.0,0.0); break;
case GLUT_KEY_UP: glTranslatef(0.0,0.4,0.0); break;
case GLUT_KEY_DOWN: glTranslatef(0.0,-0.3,0.0); break;
}
glutPostRedisplay();
}
void myinit()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,200,0,400,-1,1);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc,char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);
glutInitWindowSize(600,600);
glutCreateWindow("hello");
glutDisplayFunc(display);
glutSpecialFunc(mykey);
glutMainLoop();
return 0;
}
OpenGL is a drawing API, not a scene renderer. You want to change something? Then you have to redraw the whole thing.

How to draw text letter by letter in glut?

I can't get my GLUT program to work properly.I want to draw text (a char array) letter by letter with some miliseconds interval. My program:
#include <string.h>
#include <windows.h>
#include <glut.h>
#include<iostream>
int hei = glutGet(GLUT_SCREEN_HEIGHT)/2;
int wid = glutGet(GLUT_SCREEN_WIDTH)/2;
void *font = GLUT_BITMAP_TIMES_ROMAN_24;
void *fonts[] =
{
GLUT_BITMAP_9_BY_15,
GLUT_BITMAP_TIMES_ROMAN_10,
GLUT_BITMAP_TIMES_ROMAN_24
};
void selectFont(int newfont)
{
font = fonts[newfont];
glutPostRedisplay();
}
void selectColor(float r, float g, float b)
{
glColor3f(r, g, b);
glutPostRedisplay();
}
char *msg;
void tick(void)
{
glutPostRedisplay();
}
void timer(int value) {
}
int element=0;
void output(int x, int y, char *string, bool center=true) {
int len;
len = strlen(string);
if(center){
glRasterPos2f((wid-len), y);
}
else {
glRasterPos2f(x, y);
}
for(int i=0;i<len;i++) {
glutBitmapCharacter(font, string[i]);
glPopMatrix();
glutSwapBuffers();
Sleep(500);
}
}
void outputmsg(int x, int y, bool center=true) {
int len;
len = strlen(msg);
if(center){
glRasterPos2f((wid-len), y);
}
else {
glRasterPos2f(x, y);
}
for(int i=0;i<len;i++) {
glutBitmapCharacter(font, msg[i]);
}
}
void updatemsg() {
msg="test msg letter by letter";
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
msg="|";
updatemsg();
if(msg!="|")
output(wid, hei, msg, true);
else
output(wid,hei,msg,true);
}
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, w, h, 0);
glMatrixMode(GL_MODELVIEW);
}
void keyboard(unsigned char key, int x, int y) {
switch(key){
case 27:
exit(1);
break;
}
}
int main(int argc, char **argv)
{
int i, msg_submenu, color_submenu;
glutInit(&argc, argv);
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-mono")) {
font = GLUT_BITMAP_9_BY_15;
}
}
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(wid*2, hei*2);
glutCreateWindow("CHAT");
glutFullScreen();
glClearColor(0.0, 0.0, 0.0, 1.0);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutIdleFunc(tick);
selectFont(0);
glutMainLoop();
return 0; /* ANSI C requires main to return int. */
}
It does really weird stuff like erasing the previus one char then printing then printing the next one and the erased one. I tried everything what i could find about this topic on the forums. How can i fix it?
What you should do is also hold the length of the string you want to display and increment it every few milliseconds:
int len;
char *msg;
void incrementLength(int value){
if(msg[len]==0)return; //end of string stop the callback
len++;
glutTimerFunc(100, incrementLength, 0);
glutPostRedisplay();
}
void updatemsg() {
msg="test msg letter by letter";
len=0;
glutTimerFunc(100, incrementLength, 0);
}
And then in outputmsg (if you actually call it) you only loop until len:
void outputmsg(int x, int y, bool center=true) {
if(center){
glRasterPos2f((wid-len), y);
}
else {
glRasterPos2f(x, y);
}
for(int i=0;i<len;i++) {
glutBitmapCharacter(font, msg[i]);
}
}
This code has a couple of issues:
for(int i=0;i<len;i++) {
glutBitmapCharacter(font, string[i]);
glPopMatrix();
glutSwapBuffers();
Sleep(500);
}
You are popping a matrix that you never pushed anywhere, and you are doing it len-many times.
You are swapping buffers without clearing the screen in-between... that's going to lead to undefined results (generally a garbled mess of characters from previous frames).
You really need to re-think how you've implemented this.
I would suggest you implement some elapsed time check in your display (...) function that determines which character to print, rather than doing this in a loop that calls Sleep (...).

How do I specify a keyboard's directional keys in glut?

I wanna use up, down, left, right as part of the controls of an opengl + glut application. How do I refer to the keys inside my 'keyboard' function (the one that I pass to glutKeyboardFunc)?
You need glutSpecialFunc.
For example -
#include<GL/gl.h>
#include<GL/glut.h>
#include<stdio.h>
void
init(void)
{
/*initialize the x-y co-ordinate*/
glClearColor(0,0,0,0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-320, 319,-240, 239);
glClear (GL_COLOR_BUFFER_BIT);
glFlush();
}
void
catchKey(int key, int x, int y)
{
if(key == GLUT_KEY_LEFT)
printf("Left key is pressed\n");
else if(key == GLUT_KEY_RIGHT)
printf("Right key is pressed\n");
else if(key == GLUT_KEY_DOWN)
printf("Down key is pressed\n");
else if(key == GLUT_KEY_UP)
printf("Up key is pressed\n");
}
int
main(int argc, char *argv[])
{
double x_0, y_0, x_1, y_1;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(640, 480);
glutInitWindowPosition(400, 400);
glutCreateWindow("Special key");
init();
glutSpecialFunc(catchKey);
glutMainLoop();
}
your functions should be something like these
void handleSpecialKeypress(int key, int x, int y) {
switch (key) {
case GLUT_KEY_LEFT:
isLeftKeyPressed = true;
if (!isRightKeyPressed) {
DO SOMETHING HERE;
}
break;
case GLUT_KEY_RIGHT:
isRightKeyPressed = true;
if (!isLeftKeyPressed) {
DO SOMETHING HERE;
}
break;
}
}
void handleSpecialKeyReleased(int key, int x, int y) {
switch (key) {
case GLUT_KEY_LEFT:
isLeftKeyPressed = false;
break;
case GLUT_KEY_RIGHT:
isRightKeyPressed = false;
break;
}
}
and you also need to invoke these in your main() method
glutSpecialFunc(handleSpecialKeypress);
glutSpecialUpFunc(handleSpecialKeyReleased);
The variables isRightKeyPressed and isLeftKeyPressed are global variables I defined.