Superposition OpenGL

Résolu
mush74 Messages postés 12 Date d'inscription mercredi 7 novembre 2007 Statut Membre Dernière intervention 8 mars 2008 - 30 janv. 2008 à 13:22
mush74 Messages postés 12 Date d'inscription mercredi 7 novembre 2007 Statut Membre Dernière intervention 8 mars 2008 - 3 févr. 2008 à 22:04
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

luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
31 janv. 2008 à 12:04
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
3
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
30 janv. 2008 à 18:39
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.
0
mush74 Messages postés 12 Date d'inscription mercredi 7 novembre 2007 Statut Membre Dernière intervention 8 mars 2008
30 janv. 2008 à 22:54
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();
}
0
mush74 Messages postés 12 Date d'inscription mercredi 7 novembre 2007 Statut Membre Dernière intervention 8 mars 2008
31 janv. 2008 à 14:04
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
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
31 janv. 2008 à 21:03
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).
0
mush74 Messages postés 12 Date d'inscription mercredi 7 novembre 2007 Statut Membre Dernière intervention 8 mars 2008
31 janv. 2008 à 22:10
ok, je regarde ça ce week end. Merci pour ton aide.
0
mush74 Messages postés 12 Date d'inscription mercredi 7 novembre 2007 Statut Membre Dernière intervention 8 mars 2008
3 févr. 2008 à 22:04
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 !!! ;-)
0
Rejoignez-nous