//======================================== // 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 "textfile.h" // Includes #include "CMesh.h" #include "vcObscuranceMap.h" #include #include #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; //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; // Global variables CVert Vertex, Direccio, Increment, Primer, Ultim, Origin; static GLuint texName[2]; static int ResX; //Resolution static int ResY; static int Res2X; //Resolution static int Res2Y; //Resolution static GLuint texProjeccions[2]; //Texture name static GLuint texTransfer[1]; static GLuint texReflect[1]; static GLuint texCopy[1]; static GLuint fb1; // Framebuffer Reflectivity static GLuint fb2; // Framebuffer Projeccions static GLuint fb3; // Framebuffer Transfer static GLuint fb4; // Framebuffer Copy 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); } // Returns a random point in the surface of the sphere CVert ranpoint(float r, CVert c) { double ale1, ale2; CVert p; float alfa,beta; 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() { 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); 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; i++) { for(int j = 0; j < iterations; j++) { printf("\rProgress: %d%%",i*100/steps + j*100/(steps*iterations)); BuscarDireccio(); // 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!!!!"); } // 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; 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]); } geom = g_pMesh; imdebug("rgba b=32f w=%d h=%d %p", Res2X, Res2Y, dadesf); *imgRgbBuffer = dadesf; return 0; }