void Textures::Bind(GLuint unit) { glActiveTexture(GL_TEXTURE0); glBindTexture(this->target, this->textureID); glBindImageTexture(unit, this->textureID, 0, GL_FALSE, 0, GL_WRITE_ONLY, gpuSideFormat); }
int main() { int width = 640; int height = 480; if(glfwInit() == GL_FALSE) { std::cerr << "failed to init GLFW" << std::endl; return 1; } glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 4); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 3); // create a window if(glfwOpenWindow(width, height, 0, 0, 0, 8, 24, 8, GLFW_WINDOW) == GL_FALSE) { std::cerr << "failed to open window" << std::endl; glfwTerminate(); return 1; } // setup windows close callback glfwSetWindowCloseCallback(closedWindow); glfwSwapInterval(0); if (gl3wInit()) { std::cerr << "failed to init GL3W" << std::endl; glfwCloseWindow(); glfwTerminate(); return 1; } // shader source code // the vertex shader simply passes through data std::string vertex_source = "#version 430\n" "layout(location = 0) in vec4 vposition;\n" "void main() {\n" " gl_Position = vposition;\n" "}\n"; // the geometry shader creates the billboard quads std::string geometry_source = "#version 430\n" "layout(location = 0) uniform mat4 View;\n" "layout(location = 1) uniform mat4 Projection;\n" "layout (points) in;\n" "layout (triangle_strip, max_vertices = 4) out;\n" "out vec2 txcoord;\n" "void main() {\n" " vec4 pos = View*gl_in[0].gl_Position;\n" " txcoord = vec2(-1,-1);\n" " gl_Position = Projection*(pos+0.2*vec4(txcoord,0,0));\n" " EmitVertex();\n" " txcoord = vec2( 1,-1);\n" " gl_Position = Projection*(pos+0.2*vec4(txcoord,0,0));\n" " EmitVertex();\n" " txcoord = vec2(-1, 1);\n" " gl_Position = Projection*(pos+0.2*vec4(txcoord,0,0));\n" " EmitVertex();\n" " txcoord = vec2( 1, 1);\n" " gl_Position = Projection*(pos+0.2*vec4(txcoord,0,0));\n" " EmitVertex();\n" "}\n"; // the fragment shader creates a bell like radial color distribution std::string fragment_source = "#version 330\n" "in vec2 txcoord;\n" "layout(location = 0) out vec4 FragColor;\n" "void main() {\n" " float s = (1/(1+15.*dot(txcoord, txcoord))-1/16.);\n" " FragColor = s*vec4(0.3,0.3,1.0,1);\n" "}\n"; // program and shader handles GLuint shader_program, vertex_shader, geometry_shader, fragment_shader; // we need these to properly pass the strings const char *source; int length; // create and compiler vertex shader vertex_shader = glCreateShader(GL_VERTEX_SHADER); source = vertex_source.c_str(); length = vertex_source.size(); glShaderSource(vertex_shader, 1, &source, &length); glCompileShader(vertex_shader); if(!check_shader_compile_status(vertex_shader)) { return 1; } // create and compiler geometry shader geometry_shader = glCreateShader(GL_GEOMETRY_SHADER); source = geometry_source.c_str(); length = geometry_source.size(); glShaderSource(geometry_shader, 1, &source, &length); glCompileShader(geometry_shader); if(!check_shader_compile_status(geometry_shader)) { return 1; } // create and compiler fragment shader fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); source = fragment_source.c_str(); length = fragment_source.size(); glShaderSource(fragment_shader, 1, &source, &length); glCompileShader(fragment_shader); if(!check_shader_compile_status(fragment_shader)) { return 1; } // create program shader_program = glCreateProgram(); // attach shaders glAttachShader(shader_program, vertex_shader); glAttachShader(shader_program, geometry_shader); glAttachShader(shader_program, fragment_shader); // link the program and check for errors glLinkProgram(shader_program); check_program_link_status(shader_program); std::string acceleration_source = "#version 430\n" "layout(local_size_x=256) in;\n" "layout(location = 0) uniform float dt;\n" "layout(rgba32f, location = 1) uniform imageBuffer positions;\n" "layout(rgba32f, location = 2) uniform imageBuffer velocities;\n" "void main() {\n" " int N = int(gl_NumWorkGroups.x*gl_WorkGroupSize.x);\n" " int index = int(gl_GlobalInvocationID);\n" " vec3 position = imageLoad(positions, index).xyz;\n" " vec3 velocity = imageLoad(velocities, index).xyz;\n" " vec3 acceleration = vec3(0,0,0);\n" " for(int i = 0;i<N;++i) {\n" " vec3 other = imageLoad(positions, i).xyz;\n" " vec3 diff = position - other;\n" " float dist = length(diff)+0.001;\n" " acceleration -= 0.1*diff/(dist*dist*dist);\n" " }\n" " imageStore(velocities, index, vec4(velocity+dt*acceleration,0));\n" "}\n"; // program and shader handles GLuint acceleration_program, acceleration_shader; // create and compiler vertex shader acceleration_shader = glCreateShader(GL_COMPUTE_SHADER); source = acceleration_source.c_str(); length = acceleration_source.size(); glShaderSource(acceleration_shader, 1, &source, &length); glCompileShader(acceleration_shader); if(!check_shader_compile_status(acceleration_shader)) { return 1; } // create program acceleration_program = glCreateProgram(); // attach shaders glAttachShader(acceleration_program, acceleration_shader); // link the program and check for errors glLinkProgram(acceleration_program); check_program_link_status(acceleration_program); std::string tiled_acceleration_source = "#version 430\n" "layout(local_size_x=256) in;\n" "layout(location = 0) uniform float dt;\n" "layout(rgba32f, location = 1) uniform imageBuffer positions;\n" "layout(rgba32f, location = 2) uniform imageBuffer velocities;\n" "layout(location = 3) uniform int tile;\n" "shared vec4 tmp[256];\n" "void main() {\n" " int index = int(gl_GlobalInvocationID);\n" " vec3 position = imageLoad(positions, index).xyz;\n" " vec3 velocity = imageLoad(velocities, index).xyz;\n" " vec3 acceleration = vec3(0,0,0);\n" " tmp[gl_LocalInvocationIndex] = imageLoad(positions, 256*tile + int(gl_LocalInvocationIndex));\n" " groupMemoryBarrier();\n" " barrier();\n" " for(int i = 0;i<gl_WorkGroupSize.x;++i) {\n" " vec3 other = tmp[i].xyz;\n" " vec3 diff = position - other;\n" " float invdist = 1/sqrt(dot(diff,diff)+0.00001);\n" " acceleration -= diff*0.1*invdist*invdist*invdist;\n" " }\n" " imageStore(velocities, index, vec4(velocity+dt*acceleration,0));\n" "}\n"; // program and shader handles GLuint tiled_acceleration_program, tiled_acceleration_shader; // create and compiler vertex shader tiled_acceleration_shader = glCreateShader(GL_COMPUTE_SHADER); source = tiled_acceleration_source.c_str(); length = tiled_acceleration_source.size(); glShaderSource(tiled_acceleration_shader, 1, &source, &length); glCompileShader(tiled_acceleration_shader); if(!check_shader_compile_status(tiled_acceleration_shader)) { return 1; } // create program tiled_acceleration_program = glCreateProgram(); // attach shaders glAttachShader(tiled_acceleration_program, tiled_acceleration_shader); // link the program and check for errors glLinkProgram(tiled_acceleration_program); check_program_link_status(tiled_acceleration_program); std::string integrate_source = "#version 430\n" "layout(local_size_x=256) in;\n" "layout(location = 0) uniform float dt;\n" "layout(rgba32f, location = 1) uniform imageBuffer positions;\n" "layout(rgba32f, location = 2) uniform imageBuffer velocities;\n" "void main() {\n" " int index = int(gl_GlobalInvocationID);\n" " vec4 position = imageLoad(positions, index);\n" " vec4 velocity = imageLoad(velocities, index);\n" " position.xyz += dt*velocity.xyz;\n" " imageStore(positions, index, position);\n" "}\n"; // program and shader handles GLuint integrate_program, integrate_shader; // create and compiler vertex shader integrate_shader = glCreateShader(GL_COMPUTE_SHADER); source = integrate_source.c_str(); length = integrate_source.size(); glShaderSource(integrate_shader, 1, &source, &length); glCompileShader(integrate_shader); if(!check_shader_compile_status(integrate_shader)) { return 1; } // create program integrate_program = glCreateProgram(); // attach shaders glAttachShader(integrate_program, integrate_shader); // link the program and check for errors glLinkProgram(integrate_program); check_program_link_status(integrate_program); const int particles = 32*1024; // randomly place particles in a cube std::vector<glm::vec4> positionData(particles); std::vector<glm::vec4> velocityData(particles); for(int i = 0;i<particles;++i) { // initial position positionData[i] = glm::vec4( 1.5f-(float(std::rand())/RAND_MAX+float(std::rand())/RAND_MAX+float(std::rand())/RAND_MAX), 1.5f-(float(std::rand())/RAND_MAX+float(std::rand())/RAND_MAX+float(std::rand())/RAND_MAX), 1.5f-(float(std::rand())/RAND_MAX+float(std::rand())/RAND_MAX+float(std::rand())/RAND_MAX), 0 ); positionData[i] = glm::vec4(0.0f,0.0f,0.0f,1) + glm::vec4(4.0f,1.0f,4.0f,1)*positionData[i]; velocityData[i] = 40.0f*glm::vec4(glm::cross(glm::vec3(positionData[i].xyz()), glm::vec3(0,1,0)), 0)/glm::dot(glm::vec3(positionData[i].xyz()),glm::vec3(positionData[i].xyz())); } // generate positions_vbos and vaos GLuint vao, positions_vbo, velocities_vbo; glGenVertexArrays(1, &vao); glGenBuffers(1, &positions_vbo); glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, positions_vbo); // fill with initial data glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec4)*particles, &positionData[0], GL_STATIC_DRAW); // set up generic attrib pointers glEnableVertexAttribArray(0); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4*sizeof(GLfloat), (char*)0 + 0*sizeof(GLfloat)); // "unbind" vao glBindVertexArray(0); glm::vec4 zero(0,0,0,0); glGenBuffers(1, &velocities_vbo); glBindBuffer(GL_TEXTURE_BUFFER, velocities_vbo); glBufferData(GL_TEXTURE_BUFFER, sizeof(glm::vec4)*particles, &velocityData[0], GL_STATIC_DRAW); // texture handle GLuint positions_texture, velocities_texture; glGenTextures(1, &positions_texture); glBindTexture(GL_TEXTURE_BUFFER, positions_texture); glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, positions_vbo); glGenTextures(1, &velocities_texture); glBindTexture(GL_TEXTURE_BUFFER, velocities_texture); glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, velocities_vbo); // bind images glBindImageTexture(0, positions_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); glBindImageTexture(1, velocities_texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); // physical parameters float dt = 1.0f/60.0f; // setup uniforms glUseProgram(tiled_acceleration_program); glUniform1f(0, dt); glUniform1i(1, 0); glUniform1i(2, 1); glUseProgram(acceleration_program); glUniform1f(0, dt); glUniform1i(1, 0); glUniform1i(2, 1); glUseProgram(integrate_program); glUniform1f(0, dt); glUniform1i(1, 0); glUniform1i(2, 1); // we are blending so no depth testing glDisable(GL_DEPTH_TEST); // enable blending glEnable(GL_BLEND); // and set the blend function to result = 1*source + 1*destination glBlendFunc(GL_ONE, GL_ONE); GLuint query; glGenQueries(1, &query); bool tiled = false; bool space_down = false; running = true; while(running) { // get the time in seconds float t = glfwGetTime(); // terminate on excape if(glfwGetKey(GLFW_KEY_ESC)) { running = false; } // toggle occlusion culling if(glfwGetKey(GLFW_KEY_SPACE) && !space_down) { tiled = !tiled; } space_down = glfwGetKey(GLFW_KEY_SPACE); glBeginQuery(GL_TIME_ELAPSED, query); if(tiled) { glUseProgram(tiled_acceleration_program); int tiles = particles/256; for(int tile = 0;tile<tiles;++tile) { glUniform1i(3, tile); glDispatchCompute(particles/256, 1, 1); } } else { glUseProgram(acceleration_program); glDispatchCompute(particles/256, 1, 1); } glEndQuery(GL_TIME_ELAPSED); glUseProgram(integrate_program); glDispatchCompute(particles/256, 1, 1); // clear first glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // use the shader program glUseProgram(shader_program); // calculate ViewProjection matrix glm::mat4 Projection = glm::perspective(90.0f, 4.0f / 3.0f, 0.1f, 100.f); // translate the world/view position glm::mat4 View = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -30.0f)); // tilt the camera View = glm::rotate(View, 30.0f, glm::vec3(1.0f, 0.0f, 0.0f)); // set the uniforms glUniformMatrix4fv(0, 1, GL_FALSE, glm::value_ptr(View)); glUniformMatrix4fv(1, 1, GL_FALSE, glm::value_ptr(Projection)); // bind the current vao glBindVertexArray(vao); // draw glDrawArrays(GL_POINTS, 0, particles); // check for errors GLenum error = glGetError(); if(error != GL_NO_ERROR) { std::cerr << gluErrorString(error); running = false; } // finally swap buffers glfwSwapBuffers(); { GLuint64 result; glGetQueryObjectui64v(query, GL_QUERY_RESULT, &result); std::cout << result*1.e-6 << " ms/frame" << std::endl; } } // delete the created objects glDeleteVertexArrays(1, &vao); glDeleteBuffers(1, &positions_vbo); glDeleteBuffers(1, &velocities_vbo); glDeleteTextures(1, &positions_texture); glDeleteTextures(1, &velocities_texture); glDetachShader(shader_program, vertex_shader); glDetachShader(shader_program, geometry_shader); glDetachShader(shader_program, fragment_shader); glDeleteShader(vertex_shader); glDeleteShader(geometry_shader); glDeleteShader(fragment_shader); glDeleteProgram(shader_program); glDetachShader(acceleration_program, acceleration_shader); glDeleteShader(acceleration_shader); glDeleteProgram(acceleration_program); glfwCloseWindow(); glfwTerminate(); return 0; }
int main(int argc, char **argv) { GLFWwindow *window; GLfloat *temperatures = NULL, *temperatures2 = NULL, *temperature_buf = NULL ; GLint coord2d_location, textureSampler_location, vertexUv_location, width_location ; GLuint compute_program, ebo, height, window_height, program, ssbo, texture, width, window_width, work_group_width, vao, vbo ; char *compute_shader_source, *work_group_width_str; double cursor_pos_x = 0.0, cursor_pos_y = 0.0, window_grid_ratio_x = 0.0, window_grid_ratio_y = 0.0 ; int cpu, step = 0, which_boundary; float conduction_coeff; size_t n_temperatures, square_x, square_y, square_width, square_height ; unsigned int steps_per_frame, window_x; /* CLI arguments. */ if (argc > 1) { width = strtol(argv[1], NULL, 10); } else { width = WIDTH; } height = width; if (argc > 2) { window_width = strtol(argv[2], NULL, 10); } else { window_width = WINDOW_WIDTH; } window_height = window_width; if (argc > 3) { work_group_width = strtol(argv[3], NULL, 10); } else { work_group_width = WORK_GROUP_WIDTH; } if (argc > 4) { cpu = (argv[4][0] == '1'); } else { cpu = 0; } /* TODO remove this when we implement GPU. */ cpu = 1; /* Must be between 0.0 and 1.0. * * Physics allows it to be in 0 / infinity. * * Anything greater than 1.0 leads to numeric instabilities * for our simplistic method. For example, the following: * * 1.0 * * 1.0 0.0 1.0 * * 1.0 * * the center point goes above its surroundings on the next time step (2.0) * for a conduction coefficient of 2.0. * * Negative values make temperatures unbounded and breaks energy conservation. * * But you obviously will try out "bad" values in the simulation to see what happens. * The behaviour of this value around 1.99, 2.0, 2.01, 3.0 is specially interesting. * * At 0.0, the system does not evolve. Your mouse heat source becomes a permanent pen. * The close to one, the faster your writting dissipates. * */ conduction_coeff = 1.0; if (argc > 5) { conduction_coeff = strtod(argv[5], NULL); } which_boundary = 0; if (argc > 6) { which_boundary = strtol(argv[6], NULL, 10); } /* Ideally set to make simulation be 60 FPS. */ steps_per_frame = 1; if (argc > 7) { steps_per_frame = strtol(argv[7], NULL, 10); } window_x = 0; if (argc > 8) { window_x = strtol(argv[8], NULL, 10); } square_x = width / 2; square_y = height / 2; square_width = width / 20; square_height = height / 20; window_grid_ratio_x = width / (double)window_width; window_grid_ratio_y = height / (double)window_height; /* Window. */ glfwInit(); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); window = glfwCreateWindow(window_width, window_height, __FILE__, NULL, NULL); glfwSetWindowPos(window, window_x, 0); glfwMakeContextCurrent(window); glfwSwapInterval(1); glewInit(); /* Shader. */ program = common_get_shader_program(vertex_shader_source, fragment_shader_source); coord2d_location = glGetAttribLocation(program, "coord2d"); vertexUv_location = glGetAttribLocation(program, "vertexUv"); textureSampler_location = glGetUniformLocation(program, "textureSampler"); if (!cpu) { /* Compute shader. */ int work_group_width_len = snprintf(NULL, 0, "%d", work_group_width); size_t compute_shader_source_len = sizeof(compute_shader_source_template) + 2 * work_group_width_len; compute_shader_source = malloc(compute_shader_source_len); snprintf( compute_shader_source, compute_shader_source_len, compute_shader_source_template, work_group_width, work_group_width ); compute_program = common_get_compute_program(compute_shader_source); free(compute_shader_source); width_location = glGetUniformLocation(compute_program, "width"); } /* vbo */ glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices_xy_uv), vertices_xy_uv, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); /* ebo */ glGenBuffers(1, &ebo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); /* vao */ glGenVertexArrays(1, &vao); glBindVertexArray(vao); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glVertexAttribPointer(coord2d_location, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(vertices_xy_uv[0]), (GLvoid*)0); glEnableVertexAttribArray(coord2d_location); glVertexAttribPointer(vertexUv_location, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(vertices_xy_uv[0]), (GLvoid*)(2 * sizeof(vertices_xy_uv[0]))); glEnableVertexAttribArray(vertexUv_location); glBindVertexArray(0); /* ssbo */ srand(time(NULL)); n_temperatures = width * height; temperatures = malloc(n_temperatures * sizeof(temperatures[0])); /* Initial condition. TODO: make continuous with boundary conditions. */ for (size_t i = 1; i < height - 1; ++i) { for (size_t j = 1; j < width - 1; ++j) { temperatures[i * width + j] = 0.0; } } if (cpu) { temperatures2 = malloc(n_temperatures * sizeof(temperatures[0])); /* Boundary must also be initialized for this buffer, * since the boundary is never touched after the beginning. */ init_boundary(temperatures2, width, height, which_boundary, step); } else { glGenBuffers(1, &ssbo); glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo); glBufferData(GL_SHADER_STORAGE_BUFFER, n_temperatures * sizeof(temperatures[0]), temperatures, GL_DYNAMIC_COPY); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo); glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); free(temperatures); } /* Texture. */ glGenTextures(1, &texture); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); if (!cpu) { glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, width, height, 0, GL_RED, GL_FLOAT, NULL); /* Bind to image unit so can write to specific pixels from the compute shader. */ glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32F); } /* Constant state. */ glViewport(0, 0, window_width, window_height); glClearColor(1.0f, 1.0f, 1.0f, 1.0f); /* Main loop. */ common_fps_init(); while (!glfwWindowShouldClose(window)) { if (cpu) { for ( unsigned int steps_this_frame = 0; steps_this_frame < steps_per_frame; ++steps_this_frame ) { glfwPollEvents(); glfwGetCursorPos(window, &cursor_pos_x, &cursor_pos_y); glfwSetMouseButtonCallback(window, mouse_button_callback); square_x = width - (cursor_pos_x * window_grid_ratio_y); square_y = cursor_pos_y * window_grid_ratio_y; moving_boundary_set_square( temperatures, width, height, square_x, square_y, square_width, square_height, moving_boundary_value ); init_boundary(temperatures, width, height, which_boundary, step); for (unsigned int i = 1; i < height - 1; ++i) { for (unsigned int j = 1; j < width - 1; ++j) { size_t idx = i * width + j; temperatures2[idx] = (1.0 - conduction_coeff) * temperatures2[idx] + conduction_coeff * ( temperatures[idx - 1] + temperatures[idx + 1] + temperatures[idx - width] + temperatures[idx + width] ) / 4.0; } } /* Swap old and new. */ temperature_buf = temperatures; temperatures = temperatures2; temperatures2 = temperature_buf; step++; } glTexImage2D( GL_TEXTURE_2D, 0, GL_RED, width, height, 0, GL_RED, GL_FLOAT, temperatures2 ); } else { /* Compute. */ glUseProgram(compute_program); glUniform1ui(width_location, width); glDispatchCompute((GLuint)width / work_group_width, (GLuint)height / work_group_width, 1); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); } /* Draw. */ glClear(GL_COLOR_BUFFER_BIT); glUseProgram(program); glUniform1i(textureSampler_location, 0); glBindVertexArray(vao); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glBindVertexArray(0); glfwSwapBuffers(window); glfwPollEvents(); common_fps_print(); } /* Cleanup. */ glDeleteBuffers(1, &ebo); if (cpu) { free(temperatures); free(temperatures2); } else { glDeleteBuffers(1, &ssbo); } glDeleteBuffers(1, &vbo); glDeleteVertexArrays(1, &vao); glDeleteTextures(1, &texture); glDeleteProgram(program); glDeleteProgram(compute_program); glfwTerminate(); return EXIT_SUCCESS; }
static void triangle_normal(void) { FILE* file; GLubyte* data; GLuint textureObject[3]; GLuint pbo[1]; // load texture glGenTextures(3, textureObject); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textureObject[0]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_R8UI, encoded_width / 4 * 8, encoded_height / 4, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, textureData); glBindTexture(GL_TEXTURE_2D, textureObject[1]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, encoded_width, encoded_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); // compute etc1 glUseProgram(computeProgramETC1); // assume output image unit is 0 glUniform1i(u_OutComputeETC1, 0); // assume input image unit is 1 glUniform1i(u_TextureComputeETC1, 1); glBindImageTexture(0, textureObject[1], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8); glBindImageTexture(1, textureObject[0], 0, GL_FALSE, 0, GL_READ_ONLY, GL_R8UI); glDispatchCompute(encoded_width / 4, encoded_height / 4, 1); // image memory barrier glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); // compute s3tc glUseProgram(computeProgramS3TC); glGenBuffers(1, pbo); glBindBuffer(GL_SHADER_STORAGE_BUFFER, pbo[0]); glBufferData(GL_SHADER_STORAGE_BUFFER, encoded_width * encoded_height / 2, NULL, GL_DYNAMIC_COPY); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 10, pbo[0]); glBindImageTexture(0, textureObject[1], 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8); // assume input image unit is 1 glUniform1i(u_TextureComputeS3TC, 0); glDispatchCompute(encoded_width / 4, encoded_height / 4, 1); // pixel buffer barrier glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT | GL_PIXEL_BUFFER_BARRIER_BIT); glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); // init the render texture glBindTexture(GL_TEXTURE_2D, textureObject[2]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo[0]); glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, encoded_width, encoded_height, 0, encoded_width * encoded_height / 2, NULL); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); // render glUseProgram(renderProgram); glBindBuffer(GL_ARRAY_BUFFER, vertexBufferName); glVertexAttribPointer(a_Position, numVertexComponents, GL_FLOAT, GL_FALSE, stride, 0); glUniform1i(u_TextureRender, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, numElements); glDeleteTextures(3, textureObject); glDeleteBuffers(1, pbo); checkError("triangle_normal"); }
GLUSboolean init(GLUSvoid) { GLUStextfile vertexSource; GLUStextfile fragmentSource; GLUStextfile computeSource; GLUSshape plane; glusFileLoadText("../Example21/shader/texture.vert.glsl", &vertexSource); glusFileLoadText("../Example21/shader/texture.frag.glsl", &fragmentSource); glusProgramBuildFromSource(&g_program, (const GLchar**) &vertexSource.text, 0, 0, 0, (const GLchar**) &fragmentSource.text); glusFileDestroyText(&vertexSource); glusFileDestroyText(&fragmentSource); glusFileLoadText("../Example21/shader/texture.comp.glsl", &computeSource); glusProgramBuildComputeFromSource(&g_computeProgram, (const GLchar**) &computeSource.text); glusFileDestroyText(&computeSource); // // Retrieve the uniform locations in the program. g_modelViewProjectionMatrixLocation = glGetUniformLocation(g_program.program, "u_modelViewProjectionMatrix"); g_textureLocation = glGetUniformLocation(g_program.program, "u_texture"); g_vertexLocation = glGetAttribLocation(g_program.program, "a_vertex"); g_texCoordLocation = glGetAttribLocation(g_program.program, "a_texCoord"); g_computeTextureLocation = glGetUniformLocation(g_computeProgram.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); // // Use a helper function to create a rectangular plane. glusShapeCreateRectangularPlanef(&plane, (GLfloat) g_imageWidth / 2.0f, (GLfloat) g_imageHeight / 2.0f); // Store the number indices, as we will render with glDrawElements. g_numberIndicesPlane = plane.numberIndices; glGenBuffers(1, &g_verticesVBO); glBindBuffer(GL_ARRAY_BUFFER, g_verticesVBO); glBufferData(GL_ARRAY_BUFFER, plane.numberVertices * 4 * sizeof(GLfloat), (GLfloat*) plane.vertices, GL_STATIC_DRAW); glGenBuffers(1, &g_texCoordsVBO); glBindBuffer(GL_ARRAY_BUFFER, g_texCoordsVBO); glBufferData(GL_ARRAY_BUFFER, plane.numberVertices * 2 * sizeof(GLfloat), (GLfloat*) plane.texCoords, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); // Generate a VBO for the indices. glGenBuffers(1, &g_indicesVBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_indicesVBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, plane.numberIndices * sizeof(GLuint), (GLuint*) plane.indices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // Now we can destroy the shape, as all data is now on the GPU. glusShapeDestroyf(&plane); // glUseProgram(g_program.program); glGenVertexArrays(1, &g_vao); glBindVertexArray(g_vao); glBindBuffer(GL_ARRAY_BUFFER, g_verticesVBO); glVertexAttribPointer(g_vertexLocation, 4, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(g_vertexLocation); glBindBuffer(GL_ARRAY_BUFFER, g_texCoordsVBO); glVertexAttribPointer(g_texCoordLocation, 2, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(g_texCoordLocation); // Also bind the indices to the VAO. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_indicesVBO); // // Also bind created texture ... glBindTexture(GL_TEXTURE_2D, g_texture); // ... and bind this texture as an image, as we will write to it. 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); // Pass texture number 0 to the compute shader as well. glUniform1i(g_computeTextureLocation, 0); // glClearColor(0.0f, 0.0f, 0.0f, 0.0f); return GLUS_TRUE; }
void DispatchVoxelizeComputeShader::call() { // use compute program p_computeShader->useProgram(); // unbind output texture p_voxelGrid->texture->unbindFromActiveUnit(); // upload output texture glBindImageTexture(0, p_voxelGrid->handle, 0, GL_FALSE, 0, GL_READ_WRITE, // allow both GL_R32UI); // 1 channel 32 bit unsigned int to make sure OR-ing works // upload bit mask glBindImageTexture(1, p_bitMask->getTextureHandle(), 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI ); double totalExecutionTime = 0.0; // dispatch this shader once per object for ( unsigned int i = 0; i < m_objects.size(); i++) { Object* object = m_objects[i].first; RenderableNode* objectNode = m_objects[i].second; int numVertices = 0; int numIndices = 0; int numFaces = 0; if ( object->getModel() ) { // bind positions VBO to shader storage buffer glBindBufferBase( GL_SHADER_STORAGE_BUFFER, // target 0, // target binding index object->getModel()->getPositionBufferHandle() ); // buffer numVertices = object->getModel()->getNumVertices(); // bind index buffer glBindBufferBase( GL_SHADER_STORAGE_BUFFER, // target 1, // target binding index object->getModel()->getIndexBufferHandle() ); // buffer numIndices = object->getModel()->getNumIndices(); numFaces = object->getModel()->getNumFaces(); } else { continue; } glm::mat4 modelMatrix = glm::mat4(1.0f); if (objectNode) { modelMatrix = objectNode->getAccumulatedModelMatrix(); } // upload uniform model matrix p_computeShader->uploadUniform( modelMatrix, "uniformModel"); // upload voxel grid info p_computeShader->uploadUniform( p_voxelGrid->worldToVoxel, "uniformWorldToVoxel"); // upload geometric info p_computeShader->uploadUniform( numVertices, "uniformNumVertices"); p_computeShader->uploadUniform( numIndices, "uniformNumIndices"); p_computeShader->uploadUniform( numFaces, "uniformNumFaces"); // set local group amount suitable for object size: m_num_groups_x = numFaces / p_computeShader->getLocalGroupSizeX() + ( ( numFaces % p_computeShader->getLocalGroupSizeX() == 0 ) ? 0 : 1 ); m_num_groups_y = 1; m_num_groups_z = 1; // dispatch as usual DispatchComputeShaderListener::call(); glMemoryBarrier( GL_ALL_BARRIER_BITS ); if ( m_queryTime ) { totalExecutionTime += m_executionTime; } } if ( m_queryTime ) { m_executionTime = totalExecutionTime; } // unbind image textures glBindImageTexture(0, 0, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI); glBindImageTexture(1, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI); }
bool upload_image_levels(const struct image_info img, unsigned num_levels, unsigned level, unsigned unit, const uint32_t *pixels) { const unsigned m = image_num_components(img.format); int i, l; if (get_texture(unit)) { glDeleteTextures(1, &textures[unit]); textures[unit] = 0; } if (get_buffer(unit)) { glDeleteBuffers(1, &buffers[unit]); buffers[unit] = 0; } glGenTextures(1, &textures[unit]); glBindTexture(img.target->target, textures[unit]); switch (img.target->target) { case GL_TEXTURE_1D: for (l = 0; l < num_levels; ++l) { const struct image_extent size = image_level_size(img, l); glTexImage1D(GL_TEXTURE_1D, l, img.format->format, size.x, 0, img.format->pixel_format, image_base_type(img.format), &pixels[m * image_level_offset(img, l)]); } break; case GL_TEXTURE_2D: for (l = 0; l < num_levels; ++l) { const struct image_extent size = image_level_size(img, l); glTexImage2D(GL_TEXTURE_2D, l, img.format->format, size.x, size.y, 0, img.format->pixel_format, image_base_type(img.format), &pixels[m * image_level_offset(img, l)]); } break; case GL_TEXTURE_3D: for (l = 0; l < num_levels; ++l) { const struct image_extent size = image_level_size(img, l); glTexImage3D(GL_TEXTURE_3D, l, img.format->format, size.x, size.y, size.z, 0, img.format->pixel_format, image_base_type(img.format), &pixels[m * image_level_offset(img, l)]); } break; case GL_TEXTURE_RECTANGLE: assert(num_levels == 1); glTexImage2D(GL_TEXTURE_RECTANGLE, 0, img.format->format, img.size.x, img.size.y, 0, img.format->pixel_format, image_base_type(img.format), pixels); break; case GL_TEXTURE_CUBE_MAP: for (l = 0; l < num_levels; ++l) { const unsigned offset = m * image_level_offset(img, l); const struct image_extent size = image_level_size(img, l); const unsigned face_sz = m * product(size) / 6; for (i = 0; i < 6; ++i) glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, l, img.format->format, size.x, size.y, 0, img.format->pixel_format, image_base_type(img.format), &pixels[offset + face_sz * i]); } break; case GL_TEXTURE_BUFFER: { /* * glTexImage*() isn't supposed to work with buffer * textures. We copy the unpacked pixels to a texture * with the desired internal format to let the GL pack * them for us. */ const struct image_extent grid = image_optimal_extent(img.size); GLuint packed_tex; assert(num_levels == 1); glGenBuffers(1, &buffers[unit]); glBindBuffer(GL_PIXEL_PACK_BUFFER, buffers[unit]); glBufferData(GL_PIXEL_PACK_BUFFER, img.size.x * image_pixel_size(img.format) / 8, NULL, GL_STATIC_DRAW); glGenTextures(1, &packed_tex); glBindTexture(GL_TEXTURE_2D, packed_tex); glTexImage2D(GL_TEXTURE_2D, 0, img.format->format, grid.x, grid.y, 0, img.format->pixel_format, image_base_type(img.format), pixels); glGetTexImage(GL_TEXTURE_2D, 0, img.format->pixel_format, img.format->pixel_type, NULL); glDeleteTextures(1, &packed_tex); glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); glTexBuffer(GL_TEXTURE_BUFFER, image_compat_format(img.format), buffers[unit]); break; } case GL_TEXTURE_1D_ARRAY: for (l = 0; l < num_levels; ++l) { const struct image_extent size = image_level_size(img, l); glTexImage2D(GL_TEXTURE_1D_ARRAY, l, img.format->format, size.x, size.y, 0, img.format->pixel_format, image_base_type(img.format), &pixels[m * image_level_offset(img, l)]); } break; case GL_TEXTURE_2D_ARRAY: for (l = 0; l < num_levels; ++l) { const struct image_extent size = image_level_size(img, l); glTexImage3D(GL_TEXTURE_2D_ARRAY, l, img.format->format, size.x, size.y, size.z, 0, img.format->pixel_format, image_base_type(img.format), &pixels[m * image_level_offset(img, l)]); } break; case GL_TEXTURE_CUBE_MAP_ARRAY: for (l = 0; l < num_levels; ++l) { const struct image_extent size = image_level_size(img, l); glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, l, img.format->format, size.x, size.y, size.z, 0, img.format->pixel_format, image_base_type(img.format), &pixels[m * image_level_offset(img, l)]); } break; case GL_TEXTURE_2D_MULTISAMPLE: case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: { /* * GL doesn't seem to provide any direct way to * initialize a multisample texture, so we use * imageStore() to render to it from the fragment * shader copying the contents of a larger * single-sample 2D texture. */ const struct grid_info grid = { get_image_stage(GL_FRAGMENT_SHADER)->bit, img.format, image_optimal_extent(img.size) }; GLuint prog = generate_program( grid, GL_FRAGMENT_SHADER, concat(image_hunk(image_info_for_grid(grid), "SRC_"), image_hunk(img, "DST_"), hunk("readonly SRC_IMAGE_UNIFORM_T src_img;\n" "writeonly DST_IMAGE_UNIFORM_T dst_img;\n" "\n" "GRID_T op(ivec2 idx, GRID_T x) {\n" " imageStore(dst_img, DST_IMAGE_ADDR(idx),\n" " imageLoad(src_img, SRC_IMAGE_ADDR(idx)));\n" " return x;\n" "}\n"), NULL)); bool ret = prog && generate_fb(grid, 1); GLuint tmp_tex; assert(num_levels == 1); glGenTextures(1, &tmp_tex); glBindTexture(GL_TEXTURE_2D, tmp_tex); if (img.target->target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) { glTexImage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, img.size.x, img.format->format, img.size.y, img.size.z, img.size.w, GL_FALSE); } else { glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, img.size.x, img.format->format, img.size.y, img.size.z, GL_FALSE); } glTexImage2D(GL_TEXTURE_2D, 0, img.format->format, grid.size.x, grid.size.y, 0, img.format->pixel_format, image_base_type(img.format), pixels); glBindImageTexture(unit, textures[unit], 0, GL_TRUE, 0, GL_WRITE_ONLY, img.format->format); glBindImageTexture(6, tmp_tex, 0, GL_TRUE, 0, GL_READ_ONLY, img.format->format); ret &= set_uniform_int(prog, "src_img", 6) && set_uniform_int(prog, "dst_img", unit) && draw_grid(grid, prog); glDeleteProgram(prog); glDeleteTextures(1, &tmp_tex); glBindFramebuffer(GL_FRAMEBUFFER, fb[0]); glViewportIndexedfv(0, vp[0]); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); if (!ret) return false; break; } default: abort(); } glBindImageTexture(unit, textures[unit], level, GL_TRUE, 0, GL_READ_WRITE, img.format->format); return piglit_check_gl_error(GL_NO_ERROR); }
void OpenGLWidget::resizeGL(int w, int h) { WINDOW_WIDTH = w; WINDOW_HEIGHT = h; RATIO = float(float(WINDOW_WIDTH) / float(WINDOW_HEIGHT)); IMAGE_WIDTH = BLOCKS_TOTAL_HORIZONTAL * BLOCK_WIDTH; IMAGE_HEIGHT = BLOCKS_TOTAL_VERTICAL * BLOCK_HEIGHT; pane->config(QRect(0, 0, WINDOW_WIDTH / 5, WINDOW_HEIGHT), QRect(-WINDOW_WIDTH / 5, 0, WINDOW_WIDTH / 5, WINDOW_HEIGHT)); ::anim->config(QRect(WINDOW_WIDTH * 0.8, 0, WINDOW_WIDTH / 5, WINDOW_HEIGHT), QRect(WINDOW_WIDTH, 0, WINDOW_WIDTH / 5, WINDOW_HEIGHT)); animButton->setGeometry(QRect(WINDOW_WIDTH - 25, 0, 25, 25)); // Create block vertices { int a = BLOCKS_TOTAL_VERTICAL / 2; int b = (BLOCKS_TOTAL_VERTICAL + 1) - a; int m = BLOCKS_TOTAL_HORIZONTAL / 2; int n = (BLOCKS_TOTAL_HORIZONTAL + 1) - m; vertices.clear(); // Tesselate render area with triangles for (int i = -a; i < b; ++i) { for (int j = -m; j < n; ++j) { float x = float(j) / (BLOCKS_HORIZONTAL / 2); float y = float(i) / (BLOCKS_VERTICAL / 2); vertices.push_back(x); // X co-ord vertices.push_back(y); // Y co-ord vertices.push_back(0.0f); // Z co-ord (0 because on a flat plane) } } } // Create block indices (works with vertex co-ords for more efficient rendering) { int a = BLOCKS_TOTAL_HORIZONTAL + 1; indices.clear(); // Loop through each triangle pair (square) getting their vertices in order for (int i = 0; i < BLOCKS_TOTAL_VERTICAL; ++i) { for (int j = 0; j < BLOCKS_TOTAL_HORIZONTAL; ++j) { int index = ((i * a) + j) * 6; indices.push_back((i * a) + j); // Top left indices.push_back((i * a) + 1 + j); // Top right indices.push_back((i * a) + 1 + a + j); // Bottom right indices.push_back((i * a) + j); // Top left indices.push_back((i * a) + a + j); // Bottom left indices.push_back((i * a) + a + 1 + j); // Bottom right } } } m_vao.bind(); QOpenGLBuffer m_vvbo(QOpenGLBuffer::VertexBuffer); m_vvbo.create(); m_vvbo.bind(); m_vvbo.setUsagePattern(QOpenGLBuffer::StaticDraw); m_vvbo.allocate(vertices.data(), vertices.size() * sizeof(float)); QOpenGLBuffer m_ebo(QOpenGLBuffer::IndexBuffer); m_ebo.create(); m_ebo.bind(); m_ebo.setUsagePattern(QOpenGLBuffer::StaticDraw); m_ebo.allocate(indices.data(), indices.size() * sizeof(int)); m_vao.release(); m_vvbo.release(); m_ebo.release(); glDeleteTextures(1, tex); glGenTextures(1, tex); glBindTexture(GL_TEXTURE_2D, tex[0]); glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32F, IMAGE_WIDTH, IMAGE_HEIGHT); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, GL_RED, GL_FLOAT, NULL); glBindTexture(GL_TEXTURE_2D, NULL); fractal.computeProgram->bind(); glBindImageTexture(0, tex[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F); fractal.computeProgram->release(); fractal.renderProgram->bind(); m_vao.bind(); m_vvbo.bind(); fractal.renderProgram->enableAttributeArray("position"); fractal.renderProgram->setAttributeBuffer("position", GL_FLOAT, 0, 3); m_vvbo.release(); m_vao.release(); glBindImageTexture(0, tex[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F); fractal.renderProgram->release(); rendermodeLR = ALL; }
GLUSboolean init(GLUSvoid) { GLint i; 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, 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; }
int main() { int width = 512; int height = 512; if(glfwInit() == GL_FALSE) { std::cerr << "failed to init GLFW" << std::endl; return 1; } // select opengl version glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 4); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 2); // create a window if(glfwOpenWindow(width, height, 0, 0, 0, 8, 24, 8, GLFW_WINDOW) == GL_FALSE) { std::cerr << "failed to open window" << std::endl; glfwTerminate(); return 1; } // setup windows close callback glfwSetWindowCloseCallback(closedWindow); if (gl3wInit()) { std::cerr << "failed to init GL3W" << std::endl; glfwCloseWindow(); glfwTerminate(); return 1; } glfwSwapInterval(1); // shader source code // shared vertex shader std::string vertex_source = "#version 420\n" "layout(location = 0) in vec4 vposition;\n" "void main() {\n" " gl_Position = vposition;\n" "}\n"; // the first fragment shader doesn't output anything since it only // updates the image in place std::string fragment1_source = "#version 420\n" "uniform float dt;\n" "uniform ivec2 image_size;\n" "uniform layout(rgba32f) image2D image;\n" "layout(location = 0) out vec4 FragColor;\n" "void main() {\n" " ivec2 coords = ivec2(gl_FragCoord.xy);\n" " vec4 HE = imageLoad(image, coords);\n" " float Ezdx = HE.z-imageLoad(image, coords-ivec2(1, 0)).z;\n" " float Ezdy = HE.z-imageLoad(image, coords-ivec2(0, 1)).z;\n" " HE.xy += dt*vec2(-Ezdy, Ezdx);\n" " imageStore(image, coords, HE);\n" "}\n"; // the second fragment shader also outputs the frag color for display // purposes std::string fragment2_source = "#version 420\n" "uniform float t;\n" "uniform float dt;\n" "uniform ivec2 image_size;\n" "uniform layout(rgba32f) image2D image;\n" "layout(location = 0) out vec4 FragColor;\n" "void main() {\n" " ivec2 coords = ivec2(gl_FragCoord.xy);\n" " float e = 1;\n" " vec4 HE = imageLoad(image, coords);\n" " float r = HE.w;\n" " float Hydx = imageLoad(image, coords+ivec2(1, 0)).y\n" " -HE.y;\n" " float Hxdy = imageLoad(image, coords+ivec2(0, 1)).x\n" " -HE.x;\n" " float Eout = dt*(Hydx-Hxdy)/(e);\n" " HE.z = HE.z*(1-dt*r/e) + Eout;\n" // add source at image center " if(coords.x == image_size.x/2 && coords.y == image_size.y/2) {\n" " HE.z += 30*sin(15*t)*exp(-10*(t-2)*(t-2));\n" " }\n" " imageStore(image, coords, HE);\n" " FragColor = vec4(HE.z, HE.w, -HE.z, 1);\n" "}\n"; // program and shader handles GLuint shader1_program, shader2_program, vertex_shader, fragment1_shader, fragment2_shader; // we need these to properly pass the strings const char *source; int length; // create and compiler vertex shader vertex_shader = glCreateShader(GL_VERTEX_SHADER); source = vertex_source.c_str(); length = vertex_source.size(); glShaderSource(vertex_shader, 1, &source, &length); glCompileShader(vertex_shader); if(!check_shader_compile_status(vertex_shader)) { return 1; } // create and compiler fragment shader fragment1_shader = glCreateShader(GL_FRAGMENT_SHADER); source = fragment1_source.c_str(); length = fragment1_source.size(); glShaderSource(fragment1_shader, 1, &source, &length); glCompileShader(fragment1_shader); if(!check_shader_compile_status(fragment1_shader)) { return 1; } // create and compiler fragment shader fragment2_shader = glCreateShader(GL_FRAGMENT_SHADER); source = fragment2_source.c_str(); length = fragment2_source.size(); glShaderSource(fragment2_shader, 1, &source, &length); glCompileShader(fragment2_shader); if(!check_shader_compile_status(fragment2_shader)) { return 1; } // create program shader1_program = glCreateProgram(); // attach shaders glAttachShader(shader1_program, vertex_shader); glAttachShader(shader1_program, fragment1_shader); // link the program and check for errors glLinkProgram(shader1_program); check_program_link_status(shader1_program); // get texture uniform location GLint image_size_location1 = glGetUniformLocation(shader1_program, "image_size"); GLint image_location1 = glGetUniformLocation(shader1_program, "image"); GLint dt_location1 = glGetUniformLocation(shader1_program, "dt"); // create program shader2_program = glCreateProgram(); // attach shaders glAttachShader(shader2_program, vertex_shader); glAttachShader(shader2_program, fragment2_shader); // link the program and check for errors glLinkProgram(shader2_program); check_program_link_status(shader2_program); // get texture uniform location GLint image_size_location2 = glGetUniformLocation(shader2_program, "image_size"); GLint image_location2 = glGetUniformLocation(shader2_program, "image"); GLint t_location2 = glGetUniformLocation(shader2_program, "t"); GLint dt_location2 = glGetUniformLocation(shader2_program, "dt"); // vao and vbo handle GLuint vao, vbo, ibo; // generate and bind the vao glGenVertexArrays(1, &vao); glBindVertexArray(vao); // generate and bind the vertex buffer object glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); // data for a fullscreen quad GLfloat vertexData[] = { // X Y Z 1.0f, 1.0f, 0.0f, // vertex 0 -1.0f, 1.0f, 0.0f, // vertex 1 1.0f,-1.0f, 0.0f, // vertex 2 -1.0f,-1.0f, 0.0f, // vertex 3 }; // 4 vertices with 3 components (floats) each // fill with data glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*4*3, vertexData, GL_STATIC_DRAW); // set up generic attrib pointers glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat), (char*)0 + 0*sizeof(GLfloat)); // generate and bind the index buffer object glGenBuffers(1, &ibo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); GLuint indexData[] = { 0,1,2, // first triangle 2,1,3, // second triangle }; // fill with data glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*2*3, indexData, GL_STATIC_DRAW); // "unbind" vao glBindVertexArray(0); // texture handle GLuint texture; // generate texture glGenTextures(1, &texture); // bind the texture glBindTexture(GL_TEXTURE_2D, texture); // create some image data std::vector<GLfloat> image(4*width*height); for(int j = 0;j<height;++j) for(int i = 0;i<width;++i) { size_t index = j*width + i; image[4*index + 0] = 0.0f; image[4*index + 1] = 0.0f; image[4*index + 2] = 0.0f; image[4*index + 3] = 20.0f*glm::clamp(glm::perlin(0.008f*glm::vec2(i,j+70)),0.0f,0.1f); } // set 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_MIRRORED_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); // set texture content glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, &image[0]); float t = 0; float dt = 1.0f/60.0f; running = true; while(running) { t += dt; // reset time every 10 seconds to repeat the sequence if(t>10) t -= 10; // terminate on escape if(glfwGetKey(GLFW_KEY_ESC)) { running = false; } // clear first glClear(GL_COLOR_BUFFER_BIT); glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F); // bind the vao glBindVertexArray(vao); int substeps = 5; glUseProgram(shader1_program); glUniform2i(image_size_location1, width, height); glUniform1i(image_location1, 0); glUniform1f(dt_location1, 50*dt/substeps); glUseProgram(shader2_program); glUniform2i(image_size_location2, width, height); glUniform1i(image_location2, 0); glUniform1f(dt_location2, 50*dt/substeps); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); int i = 0; for(;i<substeps-1;++i) { glUseProgram(shader1_program); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glUseProgram(shader2_program); glUniform1f(t_location2, t+i*dt/substeps); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); } glUseProgram(shader1_program); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glUseProgram(shader2_program); glUniform1f(t_location2, t+i*dt/substeps); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); // check for errors GLenum error = glGetError(); if(error != GL_NO_ERROR) { std::cerr << gluErrorString(error); running = false; } // finally swap buffers glfwSwapBuffers(); } // delete the created objects glDeleteTextures(1, &texture); glDeleteVertexArrays(1, &vao); glDeleteBuffers(1, &vbo); glDeleteBuffers(1, &ibo); glDetachShader(shader1_program, vertex_shader); glDetachShader(shader1_program, fragment1_shader); glDetachShader(shader2_program, vertex_shader); glDetachShader(shader2_program, fragment2_shader); glDeleteShader(vertex_shader); glDeleteShader(fragment1_shader); glDeleteProgram(shader1_program); glDeleteShader(fragment2_shader); glDeleteProgram(shader2_program); glfwCloseWindow(); glfwTerminate(); return 0; }
void OpenGLWidget::createFractal(QString intName, QString extName) { QLayoutItem* child; while ((child = paneLayout->takeAt(0)) != 0) child->widget()->deleteLater(); paneLayout->addWidget(selector); fractal = Fractal(intName, extName); fractal.init(); fractal.addComputeVariable("WINDOW_WIDTH", "", WINDOW_WIDTH, WINDOW_WIDTH, WINDOW_WIDTH, WINDOW_WIDTH, false, &WINDOW_WIDTH); fractal.copyComputeVariableToRender(); fractal.addComputeVariable("WINDOW_HEIGHT", "", WINDOW_HEIGHT, WINDOW_HEIGHT, WINDOW_HEIGHT, WINDOW_HEIGHT, false, &WINDOW_HEIGHT); fractal.copyComputeVariableToRender(); fractal.addComputeVariable("BLOCK_WIDTH", "", BLOCK_WIDTH, BLOCK_WIDTH, BLOCK_WIDTH, BLOCK_WIDTH, false, &BLOCK_WIDTH); fractal.copyComputeVariableToRender(); fractal.addComputeVariable("BLOCK_HEIGHT", "", BLOCK_HEIGHT, BLOCK_HEIGHT, BLOCK_HEIGHT, BLOCK_HEIGHT, false, &BLOCK_HEIGHT); fractal.copyComputeVariableToRender(); fractal.addComputeVariable("IMAGE_WIDTH", "", IMAGE_WIDTH, IMAGE_WIDTH, IMAGE_WIDTH, IMAGE_WIDTH, false, &IMAGE_WIDTH); fractal.copyComputeVariableToRender(); fractal.addComputeVariable("IMAGE_HEIGHT", "", IMAGE_HEIGHT, IMAGE_HEIGHT, IMAGE_HEIGHT, IMAGE_HEIGHT, false, &IMAGE_HEIGHT); fractal.copyComputeVariableToRender(); fractal.addComputeVariable("renderOffset", "", renderOffset, renderOffset, renderOffset, renderOffset, false, &renderOffset); fractal.addComputeVariable("offset", "", majorOffset, majorOffset, majorOffset, majorOffset, false, &majorOffset); fractal.copyComputeVariableToRender(); fractal.addComputeVariable("ratio", "", RATIO, RATIO, RATIO, RATIO, false, &RATIO); fractal.addComputeVariable("zoom", "Zoom", zoom, zoom, 0.0f, float(std::pow(2, 64)), true, &zoom); m_vao.bind(); m_vvbo.create(); m_vvbo.bind(); m_vvbo.setUsagePattern(QOpenGLBuffer::StaticDraw); m_vvbo.allocate(vertices.data(), vertices.size() * sizeof(float)); m_ebo.create(); m_ebo.bind(); m_ebo.setUsagePattern(QOpenGLBuffer::StaticDraw); m_ebo.allocate(indices.data(), indices.size() * sizeof(int)); m_vao.release(); m_vvbo.release(); m_ebo.release(); fractal.computeProgram->bind(); glBindImageTexture(0, tex[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F); fractal.computeProgram->release(); fractal.renderProgram->bind(); m_vao.bind(); m_vvbo.bind(); fractal.renderProgram->enableAttributeArray("position"); fractal.renderProgram->setAttributeBuffer("position", GL_FLOAT, 0, 3); m_vvbo.release(); m_vao.release(); glBindImageTexture(0, tex[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F); fractal.renderProgram->release(); rendermodeLR = ALL; }
void DepthBuffer::bindDepthImageTexture() { #ifdef GL_IMAGE_TEXTURES_SUPPORT glBindImageTexture(depthImageUnit, m_pDepthImageTexture->glName, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RG32F); #endif }
void Ex11_04::InitGL() { if (! LoadGL() ) return; render_scene_prog = -1; resolve_program = -1; InitPrograms(); // Create palette texture glGenBuffers(1, &image_palette_buffer); glBindBuffer(GL_TEXTURE_BUFFER, image_palette_buffer); glBufferData(GL_TEXTURE_BUFFER, 256 * 4 * sizeof(float), NULL, GL_STATIC_DRAW); glGenTextures(1, &image_palette_texture); glBindTexture(GL_TEXTURE_BUFFER, image_palette_texture); glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, image_palette_buffer); vmath::vec4 * data = (vmath::vec4 *)glMapBuffer(GL_TEXTURE_BUFFER, GL_WRITE_ONLY); for (int i = 0; i < 256; i++) { data[i] = vmath::vec4((float)i); } glUnmapBuffer(GL_TEXTURE_BUFFER); // Create head pointer texture glActiveTexture(GL_TEXTURE0); glGenTextures(1, &output_texture); glBindTexture(GL_TEXTURE_2D, output_texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, MAX_FRAMEBUFFER_WIDTH, MAX_FRAMEBUFFER_HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL); glBindTexture(GL_TEXTURE_2D, 0); glBindImageTexture(0, output_texture, 0, GL_TRUE, 0, GL_READ_WRITE, GL_RGBA32F); // Create buffer for clearing the head pointer texture glGenBuffers(1, &output_texture_clear_buffer); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, output_texture_clear_buffer); glBufferData(GL_PIXEL_UNPACK_BUFFER, MAX_FRAMEBUFFER_WIDTH * MAX_FRAMEBUFFER_HEIGHT * sizeof(GLuint), NULL, GL_STATIC_DRAW); data = (vmath::vec4 *)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY); memset(data, 0x00, MAX_FRAMEBUFFER_WIDTH * MAX_FRAMEBUFFER_HEIGHT * sizeof(GLuint)); glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); // Create VAO containing quad for the final blit glGenVertexArrays(1, &quad_vao); glBindVertexArray(quad_vao); static const GLfloat quad_verts[] = { -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, }; glGenBuffers(1, &quad_vbo); glBindBuffer(GL_ARRAY_BUFFER, quad_vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(quad_verts), quad_verts, GL_STATIC_DRAW); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray(0); glClearDepth(1.0f); object.LoadFromVBM("Media/torus.vbm", 0, 1, 2); }
void Textures::Unbind() { glBindImageTexture (0, 0, 0, GL_FALSE, 0, GL_WRITE_ONLY, gpuSideFormat); glBindTexture(this->target, 0); }
void Application::prepare_Order_Independent_Transparency() { GLuint* data; // Create buffer for clearing the head pointer texture glGenBuffers(1, &head_pointer_clear_buffer); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, head_pointer_clear_buffer); glBufferData(GL_PIXEL_UNPACK_BUFFER, MAX_FRAMEBUFFER_WIDTH * MAX_FRAMEBUFFER_HEIGHT * sizeof(GLuint), NULL, GL_STATIC_DRAW); data = (GLuint *)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY); memset(data, 0x00, MAX_FRAMEBUFFER_WIDTH * MAX_FRAMEBUFFER_HEIGHT * sizeof(GLuint)); glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); for (int i = 0; i < NUM_FRAME_BUFFERS; i++){ // Create head pointer texture glActiveTexture(GL_TEXTURE0); glGenTextures(1, &head_pointer_texture[i]); glBindTexture(GL_TEXTURE_2D, head_pointer_texture[i]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, MAX_FRAMEBUFFER_WIDTH, MAX_FRAMEBUFFER_HEIGHT, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL); glBindTexture(GL_TEXTURE_2D, 0); glBindImageTexture(0, head_pointer_texture[i], 0, GL_TRUE, 0, GL_READ_WRITE, GL_R32UI); // Create the atomic counter buffer glGenBuffers(1, &atomic_counter_buffer[i]); glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomic_counter_buffer[i]); glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), NULL, GL_DYNAMIC_COPY); // Create the linked list storage buffer glGenBuffers(1, &linked_list_buffer[i]); glBindBuffer(GL_TEXTURE_BUFFER, linked_list_buffer[i]); glBufferData(GL_TEXTURE_BUFFER, MAX_FRAMEBUFFER_WIDTH * MAX_FRAMEBUFFER_HEIGHT * 6 * sizeof(glm::vec4), NULL, GL_DYNAMIC_COPY); glBindBuffer(GL_TEXTURE_BUFFER, 0); // Bind it to a texture (for use as a TBO) glGenTextures(1, &linked_list_texture[i]); glBindTexture(GL_TEXTURE_BUFFER, linked_list_texture[i]); glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32UI, linked_list_buffer[i]); glBindTexture(GL_TEXTURE_BUFFER, 0); glBindImageTexture(1, linked_list_texture[i], 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32UI); } // Create head pointer texture glActiveTexture(GL_TEXTURE0); glGenTextures(1, &main_head_pointer_texture); glBindTexture(GL_TEXTURE_2D, main_head_pointer_texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, MAX_FRAMEBUFFER_WIDTH, MAX_FRAMEBUFFER_HEIGHT, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, NULL); glBindTexture(GL_TEXTURE_2D, 0); glBindImageTexture(0, main_head_pointer_texture, 0, GL_TRUE, 0, GL_READ_WRITE, GL_R32UI); // Create the atomic counter buffer glGenBuffers(1, &main_atomic_counter_buffer); glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, main_atomic_counter_buffer); glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), NULL, GL_DYNAMIC_COPY); // Create the linked list storage buffer glGenBuffers(1, &main_linked_list_buffer); glBindBuffer(GL_TEXTURE_BUFFER, main_linked_list_buffer); glBufferData(GL_TEXTURE_BUFFER, MAX_FRAMEBUFFER_WIDTH * MAX_FRAMEBUFFER_HEIGHT * 6 * sizeof(glm::vec4), NULL, GL_DYNAMIC_COPY); glBindBuffer(GL_TEXTURE_BUFFER, 0); // Bind it to a texture (for use as a TBO) glGenTextures(1, &main_linked_list_texture); glBindTexture(GL_TEXTURE_BUFFER, main_linked_list_texture); glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32UI, main_linked_list_buffer); glBindTexture(GL_TEXTURE_BUFFER, 0); glBindImageTexture(1, main_linked_list_texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32UI); }
GLUSboolean init(GLUSvoid) { // This is a white light. struct LightProperties light = { { 1.0f, 1.0f, 1.0f }, { 0.3f, 0.3f, 0.3f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }; // Green color material with white specular color, half transparent. struct MaterialProperties material = { { 0.0f, 1.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f }, 20.0f, 0.5f }; // Buffer for cleaning the head index testure. static GLuint clearBuffer[SCREEN_WIDTH * SCREEN_HEIGHT]; GLUStextfile vertexSource; GLUStextfile fragmentSource; GLUSshape wavefrontObj; GLuint i; for (i = 0; i < SCREEN_WIDTH * SCREEN_HEIGHT; i++) { // 0xffffffff means end of list, so for the start tehre is no entry. clearBuffer[i] = 0xffffffff; } // glusFileLoadText("../Example36/shader/phong_linked_list.vert.glsl", &vertexSource); glusFileLoadText("../Example36/shader/phong_linked_list.frag.glsl", &fragmentSource); glusProgramBuildFromSource(&g_program, (const GLUSchar**) &vertexSource.text, 0, 0, 0, (const GLUSchar**) &fragmentSource.text); glusFileDestroyText(&vertexSource); glusFileDestroyText(&fragmentSource); // g_projectionMatrixLocation = glGetUniformLocation(g_program.program, "u_projectionMatrix"); g_modelViewMatrixLocation = glGetUniformLocation(g_program.program, "u_modelViewMatrix"); g_normalMatrixLocation = glGetUniformLocation(g_program.program, "u_normalMatrix"); g_light.directionLocation = glGetUniformLocation(g_program.program, "u_light.direction"); g_light.ambientColorLocation = glGetUniformLocation(g_program.program, "u_light.ambientColor"); g_light.diffuseColorLocation = glGetUniformLocation(g_program.program, "u_light.diffuseColor"); g_light.specularColorLocation = glGetUniformLocation(g_program.program, "u_light.specularColor"); g_material.ambientColorLocation = glGetUniformLocation(g_program.program, "u_material.ambientColor"); g_material.diffuseColorLocation = glGetUniformLocation(g_program.program, "u_material.diffuseColor"); g_material.specularColorLocation = glGetUniformLocation(g_program.program, "u_material.specularColor"); g_material.specularExponentLocation = glGetUniformLocation(g_program.program, "u_material.specularExponent"); g_material.alphaLocation = glGetUniformLocation(g_program.program, "u_material.alpha"); g_maxNodesLocation = glGetUniformLocation(g_program.program, "u_maxNodes"); g_vertexLocation = glGetAttribLocation(g_program.program, "a_vertex"); g_normalLocation = glGetAttribLocation(g_program.program, "a_normal"); // glusFileLoadText("../Example36/shader/fullscreen_blend.vert.glsl", &vertexSource); glusFileLoadText("../Example36/shader/fullscreen_blend.frag.glsl", &fragmentSource); glusProgramBuildFromSource(&g_blendFullscreenProgram, (const GLchar**)&vertexSource.text, 0, 0, 0, (const GLchar**)&fragmentSource.text); glusFileDestroyText(&vertexSource); glusFileDestroyText(&fragmentSource); // Atomic counter to gather a free node slot concurrently. glGenBuffers(1, &g_freeNodeIndex); glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, BINDING_ATOMIC_FREE_INDEX, g_freeNodeIndex); glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), 0, GL_DYNAMIC_DRAW); // Head index texture/image, which contains the glGenTextures(1, &g_headIndexTexture); glBindTexture(GL_TEXTURE_2D, g_headIndexTexture); glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, SCREEN_WIDTH, SCREEN_HEIGHT, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glBindTexture(GL_TEXTURE_2D, 0); glBindImageTexture(BINDING_IMAGE_HEAD_INDEX, g_headIndexTexture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI); // Buffer to clear/reset the head pointers. glGenBuffers(1, &g_clearBuffer); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, g_clearBuffer); glBufferData(GL_PIXEL_UNPACK_BUFFER, SCREEN_WIDTH * SCREEN_HEIGHT * sizeof(GLuint), clearBuffer, GL_STATIC_COPY); // Buffer for the linked list. glGenBuffers(1, &g_linkedListBuffer); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, BINDING_BUFFER_LINKED_LIST, g_linkedListBuffer); // Size is RGBA, depth (5 * GLfloat), next pointer (1 * GLuint) and 2 paddings (2 * GLfloat). glBufferData(GL_SHADER_STORAGE_BUFFER, MAX_NODES * (sizeof(GLfloat) * 5 + sizeof(GLuint) * 1) + sizeof(GLfloat) * 2, 0, GL_DYNAMIC_DRAW); // // Use a helper function to load an wavefront object file. glusShapeLoadWavefront("dragon.obj", &wavefrontObj); g_numberVertices = wavefrontObj.numberVertices; glGenBuffers(1, &g_verticesVBO); glBindBuffer(GL_ARRAY_BUFFER, g_verticesVBO); glBufferData(GL_ARRAY_BUFFER, wavefrontObj.numberVertices * 4 * sizeof(GLfloat), (GLfloat*) wavefrontObj.vertices, GL_STATIC_DRAW); glGenBuffers(1, &g_normalsVBO); glBindBuffer(GL_ARRAY_BUFFER, g_normalsVBO); glBufferData(GL_ARRAY_BUFFER, wavefrontObj.numberVertices * 3 * sizeof(GLfloat), (GLfloat*) wavefrontObj.normals, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); glusShapeDestroyf(&wavefrontObj); // glUseProgram(g_blendFullscreenProgram.program); glGenVertexArrays(1, &g_blendFullscreenVAO); glBindVertexArray(g_blendFullscreenVAO); glBindVertexArray(0); // glUseProgram(g_program.program); glGenVertexArrays(1, &g_vao); glBindVertexArray(g_vao); glBindBuffer(GL_ARRAY_BUFFER, g_verticesVBO); glVertexAttribPointer(g_vertexLocation, 4, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(g_vertexLocation); glBindBuffer(GL_ARRAY_BUFFER, g_normalsVBO); glVertexAttribPointer(g_normalLocation, 3, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(g_normalLocation); glBindVertexArray(0); // glusMatrix4x4LookAtf(g_viewMatrix, 0.0f, 0.0f, 3.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); // glusVector3Normalizef(light.direction); // Transform light to camera space, as it is currently in world space. glusMatrix4x4MultiplyVector3f(light.direction, g_viewMatrix, light.direction); // Set up light ... glUniform3fv(g_light.directionLocation, 1, light.direction); glUniform4fv(g_light.ambientColorLocation, 1, light.ambientColor); glUniform4fv(g_light.diffuseColorLocation, 1, light.diffuseColor); glUniform4fv(g_light.specularColorLocation, 1, light.specularColor); // ... and material values. glUniform4fv(g_material.ambientColorLocation, 1, material.ambientColor); glUniform4fv(g_material.diffuseColorLocation, 1, material.diffuseColor); glUniform4fv(g_material.specularColorLocation, 1, material.specularColor); glUniform1f(g_material.specularExponentLocation, material.specularExponent); glUniform1f(g_material.alphaLocation, material.alpha); glUniform1ui(g_maxNodesLocation, MAX_NODES); // glDisable(GL_DEPTH_TEST); return GLUS_TRUE; }
void DispatchVoxelizeWithTexAtlasComputeShader::call() { // use compute program p_computeShader->useProgram(); // upload output texture glBindImageTexture(0, p_voxelGrid->handle, 0, GL_FALSE, 0, GL_READ_WRITE, // allow both for atomic operations GL_R32UI); // 1 channel 32 bit unsigned int to make sure OR-ing works // upload bit mask glBindImageTexture(1, p_bitMask->getTextureHandle(), 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI ); double totalExecutionTime = 0.0; // dispatch this shader once per object for ( unsigned int i = 0; i < m_objects.size(); i++) { Object* pixelsObject = m_objects[i].first; TexAtlas::TextureAtlas* textureAtlas = m_objects[i].second; int numVertices = 0; if ( pixelsObject->getModel() ) { // bind positions VBO to shader storage buffer glBindBufferBase( GL_SHADER_STORAGE_BUFFER, 0, pixelsObject->getModel()->getPositionBufferHandle() ); numVertices = pixelsObject->getModel()->getNumVertices(); } else { continue; } if (textureAtlas) { textureAtlas->unbindFromActiveUnit(); // bind textureAtlas textureAtlas->bindToTextureUnit(3); // upload uniform textureAtlas position if ( !p_computeShader->uploadUniform(3 , "uniformTextureAtlas" ) ) { DEBUGLOG->log("ERROR : Failed to upload uniform texture atlas"); } } // upload uniform voxel grid matrix p_computeShader->uploadUniform( p_voxelGrid->worldToVoxel, "uniformWorldToVoxel" ); // upload uniform vertices amount p_computeShader->uploadUniform( numVertices, "uniformNumVertices"); // set local group amount suitable for object size: m_num_groups_x = numVertices / p_computeShader->getLocalGroupSizeX() + ( ( numVertices % p_computeShader->getLocalGroupSizeX() == 0 ) ? 0 : 1 ); m_num_groups_y = 1; m_num_groups_z = 1; // dispatch as usual DispatchComputeShaderListener::call(); glMemoryBarrier( GL_ALL_BARRIER_BITS ); if ( m_queryTime ) { totalExecutionTime += m_executionTime; } } if ( m_queryTime ) { m_executionTime = totalExecutionTime; } // unbind image textures glBindImageTexture(0, 0, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI); glBindImageTexture(1, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI); }
GLUSvoid terminate(GLUSvoid) { glBindBuffer(GL_ARRAY_BUFFER, 0); if (g_verticesVBO) { glDeleteBuffers(1, &g_verticesVBO); g_verticesVBO = 0; } if (g_normalsVBO) { glDeleteBuffers(1, &g_normalsVBO); g_normalsVBO = 0; } glBindVertexArray(0); if (g_vao) { glDeleteVertexArrays(1, &g_vao); g_vao = 0; } if (g_vao) { glDeleteVertexArrays(1, &g_blendFullscreenVAO); g_vao = 0; } glUseProgram(0); glusProgramDestroy(&g_program); glusProgramDestroy(&g_blendFullscreenProgram); // // // glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0); if (g_freeNodeIndex) { glDeleteBuffers(1, &g_freeNodeIndex); g_freeNodeIndex = 0; } // glBindTexture(GL_TEXTURE_2D, 0); glBindImageTexture(BINDING_IMAGE_HEAD_INDEX, 0, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI); if (g_headIndexTexture) { glDeleteTextures(1, &g_headIndexTexture); g_headIndexTexture = 0; } // glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); if (g_clearBuffer) { glDeleteBuffers(1, &g_clearBuffer); g_clearBuffer = 0; } // glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); if (g_linkedListBuffer) { glDeleteBuffers(1, &g_linkedListBuffer); g_linkedListBuffer = 0; } }
void DispatchMipmapVoxelGridComputeShader::call() { p_computeShader->useProgram(); // bind to access image size glBindTexture( GL_TEXTURE_2D, p_voxelGrid->handle ); int current_mipmap_res; double totalExecutionTime = 0.0; for ( int i = 1; i <= p_voxelGrid->numMipmaps; i++ ) { // bind voxel grid mipmap base level glBindImageTexture( 0, // texture image unit p_voxelGrid->handle, // texture name i-1, // mipmap level GL_FALSE, // layered 0, // layer GL_READ_ONLY, // only read access GL_R32UI); // 1 channel 32 bit unsigned int // bind voxel grid mipmap target level glBindImageTexture( 1, // texture image unit p_voxelGrid->handle, // texture name i, // mipmap level GL_FALSE, // layered 0, // layer GL_WRITE_ONLY, // only write access GL_R32UI); // 1 channel 32 bit unsigned int glGetTexLevelParameteriv( GL_TEXTURE_2D, i, GL_TEXTURE_WIDTH, ¤t_mipmap_res ); // DEBUGLOG->log( "current mipmap target level size : ", current_mipmap_res ); // make sure mipmap is written before proceeding glMemoryBarrier( GL_SHADER_IMAGE_ACCESS_BARRIER_BIT ); // set suitable amount of work groups m_num_groups_x = current_mipmap_res / p_computeShader->getLocalGroupSizeX() + ( ( current_mipmap_res % p_computeShader->getLocalGroupSizeX() == 0 ) ? 0 : 1 ); m_num_groups_y = current_mipmap_res / p_computeShader->getLocalGroupSizeY() + ( ( current_mipmap_res % p_computeShader->getLocalGroupSizeY() == 0 ) ? 0 : 1 ); m_num_groups_z = 1; // dispatch compute shader DispatchComputeShaderListener::call(); // add this execution time to the total execution time if ( m_queryTime ) { totalExecutionTime += m_executionTime; } } if ( m_queryTime ) { m_executionTime = totalExecutionTime; } // arbitrary barrier glMemoryBarrier( GL_ALL_BARRIER_BITS ); // unbind textures glBindTexture( GL_TEXTURE_2D, 0); glBindImageTexture(0, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI ); glBindImageTexture(1, 0, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32UI ); }
void CollisionAvoidanceFBO::BindForDensityImageReading(GLenum TextureUnit_Index) { glBindImageTexture(TextureUnit_Index, m_writeDensityTex, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32I); }
bool download_image_levels(const struct image_info img, unsigned num_levels, unsigned unit, uint32_t *r_pixels) { const unsigned m = image_num_components(img.format); int i, l; glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT | GL_PIXEL_BUFFER_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); glBindTexture(img.target->target, textures[unit]); switch (img.target->target) { case GL_TEXTURE_1D: case GL_TEXTURE_2D: case GL_TEXTURE_3D: case GL_TEXTURE_RECTANGLE: case GL_TEXTURE_1D_ARRAY: case GL_TEXTURE_2D_ARRAY: case GL_TEXTURE_CUBE_MAP_ARRAY: assert(img.target->target != GL_TEXTURE_RECTANGLE || num_levels == 1); for (l = 0; l < num_levels; ++l) glGetTexImage(img.target->target, l, img.format->pixel_format, image_base_type(img.format), &r_pixels[m * image_level_offset(img, l)]); break; case GL_TEXTURE_CUBE_MAP: for (l = 0; l < num_levels; ++l) { const unsigned offset = m * image_level_offset(img, l); const unsigned face_sz = m * product(image_level_size(img, l)) / 6; for (i = 0; i < 6; ++i) glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, l, img.format->pixel_format, image_base_type(img.format), &r_pixels[offset + face_sz * i]); } break; case GL_TEXTURE_BUFFER: { /* * glGetTexImage() isn't supposed to work with buffer * textures. We copy the packed pixels to a texture * with the same internal format as the image to let * the GL unpack it for us. */ const struct image_extent grid = image_optimal_extent(img.size); GLuint packed_tex; assert(num_levels == 1); glGenTextures(1, &packed_tex); glBindTexture(GL_TEXTURE_2D, packed_tex); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffers[unit]); glTexImage2D(GL_TEXTURE_2D, 0, img.format->format, grid.x, grid.y, 0, img.format->pixel_format, img.format->pixel_type, NULL); glGetTexImage(GL_TEXTURE_2D, 0, img.format->pixel_format, image_base_type(img.format), r_pixels); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); glDeleteTextures(1, &packed_tex); break; } case GL_TEXTURE_2D_MULTISAMPLE: case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: { /* * GL doesn't seem to provide any direct way to read * back a multisample texture, so we use imageLoad() * to copy its contents to a larger single-sample 2D * texture from the fragment shader. */ const struct grid_info grid = { get_image_stage(GL_FRAGMENT_SHADER)->bit, img.format, image_optimal_extent(img.size) }; GLuint prog = generate_program( grid, GL_FRAGMENT_SHADER, concat(image_hunk(img, "SRC_"), image_hunk(image_info_for_grid(grid), "DST_"), hunk("readonly SRC_IMAGE_UNIFORM_T src_img;\n" "writeonly DST_IMAGE_UNIFORM_T dst_img;\n" "\n" "GRID_T op(ivec2 idx, GRID_T x) {\n" " imageStore(dst_img, DST_IMAGE_ADDR(idx),\n" " imageLoad(src_img, SRC_IMAGE_ADDR(idx)));\n" " return x;\n" "}\n"), NULL)); bool ret = prog && generate_fb(grid, 1); GLuint tmp_tex; assert(num_levels == 1); glGenTextures(1, &tmp_tex); glBindTexture(GL_TEXTURE_2D, tmp_tex); glTexImage2D(GL_TEXTURE_2D, 0, img.format->format, grid.size.x, grid.size.y, 0, img.format->pixel_format, image_base_type(img.format), NULL); glBindImageTexture(unit, textures[unit], 0, GL_TRUE, 0, GL_READ_ONLY, img.format->format); glBindImageTexture(6, tmp_tex, 0, GL_TRUE, 0, GL_WRITE_ONLY, img.format->format); ret &= set_uniform_int(prog, "src_img", unit) && set_uniform_int(prog, "dst_img", 6) && draw_grid(grid, prog); glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT); glGetTexImage(GL_TEXTURE_2D, 0, img.format->pixel_format, image_base_type(img.format), r_pixels); glDeleteProgram(prog); glDeleteTextures(1, &tmp_tex); glBindFramebuffer(GL_FRAMEBUFFER, fb[0]); glViewportIndexedfv(0, vp[0]); if (!ret) return false; break; } default: abort(); } return piglit_check_gl_error(GL_NO_ERROR); }
void CollisionAvoidanceFBO::BindForAntiGradientImageReading(GLenum TextureUnit_Index) { glBindImageTexture(TextureUnit_Index, m_writeAntiGradientTex, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8I); }
void DepthBuffer::bindDepthImageTexture() { #ifdef GL_IMAGE_TEXTURES_SUPPORT glBindImageTexture(depthImageUnit, m_pDepthImageTexture->glName, 0, GL_FALSE, 0, GL_READ_WRITE, fboFormats.depthImageInternalFormat); #endif }
void CollisionAvoidanceFBO::BindForDensityBufferWriting(GLenum TextureUnit, GLenum TextureUnit_Index) { //miplevel = 0 glBindImageTexture(TextureUnit_Index, m_writeDensityBufferTex, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32I); }
void GL3PlusTexture::createShaderAccessPoint(uint bindPoint, TextureAccess access, int mipmapLevel, int textureArrayIndex, PixelFormat* format) { GLenum GlAccess = 0; switch (access) { case TA_READ: GlAccess = GL_READ_ONLY; break; case TA_WRITE: GlAccess = GL_WRITE_ONLY; break; case TA_READ_WRITE: GlAccess = GL_READ_WRITE; break; default: //TODO error handling break; } if (!format) format = &mFormat; GLenum GlFormat = GL3PlusPixelUtil::getClosestGLImageInternalFormat(*format); GLboolean isArrayTexture; switch(mTextureType) { case TEX_TYPE_2D_ARRAY: isArrayTexture = GL_TRUE; break; default: isArrayTexture = GL_FALSE; break; } // TODO // * add memory barrier // * material script access (can have multiple instances for a single texture_unit) // shader_access <binding point> [<access>] [<mipmap level>] [<texture array layer>] [<format>] // shader_access 2 read_write 0 0 PF_UINT32_R // binding point - location to bind for shader access; for OpenGL this must be unique and is not related to texture binding point // access - give the shader read, write, or read_write privileges [default read_write] // mipmap level - texture mipmap level to use [default 0] // texture array layer - layer of texture array to use: 'all', or layer number (if not layered, just use 0) [default 0] // format - texture format to be read in shader; for OpenGL this may be different than bound texture format - not sure about DX11 [default same format as texture] // Note that for OpenGL the shader access (image) binding point // must be specified, it is NOT the same as the texture binding point, // and it must be unique among textures in this pass. // * enforce binding point uniqueness by checking against // image binding point allocation list in GL3PlusTextureManager // * generalize for other render systems by introducing vitual method in Texture // for (image in mImages) // { // OGRE_CHECK_GL_ERROR( // glBindImageTexture( // mImageBind, mTextureID, // mMipmapLevel, // mLayered.find('all') != str::npos ? GL_TRUE : GL_FALSE, mLayer, // mImageAccess (READ, WRITE, READ_WRITE), // toImageFormat(mFormatInShader))); //GL_RGBA8)); //GL_R32UI)); GL_READ_WRITE if (mRenderSystem->hasMinGLVersion(4, 2) || mRenderSystem->checkExtension("GL_ARB_shader_image_load_store")) { OGRE_CHECK_GL_ERROR(glBindImageTexture(bindPoint, mTextureID, mipmapLevel, isArrayTexture, textureArrayIndex, GlAccess, GlFormat)); } }
void CollisionAvoidanceFBO::BindForAntiGradientWriting(GLenum TextureUnit, GLenum TextureUnit_Index) { //miplevel = 0 glBindImageTexture(TextureUnit_Index, m_writeAntiGradientTex, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8I); }
void shadowmapping_app::render(double currentTime) { static const GLfloat zeros[] = { 0.0f, 0.0f, 0.0f, 0.0f }; static double last_time = 0.0; static double total_time = 0.0; if (!paused) total_time += (currentTime - last_time); last_time = currentTime; const float f = (float)total_time + 30.0f; vmath::vec3 view_position = vmath::vec3(0.0f, 0.0f, 40.0f); camera_proj_matrix = vmath::perspective(50.0f, (float)info.windowWidth / (float)info.windowHeight, 2.0f, 300.0f); camera_view_matrix = vmath::lookat(view_position, vmath::vec3(0.0f), vmath::vec3(0.0f, 1.0f, 0.0f)); objects[0].model_matrix = vmath::translate(5.0f, 0.0f, 20.0f) * vmath::rotate(f * 14.5f, 0.0f, 1.0f, 0.0f) * vmath::rotate(20.0f, 1.0f, 0.0f, 0.0f) * vmath::translate(0.0f, -4.0f, 0.0f); objects[1].model_matrix = vmath::translate(-5.0f, 0.0f, 0.0f) * vmath::rotate(f * 14.5f, 0.0f, 1.0f, 0.0f) * vmath::rotate(20.0f, 1.0f, 0.0f, 0.0f) * vmath::translate(0.0f, -4.0f, 0.0f); objects[2].model_matrix = vmath::translate(-15.0f, 0.0f, -20.0f) * vmath::rotate(f * 14.5f, 0.0f, 1.0f, 0.0f) * vmath::rotate(20.0f, 1.0f, 0.0f, 0.0f) * vmath::translate(0.0f, -4.0f, 0.0f); objects[3].model_matrix = vmath::translate(-25.0f, 0.0f, -40.0f) * vmath::rotate(f * 14.5f, 0.0f, 1.0f, 0.0f) * vmath::rotate(20.0f, 1.0f, 0.0f, 0.0f) * vmath::translate(0.0f, -4.0f, 0.0f); objects[4].model_matrix = vmath::translate(-35.0f, 0.0f, -60.0f) * vmath::rotate(f * 14.5f, 0.0f, 1.0f, 0.0f) * vmath::rotate(20.0f, 1.0f, 0.0f, 0.0f) * vmath::translate(0.0f, -4.0f, 0.0f); glEnable(GL_DEPTH_TEST); render_scene(total_time); glUseProgram(filter_program); glBindImageTexture(0, color_tex, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); glBindImageTexture(1, temp_tex, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F); glDispatchCompute(info.windowHeight, 1, 1); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); glBindImageTexture(0, temp_tex, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F); glBindImageTexture(1, color_tex, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F); glDispatchCompute(info.windowWidth, 1, 1); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); glBindTexture(GL_TEXTURE_2D, color_tex); glDisable(GL_DEPTH_TEST); glUseProgram(display_program); glUniform1f(uniforms.dof.focal_distance, focal_distance); glUniform1f(uniforms.dof.focal_depth, focal_depth); glBindVertexArray(quad_vao); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL42C_glBindImageTexture(JNIEnv *__env, jclass clazz, jint unit, jint texture, jint level, jboolean layered, jint layer, jint access, jint format) { glBindImageTexturePROC glBindImageTexture = (glBindImageTexturePROC)tlsGetFunction(867); UNUSED_PARAM(clazz) glBindImageTexture(unit, texture, level, layered, layer, access, format); }
void GL3GraphicContextProvider::reset_image_texture(int unit_index) { OpenGL::set_active(this); glBindImageTexture(unit_index, 0, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8); }
void FrameBufferObject::Bind() { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, this->textureID); glBindImageTexture (0, this->textureID, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F); }