Ver Mensaje Individual
  #1 (permalink)  
Antiguo 20/01/2013, 03:27
TitoFlecks
 
Fecha de Ingreso: enero-2012
Mensajes: 87
Antigüedad: 12 años, 3 meses
Puntos: 1
Trazador de rayos, acceso a memoria

Hola gente.

Veréis, tengo un problema bastante frustrante. He desarrollado un trazador de rayos al que le he aplicado antialiasing (enviando 5 rayos por píxel) utilizando openGL y librerías mías.

He ejecutado la aplicación en un win7 de 32 bits y funciona perfectamente, pero en uno de 64 me hace mal el antialiasing y asumo que es porque se accede de manera distinta a la memoria.

El código del trazador principal y donde se da la anomalía es el siguiente:


Cita:
int i=0, j, fsa, dfgd;
Color color;
double x1, y1, a, b, xb, xa, ya, yb;
unsigned char *t;
float p_ancho, p_alto;

//Si es la primera vez, o hay que redibujar la escena...
if (raster==NULL) {
raster=(unsigned char *)malloc(sizeof(unsigned char)*3*ancho*alto);
if (raster==NULL) {
fprintf(stderr, "Sin memoria\n");
exit(-1);
}
}
if (p_bajo==NULL) {
p_bajo=(float *)malloc(sizeof(float)*3*(ancho+1));
if (p_bajo==NULL) {
fprintf(stderr, "Sin memoria\n");
exit(-1);
}
}
if (p_central==NULL) {
p_central=(float *)malloc(sizeof(float)*3*ancho);
if (p_central==NULL) {
fprintf(stderr, "Sin memoria\n");
exit(-1);
}
}
if (p_arriba==NULL) {
p_arriba=(float *)malloc(sizeof(float)*3*(ancho+1));
if (p_arriba==NULL) {
fprintf(stderr, "Sin memoria\n");
exit(-1);
}
}


b = get_B(pos_z, fov);
a = AspectRatio * b;
t = raster;//t es el primer valor del vector


//Con antialiasing
if(escena->AntialiasingOn == 1){

p_ancho = a/ancho;
p_alto = b/alto;

for(j=0; j < alto; j++) {

y1 = get_Y(b, alto, j);

if(i == ancho){

for(int ar=0; ar < ancho; ar++){
//rojo
*t++ = (unsigned char)(p_central[3*ar] + p_bajo[3*ar] + p_bajo[3*ar+3] + p_arriba[3*ar] + p_arriba[3*ar+3]);
//verde
*t++ =(unsigned char) (p_central[3*ar+1] + p_bajo[3*ar+1] + p_bajo[3*ar+4] + p_arriba[3*ar+1] + p_arriba[3*ar+4]);
//azul
*t++= (unsigned char)(p_central[3*ar+2] + p_bajo[3*ar+2] + p_bajo[3*ar+5] + p_arriba[3*ar+2] + p_arriba[3*ar+5]);


}

//Copiamos el vector p_arriba a p_bajo
for (int c = 0; c < 3*(ancho+1); c++){
p_bajo[c]=p_arriba[c];
}
}

for (i=0; i < ancho; i++){

x1 = get_X(a, ancho, i);
dir = Vector(x1, y1, -pos_z);
dir = dir.unitary();
xa = get_Xa(a, ancho, i);
ya = get_Ya(a, ancho, j);
xb = get_Xb(a, ancho, i);
yb = get_Yb(a, ancho, j);

//Primer punto
if(i == 0){
dirA = Vector(xb, ya, -pos_z);
dirA = dirA.unitary();
color = escena->rayTrace(Punto(0.0, 0.0, pos_z), dirA,0);

// 1/8 //
p_arriba[0] = (color.r()*255*0.125);
p_arriba[1] = (color.g()*255*0.125);
p_arriba[2] = (color.b()*255*0.125);

//Primer punto, primera fila.
if(j == 0){

dirB = Vector(xb, yb, -pos_z);
dirB = dirB.unitary();
color = escena->rayTrace(Punto(0.0, 0.0, pos_z), dirB,0);

// 1/8 //
p_bajo[0]=(color.r()*255*0.125);
p_bajo[1]=(color.g()*255*0.125);
p_bajo[2]=(color.b()*255*0.125);
}

}

//Lanzamos rayos para los demás puntos. Si es la fila 0, leemos los valores inferiores una vez.
if(j == 0){

dirB = Vector(xa, yb, -pos_z);
dirB = dirB.unitary();
color = escena->rayTrace(Punto(0.0, 0.0, pos_z), dirB,0);

// 1/8 //
p_bajo[3*i+3]=(color.r()*255*0.125);
p_bajo[3*i+4]=(color.g()*255*0.125);
p_bajo[3*i+5]=(color.b()*255*0.125);
}

dirA = Vector(xa, ya, -pos_z);
dirA = dirA.unitary();
color=escena->rayTrace(Punto(0.0, 0.0, pos_z), dirA,0);

// 1/8 //
p_arriba[3*i+3]=(color.r()*255*0.125);
p_arriba[3*i+4]=(color.g()*255*0.125);
p_arriba[3*i+5]=(color.b()*255*0.125);

color=escena->rayTrace(Punto(0.0, 0.0, pos_z), dir,0);

// 1/2 //
p_central[3*i]=(color.r()*255*0.5);
p_central[3*i+1]=(color.g()*255*0.5);
p_central[3*i+2]=(color.b()*255*0.5);


}
}
}
else if(escena->AntialiasingOn == 0){ //Sin antialiasing

for (j=0; j < alto; j++) {

y1 = get_Y(b, alto, j);
for (i=0; i < ancho; i++){
x1 = get_X(a, ancho, i);
dir = Vector(x1, y1, -pos_z);
dir = dir.unitary();

color=escena->rayTrace(Punto(0.0, 0.0, pos_z), dir,0);

*t++=(unsigned char)(color.r()*255);
*t++=(unsigned char)(color.g()*255);
*t++=(unsigned char)(color.b()*255);
}
}
}

sucio=0;
}

Podéis observar que hay un trozo dedicado al sobremuestreo (con antialiasing) y otro que no.

Imagino que el problema está el trozo en negrita, donde reservo memoria usando malloc. Lo que ocurre al ejecutarlo en un sist. operativo de 64 es que la imagen me aparece dividida, cosa que no ocurre en uno de 32

¿Tengo alguna alternativa para hacerlo funcionar en 64 bits?

Gracias