Historique des modifications - Message

Message #11618

Sujet: Interfacer du C avec du C++


Type Date Auteur Contenu
Dernière modification 14-05-2015 18:57:37 ovni007
Bonsoir,

J'ai trouvé un code de perlin noise qui génère une heightmap, mais écrit en C et qui utilise la SDL.
J'aimerais l'ajouter à mon code C++ et ouvrir la heightmap avec les fonctions d'Irrlicht qui gèrent cela.
Je pense avoir compris comment interfacer, tout est bien linker, mais mon problème se situe au niveau de la fonction "enregistrer_bmp(..)" (perlin.c),
à la compilation Code::Blocks m'annonce 7 erreur de type "dereferencing pointer to incomplete type" sur les lignes contenant "c->taille".

Lorsque je compile le code dans un projet à part uniquement en C, aucun problème ...

Quelqu'un pourrait-il m'expliquer ce qui ne va pas ? Comment puis-je régler ça ?

D'avance, merci !

(Désolé pour la longueur du post ... )


main.cpp

Code c++ :


#include <time.h>
#include <irrlicht.h>
#include "global.h"
#include "perlin.h"
#include "perlin_calque.h"

int perlinNoise()
{
    srand((int)time(NULL));

    // valeurs d'entrée
	int octaves=3;
	int frequence=4;
	float persistence=.5;
    int taille_de_sortie=200;
    int lissage = 3;

    // création de calque
    struct calque *s;

    // initialisation du calque
    s=init_calque(taille_de_sortie,1);
    if (!s)
        return 1;

    generer_calque(frequence,
                   octaves,
                   persistence,
                   lissage,
                   s);

    enregistrer_bmp(s, "data/resultat.bmp");

	return 0;
}

...

int main(int argc, char** argv)
{
    init();
    perlinNoise();


    smgr->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0));
    while(device->run())
    {
        driver->beginScene(true, true, SColor(0,200,200,200));
        smgr->drawAll();
        driver->endScene();
    }
    device->drop();
    return 0;
}


perlin.h

Code c++ :


#ifndef __perlin_h__
#define __perlin_h__

#include <SDL/SDL.h>
#ifdef __cplusplus

extern "C" { // la ligne est 'extern "C" { ' je ne comprend pas pourquoi, mais la ligne change toute seule quand je veux poster Oo


//int perlinNoise();
void colorerPixel(SDL_Surface*, int, int, Uint32);
unsigned char aleatoire(float);
void enregistrer_bmp(struct calque *, const char *);
#ifdef __cplusplus
}
#endif
#endif
#endif 


perlin.c

Code c++ :


#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <SDL/SDL.h>

#include "perlin_calque.h"
#include "perlin.h"



void colorerPixel(SDL_Surface* s, int x, int y, Uint32 coul){
    *((Uint32*)(s->pixels) + x + y * s->w) = coul;
}

// fourni une valeur entre 0 et a
unsigned char aleatoire(float a){
    return (float)rand() / RAND_MAX * a;
}


void enregistrer_bmp(struct calque *c, const char *filename){

    SDL_Surface *s = SDL_CreateRGBSurface(SDL_SWSURFACE,c->taille, c->taille, 32,0, 0, 0, 0);
    if (!s)
        printf("erreur SDL sur SDL_CreateRGBSurface");

    int i,j;
    Uint32 u;
    SDL_PixelFormat *fmt = s->format;
    for (i=0; i<c->taille; i++)
        for (j=0; j<c->taille; j++){
            u = SDL_MapRGB  (fmt, (char)c->v[i][j], (char)c->v[i][j], (char)c->v[i][j]);
            colorerPixel(s, i, j, u);
        }

    SDL_SaveBMP(s, filename);
    SDL_FreeSurface(s);
}



// end of file




perlin_calque.h

Code c++ :


#ifndef __perlin_calque_h__
#define __perlin_calque_h__

