Click here to Skip to main content
15,885,689 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
Hi all,

I have a problem.

I need to redraw the 3D scene in a OpenGL window ONLY when the content of the array that contain the center of all the cubes that I need to draw, change.

This happened at every step of elaboration in a main program, but I need the OpenGL window refresh content only when the step was completed, because I think that this create problem at me.

My code now create crash, blocked window (unmovable) or grey window on a PC that is equipped with a Nvidia Quadro 4000, i7 2600 at 3,4Ghz...

This code run without problem (instead) on a lifebook P6100 dual core, with an integrated IntelHD graphics card...run slowly, but don't crash, don't freeze...it's so slowly, but run.

I post here my code, and wait for your suggestion to make this window fluid and that refresh (redraw) only when the object it's different...I don't know how do this and how this code it's so heavy on that machine that is so powerful...Nvidia Quadro 4000 it's a powerful card...

I go crazy!!!

Please help me. This is my code:

C++
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                         PARTE DELLE FUNZIONI OPENGL PER LA RICOSTRUZIONE 3D    
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//Premessa delle funzioni di posizionamento con mouse 
void mouseCB(int button, int stat, int x, int y);
void mouseMotionCB(int x, int y);

//funzioni di inizializzazione e pulizia
bool initSharedMem();
void clearSharedMem();
void initLights();
void setCamera(float posX, float posY, float posZ, float targetX, float targetY, float targetZ);
void toOrtho();
void toPerspective();

//variabili e costanti
const int   SCREEN_WIDTH    = 640;
const int   SCREEN_HEIGHT   = 480;
const float CAMERA_DISTANCE = 10.0f;

int screenWidth;
int screenHeight;
bool mouseLeftDown;
bool mouseRightDown;
bool mouseMiddleDown;
float mouseX, mouseY;
float cameraAngleX;
float cameraAngleY;
float cameraDistance;
int drawMode;

///////////////////////////////////////////////////////////////////////////////
// Funzione inizializzazione OpenGL standard
///////////////////////////////////////////////////////////////////////////////
void init()
{
	glShadeModel(GL_SMOOTH);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
	glEnable(GL_DEPTH_TEST);
    glEnable(GL_LIGHTING); 
	glEnable(GL_TEXTURE_2D);
    glEnable(GL_CULL_FACE);
    glEnable(GL_COLOR_MATERIAL);
	initLights();
}

///////////////////////////////////////////////////////////////////////////////
// Funzione di inizializzazione globale delle variabili
///////////////////////////////////////////////////////////////////////////////
bool initSharedMem()
{
    screenWidth = SCREEN_WIDTH;
    screenHeight = SCREEN_HEIGHT;

    mouseLeftDown = mouseRightDown = mouseMiddleDown = false;
    mouseX = mouseY = 0;

    cameraAngleX = cameraAngleY = 0.0f;
    //cameraDistance = CAMERA_DISTANCE;
	cameraDistance = 0.3f;
    drawMode = 0; // 0:pieno, 1: solo contorni, 2:punti

    return true;
}

///////////////////////////////////////////////////////////////////////////////
// Funzione di pulitura variabili globali
///////////////////////////////////////////////////////////////////////////////
void clearSharedMem()
{
}

///////////////////////////////////////////////////////////////////////////////
// Inizializzazione Luci
///////////////////////////////////////////////////////////////////////////////
void initLights()
{
    GLfloat lightKa[] = {.2f, .2f, .2f, 1.0f};  // luce ambientale
    GLfloat lightKd[] = {.7f, .7f, .7f, 1.0f};  // luce diffusa
    GLfloat lightKs[] = {1, 1, 1, 1};           // luce speculare
   
	glLightfv(GL_LIGHT0, GL_AMBIENT, lightKa);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, lightKd);
    glLightfv(GL_LIGHT0, GL_SPECULAR, lightKs);

    // posizione delle luci
    float lightPos[4] = {0, 0, 20, 1}; 
    glLightfv(GL_LIGHT0, GL_POSITION, lightPos);

	//Attiva tutti i settaggi delle luci
    glEnable(GL_LIGHT0);                        }

