Superposition OpenGL [Résolu]

Signaler
Messages postés
12
Date d'inscription
mercredi 7 novembre 2007
Statut
Membre
Dernière intervention
8 mars 2008
-
Messages postés
12
Date d'inscription
mercredi 7 novembre 2007
Statut
Membre
Dernière intervention
8 mars 2008
-
Je cherche a développer un petit programme en C/C++ sous OpenGL (2D uniquement) et GLUT qui représente un altimètre. Dans ce type d'objet, il y a un fond fixe (cadran, graduation,...) et des objets en mouvements (aiguilles).

Cela fonctionne correctement mais les ressources CPU sont trop importantes, en partie a cause du fait que le programme doit redessiner constamment les éléments fixes et les éléments mobiles, alors que seul les éléments mobiles devraient l'être.

Connaissez vous une méthode qui permette soit de placer un fond d'écran (image fixe) ou bien de créer une sorte de calque qui ne serait dessiné qu'une fois sur lequel serait appliqué la partie contenant le dessin des éléments mobiles ? Cela permettrait de ne travailler qu'au niveau de la mémoire et éviter des tas d'opérations mathématiques coûteuses (j'utilise des cercles dans la partie fixe).

Merci

Romuald

7 réponses

Messages postés
2023
Date d'inscription
mardi 24 septembre 2002
Statut
Membre
Dernière intervention
28 juillet 2008
5
Il faut bannir toutes les fonctions glBegin/End, glVertex*. Je sais pas combien de temps il faudra pour réussir à exterminer l'usage de ces fonctions. La première étape serait de virer tous les tutoriels d'openGL d'internet qui utilisent ces fonctions totalement dépassées. Elles vont disparaitre dans Opengl 3.0 et il est temps.

Faut utiliser la méthode décrite sur ce lien:
http://www.g-truc.net/article/vbo-fr.pdf
Messages postés
2023
Date d'inscription
mardi 24 septembre 2002
Statut
Membre
Dernière intervention
28 juillet 2008
5
Non, c'est pas du au fait que tu redessines tout, c'est du à la facon dont tu affiches tes éléments. Post un peu de code de ta partie d'affichage. Il faut également ajouter un timer pour éviter que le fps ne soit trop élevé si tu n'utilises pas la synchro verticale.
Messages postés
12
Date d'inscription
mercredi 7 novembre 2007
Statut
Membre
Dernière intervention
8 mars 2008

Voici un bout de code. Je suis newbie en C et openGL et pour couronner le tout je développe dans le RER...alors un peu d'indulgence svp ;-)

pour résumer, j'affiche une fenetre GLUT avec un fond de couleur. J'ajoute 6 cadrans de fond noir. La méthode employée n'est d'ailleurs pas élégante, mais j'ai pas trouvé mieux... Puis sur tout cela, je fait varier ici des graduations (ce n'est pas une aiguille sur ce bout de code, mais le principe est le même).

luhtor, tes remarques semblent interressantes, mais je n'ai pas du tout entendu parlé de timer ni de synchro verticale dans les docs que j'ai pu me procurer sur le net. Si tu as des infos...voire un bout de code qui explique ce principe...

int main(int argc, char **argv)
{
glutInitWindowSize(HSIZE, VSIZE);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowPosition(0, 0);

glutCreateWindow("EFIS");
glutInit();
glutDisplayFunc(efis_run);
glutKeyboardFunc(capteurs);
glutIdleFunc(data_process);
glutReshapeFunc(reshape);

glutMainLoop();

return 0;
}
// Fonction data_process : Simule l'entrée de signaux des capteurs
void data_process()
{
cap+=8; //ajout de +8° (tests)

efis_cap_move(cptposH[cap_pos], cptposV[cap_pos], CPT_SIZE, cap);
glutPostRedisplay();
glutSwapBuffers();

}

// Fonction efis_run : Affichage de l'EFIS
void efis_run()
{
efis_background();
glutSwapBuffers();
}

// Fonction glutInit : Initialisation fenêtre GLUT
void glutInit(void)
{
glShadeModel (GL_SMOOTH);
glEnable (GL_LINE_SMOOTH);
glEnable (GL_POLYGON_SMOOTH);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
glClear (GL_COLOR_BUFFER_BIT);
}

void reshape (int width, int height)
{
GLfloat w, h;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (width > height)
{
w = (6.0 * width) / height;
h = 6.0;
}
else
{
w = 6.0;
h = (6.0 * height) / width;
}
glOrtho(-w, w, -h, h, -1, 1);
glutPostRedisplay();
}