#ifdef __cplusplus
extern "C" { // la ligne est 'extern "C" { ' je ne comprend pas pourquoi, mais la ligne change toute seule quand je veux poster Oo

struct calque{
    int **v;
    int taille;
    float persistance;
};

struct calque* init_calque(int, float);
void free_calque(struct calque*);
void generer_calque(int, int, float, int, struct calque*);
int interpolate(int, int, int, int);
int valeur_interpolee(int, int, int, struct calque*);


#ifdef __cplusplus
}
#endif
#endif
#endif /* CODEC_H_ */



perlin_calque.c

Code c++ :


#include "calque.h"
#include "main.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

struct calque* init_calque(int t, float p){
    struct calque *s = malloc(sizeof(struct calque));
    if(!s){
        printf("erreur d'alloc");
        return NULL;
    }

    s->v = malloc(t*sizeof(int*));
    if(!s->v){
        printf("erreur d'alloc");
        return NULL;
    }
    int i,j;
    for (i=0; i<t ; i++){
        s->v[i]= malloc(t*sizeof(int));
        if(!s->v[i]) {
            printf("erreur d'alloc");
            return NULL;
        }
        for (j=0; j<t; j++)
            s->v[i][j]=0;
    }
    s->taille = t;
    s->persistance = p;

    return s;
}

void free_calque(struct calque* s){
    int j;
    for (j=0; j<s->taille; j++)
        free(s->v[j]);
    free(s->v);
}

void generer_calque(int frequence,
                    int octaves,
                    float persistance,
                    int liss,
                    struct calque *c){
    // itératif
    int taille = c->taille;
    int i,j,n,f_courante;
    int x,y,k,l;
    int a;
    float pas, sum_persistances;

    pas = (float)(taille)/frequence;
    float persistance_courante = persistance;

    // calque aléatoire
    struct calque *random;
    random = init_calque(taille,1);
    if (!random)
        return;

    for (i=0; i<taille; i++)
        for (j=0; j<taille; j++)
            random->v[i][j]=aleatoire(256);

    enregistrer_bmp(random, "alea.bmp");

    // calques de travail
    struct calque **mes_calques = malloc(octaves*sizeof(struct calque*));
    for (i=0; i<octaves; i++){
        mes_calques[i] = init_calque(taille,persistance_courante);
        if (!mes_calques[i])
            return;
        persistance_courante*=persistance;
    }

    f_courante = frequence;

    // remplissage de calque
    for (n=0; n<octaves; n++){
        for(i=0; i<taille; i++)
            for(j=0; j<taille; j++) {
                a = valeur_interpolee(i, j, f_courante, random);
                mes_calques[n]->v[i][j]=a;
            }
        f_courante*=frequence;
    }

    sum_persistances = 0;
    for (i=0; i<octaves; i++)
        sum_persistances+=mes_calques[i]->persistance;

    // ajout des calques successifs
    for (i=0; i<taille; i++)
        for (j=0; j<taille; j++){
            for (n=0; n<octaves; n++)
                c->v[i][j]+=mes_calques[n]->v[i][j]*mes_calques[n]->persistance;

            // normalisation
            c->v[i][j] =  c->v[i][j] / sum_persistances;
        }


    // lissage
    struct calque *lissage;
    lissage = init_calque(taille, 0);
    if(!lissage)
        return;

    for (x=0; x<taille; x++)
        for (y=0; y<taille; y++){
            a=0;
            n=0;
            for (k=x-liss; k<=x+liss; k++)
                for (l=y-liss; l<=y+liss; l++)
                    if ((k>=0) && (k<taille) && (l>=0) && (l<taille)) {
                        n++;
                        a+=c->v[k][l];
                    }
            lissage->v[x][y] = (float)a/n;
        }

    enregistrer_bmp(lissage, "lisse.bmp");


    // libération mémoire
    free_calque(random);
    free_calque(lissage);
    for (i=0; i<octaves; i++)
        free_calque(mes_calques[i]);
    free(mes_calques);
}