///////////////////////////////////////////////////////////////////////////////
//  Posizione della telecamera e direzioni
///////////////////////////////////////////////////////////////////////////////
void setCamera(float posX, float posY, float posZ, float targetX, float targetY, float targetZ)
{
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(posX, posY, posZ, targetX, targetY, targetZ, 0, 1, 0); // eye(x,y,z), focal(x,y,z), up(x,y,z)
}

///////////////////////////////////////////////////////////////////////////////
// Impostazione proiezione ortogonale
///////////////////////////////////////////////////////////////////////////////
void toOrtho()
{
    // Imposta il viewport di tutta la finestra
    glViewport(0, 0, (GLsizei)screenWidth, (GLsizei)screenHeight);

    // Imposta il frustum di visione
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, screenWidth, 0, screenHeight, -1, 1);

    // passaggio a modelview per interattività
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}



///////////////////////////////////////////////////////////////////////////////
// Impostazione come perspective
///////////////////////////////////////////////////////////////////////////////
void toPerspective()
{
    // Imposta il viewport di tutta la finestra
    glViewport(0, 0, (GLsizei)screenWidth, (GLsizei)screenHeight);

    //frustum perspective
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    
	//gluPerspective(60.0f, (float)(screenWidth)/screenHeight, 1.0f, 1000.0f);
	
	gluPerspective(60.0f, (float)(screenWidth)/screenHeight, 10.0f, 0.0f); // FOV, AspectRatio, NearClip, FarClip
    
	// switch to modelview matrix in order to set scene
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

///////////////////////////////////////////////////////////////////////////////
//  Funzione ricorsiva di disegno
///////////////////////////////////////////////////////////////////////////////
void addraw(cubo temp)
{
	//se non ci sono sottocubi
	if (temp.lista_sottocubi.size() == 0)
	{		
			if (temp.livello == LMAXI) {
				 double centro[3]={(temp.V[6].x)/2, (temp.V[6].y)/2,(temp.V[6].z)/2};
				 glPushMatrix();
				 glTranslatef(centro[0],centro[1],centro[2]);
				 glColor3ub(0,0,255);
				 glutSolidCube(temp.lato);
				 glPopMatrix();
			}
	}
//se i sottocubi ci sono
else {
		for (int i=0;i<(int)temp.lista_sottocubi.size();i++){
				addraw(temp.lista_sottocubi[i]);
			}
	 }
}

///////////////////////////////////////////////////////////////////////////////
// Funzione disegno principale
///////////////////////////////////////////////////////////////////////////////
void draw()
{
	
	// clear buffer
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
	glPushMatrix();

	//spostamento del disegno
	glTranslatef(0, 0, -cameraDistance);
    glRotatef(cameraAngleX, 1, 0, 0);   // pitch
    glRotatef(cameraAngleY, 0, 1, 0);   // heading
	
	//lancio funzione di disegno vera e propria
	addraw(prova);
	
	//reset
	glPopMatrix();
	glutSwapBuffers();
}

///////////////////////////////////////////////////////////////////////////////
//  Funzione di reshape
///////////////////////////////////////////////////////////////////////////////
void reshape(int w, int h)
{
   screenWidth = w;
   screenHeight = h;
   toPerspective();
}

///////////////////////////////////////////////////////////////////////////////
//  Funzione di refresh temporizzato della finestra
///////////////////////////////////////////////////////////////////////////////

void timerCB(int millisec){
	glutTimerFunc(millisec, timerCB, millisec);
	glutPostRedisplay();
}

///////////////////////////////////////////////////////////////////////////////
// Funzione rilevamento movimenti del mouse
///////////////////////////////////////////////////////////////////////////////
void Motion(int x,int y)
{
	if(mouseLeftDown)
    {
        cameraAngleY += (x - mouseX);
        cameraAngleX += (y - mouseY);
        mouseX = x;
        mouseY = y;
    }
    if(mouseRightDown)
    {
        cameraDistance -= (y - mouseY) * 0.2f;
        mouseY = y;
    }
}

///////////////////////////////////////////////////////////////////////////////
// Funzione per rilevamento bottoni mouse
///////////////////////////////////////////////////////////////////////////////
void Mouse(int button, int state, int x, int y)
{
	mouseX = x;
    mouseY = y;

    if(button == GLUT_LEFT_BUTTON)
    {
        if(state == GLUT_DOWN)
        {
            mouseLeftDown = true;
        }
        else if(state == GLUT_UP)
            mouseLeftDown = false;
    }

    else if(button == GLUT_RIGHT_BUTTON)
    {
        if(state == GLUT_DOWN)
        {
            mouseRightDown = true;
        }
        else if(state == GLUT_UP)
            mouseRightDown = false;
    }

    else if(button == GLUT_MIDDLE_BUTTON)
    {
        if(state == GLUT_DOWN)
        {
            mouseMiddleDown = true;
        }
        else if(state == GLUT_UP)
            mouseMiddleDown = false;
    }
}

///////////////////////////////////////////////////////////////////////////////
// Inizializzazione di GLUT
///////////////////////////////////////////////////////////////////////////////
void initGLUT(){
    //parametri fake per il lancio di InitGlut
	char *myargv[1];
	int myargc = 1;
	myargv[0]=strdup("MyOpenGL");
	
	//Inizializzazione Glut basso livello
	glutInit(&myargc,myargv);
	
	//Lancio funzioni di settaggio finestra,visualizzazione ed altro
	glutInitDisplayMode( GLUT_RGBA| GLUT_DOUBLE | GLUT_DEPTH |GLUT_STENCIL);	
	glutInitWindowSize(screenWidth, screenHeight);
    glutInitWindowPosition(850,100);
    glutCreateWindow("Ricostruzione attuale");
	
	    //callback delle funzioni richiamate
		glutDisplayFunc(draw);
		glutTimerFunc(33,timerCB,33);
		glutReshapeFunc(reshape);
		glutMouseFunc(Mouse);
		glutMotionFunc(Motion);

}

///////////////////////////////////////////////////////////////////////////////
//  Thread richiamato per lanciare OPENGL
///////////////////////////////////////////////////////////////////////////////

void DRAW3D (void *param){
		
	//abbassa priorità del thread a backgroud
	if(!SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_BEGIN))
		{
			dwError = GetLastError();
			if (ERROR_THREAD_MODE_ALREADY_BACKGROUND == dwError)
			_tprintf(TEXT("Gia' in background\n"));
			else _tprintf(TEXT("Errore nell'entrare in modalita' background (%d)\n"), dwError);
	    }

	 	// Lancia funzione di inizializzazione variabili globali
        initSharedMem();
		
		//initiGLUT
		initGLUT();
		init();

		//ciclo OpenGL
		glutMainLoop();
		
		_endthread();
}



