Problème avec OpenGL

Ascriptel

Membre confirmé
20 Juin 2003
17
0
J'ai essayé sans problème les tutoriaux OpenGL de la doc Xcode d'Apple, et j'ai essayé d'y apporter quelques modifications. Voici le code de la seule classe de mon code, MyOpenGLView :
Bloc de code:
#import "MyOpenGLView.h"

#include <OpenGL/gl.h>

@implementation MyOpenGLView

- (id) init
{
	self = [super init];
	[self initGL];
	return self;
}

- (BOOL) initGL
{
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	glClearDepth(1.0f);
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);
	
	return true;
}

- (void) drawRect: (NSRect) bounds
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
    glColor3f(0.0f, 1.0f, 0.0f);
	glTranslatef(0.0f, 0.0f, -1.0f);
	
    glBegin(GL_TRIANGLES);
    {
        glVertex3f(-1.0f, 1.0f, 0.0f);
        glVertex3f(1.0f, 1.0f, 0.0f);
        glVertex3f(0.0f, -1.0f, 0.0f);
    }
    glEnd();
	
    glFlush();
}

@end

Le problème réside à l'appel de glTranslatef(). Autant une translation suivant x ne pose pas de problème, autant glTranslatef(0.0f, 0.0f, -1.0f) semble n'avoir aucun effet et si j'augmente encore le déplacement suivant z, l'écran devient noir, sans plus aucun triangle vert :( . Quelqu'un sait-il quelle est mon (mes) erreur(s) ?

Merci d'avance.
 
Je ne connais pas grand chose a OpenGL mais je crois avoir trouve d'ou vient ton probleme.
Le type de projection que tu fais est une projection GL_EQUAL donc cela signifie que quelle que soit
la position de ton objet en Z, il sera représenté de la même facon.
Si tu change la valeur en Z de facon a ce qu'elle soit superieure a 1.0 en valeur absolue,
ton objet sort de la sphère qui contient les parties a afficher. Cela sert a alleger le rendu.
ici dans ton initialisation, tu as defini :
glClearDepth(1.0f);
donc la tout ce qui est situé entre 1.0 et -1.0 est affiche et le reste non.

J'espere que j'ai pu t'aider meme si je suis pas tres tres sur de moi.
A+
Vincent
 
Le mieux, tu fais une petite anim, et tu changes le paramètre z glTranslate par un sin(z) avec z qui varie dans le temps, ainsi, tu pourra bien voir le mouvement oscillatoire de l'objet, et voir si ça bouge ou pas.

Mais peut-etre tout simplement que tes vertex ne sont pas multipliés par la matrice homogène ou ta translation est définie.
Je ne vois pas de glPushMatrix().

Bloc de code:
- (void) drawRect: (NSRect) rect
{
    if (!perlArrayRepresentation) {
        return;
    }
    glViewport(0, 0, (GLsizei) rect.size.width, (GLsizei) rect.size.height);
	
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT+GL_DEPTH_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);
    //glEnable(GL_LIGHT0);
    //glEnable(GL_LIGHT1);
    //glEnable(GL_LIGHTING);
    
    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0f ,1.0f,0.3f, 30.0f);
    glMatrixMode(GL_MODELVIEW);
    
    glPushMatrix();
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
    glRotatef(currentRotY + rotY , 0.0f, 1.0f, 0.0f);
    glRotatef(currentRotX + rotX, 1.0f, 0.0f, 1.0f);
    glDisable(GL_BLEND);
    [mMainWC renderTable];
    float x,y;
    x = -3.0f;
    y = -3.0f;
    glTranslatef(0.12f, 0.02f, 0.20f);
    
    for (int i=0;i<16;i++) {
        if (i % 4 == 0) {
            
            glTranslatef(-0.32f, 0.0f, -0.08f);
        }
        glTranslatef(0.08f, 0.0f, 0.0f);
        [mMainWC renderCylinder];
    }
    glDisable(GL_BLEND);
    glTranslatef(0.0f, -0.01f, 0.24f);
    for (int i=0;i<64;i++) {
        if (perlArrayRepresentation[i]>2) {
            glEnable(GL_BLEND);
            glBlendFunc(GL_ONE, GL_ONE);
        } else {
            glDisable(GL_BLEND);
        }
        if (i % 16 == 0) {
            glTranslatef(0.0f, 0.02f, -0.32f);
        }
        if (i % 4 == 0) {
            glTranslatef(-0.32f, 0.0f, 0.08f);
        }
        glTranslatef(0.08f, 0.0f, 0.0f);
        if (perlArrayRepresentation[i]) {
            if (perlArrayRepresentation[i] % 2 == 0) {
                [mMainWC renderPinkPerl];
            } else {
                [mMainWC renderGreenPerl];
            }
        }
    }
    glEnable(GL_BLEND);
    glPopMatrix();
    
    [[self openGLContext] flushBuffer];
}
 
Dans la mesure ou tu ne donnes pas d'information sur l'état des piles de matrices (GL_MODELVIEW et GL_PROJECTION) il est impossible de te répondre. Où se trouve le point de vue, quel sont les transformations courantes ?...

Par ailleurs quel est la pile de matrice active au moment ou tu fais ton glTranslate ?

En effet glMatrixMode permet de spécifier la pile courante pour opérer via glTranslate, glScale, glRotate, glMulMatrix glLoadIdentity, .... Dans le cas qui te concerne il faut que ce soit la pile GL_MODELVIEW (glMatrixMode(GL_MODELVIEW)) qui est grosso modod la pile des matrices de transformations des objets...
 
Ptit-beignet a dit:
Je ne connais pas grand chose a OpenGL mais je crois avoir trouve d'ou vient ton probleme.
Le type de projection que tu fais est une projection GL_EQUAL donc cela signifie que quelle que soit
la position de ton objet en Z, il sera représenté de la même facon.
Si tu change la valeur en Z de facon a ce qu'elle soit superieure a 1.0 en valeur absolue,
ton objet sort de la sphère qui contient les parties a afficher. Cela sert a alleger le rendu.
ici dans ton initialisation, tu as defini :

donc la tout ce qui est situé entre 1.0 et -1.0 est affiche et le reste non.

J'espere que j'ai pu t'aider meme si je suis pas tres tres sur de moi.
A+
Vincent

il s'agit de GL_LEQUAL, qui signifie Less or EQUAL, et non GL_EQUAL.
glDepthFunc (GL_LEQUAL) signifie que seuls les couleur et profondeur d'un fragment dont la profondeur est inférieure ou égale à celle précédement stockée dans le depth buffer seront écrits dnas leurs buffers respectifs. Ce qui en language clair ;) signifie qu'un pixel d'un objet apparaîtra s'il il n'es pas masqué par un pixel qui se trouve devant.

Le mode par défaut d'OpengL est GL_LESS, mais GL_LEQUAL ne change pas grand chose.

Quand à glClearDepth(1.0f), il signifie que la valeur par défaut du depth buffer (celle qui remplie initialement le depth buffer) est 1. Comme l'espace de mapping des profondeurs par défaut d'OpenGL (mais qui peut être redéfinit) est [0, 1], c'est tout a fait logique de le nettoyer avec la valeur la plus importantes en l'occurrence 1. Dès lors on n'affichera un pixel que si son Z, après projection, est au moins < à 1.

Mais la valeur finale de la profondeur n'est obtenue qu'après projection dans l'espace de la caméra ([-1,1] x [-1,1] x [0,1]). C'est dans cet espace que seront effectués les clippings.

Pour parvenir à cet espace il faut fixer les projections et transformations via les piles de matrices d'OpenGL.