int interpolate(int y1, int y2, int n, int delta){

    // interpolation non linéaire
    if (n==0)
        return y1;
    if (n==1)
        return y2;

    float a = (float)delta/n;

    float fac1 = 3*pow(1-a, 2) - 2*pow(1-a,3);
    float fac2 = 3*pow(a, 2) - 2*pow(a, 3);

    return y1*fac1 + y2*fac2;

	//////////////////////////////////////////////

    // interpolation linéaire
    /*if (n!=0)
        return y1+delta*((float)y2-(float)y1)/(float)n;
    else
        return y1;*/
}


int valeur_interpolee(int i, int j, int frequence, struct calque *r){
    // valeurs des bornes
    int borne1x, borne1y, borne2x, borne2y, q;
    float pas;
    pas = (float)r->taille/frequence;

    q = (float)i/pas;
    borne1x = q*pas;
    borne2x = (q+1)*pas;

    if(borne2x >= r->taille)
        borne2x = r->taille-1;

    q = (float)j/pas;
    borne1y = q*pas;
    borne2y = (q+1)*pas;

    if(borne2y >= r->taille)
        borne2y = r->taille-1;

    int b00,b01,b10,b11;
    b00 = r->v[borne1x][borne1y];
    b01 = r->v[borne1x][borne2y];
    b10 = r->v[borne2x][borne1y];
    b11 = r->v[borne2x][borne2y];

    int v1 = interpolate(b00, b01, borne2y-borne1y, j-borne1y);
    int v2 = interpolate(b10, b11, borne2y-borne1y, j-borne1y);
    int fin = interpolate(v1, v2, borne2x-borne1x , i-borne1x);

    return fin;
}
Création du message 14-05-2015 18:47:17 ovni007
Bonsoir,

J'ai trouvé un code de perlin noise qui génère une heightmap, mais écrit en C et qui utilise la SDL.
J'aimerais l'ajouter à mon code C++ et ouvrir la heightmap avec les fonctions d'Irrlicht qui gèrent cela.
Je pense avoir compris comment interfacer, tout est bien linker, mais mon problème se situe au niveau de la fonction "enregistrer_bmp(..)" (perlin.c),
à la compilation Code::Blocks m'annonce 7 erreur de type "dereferencing pointer to incomplete type" sur les lignes contenant "c->taille".

Lorsque je compile le code dans un projet à part uniquement en C, aucun problème ...

Quelqu'un pourrait-il m'expliquer ce qui ne va pas ? Comment puis-je régler ça ?

D'avance, merci !

(Désolé pour la longueur du post ... )


main.cpp

Code c++ :


#include <time.h>
#include <irrlicht.h>
#include "global.h"
#include "perlin.h"
#include "perlin_calque.h"

int perlinNoise()
{
    srand((int)time(NULL));

    // valeurs d'entrée
	int octaves=3;
	int frequence=4;
	float persistence=.5;
    int taille_de_sortie=200;
    int lissage = 3;

    // création de calque
    struct calque *s;

    // initialisation du calque
    s=init_calque(taille_de_sortie,1);
    if (!s)
        return 1;

    generer_calque(frequence,
                   octaves,
                   persistence,
                   lissage,
                   s);

    enregistrer_bmp(s, "data/resultat.bmp");

	return 0;
}

...

int main(int argc, char** argv)
{
    init();
    perlinNoise();


    smgr->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0));
    while(device->run())
    {
        driver->beginScene(true, true, SColor(0,200,200,200));
        smgr->drawAll();
        driver->endScene();
    }
    device->drop();
    return 0;
}


perlin.h

Code c++ :


#ifndef __perlin_h__
#define __perlin_h__

#include <SDL/SDL.h>
#ifdef __cplusplus

