GLUSboolean GLUSAPIENTRY glusLoadBinaryFile(const GLUSchar* filename, GLUSbinaryfile* binaryfile) { FILE* f; size_t elementsRead; if (!filename || !binaryfile) { return GLUS_FALSE; } binaryfile->binary = 0; binaryfile->length = 0; f = fopen(filename, "rb"); if (!f) { return GLUS_FALSE; } if(fseek(f, 0, SEEK_END)) { fclose(f); return GLUS_FALSE; } binaryfile->length = ftell(f); if (binaryfile->length < 0 || binaryfile->length == GLUS_MAX_BINARYILE_LENGTH) { fclose(f); binaryfile->length = 0; return GLUS_FALSE; } binaryfile->binary = (GLUSubyte*) malloc((size_t)binaryfile->length); if (!binaryfile->binary) { fclose(f); binaryfile->length = 0; return GLUS_FALSE; } memset(binaryfile->binary, 0, (size_t)binaryfile->length); rewind(f); elementsRead = fread(binaryfile->binary, 1, (size_t)binaryfile->length, f); if (!glusCheckFileRead(f, elementsRead, (size_t)binaryfile->length)) { glusDestroyBinaryFile(binaryfile); return GLUS_FALSE; } fclose(f); return GLUS_TRUE; }
GLUSboolean init(GLUSvoid) { GLUSshape backgroundSphere; GLUSshape wavefront; // 6 sides of diffuse and specular; all roughness levels of specular. GLUShdrimage image[6 * NUMBER_ROUGHNESS + 6]; // The look up table (LUT) is stored in a raw binary file. GLUSbinaryfile rawimage; GLUStextfile vertexSource; GLUStextfile fragmentSource; GLchar buffer[27] = "doge2/doge2_POS_X_00_s.hdr"; GLint i, k, m; // glusLoadTextFile("../Example33/shader/brdf.vert.glsl", &vertexSource); glusLoadTextFile("../Example33/shader/brdf.frag.glsl", &fragmentSource); glusBuildProgramFromSource(&g_modelProgram, (const GLchar**)&vertexSource.text, 0, 0, 0, (const GLchar**)&fragmentSource.text); glusDestroyTextFile(&vertexSource); glusDestroyTextFile(&fragmentSource); g_viewProjectionMatrixModelLocation = glGetUniformLocation(g_modelProgram.program, "u_viewProjectionMatrix"); g_modelMatrixModelLocation = glGetUniformLocation(g_modelProgram.program, "u_modelMatrix"); g_normalMatrixModelLocation = glGetUniformLocation(g_modelProgram.program, "u_normalMatrix"); g_eyeModelLocation = glGetUniformLocation(g_modelProgram.program, "u_eye"); g_textureSpecularModelLocation = glGetUniformLocation(g_modelProgram.program, "u_textureSpecular"); g_textureDiffuseModelLocation = glGetUniformLocation(g_modelProgram.program, "u_textureDiffuse"); g_textureLUTModelLocation = glGetUniformLocation(g_modelProgram.program, "u_textureLUT"); g_colorMaterialModelLocation = glGetUniformLocation(g_modelProgram.program, "u_colorMaterial"); g_roughnessMaterialModelLocation = glGetUniformLocation(g_modelProgram.program, "u_roughnessMaterial"); g_roughnessScaleModelLocation = glGetUniformLocation(g_modelProgram.program, "u_roughnessScale"); g_R0MaterialModelLocation = glGetUniformLocation(g_modelProgram.program, "u_R0Material"); g_vertexModelLocation = glGetAttribLocation(g_modelProgram.program, "a_vertex"); g_normalModelLocation = glGetAttribLocation(g_modelProgram.program, "a_normal"); // glusLoadTextFile("../Example33/shader/fullscreen.vert.glsl", &vertexSource); glusLoadTextFile("../Example33/shader/fullscreen.frag.glsl", &fragmentSource); glusBuildProgramFromSource(&g_fullscreenProgram, (const GLchar**)&vertexSource.text, 0, 0, 0, (const GLchar**)&fragmentSource.text); glusDestroyTextFile(&vertexSource); glusDestroyTextFile(&fragmentSource); // g_framebufferTextureFullscreenLocation = glGetUniformLocation(g_fullscreenProgram.program, "u_framebufferTexture"); g_msaaSamplesFullscreenLocation = glGetUniformLocation(g_fullscreenProgram.program, "u_msaaSamples"); g_exposureFullscreenLocation = glGetUniformLocation(g_fullscreenProgram.program, "u_exposure"); g_gammaFullscreenLocation = glGetUniformLocation(g_fullscreenProgram.program, "u_gamma"); // // glusLoadTextFile("../Example33/shader/background.vert.glsl", &vertexSource); glusLoadTextFile("../Example33/shader/background.frag.glsl", &fragmentSource); glusBuildProgramFromSource(&g_backgroundProgram, (const GLUSchar**)&vertexSource.text, 0, 0, 0, (const GLUSchar**)&fragmentSource.text); glusDestroyTextFile(&vertexSource); glusDestroyTextFile(&fragmentSource); // g_viewProjectionMatrixBackgroundLocation = glGetUniformLocation(g_backgroundProgram.program, "u_viewProjectionMatrix"); g_textureBackgroundLocation = glGetUniformLocation(g_backgroundProgram.program, "u_texture"); g_vertexBackgroundLocation = glGetAttribLocation(g_backgroundProgram.program, "a_vertex"); // // Setting up the full screen frame buffer. // glGenTextures(1, &g_fullscreenTexture); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, g_fullscreenTexture); // Create MSAA texture. glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, MSAA_SAMPLES, GL_RGB32F, SCREEN_WIDTH, SCREEN_HEIGHT, GL_TRUE); glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0); // No need to access the depth buffer, so a render buffer is sufficient. glGenRenderbuffers(1, &g_fullscreenDepthRenderbuffer); glBindRenderbuffer(GL_RENDERBUFFER, g_fullscreenDepthRenderbuffer); glRenderbufferStorageMultisample(GL_RENDERBUFFER, MSAA_SAMPLES, GL_DEPTH_COMPONENT, SCREEN_WIDTH, SCREEN_HEIGHT); glBindRenderbuffer(GL_RENDERBUFFER, 0); // glGenFramebuffers(1, &g_fullscreenFBO); glBindFramebuffer(GL_FRAMEBUFFER, g_fullscreenFBO); // Attach the color buffer ... glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, g_fullscreenTexture, 0); // ... and the depth buffer. glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, g_fullscreenDepthRenderbuffer); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { printf("GL_FRAMEBUFFER_COMPLETE error 0x%x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); return GLUS_FALSE; } glBindFramebuffer(GL_FRAMEBUFFER, 0); // // // for (i = 0; i < 2; i++) { if (i == 0) { buffer[21] = 's'; } else { buffer[21] = 'd'; } for (k = 0; k < NUMBER_ROUGHNESS; k++) { if (i == 1 && k > 0) { continue; } buffer[18] = '0' + k / 10; buffer[19] = '0' + k % 10; for (m = 0; m < 6; m++) { if (m % 2 == 0) { buffer[12] = 'P'; buffer[13] = 'O'; buffer[14] = 'S'; } else { buffer[12] = 'N'; buffer[13] = 'E'; buffer[14] = 'G'; } switch (m) { case 0: case 1: buffer[16] = 'X'; break; case 2: case 3: buffer[16] = 'Y'; break; case 4: case 5: buffer[16] = 'Z'; break; } printf("Loading '%s' ...", buffer); if (!glusLoadHdrImage(buffer, &image[i*NUMBER_ROUGHNESS*6 + k*6 + m])) { printf(" error!\n"); continue; } printf(" done.\n"); } } } glGenTextures(1, &g_texture[0]); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, g_texture[0]); glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGB32F, image[0].width, image[0].height, 6*NUMBER_ROUGHNESS, 0, GL_RGB, GL_FLOAT, 0); glusLogPrintError(GLUS_LOG_INFO, "glTexImage3D()"); for (i = 0; i < NUMBER_ROUGHNESS; i++) { for (k = 0; k < 6; k++) { glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, 6*i + k, image[i*6 + k].width, image[i*6 + k].height, 1, image[i*6 + k].format, GL_FLOAT, image[i*6 + k].data); glusLogPrintError(GLUS_LOG_INFO, "glTexSubImage3D() %d %d", i, k); } } glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0); // glGenTextures(1, &g_texture[1]); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_CUBE_MAP, g_texture[1]); for (i = 0; i < 6; i++) { glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, image[i + 6*NUMBER_ROUGHNESS].format, image[i + 6*NUMBER_ROUGHNESS].width, image[i + 6*NUMBER_ROUGHNESS].height, 0, image[i + 6*NUMBER_ROUGHNESS].format, GL_FLOAT, image[i + 6*NUMBER_ROUGHNESS].data); glusLogPrintError(GLUS_LOG_INFO, "glTexImage2D() %d", i); } glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glBindTexture(GL_TEXTURE_CUBE_MAP, 0); // printf("Loading 'doge2/EnvironmentBRDF_1024.data' ..."); if (!glusLoadBinaryFile("doge2/EnvironmentBRDF_1024.data", &rawimage)) { printf(" error!\n"); } else { printf(" done.\n"); } glGenTextures(1, &g_texture[2]); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, g_texture[2]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RG32F, 1024, 1024, 0, GL_RG, GL_FLOAT, (GLfloat*)rawimage.binary); glusLogPrintError(GLUS_LOG_INFO, "glTexImage2D()"); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glBindTexture(GL_TEXTURE_2D, 0); glusDestroyBinaryFile(&rawimage); // for (i = 0; i < 2; i++) { for (k = 0; k < NUMBER_ROUGHNESS; k++) { if (i == 1 && k > 0) { continue; } for (m = 0; m < 6; m++) { glusDestroyHdrImage(&image[i*NUMBER_ROUGHNESS*6 + k*6 + m]); } } } // glusCreateSpheref(&backgroundSphere, 500.0f, 32); g_numberIndicesBackground = backgroundSphere.numberIndices; glGenBuffers(1, &g_verticesBackgroundVBO); glBindBuffer(GL_ARRAY_BUFFER, g_verticesBackgroundVBO); glBufferData(GL_ARRAY_BUFFER, backgroundSphere.numberVertices * 4 * sizeof(GLfloat), (GLfloat*)backgroundSphere.vertices, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); glGenBuffers(1, &g_indicesBackgroundVBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_indicesBackgroundVBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, backgroundSphere.numberIndices * sizeof(GLuint), (GLuint*)backgroundSphere.indices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glusDestroyShapef(&backgroundSphere); // // // Use a helper function to load an wavefront object file. glusLoadObjFile("venusm.obj", &wavefront); g_numberVerticesModel = wavefront.numberVertices; glGenBuffers(1, &g_verticesModelVBO); glBindBuffer(GL_ARRAY_BUFFER, g_verticesModelVBO); glBufferData(GL_ARRAY_BUFFER, wavefront.numberVertices * 4 * sizeof(GLfloat), (GLfloat*)wavefront.vertices, GL_STATIC_DRAW); glGenBuffers(1, &g_normalsModelVBO); glBindBuffer(GL_ARRAY_BUFFER, g_normalsModelVBO); glBufferData(GL_ARRAY_BUFFER, wavefront.numberVertices * 3 * sizeof(GLfloat), (GLfloat*)wavefront.normals, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); glusDestroyShapef(&wavefront); // glUseProgram(g_modelProgram.program); glUniform4fv(g_eyeModelLocation, 1, g_eye); glUniform1i(g_textureSpecularModelLocation, 0); glUniform1i(g_textureDiffuseModelLocation, 1); glUniform1i(g_textureLUTModelLocation, 2); glUniform1f(g_roughnessScaleModelLocation, (GLfloat)(NUMBER_ROUGHNESS - 1)); glGenVertexArrays(1, &g_modelVAO); glBindVertexArray(g_modelVAO); glBindBuffer(GL_ARRAY_BUFFER, g_verticesModelVBO); glVertexAttribPointer(g_vertexModelLocation, 4, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(g_vertexModelLocation); glBindBuffer(GL_ARRAY_BUFFER, g_normalsModelVBO); glVertexAttribPointer(g_normalModelLocation, 3, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(g_normalModelLocation); // glUseProgram(g_fullscreenProgram.program); glUniform1i(g_framebufferTextureFullscreenLocation, 0); glUniform1i(g_msaaSamplesFullscreenLocation, MSAA_SAMPLES); glGenVertexArrays(1, &g_fullscreenVAO); glBindVertexArray(g_fullscreenVAO); // glUseProgram(g_backgroundProgram.program); glUniform1i(g_textureBackgroundLocation, 0); glGenVertexArrays(1, &g_backgroundVAO); glBindVertexArray(g_backgroundVAO); glBindBuffer(GL_ARRAY_BUFFER, g_verticesBackgroundVBO); glVertexAttribPointer(g_vertexBackgroundLocation, 4, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(g_vertexBackgroundLocation); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_indicesBackgroundVBO); // glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearDepth(1.0f); glEnable(GL_CULL_FACE); return GLUS_TRUE; }