//======================================== // Class to interface the VisualCAD specifications. // Nicolau Sunyer & Sergi Funtané (10/13/2005). // Universitat de Girona. //======================================== #pragma warning(disable:4244) // Includes #define GLEW_STATIC 1 #include "glew.h" #include //#include #include "stdlib.h" #include "time.h" // Includes #include "CMesh.h" #include "vcObscuranceMap.h" #define ROUND(x) (floor(x+0.5)) #ifndef M_PI #define M_PI 3.14159265358979323846 #endif // DepthPeeling Layers. #define MAX_LAYERS 12 // To use Offsets in the PBOs. #define BUFFER_OFFSET(i) ((char *)NULL + (i)) //GLSL // Handlers GLuint vProjection,fProjection,pProjection; GLuint vReflect, fReflect, pReflect; GLuint vCopy, fCopy, pCopy; GLuint vTransfer, fTransfer, pTransfer; GLuint vNormalize, fNormalize, pNormalize; //Uniform Parameters //Projection Step GLint TexturaDepthProjection; GLint SizeProjection; GLint FirstProjection; //Reflectivity texture generation Step. //Texture Copy Step. GLint TextureCopy; GLint Texture2Copy; //Energy Transfer Step. GLint TexturaReflectTransfer; GLint DirectionTransfer; GLint DmaxTransfer; //Lightmap Normalization Step. GLint TexturaNormalize; GLint ResolutionNormalize; // Global variables CVert Vertex, Direccio, Increment, Primer, Ultim, Origin; static GLuint texName[3]; static int ResX; //Resolution static int ResY; static int Res2X; //Resolution static int Res2Y; //Resolution //RenderTexture *ob=NULL; // RenderTexture for the Obscurances. static GLuint texProjeccions[2]; //Texture name static GLuint texTransfer[1]; static GLuint texReflect[1]; static GLuint texCopy[1]; static GLuint texNormalize[1]; static GLuint fb1; // Framebuffer Reflectivity static GLuint fb2; // Framebuffer Projeccions static GLuint fb3; // Framebuffer Transfer static GLuint fb4; // Framebuffer Copy static GLuint fb5; // Lightmap Normalization GLenum glerror; GLfloat *m_pTextureImage;// Texture of diferent colors. GLfloat *m_pTextureReflect; //Texture of reflectivitat. GLfloat *m_pBlau; GLfloat *m_pNegre; int obs_global_cancelar; CMesh g_pMesh; // Mesh Data static CSphere Esfera; static GLuint ProjectionsPBO[MAX_LAYERS+2]; // PBOs to store the projections. static GLuint ObscurancesPBO; // PBOs to store the projections. static GLuint ztex; //Texture with the depth. // Function to use when the window is resized void changeSize(int w, int h) { if(h == 0) h = 1; float ratio = 1.0 * (float)w / (float)h; //Camera Set up glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-w,w,-h,h); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glViewport(0, 0, w, h); } float vdc(int i, int base) { float prec = 1.0 / (float)base; float f = 0.0; while(i!=0) { f += (float)(prec * (i % base)); i /= base; prec /= base; } return f; } // Returns a random point in the surface of the sphere CVert ranpoint(float r, CVert c, int &count) { float ale1, ale2; CVert p; float alfa,beta; count++; ale1 = vdc(count, 2); ale2 = vdc(count, 3); // ale1= (float)rand()/(float)RAND_MAX; // ale2= (float)rand()/(float)RAND_MAX; alfa=1.0-2.0*ale1; /* real between -1 and 1 */ alfa=acos(alfa); /* angle between 0 and PI */ beta=2*M_PI*ale2; /* angle between 0 and 2*PI */ p.x=c.x+r*sin(alfa)*cos(beta); p.y=c.y+r*sin(alfa)*sin(beta); p.z=c.z+r*cos(alfa); return p; } // Function to find a point in the sphere in the direction that goes from the point in the surface of the sphere // to the center of the sphere. First it gets the random point in the surface. void BuscarDireccio(int &count) { Esfera.center.x = 0.0; Esfera.center.y = 0.0; Esfera.center.z = 0.0; Esfera.radius = sqrt(12.0)/2.0; Primer = ranpoint(Esfera.radius, Esfera.center, count); Vertex.x = Primer.x + (Esfera.center.x-Primer.x) * ((float)rand()/(float)RAND_MAX)*2.0; Vertex.y = Primer.y + (Esfera.center.y-Primer.y) * ((float)rand()/(float)RAND_MAX)*2.0; Vertex.z = Primer.z + (Esfera.center.z-Primer.z) * ((float)rand()/(float)RAND_MAX)*2.0; } // Function that renders the depth peeling geometry planes and stores them in PBOs. void RenderProjeccions(int buffer, int first) { int i, j, e; glUseProgram(pProjection); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb2); changeSize(ResX, ResY); glEnable (GL_DEPTH_TEST); // Enable Depth Testing glDepthFunc(GL_LESS); glDisable(GL_CULL_FACE); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-Esfera.radius,Esfera.radius,-Esfera.radius,Esfera.radius,0,Esfera.radius * 2.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(Primer.x,Primer.y,Primer.z, Esfera.center.x,Esfera.center.y,Esfera.center.z, 0.0f,1.0f,0.0f); glViewport(0,0,ResX,ResY); glUniform1f(SizeProjection, (float)ResX); glUniform1f(FirstProjection, (float)first); int other = ((buffer == 1)? 0:1); if(first == 0) { glBindBufferARB( GL_PIXEL_PACK_BUFFER_EXT, ProjectionsPBO[other] ); // Bind The Buffer glBindTexture(GL_TEXTURE_2D,texName[0]); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, ResX, ResY); glBindBufferARB( GL_PIXEL_PACK_BUFFER_EXT, 0 ); // Bind The Buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texName[0]); glUniform1i(TexturaDepthProjection, 0); } // Enable Pointers glEnableClientState( GL_VERTEX_ARRAY ); // Enable Vertex Arrays glEnableClientState( GL_TEXTURE_COORD_ARRAY ); // Enable Texture Coord Arrays glEnableClientState( GL_NORMAL_ARRAY ); // Enable Texture Coord Arrays for(i=0; i Steps: %d\n", iterations, steps); for(int i = 0; (i < steps) && cont; i++) { for(int j = 0; (j < iterations) && cont; j++) { cont = dialog.Update(i*100/steps + j*100/(steps*iterations)); BuscarDireccio(count); // Find a random direction glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb2); glClearColor(0.0,0.0,1.0,1.0); glClearDepth(1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glBindBufferARB( GL_PIXEL_PACK_BUFFER_EXT, ProjectionsPBO[0] ); // Bind The Buffer glBufferDataARB( GL_PIXEL_PACK_BUFFER_EXT, ResX*ResY*4*sizeof(float), m_pBlau, GL_STREAM_COPY ); glBindBufferARB( GL_PIXEL_PACK_BUFFER_EXT, 0 ); RenderProjeccions(1,1); RenderTransfer(1,1); int l = 0; for(int k=1; k < MAX_LAYERS; k++) { RenderProjeccions(l,0); l = (l == 0)? 1:0; RenderTransfer(l,0); } glBindBufferARB( GL_PIXEL_PACK_BUFFER_EXT, ProjectionsPBO[l] ); // Bind The Buffer glBufferDataARB( GL_PIXEL_PACK_BUFFER_EXT, ResX*ResY*4*sizeof(float), m_pBlau, GL_STREAM_COPY ); glBindBufferARB( GL_PIXEL_PACK_BUFFER_EXT, 0 ); l = (l = 0)? 1:0; RenderTransfer(l,1); } CopyTexture(); } printf("\r100%% Done!!!!"); NormalizeLightmap(); } // Function that generates the VBOs with the geometric data of the scene. // It also initializes the constant textures used. void InitGeometry(void) { int i, j; m_pBlau = new float[ResX * ResY * 4]; //Initialize a blue buffer. for(i = 0; i 10.0) \n" " { \n" " gl_FragColor = vec4(aux1.rgb/aux1.a,1.0); \n" " } \n" " else \n" " { \n" // " float res = 256.0; \n" " float dif = 1.0/res; \n" " \n" " float counter = 0.0; \n" " vec4 aux = vec4(0.0,0.0,0.0,0.0); \n" " \n" " vec4 aux2 = tex2D(texture,vec2(texCoord.r+dif,texCoord.g)); \n" " vec4 aux3 = tex2D(texture,vec2(texCoord.r+dif,texCoord.g+dif)); \n" " vec4 aux4 = tex2D(texture,vec2(texCoord.r,texCoord.g+dif)); \n" " vec4 aux5 = tex2D(texture,vec2(texCoord.r-dif,texCoord.g+dif)); \n" " vec4 aux6 = tex2D(texture,vec2(texCoord.r-dif,texCoord.g)); \n" " vec4 aux7 = tex2D(texture,vec2(texCoord.r-dif,texCoord.g-dif)); \n" " vec4 aux8 = tex2D(texture,vec2(texCoord.r,texCoord.g-dif)); \n" " vec4 aux9 = tex2D(texture,vec2(texCoord.r+dif,texCoord.g-dif)); \n" // " if(aux1.a>0.0) \n" // " { \n" // " aux += aux1; \n" // " counter += 1.0; \n" // " } \n" " if(aux2.a>10.0) \n" " { \n" " aux += aux2; \n" " counter += 1.0; \n" " } \n" " if(aux3.a>10.0) \n" " { \n" " aux += aux3; \n" " counter += 1.0; \n" " } \n" " if(aux4.a>10.0) \n" " { \n" " aux += aux4; \n" " counter += 1.0; \n" " } \n" " if(aux5.a>10.0) \n" " { \n" " aux += aux5; \n" " counter += 1.0; \n" " } \n" " if(aux6.a>10.0) \n" " { \n" " aux += aux6; \n" " counter += 1.0; \n" " } \n" " if(aux7.a>10.0) \n" " { \n" " aux += aux7; \n" " counter += 1.0; \n" " } \n" " if(aux8.a>10.0) \n" " { \n" " aux += aux8; \n" " counter += 1.0; \n" " } \n" " if(aux9.a>10.0) \n" " { \n" " aux += aux9; \n" " counter += 1.0; \n" " } \n" " if(counter < 1.0) gl_FragColor = vec4(0.0,0.0,0.0,0.0); \n" " else \n" " { \n" " aux /= counter; \n" " gl_FragColor = vec4(aux.rgb/aux.a,1.0); \n" " }; \n" " } \n" " } \n"; glShaderSource(vNormalize, 1, &vvNormalize, NULL); glShaderSource(fNormalize, 1, &ffNormalize, NULL); // free(vsNormalize); free(fsNormalize); glCompileShader(vNormalize); glCompileShader(fNormalize); pNormalize = glCreateProgram(); glAttachShader(pNormalize, vNormalize); glAttachShader(pNormalize, fNormalize); glLinkProgram(pNormalize); glUseProgram(pNormalize); TexturaNormalize = glGetUniformLocation(pNormalize, "texture"); ResolutionNormalize = glGetUniformLocation(pNormalize, "res"); glUseProgram(0); //Energy Transfer Shaders // char *vsTransfer = NULL, *fsTransfer = NULL; vTransfer = glCreateShader(GL_VERTEX_SHADER); fTransfer = glCreateShader(GL_FRAGMENT_SHADER); // vsTransfer = textFileRead("transfer.vert"); // fsTransfer = textFileRead("transfer.frag"); // const char *vvTransfer = vsTransfer; static const char *vvTransfer = " \n" " uniform float direction; \n" " \n" " varying vec2 p1; \n" " varying vec2 p2; \n" " varying float factor; \n" " \n" " void main() \n" " { \n" " vec4 position = gl_Vertex; \n" " vec4 texCoord = gl_MultiTexCoord0; \n" " if(((direction == 0) && (position.b != 1.0) && (position.b < 0.0) && ((texCoord.b > 0.0) || (texCoord.b == 1))) \n" " || ((direction == 1) && (position.b != 1.0) && (position.b > 0.0) && ((texCoord.b < 0.0) || (texCoord.b == 1)))) \n" " { \n" " \n" " p1 = vec2(position.r, position.g); \n" " \n" " p2 = vec2(texCoord.r, texCoord.g); \n" " \n" " gl_Position = vec4((p1 * 2.0) - vec2(1.0,1.0), 0.0,1.0); \n" " \n" " if (texCoord.b == 1) factor = 1; \n" " else factor = abs(texCoord.a - position.a); \n" " } \n" " else \n" " { \n" " gl_Position = vec4( 0.0,0.0, 2.0, 1.0 ); \n" " p1 = p2 = vec2(1.0,1.0); \n" " factor = 0.5; \n" " } \n" " } \n"; // const char *ffTransfer = fsTransfer; static const char *ffTransfer = " \n" " uniform sampler2D reflectivity; \n" " uniform float dmax; \n" " \n" " varying vec2 p1; \n" " varying vec2 p2; \n" " varying float factor; \n" " \n" " void main() \n" " { \n" " if(factor>=dmax) gl_FragColor.rgb = vec3(0.5,0.5,0.5); \n" " else gl_FragColor.rgb = tex2D(reflectivity,p2).rgb * sqrt(factor/dmax); \n" " gl_FragColor.a = 1.0; \n" " } \n"; glShaderSource(vTransfer, 1, &vvTransfer, NULL); glShaderSource(fTransfer, 1, &ffTransfer, NULL); // free(vsTransfer); free(fsTransfer); glCompileShader(vTransfer); glCompileShader(fTransfer); pTransfer = glCreateProgram(); glAttachShader(pTransfer, vTransfer); glAttachShader(pTransfer, fTransfer); glLinkProgram(pTransfer); glUseProgram(pTransfer); TexturaReflectTransfer = glGetUniformLocation(pTransfer, "reflectivity"); DirectionTransfer = glGetUniformLocation(pTransfer, "direction"); DmaxTransfer = glGetUniformLocation(pTransfer, "dmax"); glUseProgram(0); // Setup GL States glEnable (GL_DEPTH_TEST); // Enable Depth Testing //Generate the reflectivity texture. RenderReflect(); UpdateTexture(60, 3, count); } //Interface of the Obscurance Module int vcObscurerGenerateImage(CMesh &geom, char *argv, int quality, int *imgUsize, int *imgVsize, float **imgRgbBuffer) { // float divisor; int *DadesTemp = new int[4]; float *dadesf=NULL; int *dadesi=NULL; int qual; float aux[4]; float a; glutCreateWindow("T"); glerror = glewInit(); FILE *file = NULL; file = fopen("GPUObscurancesLog.txt", "w"); if ((!file) || (glerror != GLEW_OK)) { fprintf(file, "GPUObscurancesLog: Error initializing glew library"); exit(-1); } else fprintf(file, "GPUObscurancesLog: glew library correctly initialized"); fclose(file); memset(&aux, 0.0, 4); qual = quality; if (qual < 1) qual = 1; switch (qual) { case 1: *imgVsize = *imgUsize = 256; break; case 2: *imgVsize = *imgUsize = 512; break; case 3: *imgVsize = *imgUsize = 1024; break; case 4: *imgVsize = *imgUsize = 2048; break; default: printf("\nResolution not supported"); }; Res2X = *imgUsize; Res2Y = *imgVsize; ResX = Res2X * 2.0; ResY = Res2Y * 2.0; if(ResX == 4096) ResX = 2048; if(ResY == 4096) ResY = 2048; printf("\nRes(Plans de projeccio): ResolucioX = %d , ResolucioY = %d", ResX, ResY); printf("\nRes2(Lightmap): ResolucioX = %d , ResolucioY = %d", Res2X, Res2Y); dadesf = new float[Res2X*Res2Y*4]; dadesi = new int[Res2X*Res2Y*4]; init2(argv); //->g_pMesh.FreeMem(); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb5); glReadPixels(0,0,Res2X,Res2Y,GL_RGBA,GL_FLOAT,dadesf); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); /* for(int i=0; i15) { dadesf[4*i] = (dadesf[4*i]/divisor); dadesf[4*i+1] = (dadesf[4*i+1]/divisor); dadesf[4*i+2] = (dadesf[4*i+2]/divisor); dadesf[4*i+3] = 1.0; } else { a=0; aux[0] = 0.0; aux[1] = 0.0; aux[2] = 0.0; aux[3] = 0.0; if(i/Res2X > 0) { if(i/Res2X < Res2Y-1) { if(i%Res2X !=0) { if(dadesf[4*(i-Res2X)-1]>15) //ul(); { aux[0] += (dadesf[4*(i-Res2X)-4]/dadesf[4*(i-Res2X)-1]); aux[1] += (dadesf[4*(i-Res2X)-3]/dadesf[4*(i-Res2X)-1]); aux[2] += (dadesf[4*(i-Res2X)-2]/dadesf[4*(i-Res2X)-1]); aux[3] += 1.0; a =+ 1.0;; } if(dadesf[4*i-1]>15) //l(); { aux[0] += (dadesf[4*i-4]/dadesf[4*i-1]); aux[1] += (dadesf[4*i-3]/dadesf[4*i-1]); aux[2] += (dadesf[4*i-2]/dadesf[4*i-1]); aux[3] += 1.0; a =+ 1.0;; } if(dadesf[4*(i+Res2X)-1]>15) //dl(); { aux[0] += (dadesf[4*(i+Res2X)-4]/dadesf[4*(i+Res2X)-1]); aux[1] += (dadesf[4*(i+Res2X)-3]/dadesf[4*(i+Res2X)-1]); aux[2] += (dadesf[4*(i+Res2X)-2]/dadesf[4*(i+Res2X)-1]); aux[3] += 1.0; a =+ 1.0;; } } if(dadesf[4*(i+Res2X)+3]>15) //d(); { aux[0] += (dadesf[4*(i+Res2X)]/dadesf[4*(i+Res2X)+3]); aux[1] += (dadesf[4*(i+Res2X)+1]/dadesf[4*(i+Res2X)+3]); aux[2] += (dadesf[4*(i+Res2X)+2]/dadesf[4*(i+Res2X)+3]); aux[3] += 1.0; a =+ 1.0;; } if(i%Res2X!=Res2X-1) { if(dadesf[4*(i-Res2X)+7]>15) //ur(); { aux[0] += (dadesf[4*(i-Res2X)+4]/dadesf[4*(i-Res2X)+7]); aux[1] += (dadesf[4*(i-Res2X)+5]/dadesf[4*(i-Res2X)+7]); aux[2] += (dadesf[4*(i-Res2X)+6]/dadesf[4*(i-Res2X)+7]); aux[3] += 1.0; a =+ 1.0;; } if(dadesf[4*i+7]>15) //r(); { aux[0] += (dadesf[4*i+4]/dadesf[4*i+7]); aux[1] += (dadesf[4*i+5]/dadesf[4*i+7]); aux[2] += (dadesf[4*i+6]/dadesf[4*i+7]); aux[3] += 1.0; a =+ 1.0;; } if(dadesf[4*(i+Res2X)+7]>15) //dr(); { aux[0] += (dadesf[4*(i+Res2X)+4]/dadesf[4*(i+Res2X)+7]); aux[1] += (dadesf[4*(i+Res2X)+5]/dadesf[4*(i+Res2X)+7]); aux[2] += (dadesf[4*(i+Res2X)+6]/dadesf[4*(i+Res2X)+7]); aux[3] += 1.0; a =+ 1.0;; } } if(dadesf[4*(i-Res2X)+3]>15) //u(); { aux[0] += (dadesf[4*(i-Res2X)]/dadesf[4*(i-Res2X)+3]); aux[1] += (dadesf[4*(i-Res2X)+1]/dadesf[4*(i-Res2X)+3]); aux[2] += (dadesf[4*(i-Res2X)+2]/dadesf[4*(i-Res2X)+3]); aux[3] += 1.0; a =+ 1.0;; } } } else { if(i%Res2X !=0) { if(dadesf[4*i-1]>15) //l(); { aux[0] += (dadesf[4*i-4]/dadesf[4*i-1]); aux[1] += (dadesf[4*i-3]/dadesf[4*i-1]); aux[2] += (dadesf[4*i-2]/dadesf[4*i-1]); aux[3] += 1.0; a =+ 1.0;; } if(dadesf[4*(i+Res2X)-1]>15) //dl(); { aux[0] += (dadesf[4*(i+Res2X)-4]/dadesf[4*(i+Res2X)-1]); aux[1] += (dadesf[4*(i+Res2X)-3]/dadesf[4*(i+Res2X)-1]); aux[2] += (dadesf[4*(i+Res2X)-2]/dadesf[4*(i+Res2X)-1]); aux[3] = 1.0; a =+ 1.0;; } } if(i%Res2X!=Res2X-1) { if(dadesf[4*i+7]>15) //r(); { aux[0] += (dadesf[4*i+4]/dadesf[4*i+7]); aux[1] += (dadesf[4*i+5]/dadesf[4*i+7]); aux[2] += (dadesf[4*i+6]/dadesf[4*i+7]); aux[3] += 1.0; a =+ 1.0;; } if(dadesf[4*(i+Res2X)+7]>15) //dr(); { aux[0] += (dadesf[4*(i+Res2X)+4]/dadesf[4*(i+Res2X)+7]); aux[1] += (dadesf[4*(i+Res2X)+5]/dadesf[4*(i+Res2X)+7]); aux[2] += (dadesf[4*(i+Res2X)+6]/dadesf[4*(i+Res2X)+7]); aux[3] += 1.0; a =+ 1.0;; } } if(dadesf[4*(i+Res2X)+3]>15) //d(); { aux[0] += (dadesf[4*(i+Res2X)]/dadesf[4*(i+Res2X)+3]); aux[1] += (dadesf[4*(i+Res2X)+1]/dadesf[4*(i+Res2X)+3]); aux[2] += (dadesf[4*(i+Res2X)+2]/dadesf[4*(i+Res2X)+3]); aux[3] += 1.0; a =+ 1.0;; } } if(a > 0.0) { dadesf[4*i] = aux[0]/aux[3]; dadesf[4*i+1] = aux[1]/aux[3]; dadesf[4*i+2] = aux[2]/aux[3]; dadesf[4*i+3] = 1.0; } else { dadesf[4*i] = 0.0; dadesf[4*i+1] = 0.0; dadesf[4*i+2] = 0.0; dadesf[4*i+3] = 0.0; } } dadesi[4*i] = (int)(255.0*dadesf[4*i]); dadesi[4*i+1] = (int)(255.0*dadesf[4*i+1]); dadesi[4*i+2] = (int)(255.0*dadesf[4*i+2]); dadesi[4*i+3] = (int)(255.0*dadesf[4*i+3]); } */ *imgRgbBuffer = dadesf; geom = g_pMesh; return 0; }