Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 14/10/2013, à 11:03

z999

[Résolu] OpenGL en C

Salut a tous je c'est pas si c'est ici que je doit pose mon problème ! Voila je suis étudiant en informatique et notre prof nous a demander de faire un mini projet en OpenGL, mais nous ne l'avons pas vu en cours. Voila ce que mon terminal m'affiche lors de la compilation :

  main.c:24:1: erreur: un élément de l'initialisation n'est pas une constante
main.c:25:1: erreur: un élément de l'initialisation n'est pas une constante
main.c:26:1: erreur: un élément de l'initialisation n'est pas une constante
main.c:27:1: erreur: un élément de l'initialisation n'est pas une constante
main.c:46:1: erreur: un élément de l'initialisation n'est pas une constante

Et voici mon code :

 #include <math.h>
#include <time.h>
#include <SDL/SDL.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glext.h>


#define NBC 7000 // Nombre de champignons


static void  sdlInitGL(SDL_Surface * s);
static void sdlPrintGL(SDL_Surface * s);
static void sdlLoop(SDL_Surface * s);
static int sdlManageEvents(SDL_Surface * s);
static void sdlDraw(SDL_Surface * s);
void sol();
static void loadText();
void placeChampi();
void champignons();

static SDL_Surface * sdlInit(int w, int h);

SDL_Surface * cepe = SDL_LoadBMP("cepe.bmp");
SDL_Surface * phal = SDL_LoadBMP("phalloide.bmp");
SDL_Surface * satan = SDL_LoadBMP("satan.bmp");
SDL_Surface * Sol = SDL_LoadBMP("feuilles.bmp");

static GLuint texId[4];

struct champi
{
	float x,z;
	int variete;

};
typedef struct champi champi;

champi tab[NBC];


static int pause = 0;
static int k_haut = 0, k_bas = 0, k_droite = 0, k_gauche = 0;
static float near = 1, far = 20, vitesse = 0, angle = 0, cam[6] = {0, 1, 0, 0, 1, 10};

int k = far*far;

void placeChampi() // Calcul des coordonees des champignons a placer
{
	int i;

	srand(time(NULL));

	for(i = 0; i < NBC; i++)
	{
	    tab[i].variete = (rand()%3) + 1;
		tab[i].x =  (rand()%(k + k) + 1) - k;
		tab[i].z = (rand()%(k + k) + 1) - k;
	}
}

static SDL_Surface * sdlInit(int w, int h)
{
    SDL_Surface * s;

    if ( SDL_Init(SDL_INIT_VIDEO) < 0 )
    {
        fprintf(stderr, "Impossible d'initialiser SDL: %s\n", SDL_GetError());
        exit(1);
    }

    s = SDL_SetVideoMode(w, h, 32, SDL_OPENGL);

    if (s == NULL )
    {
        fprintf(stderr, "Impossible d'ouvrir le mode video : %s\n", SDL_GetError());
        exit(1);
    }

    sdlInitGL(s);
    return s;
}

static void loadText() //Cahrgement des textures
{

    glGenTextures(4, texId);
    glBindTexture(GL_TEXTURE_2D, texId[0]);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, Sol->w, Sol->h, 0, GL_BGR, GL_UNSIGNED_BYTE, Sol->pixels);

    glEnable(GL_TEXTURE_2D);

    SDL_FreeSurface(Sol);

    glBindTexture(GL_TEXTURE_2D, texId[1]);

    glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, cepe->w, cepe->h, 0, GL_BGRA, GL_UNSIGNED_BYTE, cepe->pixels);

    glEnable(GL_TEXTURE_2D);

    SDL_FreeSurface(cepe);

    glBindTexture(GL_TEXTURE_2D, texId[2]);

    glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, satan->w, satan->h, 0, GL_BGRA, GL_UNSIGNED_BYTE, satan->pixels);

    glEnable(GL_TEXTURE_2D);

    SDL_FreeSurface(satan);

    glBindTexture(GL_TEXTURE_2D, texId[3]);

    glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, phal->w, phal->h, 0, GL_BGRA, GL_UNSIGNED_BYTE, phal->pixels);

    glEnable(GL_TEXTURE_2D);

    SDL_FreeSurface(phal);

}

