static GLboolean renderToPixelBuffer(GLubyte* pixels, const GLint width, const GLint height) { GLint x, y, index; GLfloat pixelColor[4]; // Generate the ray directions depending on FOV, width and height. if (!glusRaytracePerspectivef(g_directionBuffer, 0, 30.0f, width, height)) { printf("Error: Could not create direction buffer.\n"); return GLUS_FALSE; } // Rendering only once, so direction buffer can be overwritten. glusRaytraceLookAtf(g_positionBuffer, g_directionBuffer, g_directionBuffer, 0, width, height, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f); // Ray marching over all pixels for (y = 0; y < HEIGHT; y++) { for (x = 0; x < WIDTH; x++) { index = (x + y * WIDTH); march(pixelColor, &g_positionBuffer[index * 4], &g_directionBuffer[index * 3], 0); // Resolve to pixel buffer, which is used for the texture. pixels[index * BYTES_PER_PIXEL + 0] = (GLubyte)(glusMathMinf(1.0f, pixelColor[0]) * 255.0f); pixels[index * BYTES_PER_PIXEL + 1] = (GLubyte)(glusMathMinf(1.0f, pixelColor[1]) * 255.0f); pixels[index * BYTES_PER_PIXEL + 2] = (GLubyte)(glusMathMinf(1.0f, pixelColor[2]) * 255.0f); } } return GLUS_TRUE; }
GLUSboolean init(GLUSvoid) { GLUStextfile vertexSource; GLUStextfile fragmentSource; GLUStextfile computeSource; glusLoadTextFile("../Example30/shader/fullscreen.vert.glsl", &vertexSource); glusLoadTextFile("../Example30/shader/texture.frag.glsl", &fragmentSource); glusBuildProgramFromSource(&g_program, (const GLchar**)&vertexSource.text, 0, 0, 0, (const GLchar**)&fragmentSource.text); glusDestroyTextFile(&vertexSource); glusDestroyTextFile(&fragmentSource); glusLoadTextFile("../Example30/shader/raytrace.comp.glsl", &computeSource); glusBuildComputeProgramFromSource(&g_computeProgram, (const GLchar**)&computeSource.text); glusDestroyTextFile(&computeSource); // // Retrieve the uniform locations in the program. g_textureLocation = glGetUniformLocation(g_program.program, "u_texture"); // // Generate and bind a texture. glGenTextures(1, &g_texture); glBindTexture(GL_TEXTURE_2D, g_texture); // Create an empty image. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, g_imageWidth, g_imageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); // Setting the texture parameters. 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_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glBindTexture(GL_TEXTURE_2D, 0); // // glUseProgram(g_program.program); glGenVertexArrays(1, &g_vao); glBindVertexArray(g_vao); // // Also bind created texture ... glBindTexture(GL_TEXTURE_2D, g_texture); // ... and bind this texture as an image, as we will write to it. see binding = 0 in shader. glBindImageTexture(0, g_texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8); // ... and as this is texture number 0, bind the uniform to the program. glUniform1i(g_textureLocation, 0); // // glUseProgram(g_computeProgram.program); // // Generate the ray directions depending on FOV, width and height. if (!glusRaytracePerspectivef(g_directionBuffer, PADDING, 30.0f, WIDTH, HEIGHT)) { printf("Error: Could not create direction buffer.\n"); return GLUS_FALSE; } // Compute shader will use these textures just for input. glusRaytraceLookAtf(g_positionBuffer, g_directionBuffer, g_directionBuffer, PADDING, WIDTH, HEIGHT, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f); // // Buffers with the initial ray position and direction. // glGenBuffers(1, &g_directionSSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, g_directionSSBO); glBufferData(GL_SHADER_STORAGE_BUFFER, WIDTH * HEIGHT * (3 + PADDING) * sizeof(GLfloat), g_directionBuffer, GL_STATIC_READ); // see binding = 1 in the shader glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, g_directionSSBO); // glGenBuffers(1, &g_positionSSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, g_positionSSBO); glBufferData(GL_SHADER_STORAGE_BUFFER, WIDTH * HEIGHT * 4 * sizeof(GLfloat), g_positionBuffer, GL_STATIC_READ); // see binding = 2 in the shader glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, g_positionSSBO); return GLUS_TRUE; }
GLUSboolean init(GLUSvoid) { GLint i; GLUStextfile vertexSource; GLUStextfile fragmentSource; GLUStextfile computeSource; glusFileLoadText("shader/fullscreen.vert.glsl", &vertexSource); glusFileLoadText("shader/texture.frag.glsl", &fragmentSource); glusProgramBuildFromSource(&g_program, (const GLchar**)&vertexSource.text, 0, 0, 0, (const GLchar**)&fragmentSource.text); glusFileDestroyText(&vertexSource); glusFileDestroyText(&fragmentSource); glusFileLoadText("shader/raytrace.comp.glsl", &computeSource); glusProgramBuildComputeFromSource(&g_computeProgram, (const GLchar**)&computeSource.text); glusFileDestroyText(&computeSource); // // Retrieve the uniform locations in the program. g_textureLocation = glGetUniformLocation(g_program.program, "u_texture"); // // Generate and bind a texture. glGenTextures(1, &g_texture); glBindTexture(GL_TEXTURE_2D, g_texture); // Create an empty image. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, WIDTH, HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); // Setting the texture parameters. 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_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glBindTexture(GL_TEXTURE_2D, 0); // // glUseProgram(g_program.program); glGenVertexArrays(1, &g_vao); glBindVertexArray(g_vao); // // Also bind created texture ... glBindTexture(GL_TEXTURE_2D, g_texture); // ... and bind this texture as an image, as we will write to it. see binding = 0 in shader. glBindImageTexture(0, g_texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8); // ... and as this is texture number 0, bind the uniform to the program. glUniform1i(g_textureLocation, 0); // // glUseProgram(g_computeProgram.program); // printf("Preparing buffers ... "); // Generate the ray directions depending on FOV, width and height. if (!glusRaytracePerspectivef(g_directionBuffer, DIRECTION_BUFFER_PADDING, 30.0f, WIDTH, HEIGHT)) { printf("failed!\n"); printf("Error: Could not create direction buffer.\n"); return GLUS_FALSE; } // Compute shader will use these textures just for input. glusRaytraceLookAtf(g_positionBuffer, g_directionBuffer, g_directionBuffer, DIRECTION_BUFFER_PADDING, WIDTH, HEIGHT, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f); for (i = 0; i < WIDTH * HEIGHT * STACK_NODE_FLOATS * NUM_STACK_NODES; i++) { g_stackBuffer[i] = 0.0f; } printf("done!\n"); // // Buffers with the initial ray position and direction. // glGenBuffers(1, &g_directionSSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, g_directionSSBO); glBufferData(GL_SHADER_STORAGE_BUFFER, WIDTH * HEIGHT * (3 + DIRECTION_BUFFER_PADDING) * sizeof(GLfloat), g_directionBuffer, GL_STATIC_DRAW); // see binding = 1 in the shader glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, g_directionSSBO); // glGenBuffers(1, &g_positionSSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, g_positionSSBO); glBufferData(GL_SHADER_STORAGE_BUFFER, WIDTH * HEIGHT * 4 * sizeof(GLfloat), g_positionBuffer, GL_STATIC_DRAW); // see binding = 2 in the shader glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, g_positionSSBO); // glGenBuffers(1, &g_stackSSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, g_stackSSBO); glBufferData(GL_SHADER_STORAGE_BUFFER, WIDTH * HEIGHT * STACK_NODE_FLOATS * NUM_STACK_NODES * sizeof(GLfloat), g_stackBuffer, GL_STATIC_DRAW); // see binding = 3 in the shader glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, g_stackSSBO); // glGenBuffers(1, &g_sphereSSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, g_sphereSSBO); glBufferData(GL_SHADER_STORAGE_BUFFER, NUM_SPHERES * sizeof(Sphere), g_sphereBuffer, GL_STATIC_DRAW); // see binding = 4 in the shader glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, g_sphereSSBO); // glGenBuffers(1, &g_pointLightSSBO); glBindBuffer(GL_SHADER_STORAGE_BUFFER, g_pointLightSSBO); glBufferData(GL_SHADER_STORAGE_BUFFER, NUM_LIGHTS * sizeof(PointLight), g_lightBuffer, GL_STATIC_DRAW); // see binding = 5 in the shader glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, g_pointLightSSBO); // return GLUS_TRUE; }