extern "C" { // la ligne est 'extern "C" { ' je ne comprend pas pourquoi, mais la ligne change toute seule quand je veux poster Oo


//int perlinNoise();
void colorerPixel(SDL_Surface*, int, int, Uint32);
unsigned char aleatoire(float);
void enregistrer_bmp(struct calque *, const char *);
#ifdef __cplusplus
}
#endif
#endif
#endif 


perlin.c

Code c++ :


#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <SDL/SDL.h>

#include "perlin_calque.h"
#include "perlin.h"



void colorerPixel(SDL_Surface* s, int x, int y, Uint32 coul){
    *((Uint32*)(s->pixels) + x + y * s->w) = coul;
}

// fourni une valeur entre 0 et a
unsigned char aleatoire(float a){
    return (float)rand() / RAND_MAX * a;
}


void enregistrer_bmp(struct calque *c, const char *filename){

    SDL_Surface *s = SDL_CreateRGBSurface(SDL_SWSURFACE,c->taille, c->taille, 32,0, 0, 0, 0);
    if (!s)
        printf("erreur SDL sur SDL_CreateRGBSurface");

    int i,j;
    Uint32 u;
    SDL_PixelFormat *fmt = s->format;
    for (i=0; i<c->taille; i++)
        for (j=0; j<c->taille; j++){
            u = SDL_MapRGB  (fmt, (char)c->v[i][j], (char)c->v[i][j], (char)c->v[i][j]);
            colorerPixel(s, i, j, u);
        }

    SDL_SaveBMP(s, filename);
    SDL_FreeSurface(s);
}



// end of file




perlin_calque.h

Code c++ :


#ifndef __perlin_calque_h__
#define __perlin_calque_h__

#ifdef __cplusplus
extern "C" { // la ligne est 'extern "C" { ' je ne comprend pas pourquoi, mais la ligne change toute seule quand je veux poster Oo

struct calque{
    int **v;
    int taille;
    float persistance;
};

struct calque* init_calque(int, float);
void free_calque(struct calque*);
void generer_calque(int, int, float, int, struct calque*);
int interpolate(int, int, int, int);
int valeur_interpolee(int, int, int, struct calque*);


#ifdef __cplusplus
}
#endif
#endif
#endif /* CODEC_H_ */



perlin_calque.c

Code c++ :


#include "calque.h"
#include "main.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

struct calque* init_calque(int t, float p){
    struct calque *s = malloc(sizeof(struct calque));
    if(!s){
        printf("erreur d'alloc");
        return NULL;
    }

    s->v = malloc(t*sizeof(int*));
    if(!s->v){
        printf("erreur d'alloc");
        return NULL;
    }
    int i,j;
    for (i=0; i<t ; i++){
        s->v[i]= malloc(t*sizeof(int));
        if(!s->v[i]) {
            printf("erreur d'alloc");
            return NULL;
        }
        for (j=0; j<t; j++)
            s->v[i][j]=0;
    }
    s->taille = t;
    s->persistance = p;

    return s;
}

void free_calque(struct calque* s){
    int j;
    for (j=0; j<s->taille; j++)
        free(s->v[j]);
    free(s->v);
}