"prova" it's a object of a class that define a cube, with 6 vertex and a dimension of side and a level. The object it's a structure like tree, with different levels...first it's father cube (level 0)...then, in elaboration of main program, others cube it's added at the vector of cubes at levels more hight (1,2,3,4...6)..I need to draw only maximum level cubes of all ramification, so I need that recursive function (addraw)....

But, If I remove recursive function, and modify addraw to draw only first levels cubes, all goes well. OpenGL window works, zoom, rotation...all good. So, it's the recursive function the problem? How can I do to scan the list in another way?

And, since the vector of cubes changes at every elaboration (add, remove cubes) how can I do to update OpenGL windows ONLY when the elaboration of every step it's done? (progressive visualization on evolve)

Someone can help me? I don't understand why this happened...
Posted
Updated 14-Apr-14 6:14am
v2
Comments
The_Inventor 13-Apr-14 6:50am    
float zoom = 0.4f;
float rotx = 0; This one is not initialized correctly like the others.
float roty = 0.001f;

If you have a scene where you or objects move then the scene typically refreshes @ 60 frames a sec.
Also you have an init() in a loop within your DRAW3D() function.
Domus1919 14-Apr-14 12:16pm    
Please taka a look at code now...I've changed it.
Domus1919 13-Apr-14 10:37am    
I have update my code...please, tell me what you thinh...I really don't understand why on a system more powerful don't work...

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900