/* File: fslutil.c * * Copyright 09 Freescale Semiconductor */ #define GL_FUNCS 1 //#ifdef GL_FUNCS #include #include //#include //#endif #include #include #include int ImageLoad(char *filename, Image *image) { FILE *file; unsigned long size; // size of the image in bytes. unsigned long i; // standard counter. unsigned short int planes; // number of planes in image (must be 1) unsigned short int bpp; // number of bits per pixel (must be 24) char temp; // temporary color storage for bgr-rgb conversion. // make sure the file is there. if ((file = fopen(filename, "rb"))==NULL) { printf("File Not Found : %s\n",filename); return 0; } // seek through the bmp header, up to the width/height: fseek(file, 18, SEEK_CUR); // read the width if ((i = fread(&image->sizeX, 4, 1, file)) != 1) { printf("Error reading width from %s.\n", filename); return 0; } //printf("Width of %s: %lu\n", filename, image->sizeX); // read the height if ((i = fread(&image->sizeY, 4, 1, file)) != 1) { printf("Error reading height from %s.\n", filename); return 0; } //printf("Height of %s: %lu\n", filename, image->sizeY); // calculate the size (assuming 24 bits or 3 bytes per pixel). size = image->sizeX * image->sizeY * 3; //printf("size is %lu\n",size); // read the planes if ((fread(&planes, 2, 1, file)) != 1) { printf("Error reading planes from %s.\n", filename); return 0; } if (planes != 1) { printf("Planes from %s is not 1: %u\n", filename, planes); return 0; } // read the bpp if ((i = fread(&bpp, 2, 1, file)) != 1) { printf("Error reading bpp from %s.\n", filename); return 0; } if (bpp != 24) { printf("Bpp from %s is not 24: %u\n", filename, bpp); return 0; } // seek past the rest of the bitmap header. fseek(file, 24, SEEK_CUR); // read the data. image->data = (char *) malloc(size); if (image->data == NULL) { printf("Error allocating memory for color-corrected image data"); return 0; } if ((i = fread(image->data, size, 1, file)) != 1) { printf("Error reading image data from %s.\n", filename); return 0; } for (i=0;i rgb) temp = image->data[i]; image->data[i] = image->data[i+2]; image->data[i+2] = temp; } // we're done. return 1; } //-------------------------------------------------------------------------------------- // Name: fslLoadCTES // Desc: Helper function to load an compressed image file (ATC, ETC, etc.) from the compressenator // At exit nFormat contains the GL //-------------------------------------------------------------------------------------- char* fslLoadCTES( char* strFileName, unsigned int* pWidth, unsigned int* pHeight, unsigned int* nFormat, unsigned int* nSize ) { unsigned int nTotalBlocks, nBytesPerBlock, nHasAlpha; char* pBits8; struct CTES_HEADER { unsigned int signature; unsigned int width; unsigned int height; unsigned int flags; unsigned int dataOffset; // From start of header/file } header; // Read the file FILE* file = fopen( strFileName, "rb" ); if( NULL == file ) { printf("Error loading file: %s \n",strFileName); return NULL; } if (fread( &header, sizeof(header), 1, file ) != 1) { printf("Error loading file : %s \n",strFileName); fclose( file ); return NULL; } nTotalBlocks = ((header.width + 3) >> 2) * ((header.height + 3) >> 2); nHasAlpha = header.flags & ATC_RGBA; nBytesPerBlock = (nHasAlpha) ? 16 : 8; (*nSize) = nTotalBlocks * nBytesPerBlock; (*pWidth) = header.width; (*pHeight) = header.height; switch (header.signature) { case ATC_SIGNATURE: if(nHasAlpha && (header.flags & ATC_ALPHA_INTERPOLATED)) (*nFormat) = GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD; else if(nHasAlpha) (*nFormat) = GL_ATC_RGBA_EXPLICIT_ALPHA_AMD; else (*nFormat) = GL_ATC_RGB_AMD; break; case ATI1N_SIGNATURE: (*nFormat) = GL_3DC_X_AMD; break; case ATI2N_SIGNATURE: (*nFormat) = GL_3DC_XY_AMD; break; case ETC_SIGNATURE: if(nHasAlpha) { printf("Unsupported texture format\n"); return NULL; } (*nFormat) = GL_ETC1_RGB8_OES; break; default: printf("Unsupported texture format\n"); return NULL; break; } pBits8 = (char*)malloc(sizeof(char) * (*nSize)); // Read the encoded image fseek(file, header.dataOffset, SEEK_SET); if (fread(pBits8, *nSize, 1, file) != 1) { printf("Error loading file : %s \n",strFileName); fclose( file ); free( pBits8 ); return NULL; } fclose( file ); return pBits8; } fslBool fslUnProject(float winx,float winy, float winz, float modelMatrix[16], float projMatrix[16], int viewport[4], float *objx, float *objy, float *objz) { float finalMatrix[16]; float finalMatrixTmp[16]; float in[4]; float out[4]; //printf("multiplying ModelMatrix \n"); //fslPrintMatrix4x4(modelMatrix); //printf("by ProjMatrix \n"); //fslPrintMatrix4x4(projMatrix); fslMultMatrix4x4(finalMatrixTmp,modelMatrix,projMatrix); //printf("result is \n"); //fslPrintMatrix4x4(finalMatrix); if(!fslInvertMatrix4x4( finalMatrixTmp, finalMatrix)) { printf("error inverting matrix \n"); return FSL_FALSE; } in[0]=winx; in[1]=winy; in[2]=winz; in[3]=1.0; //map x and y from coordinates in[0]=(in[0]-viewport[0])/ viewport[2]; in[1]=(in[1]-viewport[1])/ viewport[3]; //map range to -1 to 1 in[0]= in[0]*2-1; in[1]= in[1]*2-1; in[2]= in[2]*2-1; //printf("in: %f %f %f \n",in[0],in[1],in[2]); fslMultMatrix4x4Vec4x1 ( finalMatrix, in, out ); if(out[3]== 0.0) return FSL_FALSE; out[0] /=out[3]; out[1] /=out[3]; out[2] /=out[3]; *objx = out[0]; *objy = out[1]; *objz = out[2]; return FSL_TRUE; } //-------------------------------------------------------------------------------------- // Name: fslEGLCheck // Desc: Helper function to print EGL errors and exits application //-------------------------------------------------------------------------------------- fslBool fslEGLCheck( fslBool bExitOnFailure) { EGLint eglerr = eglGetError(); if(eglerr != EGL_SUCCESS) { switch(eglerr){ case EGL_NOT_INITIALIZED: fprintf(stdout, "EGL Fail = EGL_NOT_INITIALIZED (0x%x) \n", eglerr); break; case EGL_BAD_ACCESS: fprintf(stdout, "EGL Fail = EGL_BAD_ACCESS (0x%x) \n", eglerr); break; case EGL_BAD_ALLOC: fprintf(stdout, "EGL Fail = EGL_BAD_ALLOC (0x%x) \n", eglerr); break; case EGL_BAD_ATTRIBUTE: fprintf(stdout, "EGL Fail = EGL_BAD_ATTRIBUTE(0x%x) \n", eglerr); break; case EGL_BAD_CONFIG: fprintf(stdout, "EGL Fail = EGL_BAD_CONFIG (0x%x) \n", eglerr); break; case EGL_BAD_CONTEXT: fprintf(stdout, "EGL Fail = EGL_BAD_CONTEXT (0x%x) \n", eglerr); break; case EGL_BAD_CURRENT_SURFACE: fprintf(stdout, "EGL Fail = EGL_BAD_CURRENT_SURFACE (0x%x) \n", eglerr); break; case EGL_BAD_DISPLAY: fprintf(stdout, "EGL Fail = EGL_BAD_DISPLAY (0x%x) \n", eglerr); break; case EGL_BAD_MATCH: fprintf(stdout, "EGL Fail = EGL_BAD_MATCH (0x%x) \n", eglerr); break; case EGL_BAD_NATIVE_PIXMAP: fprintf(stdout, "EGL Fail = EGL_BAD_NATIVE_PIXMAP (0x%x) \n", eglerr); break; case EGL_BAD_NATIVE_WINDOW: fprintf(stdout, "EGL Fail = EGL_BAD_NATIVE_WINDOW (0x%x) \n", eglerr); break; case EGL_BAD_PARAMETER: fprintf(stdout, "EGL Fail = EGL_BAD_PARAMETER (0x%x) \n", eglerr); break; case EGL_BAD_SURFACE: fprintf(stdout, "EGL Fail = EGL_BAD_SURFACE (0x%x) \n", eglerr); break; case EGL_CONTEXT_LOST: fprintf(stdout, "EGL Fail = EGL_CONTEXT_LOST (0x%x) \n", eglerr); break; default: fprintf(stdout, "EGL Fail = 0x%x \n", eglerr); } if (bExitOnFailure) exit(EXIT_FAILURE); else return FSL_FALSE; } return FSL_TRUE; } #ifdef GL_FUNCS fslBool fslInit2DBMPTextureGL(char* strFileName, GLuint *pTextureHandle){ Image *image1; // allocate space for texture we will use image1 = (Image *) malloc(sizeof(Image)); if (image1 == NULL) { printf("Error allocating space for image"); exit(0); } if (!ImageLoad(strFileName, image1)) { exit(1); } glGenTextures( 1, pTextureHandle ); glBindTexture( GL_TEXTURE_2D, *pTextureHandle ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,image1->sizeX,image1->sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,image1->data); free(image1); return FSL_TRUE; } //-------------------------------------------------------------------------------------- // Name: fslInit2DCTESTextureGL // Desc: Helper function to load a CTES texture file and bind it to a given GL texture handle //-------------------------------------------------------------------------------------- fslBool fslInit2DCTESTextureGL( char* strFileName, GLuint *pTextureHandle ) { unsigned int nWidth, nHeight, nFormat, nSize; char* pImageData = fslLoadCTES( strFileName, &nWidth, &nHeight, &nFormat, &nSize ); if( NULL == pImageData ) { printf("Error loading texture! \n"); return FSL_FALSE; } else { printf("Texture [%s] succesully read (%d x %d , %d) \n",strFileName,nWidth,nHeight,nSize); } glGenTextures( 1, pTextureHandle ); glBindTexture( GL_TEXTURE_2D, *pTextureHandle ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glCompressedTexImage2D( GL_TEXTURE_2D, 0, nFormat, nWidth, nHeight, 0, nSize, pImageData ); free(pImageData); return FSL_TRUE; } #endif #ifdef FSL_EGL_USE_X11 //-------------------------------------------------------------------------------------- // Name: fslLoadFontX // Desc: Helper function to load a X11 font into given struct //-------------------------------------------------------------------------------------- void fslLoadFontX(Display *display, XFontStruct **font_info) { char *fontname = "9x15"; if ((*font_info=XLoadQueryFont(display,fontname)) == NULL) { printf("stderr, basicwin: cannot open 9x15 font\n"); exit(EXIT_FAILURE); } } //-------------------------------------------------------------------------------------- // Name: fslErrorHandlerX // Desc: Helper function to print incoming X11 server errors //-------------------------------------------------------------------------------------- int fslErrorHandlerX( Display *display, XErrorEvent *error ) { char errorText[1024]; XGetErrorText( display, error->error_code, errorText, sizeof(errorText) ); printf( "\t --- X Error: %s ---\n", errorText ); return 0; } #endif //-------------------------------------------------------------------------------------- // Name: fslGetTickCount // Desc: Helper function to get current time //-------------------------------------------------------------------------------------- unsigned int fslGetTickCount() { struct timeval tv; if(gettimeofday(&tv, NULL) != 0) { return 0; } return (tv.tv_sec * 1000) + (tv.tv_usec / 1000); } //-------------------------------------------------------------------------------------- // Name: fslMulMatrix4x4 // Desc: 4x4 Matix Muliply //-------------------------------------------------------------------------------------- void fslMultMatrix4x4( float *matC, float *matA, float *matB) { matC[ 0] = matA[ 0] * matB[ 0] + matA[ 1] * matB[ 4] + matA[ 2] * matB[ 8] + matA[ 3] * matB[12]; matC[ 1] = matA[ 0] * matB[ 1] + matA[ 1] * matB[ 5] + matA[ 2] * matB[ 9] + matA[ 3] * matB[13]; matC[ 2] = matA[ 0] * matB[ 2] + matA[ 1] * matB[ 6] + matA[ 2] * matB[10] + matA[ 3] * matB[14]; matC[ 3] = matA[ 0] * matB[ 3] + matA[ 1] * matB[ 7] + matA[ 2] * matB[11] + matA[ 3] * matB[15]; matC[ 4] = matA[ 4] * matB[ 0] + matA[ 5] * matB[ 4] + matA[ 6] * matB[ 8] + matA[ 7] * matB[12]; matC[ 5] = matA[ 4] * matB[ 1] + matA[ 5] * matB[ 5] + matA[ 6] * matB[ 9] + matA[ 7] * matB[13]; matC[ 6] = matA[ 4] * matB[ 2] + matA[ 5] * matB[ 6] + matA[ 6] * matB[10] + matA[ 7] * matB[14]; matC[ 7] = matA[ 4] * matB[ 3] + matA[ 5] * matB[ 7] + matA[ 6] * matB[11] + matA[ 7] * matB[15]; matC[ 8] = matA[ 8] * matB[ 0] + matA[ 9] * matB[ 4] + matA[10] * matB[ 8] + matA[11] * matB[12]; matC[ 9] = matA[ 8] * matB[ 1] + matA[ 9] * matB[ 5] + matA[10] * matB[ 9] + matA[11] * matB[13]; matC[10] = matA[ 8] * matB[ 2] + matA[ 9] * matB[ 6] + matA[10] * matB[10] + matA[11] * matB[14]; matC[11] = matA[ 8] * matB[ 3] + matA[ 9] * matB[ 7] + matA[10] * matB[11] + matA[11] * matB[15]; matC[12] = matA[12] * matB[ 0] + matA[13] * matB[ 4] + matA[14] * matB[ 8] + matA[15] * matB[12]; matC[13] = matA[12] * matB[ 1] + matA[13] * matB[ 5] + matA[14] * matB[ 9] + matA[15] * matB[13]; matC[14] = matA[12] * matB[ 2] + matA[13] * matB[ 6] + matA[14] * matB[10] + matA[15] * matB[14]; matC[15] = matA[12] * matB[ 3] + matA[13] * matB[ 7] + matA[14] * matB[11] + matA[15] * matB[15]; } fslBool fslInvertMatrix4x4( float *src, float *inverse) { int i, j, k, swap; double t; double temp[4][4]; for (i=0; i<4; i++) { for (j=0; j<4; j++) { temp[i][j] = src[i*4+j]; } } inverse[ 0] = 1.0f; inverse[ 1] = 0.0f; inverse[ 2] = 0.0f; inverse[ 3] = 0.0f; inverse[ 4] = 0.0f; inverse[ 5] = 1.0f; inverse[ 6] = 0.0f; inverse[ 7] = 0.0f; inverse[ 8] = 0.0f; inverse[ 9] = 0.0f; inverse[10] = 1.0f; inverse[11] = 0.0f; inverse[12] = 0.0f; inverse[13] = 0.0f; inverse[14] = 0.0f; inverse[15] = 1.0f; for (i = 0; i < 4; i++) { /* ** Look for largest element in column */ swap = i; for (j = i + 1; j < 4; j++) { if (fabs(temp[j][i]) > fabs(temp[i][i])) { swap = j; } } if (swap != i) { /* ** Swap rows. */ for (k = 0; k < 4; k++) { t = temp[i][k]; temp[i][k] = temp[swap][k]; temp[swap][k] = t; t = inverse[i*4+k]; inverse[i*4+k] = inverse[swap*4+k]; inverse[swap*4+k] = t; } } if (temp[i][i] == 0) { /* ** No non-zero pivot. The matrix is singular, which shouldn't ** happen. This means the user gave us a bad matrix. */ return FSL_FALSE; } t = temp[i][i]; for (k = 0; k < 4; k++) { temp[i][k] /= t; inverse[i*4+k] /= t; } for (j = 0; j < 4; j++) { if (j != i) { t = temp[j][i]; for (k = 0; k < 4; k++) { temp[j][k] -= temp[i][k]*t; inverse[j*4+k] -= inverse[i*4+k]*t; } } } } return FSL_TRUE; } void fslPerspectiveMatrix4x4 ( float *m, float fov, float aspect, float zNear, float zFar) { const float h = 1.0f/tan(fov*PI_OVER_360); float neg_depth = zNear-zFar; m[0] = h / aspect; m[1] = 0; m[2] = 0; m[3] = 0; m[4] = 0; m[5] = h; m[6] = 0; m[7] = 0; m[8] = 0; m[9] = 0; m[10] = (zFar + zNear)/neg_depth; m[11] = -1; m[12] = 0; m[13] = 0; m[14] = 2.0f*(zNear*zFar)/neg_depth; m[15] = 0; } void fslMultMatrix4x4Vec4x1 ( float *matA, float *vecA, float *vecB ) { int i; for ( i = 0; i < 4; i++ ) { vecB[i] = vecA[0] * matA[0*4+i] + vecA[1] * matA[1*4+i] + vecA[2] * matA[2*4+i] + vecA[3] * matA[3*4+i]; } } void fslRotateMatrix4x4 (float *m, float angle, fslAxis axis) { float radians = PI_OVER_360*2*angle; float rotate[16] = {0}; fslLoadIdentityMatrix4x4(rotate); switch (axis) { case FSL_X_AXIS: rotate[5] = cos(radians); rotate[6] = sin(radians); rotate[9] = -sin(radians); rotate[10] = cos(radians); fslMultMatrix4x4(m, rotate, m); break; case FSL_Y_AXIS: rotate[0] = cos(radians); rotate[2] = -sin(radians); rotate[8] = sin(radians); rotate[10] = cos(radians); fslMultMatrix4x4(m, rotate, m); break; case FSL_Z_AXIS: rotate[0] = cos(radians); rotate[1] = sin(radians); rotate[4] = -sin(radians); rotate[5] = cos(radians); fslMultMatrix4x4(m, rotate, m); break; default: printf("invalid axis \n"); break; } } void fslTranslateMatrix4x4 (float *m, float transX, float transY, float transZ) { float trans[16] = {0}; fslLoadIdentityMatrix4x4(trans); trans[12]=transX; trans[13]=transY; trans[14]=transZ; fslMultMatrix4x4(m, trans, m); } void fslScaleMatrix4x4 (float *m, float scaleX, float scaleY, float scaleZ) { float scale[16] = {0}; fslLoadIdentityMatrix4x4(scale); scale[0]=scaleX; scale[5]=scaleY; scale[10]=scaleZ; fslMultMatrix4x4(m, scale, m); } void fslLoadIdentityMatrix4x4 (float *m) { m[0] = 1; m[1] = 0; m[2] = 0; m[3] = 0; m[4] = 0; m[5] = 1; m[6] = 0; m[7] = 0; m[8] = 0; m[9] = 0; m[10] = 1; m[11] = 0; m[12] = 0; m[13] = 0; m[14] = 0; m[15] = 1; } float fslInnerProduct( float *v, float *q) { return v[0]*q[0]+v[1]*q[1]+v[2]*q[2]; } //result = endpoint-startPoint void fslDirectionVector(float *result, float *endPoint, float *startPoint) { result[0]= endPoint[0]-startPoint[0]; result[1]= endPoint[1]-startPoint[1]; result[2]= endPoint[2]-startPoint[2]; } //a = crossProduct(b,c) void fslCrossProduct(float *result, float *b, float* c) { result[0]= b[1]*c[2]-c[1]*b[2]; result[1]= b[2]*c[0]-c[2]*b[0]; result[2]= b[0]*c[1]-c[0]*b[1]; } //p is the startpoint, d is the direction vector, v0,v1,v2 represent the triangle int fslRayIntersectsTriangle(float *p, float *d,float *v0, float *v1, float *v2) { float e1[3]={0.0, 0.0, 0.0}; float e2[3]={0.0, 0.0, 0.0}; float h[3] = {0.0, 0.0, 0.0}; float s[3] = {0.0, 0.0, 0.0}; float q[3] = {0.0, 0.0, 0.0}; float a,f,u,v,t; fslDirectionVector(e1,v1,v0); fslDirectionVector(e2,v2,v0); fslCrossProduct(h,d,e2); //get the inner product a=fslInnerProduct(e1,h); if(a>-0.00001&& a<0.00001) return 0; f= 1/a; fslDirectionVector(s,p,v0); u=f*(fslInnerProduct(s,h)); if(u<0.0 || u>1.0) return 0; fslCrossProduct(q,s,e1); v = f*fslInnerProduct(d,q); if(v< 0.0 || u+v > 1.0) return 0; //we can compute t to find out where the intersection point is on the line t= f*fslInnerProduct(e2,q); if(t > 0.00001) //ray intersection return 1; else return 0; } void fslNormalize(float *v) { float mag =v[0]*v[0]+v[1]*v[1]+v[2]*v[2]; sqrt(mag); v[0]=v[0]/mag; v[1]=v[1]/mag; v[2]=v[2]/mag; //printf("vector Normalized is %f,%f,%f\n",v[0],v[1],v[2]); } void fslPrintMatrix4x4(float *m){ printf(" %f %f %f %f \n", m[0], m[1], m[2], m[3]); printf(" %f %f %f %f \n", m[4], m[5], m[6], m[7]); printf(" %f %f %f %f \n", m[8], m[9], m[10], m[11]); printf(" %f %f %f %f \n", m[12], m[13], m[14], m[15]); } void fslCalculateNormals(float *triangleArray, int size, float *normalArray) { printf("enter fslCalculateNormals \n"); int index =0; int i=0; for(i; i< size/3; i++){ float v1[3]={0.0f}; float v2[3]={0.0f}; float v3[3]={0.0f}; float v4[3]={0.0f}; float A[3]={0.0f}; float B[3]={0.0f}; float C[3]={0.0f}; float D[3]={0.0f}; v1[0]=triangleArray[9*i];//9 is for 9 values (3 vertices) used per loop v1[1]=triangleArray[9*i+1]; v1[2]=triangleArray[12*i+2]; v2[0]=triangleArray[9*i+3]; v2[1]=triangleArray[9*i+4]; v2[2]=triangleArray[9*i+5]; v3[0]=triangleArray[9*i+6]; v3[1]=triangleArray[9*i+7]; v3[2]=triangleArray[9*i+8]; A[0]=v1[0]-v2[0]; A[1]=v1[1]-v2[1]; A[2]=v1[2]-v2[2]; B[0]=v2[0]-v3[0]; B[1]=v2[1]-v3[1]; B[2]=v2[2]-v3[2]; float result[3]={0.0f}; printf("adding normal %i\n",index); fslCrossProduct(result, A, B); fslNormalize(result); normalArray[3*i]=result[0]; normalArray[3*i+1]=result[1]; normalArray[3*i+2]=result[2]; printf("adding normal: %f %f %f \n",result[0],result[1],result[2]); index++; } /* int i =0; for(i; i< size/4; i++){ float v1[3]={0.0f}; float v2[3]={0.0f}; float v3[3]={0.0f}; float v4[3]={0.0f}; float A[3]={0.0f}; float B[3]={0.0f}; float C[3]={0.0f}; float D[3]={0.0f}; v1[0]=triangleArray[12*i];//12 is for 12 values (4 vertices) used per loop v1[1]=triangleArray[12*i+1]; v1[2]=triangleArray[12*i+2]; v2[0]=triangleArray[12*i+3]; v2[1]=triangleArray[12*i+4]; v2[2]=triangleArray[12*i+5]; v3[0]=triangleArray[12*i+6]; v3[1]=triangleArray[12*i+7]; v3[2]=triangleArray[12*i+8]; v4[0]=triangleArray[12*i+9]; v4[1]=triangleArray[12*i+10]; v4[2]=triangleArray[12*i+11]; A[0]=v1[0]-v2[0]; A[1]=v1[1]-v2[1]; A[2]=v1[2]-v2[2]; B[0]=v2[0]-v3[0]; B[1]=v2[1]-v3[1]; B[2]=v2[2]-v3[2]; C[0]=v3[0]-v2[0]; C[1]=v3[1]-v2[1]; C[2]=v3[2]-v2[2]; D[0]=v2[0]-v4[0]; D[1]=v2[1]-v4[1]; D[2]=v2[2]-v4[2]; printf("calculating normals for face %i \n",i); //n1= (v1-v2)x(v2-v3) float result[3]={0.0f}; printf("adding normal %i\n",index); fslCrossProduct(result, A, B); fslNormalize(result); normalArray[6*i]=result[0]; normalArray[6*i+1]=result[1]; normalArray[6*i+2]=result[2]; printf("adding normal: %f %f %f \n",result[0],result[1],result[2]); index++; fslCrossProduct(result, C, D); fslNormalize(result); normalArray[6*i+3]=result[0]; normalArray[6*i+4]=result[1]; normalArray[6*i+5]=result[2]; printf("adding normal: %f %f %f \n",result[0],result[1],result[2]); index++; } */ }