void ZMinMax::update_buffers(const GraphicContextPtr &gc) { Size texture_size = find_texture_size(normal_z); if (!texture0 || texture0->size() != texture_size) { std::string vertex_shader, fragment_shader0, fragment_shader1; if (gc->shader_language() == shader_glsl) get_shader_glsl(vertex_shader, fragment_shader0, fragment_shader1); else get_shader_hlsl(vertex_shader, fragment_shader0, fragment_shader1); program0 = compile_and_link(gc, vertex_shader, fragment_shader0); program1 = compile_and_link(gc, vertex_shader, fragment_shader1); Vec4f positions[6] = { Vec4f(-1.0f, -1.0f, 1.0f, 1.0f), Vec4f( 1.0f, -1.0f, 1.0f, 1.0f), Vec4f(-1.0f, 1.0f, 1.0f, 1.0f), Vec4f( 1.0f, -1.0f, 1.0f, 1.0f), Vec4f(-1.0f, 1.0f, 1.0f, 1.0f), Vec4f( 1.0f, 1.0f, 1.0f, 1.0f) }; vertices = VertexArrayVector<Vec4f>(gc, positions, 6); prim_array = PrimitivesArray::create(gc); prim_array->set_attributes(0, vertices); texture0 = Texture2D::create(gc, texture_size.width, texture_size.height, tf_rg32f); texture0->set_min_filter(filter_nearest); texture0->set_mag_filter(filter_nearest); texture0->set_wrap_mode(wrap_clamp_to_edge, wrap_clamp_to_edge); texture1 = Texture2D::create(gc, texture_size.width, texture_size.height, tf_rg32f); texture1->set_min_filter(filter_nearest); texture1->set_mag_filter(filter_nearest); texture1->set_wrap_mode(wrap_clamp_to_edge, wrap_clamp_to_edge); fb0 = FrameBuffer::create(gc); fb0->attach_color(0, texture0); fb1 = FrameBuffer::create(gc); fb1->attach_color(0, texture1); BlendStateDescription blend_desc; blend_desc.enable_blending(false); blend_state = gc->create_blend_state(blend_desc); } result = (iterations % 2 == 0) ? texture1 : texture0; }
void LightsourceSimplePass::setup(const GraphicContextPtr &gc) { Size viewport_size = inout.viewport.size(); if (!blend_state) { BlendStateDescription blend_desc; blend_desc.enable_blending(true); blend_desc.set_blend_function(blend_one, blend_one, blend_one, blend_one); blend_state = gc->create_blend_state(blend_desc); DepthStencilStateDescription icosahedron_depth_stencil_desc; icosahedron_depth_stencil_desc.enable_depth_write(false); icosahedron_depth_stencil_desc.enable_depth_test(true); icosahedron_depth_stencil_desc.set_depth_compare_function(compare_lequal); icosahedron_depth_stencil_state = gc->create_depth_stencil_state(icosahedron_depth_stencil_desc); RasterizerStateDescription icosahedron_rasterizer_desc; icosahedron_rasterizer_desc.set_culled(true); icosahedron_rasterizer_state = gc->create_rasterizer_state(icosahedron_rasterizer_desc); DepthStencilStateDescription rect_depth_stencil_desc; rect_depth_stencil_desc.enable_depth_write(false); rect_depth_stencil_desc.enable_depth_test(false); rect_depth_stencil_state = gc->create_depth_stencil_state(rect_depth_stencil_desc); RasterizerStateDescription rect_rasterizer_desc; rect_rasterizer_desc.set_culled(false); rect_rasterizer_state = gc->create_rasterizer_state(rect_rasterizer_desc); uniforms = UniformVector<Uniforms>(gc, 1); icosahedron_prim_array = PrimitivesArray::create(gc); icosahedron_prim_array->set_attributes(0, icosahedron->vertices); Vec4f positions[6] = { Vec4f(-1.0f, -1.0f, 1.0f, 1.0f), Vec4f( 1.0f, -1.0f, 1.0f, 1.0f), Vec4f(-1.0f, 1.0f, 1.0f, 1.0f), Vec4f( 1.0f, -1.0f, 1.0f, 1.0f), Vec4f(-1.0f, 1.0f, 1.0f, 1.0f), Vec4f( 1.0f, 1.0f, 1.0f, 1.0f) }; rect_positions = VertexArrayVector<Vec4f>(gc, positions, 6); rect_prim_array = PrimitivesArray::create(gc); rect_prim_array->set_attributes(0, rect_positions); } }
void GaussianBlur::setup(const GraphicContextPtr &gc, float blur_amount, int sample_count) { for (blur_setup_index = 0; blur_setup_index < blur_setups.size(); blur_setup_index++) { if (blur_setups[blur_setup_index].blur_amount == blur_amount && blur_setups[blur_setup_index].sample_count == sample_count) return; } std::string vertex_shader, vertical_fragment_shader, horizontal_fragment_shader; if (gc->shader_language() == shader_glsl) { vertex_shader = vertex_shader_glsl(); horizontal_fragment_shader = fragment_shader_glsl(blur_amount, sample_count, false); vertical_fragment_shader = fragment_shader_glsl(blur_amount, sample_count, true); } else { vertex_shader = vertex_shader_hlsl(); horizontal_fragment_shader = fragment_shader_hlsl(blur_amount, sample_count, false); vertical_fragment_shader = fragment_shader_hlsl(blur_amount, sample_count, true); } auto vertex = ShaderObject::create(gc, ShaderType::vertex, vertex_shader); auto vertical_fragment = ShaderObject::create(gc, ShaderType::fragment, vertical_fragment_shader); auto horizontal_fragment = ShaderObject::create(gc, ShaderType::fragment, horizontal_fragment_shader); if (!vertex->try_compile()) throw Exception(string_format("Could not compile Gaussian blur vertex shader: %1", vertex->info_log())); if (!vertical_fragment->try_compile()) throw Exception(string_format("Could not compile vertical Gaussian blur fragment shader: %1", vertical_fragment->info_log())); if (!horizontal_fragment->try_compile()) throw Exception(string_format("Could not compile horizontal Gaussian blur fragment shader: %1", horizontal_fragment->info_log())); BlurSetup blur_setup(blur_amount, sample_count); blur_setup.vertical_blur_program = ProgramObject::create(gc); blur_setup.vertical_blur_program->attach(vertex); blur_setup.vertical_blur_program->attach(vertical_fragment); blur_setup.vertical_blur_program->bind_frag_data_location(0, "FragColor"); blur_setup.vertical_blur_program->bind_attribute_location(0, "PositionInProjection"); if (!blur_setup.vertical_blur_program->try_link()) throw Exception("Could not link vertical Gaussian blur program"); blur_setup.vertical_blur_program->set_uniform1i("SourceTexture", 0); blur_setup.vertical_blur_program->set_uniform1i("SourceSampler", 0); blur_setup.horizontal_blur_program = ProgramObject::create(gc); blur_setup.horizontal_blur_program->attach(vertex); blur_setup.horizontal_blur_program->attach(horizontal_fragment); blur_setup.horizontal_blur_program->bind_frag_data_location(0, "FragColor"); blur_setup.horizontal_blur_program->bind_attribute_location(0, "PositionInProjection"); if (!blur_setup.horizontal_blur_program->try_link()) throw Exception("Could not link horizontal Gaussian blur program"); blur_setup.horizontal_blur_program->set_uniform1i("SourceTexture", 0); blur_setup.horizontal_blur_program->set_uniform1i("SourceSampler", 0); blur_setups.push_back(blur_setup); if (!gpu_positions.buffer()) { Vec4f positions[6] = { Vec4f(-1.0f, -1.0f, 1.0f, 1.0f), Vec4f( 1.0f, -1.0f, 1.0f, 1.0f), Vec4f(-1.0f, 1.0f, 1.0f, 1.0f), Vec4f( 1.0f, -1.0f, 1.0f, 1.0f), Vec4f(-1.0f, 1.0f, 1.0f, 1.0f), Vec4f( 1.0f, 1.0f, 1.0f, 1.0f) }; gpu_positions = VertexArrayVector<Vec4f>(gc, positions, 6); prim_array = PrimitivesArray::create(gc); prim_array->set_attributes(0, gpu_positions); BlendStateDescription blend_desc; blend_desc.enable_blending(false); blend_state = gc->create_blend_state(blend_desc); } }
LogAverageLight::LogAverageLight(const GraphicContextPtr &gc, SceneRender &inout, int iterations) : inout(inout), iterations(iterations), current_index(0) { Size texture_size(1 << iterations, 1 << iterations); std::string vertex_program = "#version 330\r\n" "in vec4 PositionInProjection;\r\n" "void main()\r\n" "{\r\n" " gl_Position = PositionInProjection;\r\n" "}\r\n"; std::string fragment_program0 = string_format( "#version 330\r\n" "out vec4 FragAverage;\r\n" "uniform sampler2D Texture;\r\n" "void main()\r\n" "{\r\n" " vec3 rgb = texture(Texture, gl_FragCoord.xy / %1).rgb;\r\n" " float light = max(max(rgb.r, rgb.g), rgb.b);\r\n" " FragAverage = vec4(log(0.0001 + light), 0, 0, 0);\r\n" "}\r\n", texture_size.width); std::string fragment_program1 = "#version 330\r\n" "out vec4 FragAverage;\r\n" "uniform sampler2D Texture;\r\n" "void main()\r\n" "{\r\n" " ivec2 pos = ivec2(gl_FragCoord.xy) * 2;\r\n" " float light0 = texelFetch(Texture, pos, 0).x; \r\n" " float light1 = texelFetch(Texture, pos + ivec2(1,0), 0).x; \r\n" " float light2 = texelFetch(Texture, pos + ivec2(0,1), 0).x; \r\n" " float light3 = texelFetch(Texture, pos + ivec2(1,1), 0).x; \r\n" " FragAverage = vec4((light0 + light1 + light2 + light3) * 0.25, 0, 0, 0);\r\n" "}\r\n"; std::string fragment_program2 = "#version 330\r\n" "out vec4 FragAverage;\r\n" "uniform sampler2D TexturePrev;\r\n" "uniform sampler2D TextureCurrent;\r\n" "void main()\r\n" "{\r\n" " float lightPrev = texelFetch(TexturePrev, ivec2(0,0), 0).x; \r\n" " float lightCurrent = exp(texelFetch(TextureCurrent, ivec2(0,0), 0).x); \r\n" " float c = 0.04;\r\n" " FragAverage = vec4(lightPrev + c * (lightCurrent - lightPrev), 0, 0, 0);\r\n" "}\r\n"; program0 = compile_and_link(gc, vertex_program, fragment_program0); program1 = compile_and_link(gc, vertex_program, fragment_program1); program2 = compile_and_link(gc, vertex_program, fragment_program2); Vec4f positions[6] = { Vec4f(-1.0f, -1.0f, 1.0f, 1.0f), Vec4f( 1.0f, -1.0f, 1.0f, 1.0f), Vec4f(-1.0f, 1.0f, 1.0f, 1.0f), Vec4f( 1.0f, -1.0f, 1.0f, 1.0f), Vec4f(-1.0f, 1.0f, 1.0f, 1.0f), Vec4f( 1.0f, 1.0f, 1.0f, 1.0f) }; vertices = VertexArrayVector<Vec4f>(gc, positions, 6); prim_array = PrimitivesArray::create(gc); prim_array->set_attributes(0, vertices); texture0 = Texture2D::create(gc, texture_size.width, texture_size.height, tf_r32f); texture0->set_min_filter(filter_nearest); texture0->set_mag_filter(filter_nearest); texture0->set_wrap_mode(wrap_clamp_to_edge, wrap_clamp_to_edge); texture1 = Texture2D::create(gc, texture_size.width, texture_size.height, tf_r32f); texture1->set_min_filter(filter_nearest); texture1->set_mag_filter(filter_nearest); texture1->set_wrap_mode(wrap_clamp_to_edge, wrap_clamp_to_edge); auto black = PixelBuffer::create(1, 1, tf_r32f); black->data<float>()[0] = 0.0f; result_texture0 = Texture2D::create(gc, 1, 1, tf_r32f); result_texture0->set_min_filter(filter_nearest); result_texture0->set_mag_filter(filter_nearest); result_texture0->set_wrap_mode(wrap_clamp_to_edge, wrap_clamp_to_edge); result_texture0->set_subimage(gc, 0, 0, black, black->size()); result_texture1 = Texture2D::create(gc, 1, 1, tf_r32f); result_texture1->set_min_filter(filter_nearest); result_texture1->set_mag_filter(filter_nearest); result_texture1->set_wrap_mode(wrap_clamp_to_edge, wrap_clamp_to_edge); result_texture1->set_subimage(gc, 0, 0, black, black->size()); fb0 = FrameBuffer::create(gc); fb0->attach_color(0, texture0); fb1 = FrameBuffer::create(gc); fb1->attach_color(0, texture1); fb2 = FrameBuffer::create(gc); fb2->attach_color(0, result_texture0); fb3 = FrameBuffer::create(gc); fb3->attach_color(0, result_texture1); BlendStateDescription blend_desc; blend_desc.enable_blending(false); blend_state = gc->create_blend_state(blend_desc); }
void RenderBatchTriangle::flush(const GraphicContextPtr &gc) { if (position > 0) { gc->set_program_object(program_sprite); int gpu_index; VertexArrayVector<SpriteVertex> gpu_vertices(batch_buffer->get_vertex_buffer(gc, gpu_index)); if (!prim_array[gpu_index]) { prim_array[gpu_index] = PrimitivesArray::create(gc); prim_array[gpu_index]->set_attributes(0, gpu_vertices, cl_offsetof(SpriteVertex, position)); prim_array[gpu_index]->set_attributes(1, gpu_vertices, cl_offsetof(SpriteVertex, color)); prim_array[gpu_index]->set_attributes(2, gpu_vertices, cl_offsetof(SpriteVertex, texcoord)); prim_array[gpu_index]->set_attributes(3, gpu_vertices, cl_offsetof(SpriteVertex, texindex)); if (!glyph_blend) { BlendStateDescription blend_desc; blend_desc.set_blend_function(blend_constant_color, blend_one_minus_src_color, blend_zero, blend_one); glyph_blend = gc->create_blend_state(blend_desc); } } gpu_vertices.upload_data(gc, 0, vertices, position); for (int i = 0; i < num_current_textures; i++) gc->set_texture(i, current_textures[i]); #ifdef _DEBUG // Suppress a warning when the D3D debug layer is active (to do: add a boolean on gc that can report if a debug layer is present) if (num_current_textures > 0) { for (int i = num_current_textures; i < max_textures; i++) gc->set_texture(i, current_textures[0]); } #endif if (use_glyph_program) { gc->set_blend_state(glyph_blend, constant_color); gc->draw_primitives(type_triangles, position, prim_array[gpu_index]); gc->reset_blend_state(); } else { gc->draw_primitives(type_triangles, position, prim_array[gpu_index]); } for (int i = 0; i < num_current_textures; i++) gc->reset_texture(i); #ifdef _DEBUG // Suppress a warning when the D3D debug layer is active (to do: add a boolean on gc that can report if a debug layer is present) if (num_current_textures > 0) { for (int i = num_current_textures; i < max_textures; i++) gc->reset_texture(i); } #endif gc->reset_program_object(); position = 0; for (int i = 0; i < num_current_textures; i++) current_textures[i] = Texture2DPtr(); num_current_textures = 0; } }