static void sdlInitGL(SDL_Surface * s)
{
    glClearColor(0, 0, 1, 1);
    glAlphaFunc(GL_GREATER, 0.1);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_COLOR_MATERIAL);

    cam[5] = far*far;

    if(Sol == NULL)
    {
        fprintf(stderr, "Impossible d'ouvrir le fichier : %s\n", SDL_GetError());
        exit(1);
    }

    loadText();
    sdlPrintGL(s);
}

static void sdlPrintGL(SDL_Surface * s)
{
    glViewport(0, 0, s->w, s->h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(50.0, s->w / (float)s->h, near, far);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

static void sdlLoop(SDL_Surface * s)
{
    Uint32 dt;
    Uint32 t0 = 0;

    placeChampi();

    for(;;)
    {
        dt = SDL_GetTicks() - t0;
        t0 += dt;
        while(sdlManageEvents(s)) SDL_Delay(1);

        if(k_droite) angle -= M_PI * dt / 1000.0;
        else if(k_gauche) angle += M_PI * dt / 1000.0;

        if(k_haut) vitesse = far * dt / 1000.0;
        else if(k_bas)  vitesse = -far * dt / 1000.0;
        else vitesse = 0.0;

        cam[0] += vitesse * (0.2 * sin(angle));
        cam[2] += vitesse * (0.2 * cos(angle));

        cam[3] = cam[0] + far * (0.2 * sin(angle));
        cam[5] = cam[2] + far * (0.2 * cos(angle));

        sdlDraw(s);
    }
}

static int sdlManageEvents(SDL_Surface * s)
{
    static int active = 1;
    SDL_Event event;

  while(SDL_PollEvent(&event))
        switch (event.type)
        {
            case SDL_KEYDOWN:
            switch(event.key.keysym.sym)
            {
                case ' ':
                case 'p':
                pause = !pause;
                break;
                case SDLK_UP:
                k_haut = 1;
                break;
                case SDLK_DOWN:
                k_bas = 1;
                break;
                case SDLK_LEFT:
                k_gauche = 1;
                break;
                case SDLK_RIGHT:
                k_droite = 1;
                break;
                case 'a':
                exit(0);
                default:
                fprintf(stderr, "La touche %s a ete pressee\n",
                SDL_GetKeyName(event.key.keysym.sym));
                break;
            }
            break;
            case SDL_KEYUP:
            switch(event.key.keysym.sym)
            {
                case SDLK_UP:
                k_haut = 0;
                break;
                case SDLK_DOWN:
                k_bas = 0;
                break;
                case SDLK_LEFT:
                k_gauche = 0;
                break;
                case SDLK_RIGHT:
                k_droite = 0;
                break;
                default:
                break;
            }
            break;
            case SDL_ACTIVEEVENT:
            if(event.active.state & SDL_APPACTIVE)
            active = event.active.gain;
            break;
            case SDL_QUIT:
            exit(0);
        }
  return !active;
}


static void sdlDraw(SDL_Surface * s)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    gluLookAt(cam[0], cam[1], cam[2], cam[3], cam[4], cam[5], 0, 1, 0);
    sol();
    champignons();

    SDL_GL_SwapBuffers();
}

void sol() // Creation du sol et plaquage de la texture
{
    glBindTexture(GL_TEXTURE_2D, texId[0]);
    glBegin(GL_QUADS);

    glNormal3f(0, 1, 0);
    glColor3f(3, 3, 3);


    int l = k/4;

    glTexCoord2f(0, 0); glVertex3f(-k, 0, -k);
    glTexCoord2f(0, l); glVertex3f(-k, 0, k);
    glTexCoord2f(l, l); glVertex3f(k, 0, k);
    glTexCoord2f(l, 0); glVertex3f(k, 0, -k);

    glEnd();
}

void champignons() // Plaquage des champignons
{
    glEnable(GL_ALPHA_TEST);
	glAlphaFunc(GL_GREATER, 0.1);

    int i;
	for(i = 0; i < NBC; i++)
	{
		glBindTexture(GL_TEXTURE_2D, texId[tab[i].variete]);
		glBegin(GL_QUADS);

		glTexCoord2d(0, 1); glVertex3f(tab[i].x, -0.25, tab[i].z);
		glTexCoord2d(0, 0); glVertex3f(tab[i].x, 0.75, tab[i].z);
		glTexCoord2d(1, 0); glVertex3f(tab[i].x + 0.75, 0.75, tab[i].z);
		glTexCoord2d(1, 1); glVertex3f(tab[i].x + 0.75, -0.25, tab[i].z);

		glTexCoord2d(0, 1); glVertex3f(tab[i].x + 0.5, -0.25, tab[i].z -0.5);
		glTexCoord2d(0, 0); glVertex3f(tab[i].x + 0.5, 0.75, tab[i].z - 0.5);
		glTexCoord2d(1, 0); glVertex3f(tab[i].x + 0.25, 0.75, tab[i].z + 0.5);
		glTexCoord2d(1, 1); glVertex3f(tab[i].x + 0.25, -0.25, tab[i].z + 0.5);

		glEnd();
	}

	glDisable(GL_ALPHA_TEST);
}


int main(int argc, char ** argv)
{
    SDL_Surface * s;
    s = sdlInit(500, 500);
    sdlLoop(s);
    return 0;
}

Dernière modification par z999 (Le 17/09/2014, à 12:25)

Hors ligne

#2 Le 14/10/2013, à 11:42

Clémentv

Re : [Résolu] OpenGL en C

SDL_Surface * cepe = SDL_LoadBMP("cepe.bmp");

Tu initialises une variable globale avec le résultat d'une fonction : ce n'est pas un constante. Toutes les versions du C n'autorisent pas ça. Il me semble que C99 (option -std=c99) l'autorise.

N'oublie pas que tu n'as aucune garantie sur l'ordre dans lequel ces variables sont initialisées (et donc l'ordre dans lequel les fonctions sont appelées). Le plus sûr reste de les initialiser dans le main.

