//======================================== // Class to interface the VisualCAD specifications. // Nicolau Sunyer & Sergi Funtané (10/13/2005). // Universitat de Girona. //======================================== #pragma warning(disable:4244) // Includes #include "glew.h" #include #include "stdlib.h" // Includes #include "CMesh.h" #include "vcObscuranceMap.h" //progress bar #include #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; // 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); } // 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(void) { glUseProgram(pProjection); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb2); int i, j, e; changeSize(ResX, ResY); glClearColor(0.0,0.0,1.0,1.0); glClearDepth(1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 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, 1.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(); // Find a random direction RenderProjeccions(); RenderTransfer(); } 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; i0.0) \n" " { \n" " aux += vec4(aux1.rgb/aux1.a,1.0); \n" " counter += 1.0; \n" " } \n" " if(aux2.a>0.0) \n" " { \n" " aux += vec4(aux2.rgb/aux2.a,1.0); \n" " counter += 1.0; \n" " } \n" " if(aux3.a>0.0) \n" " { \n" " aux += vec4(aux3.rgb/aux3.a,1.0); \n" " counter += 1.0; \n" " } \n" " if(aux4.a>0.0) \n" " { \n" " aux += vec4(aux4.rgb/aux4.a,1.0); \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 = aux; \n" " } \n" " } \n"; glShaderSource(vNormalize, 1, &vvNormalize, NULL); glShaderSource(fNormalize, 1, &ffNormalize, NULL); glCompileShader(vNormalize); glCompileShader(fNormalize); pNormalize = glCreateProgram(); glAttachShader(pNormalize, vNormalize); glAttachShader(pNormalize, fNormalize); glLinkProgram(pNormalize); glUseProgram(pNormalize); TexturaNormalize = glGetUniformLocation(pNormalize, "texture"); glUseProgram(0); //Energy Transfer Shaders vTransfer = glCreateShader(GL_VERTEX_SHADER); fTransfer = glCreateShader(GL_FRAGMENT_SHADER); 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"; 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); 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); } // Function that interfaces with the VisualCAD. 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("tmp.txt", "w"); if (glerror != GLEW_OK) fprintf(file, "\nError initializing glew library, %s", glewGetErrorString(glerror)); else fprintf(file, "\nTot Correcte!\n"); 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); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb5); glReadPixels(0,0,Res2X,Res2Y,GL_RGBA,GL_FLOAT,dadesf); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); *imgRgbBuffer = dadesf; geom = g_pMesh; return 0; }