void efis_background()
{
glPushMatrix();
glClearColor(0.8, 0.8, 0.8, 0.0);
glClear(GL_COLOR_BUFFER_BIT);

efisCircle(0 , 10/3 , CPT_SIZE, CPT_WIDTH);
efisCircle(-5, 10/3 , CPT_SIZE, CPT_WIDTH);
efisCircle(5, 10/3 , CPT_SIZE, CPT_WIDTH);
efisCircle(0 , -10/3 , CPT_SIZE, CPT_WIDTH);
efisCircle(5, -10/3 , CPT_SIZE, CPT_WIDTH);
efisCircle(-5, -10/3 , CPT_SIZE, CPT_WIDTH);
glPopMatrix();
}

// efisGrad : Draw graduations
void efisGrad(float x,float y,float r, float w, int g, int degStart, int degEnd)
{
float angle,x1,x2,y1,y2,incg;

if (degStart > degEnd)
{
incg = ((360-degStart)+degEnd)/(g-1);
}
else
{
incg = (degEnd-degStart)/(g-1);
}


if (degStart > degEnd) degStart = degStart-360;


// Graduations principales
glLineWidth(w);
glColor3f(1.0,1.0,1.0);
glBegin(GL_LINES);
for (angle=degStart;angle<=degEnd;angle+=incg)
{
x1 = r*sin(angle/RAD)+x;
y1 = r*cos(angle/RAD)+y;
x2 = (r-0.2)*sin(angle/RAD)+x;
y2 = (r-0.2)*cos(angle/RAD)+y;
glVertex2f(x1,y1);
glVertex2f(x2,y2);
}
glEnd();

// Graduations secondaires
glLineWidth(w/2);
glBegin(GL_LINES);
for (angle=degStart;angle<=degEnd;angle+=incg/5)
{
x1 = r*sin(angle/RAD)+x;
y1 = r*cos(angle/RAD)+y;
x2 = (r-0.1)*sin(angle/RAD)+x;
y2 = (r-0.1)*cos(angle/RAD)+y;
glVertex2f(x1,y1);
glVertex2f(x2,y2);
}
glEnd();
}


void print_stroke_string(void* font, char* s)
{
if (s && strlen(s)) {
while (*s) {
glutStrokeCharacter(font, *s);
s++;
}
}
}
void efis_cap_move(float x, float y, float r, float cap)
{
glPushMatrix();
glColor3f(1.0,1.0,1.0);
efisGrad(x, y, r, CPT_WIDTH, 9, cap, 360+cap);

glPopMatrix();
}
// efisCircle : Draw circle Center x,y Ray r Width = w
void efisCircle(float x,float y,float r, float w)
{
float angle,xc,yc;

glLineWidth(w);
glColor3f(1.0,1.0,1.0);
glBegin(GL_LINE_STRIP);
for (angle=0;angle<=360;angle+=0.1f)
{
xc = r*sin(angle/RAD)+x;
yc = r*cos(angle/RAD)+y;
glVertex2f(xc,yc);
}
glColor3f(0.0,0.0,0.0);
glBegin(GL_LINE_STRIP);
for (angle=0;angle<=360;angle+=0.1f)
{
xc = r*sin(angle/RAD)+x;
yc = r*cos(angle/RAD)+y;
glVertex2f(x,y);
glVertex2f(xc,yc);
}
glEnd();
}
Messages postés
12
Date d'inscription
mercredi 7 novembre 2007
Statut
Membre
Dernière intervention
8 mars 2008

ok, je vais regarder ce lien.
Pour info, j'ai besoin de faire tourner ce programme sur des équipements "light" (systemes embarqués), donc je ne peux pas m'appuyer sur des fonctionnalités supportées uniquement par des cartes video récentes.

Je repost dès que j'ai du neuf
Messages postés
2023
Date d'inscription
mardi 24 septembre 2002
Statut
Membre
Dernière intervention
28 juillet 2008
5
Il ne s'agit pas d'extensions pour les cartes vidéo récentes. Il s'agit de la technique de base pour afficher des polygones. Le lien décrit l'utilisation des vbos, si tes équipements ne le possèdent, ils possèderont obligatoirement les Vertex Array (VA) qui sont vieux maintenant et qui restent tout de meme très rapide et surtout économise énormément les ressources processeur. Tu peux aussi aller voir du coté des Display List si tu bosses sur des vieilles version d'opengl qui sont un peu plus rapide que les VA et aussi rapide que les plus récents VBO (le lien).
Messages postés
12
Date d'inscription
mercredi 7 novembre 2007
Statut
Membre
Dernière intervention
8 mars 2008

ok, je regarde ça ce week end. Merci pour ton aide.
Messages postés
12
Date d'inscription
mercredi 7 novembre 2007
Statut
Membre
Dernière intervention
8 mars 2008

C'est fait. Merci luhtor, tes conseils étaient bons. J'ai retrouvé des perfs très acceptables et un taux d'utilisation CPU normal. Je banni les glVertex et j'utilise un timer !!! ;-)