int k = far*far;

Pareil far n'est pas une constante, donc son carré non plus. N'hésite pas à ajouter l'attribut const dans les déclarations de variables dès que c'est possible.

Dernière modification par Clémentv (Le 14/10/2013, à 11:54)

Hors ligne

#3 Le 14/10/2013, à 12:26

z999

Re : [Résolu] OpenGL en C

ah ok ! Donc si je comprend bien je deplace tout mes :

static SDL_Surface * sdlInit(int w, int h);
SDL_Surface * cepe = SDL_LoadBMP("cepe.bmp");
SDL_Surface * phal = SDL_LoadBMP("phalloide.bmp");
SDL_Surface * satan = SDL_LoadBMP("satan.bmp");
SDL_Surface * Sol = SDL_LoadBMP("feuilles.bmp");

dans mon main ? et a la place de :

int k = far*far 

par

const k = far*far 

Désoler si mes question sont bête mais je n'ai jamais coder c'est la première fois

Hors ligne

#4 Le 14/10/2013, à 13:07

Clémentv

Re : [Résolu] OpenGL en C

Tu peux déclarer les variables globalement mais les initialiser dans la fonction main. Si tu les déclares dans le main, tu devras les passer en paramètres aux fonctions qui en ont besoin.

Pour le const je pensais à far. Si far est une constante (c'est à toi de voir), tu ajoutes const dans son type. Pas seul, c'est en plus du type primitif, par exemple

static const float far = 0.0f;

Si ce n'est pas une constante la solution est la même qu'avec les fonctions, déplace l'initialisation dans le main, dans ta fonction d'initialisation, là où tu préfères tant que c'est avant de l'utiliser.

Le C99 réglerait ces erreurs de compilation mais si tu es un débutant, je te le déconseille. Le C99 est plus permissif mais peut mener à des bugs plus difficiles à comprendre.

Dernière modification par Clémentv (Le 14/10/2013, à 13:08)

Hors ligne

#5 Le 14/10/2013, à 15:14

z999

Re : [Résolu] OpenGL en C

désoler mais j'ai pas compris lol

Hors ligne