void generer_calque(int frequence,
                    int octaves,
                    float persistance,
                    int liss,
                    struct calque *c){
    // itératif
    int taille = c->taille;
    int i,j,n,f_courante;
    int x,y,k,l;
    int a;
    float pas, sum_persistances;

    pas = (float)(taille)/frequence;
    float persistance_courante = persistance;

    // calque aléatoire
    struct calque *random;
    random = init_calque(taille,1);
    if (!random)
        return;

    for (i=0; i<taille; i++)
        for (j=0; j<taille; j++)
            random->v[i][j]=aleatoire(256);

    enregistrer_bmp(random, "alea.bmp");

    // calques de travail
    struct calque **mes_calques = malloc(octaves*sizeof(struct calque*));
    for (i=0; i<octaves; i++){
        mes_calques[i] = init_calque(taille,persistance_courante);
        if (!mes_calques[i])
            return;
        persistance_courante*=persistance;
    }

    f_courante = frequence;

    // remplissage de calque
    for (n=0; n<octaves; n++){
        for(i=0; i<taille; i++)
            for(j=0; j<taille; j++) {
                a = valeur_interpolee(i, j, f_courante, random);
                mes_calques[n]->v[i][j]=a;
            }
        f_courante*=frequence;
    }

    sum_persistances = 0;
    for (i=0; i<octaves; i++)
        sum_persistances+=mes_calques[i]->persistance;

    // ajout des calques successifs
    for (i=0; i<taille; i++)
        for (j=0; j<taille; j++){
            for (n=0; n<octaves; n++)
                c->v[i][j]+=mes_calques[n]->v[i][j]*mes_calques[n]->persistance;

            // normalisation
            c->v[i][j] =  c->v[i][j] / sum_persistances;
        }


    // lissage
    struct calque *lissage;
    lissage = init_calque(taille, 0);
    if(!lissage)
        return;

    for (x=0; x<taille; x++)
        for (y=0; y<taille; y++){
            a=0;
            n=0;
            for (k=x-liss; k<=x+liss; k++)
                for (l=y-liss; l<=y+liss; l++)
                    if ((k>=0) && (k<taille) && (l>=0) && (l<taille)) {
                        n++;
                        a+=c->v[k][l];
                    }
            lissage->v[x][y] = (float)a/n;
        }

    enregistrer_bmp(lissage, "lisse.bmp");


    // libération mémoire
    free_calque(random);
    free_calque(lissage);
    for (i=0; i<octaves; i++)
        free_calque(mes_calques[i]);
    free(mes_calques);
}

int interpolate(int y1, int y2, int n, int delta){

    // interpolation non linéaire
    if (n==0)
        return y1;
    if (n==1)
        return y2;

    float a = (float)delta/n;

    float fac1 = 3*pow(1-a, 2) - 2*pow(1-a,3);
    float fac2 = 3*pow(a, 2) - 2*pow(a, 3);

    return y1*fac1 + y2*fac2;

	//////////////////////////////////////////////

    // interpolation linéaire
    /*if (n!=0)
        return y1+delta*((float)y2-(float)y1)/(float)n;
    else
        return y1;*/
}


int valeur_interpolee(int i, int j, int frequence, struct calque *r){
    // valeurs des bornes
    int borne1x, borne1y, borne2x, borne2y, q;
    float pas;
    pas = (float)r->taille/frequence;

    q = (float)i/pas;
    borne1x = q*pas;
    borne2x = (q+1)*pas;

    if(borne2x >= r->taille)
        borne2x = r->taille-1;

    q = (float)j/pas;
    borne1y = q*pas;
    borne2y = (q+1)*pas;

    if(borne2y >= r->taille)
        borne2y = r->taille-1;

    int b00,b01,b10,b11;
    b00 = r->v[borne1x][borne1y];
    b01 = r->v[borne1x][borne2y];
    b10 = r->v[borne2x][borne1y];
    b11 = r->v[borne2x][borne2y];

    int v1 = interpolate(b00, b01, borne2y-borne1y, j-borne1y);
    int v2 = interpolate(b10, b11, borne2y-borne1y, j-borne1y);
    int fin = interpolate(v1, v2, borne2x-borne1x , i-borne1x);

    return fin;
}

Retour

Options Liens officiels Caractéristiques Statistiques Communauté
Préférences cookies
Corrections
irrlicht
irrklang
irredit
irrxml
Propulsé par Django
xhtml 1.0
css 2.1
884 membres
1440 sujets
11337 messages
Dernier membre inscrit: Saidov17
231 invités en ligne
membre en ligne: -
RSS Feed