ziggyyoyo ziggyyoyo - 1 month ago 7
C++ Question

opengl tiny rendering glitch, need help & tips

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.)

Answer Source

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.