From 146f63874a2a215eb0776d11da45b68871fa02ce Mon Sep 17 00:00:00 2001 From: Mario Liebisch Date: Thu, 15 May 2014 15:29:23 +0200 Subject: [PATCH] Added a geometry shader effect to the Shader example --- examples/shader/Shader.cpp | 80 +++++++++++++++++++++++ examples/shader/resources/billboard.frag | 11 ++++ examples/shader/resources/billboard.geom | 56 ++++++++++++++++ examples/shader/resources/billboard.vert | 5 ++ examples/shader/resources/logo.png | Bin 0 -> 8849 bytes 5 files changed, 152 insertions(+) create mode 100644 examples/shader/resources/billboard.frag create mode 100644 examples/shader/resources/billboard.geom create mode 100644 examples/shader/resources/billboard.vert create mode 100644 examples/shader/resources/logo.png diff --git a/examples/shader/Shader.cpp b/examples/shader/Shader.cpp index 82ad61cf..8a81fde3 100644 --- a/examples/shader/Shader.cpp +++ b/examples/shader/Shader.cpp @@ -258,6 +258,85 @@ private: }; +//////////////////////////////////////////////////////////// +// "Geometry" geometry shader example +//////////////////////////////////////////////////////////// +class Geometry : public Effect +{ +public: + + Geometry() : + Effect("geometry shader billboards"), + m_pointCloud(sf::Points, 10000) + { + } + + bool onLoad() + { + // Check if geometry shaders are supported + if (!sf::Shader::isGeometryAvailable()) + return false; + + // Move the points in the point cloud to random positions + for (std::size_t i = 0; i < 10000; i++) + { + // Spread the coordinates from -480 to +480 + // So they'll always fill the viewport at 800x600 + m_pointCloud[i].position.x = rand() % 960 - 480.f; + m_pointCloud[i].position.y = rand() % 960 - 480.f; + } + + // Load the texture + if (!m_logoTexture.loadFromFile("resources/logo.png")) + return false; + + // Load the shader + if (!m_shader.loadFromFile("resources/billboard.vert", "resources/billboard.geom", "resources/billboard.frag")) + return false; + m_shader.setUniform("texture", sf::Shader::CurrentTexture); + + // Set the render resolution (used for proper scaling) + m_shader.setUniform("resolution", sf::Vector2f(800, 600)); + + return true; + } + + void onUpdate(float time, float x, float y) + { + // Reset our transformation matrix + m_transform = sf::Transform::Identity; + // Move to the center of the window + m_transform.translate(400, 300); + // Rotate everything based on cursor position + m_transform.rotate(x * 360.f); + + // Adjust billboard size to scale between 25 and 75 + float size = 25 + std::abs(y) * 50; + + // Update the shader parameter + m_shader.setUniform("size", sf::Vector2f(size, size)); + } + + void onDraw(sf::RenderTarget& target, sf::RenderStates states) const + { + // Prepare the render state + states.shader = &m_shader; + states.texture = &m_logoTexture; + states.transform = m_transform; + + // Draw the point cloud + target.draw(m_pointCloud, states); + } + +private: + + sf::Texture m_logoTexture; + sf::Transform m_transform; + sf::Shader m_shader; + sf::VertexArray m_pointCloud; +}; + + //////////////////////////////////////////////////////////// /// Entry point of application /// @@ -283,6 +362,7 @@ int main() effects.push_back(new WaveBlur); effects.push_back(new StormBlink); effects.push_back(new Edge); + effects.push_back(new Geometry); std::size_t current = 0; // Initialize them diff --git a/examples/shader/resources/billboard.frag b/examples/shader/resources/billboard.frag new file mode 100644 index 00000000..3057f64b --- /dev/null +++ b/examples/shader/resources/billboard.frag @@ -0,0 +1,11 @@ +#version 150 + +uniform sampler2D texture; + +in vec2 tex_coord; + +void main() +{ + // Read and apply a color from the texture + gl_FragColor = texture2D(texture, tex_coord); +} diff --git a/examples/shader/resources/billboard.geom b/examples/shader/resources/billboard.geom new file mode 100644 index 00000000..2f47a1fa --- /dev/null +++ b/examples/shader/resources/billboard.geom @@ -0,0 +1,56 @@ +#version 150 + +// The render target's resolution (used for scaling) +uniform vec2 resolution; + +// The billboards' size +uniform vec2 size; + +// Input is the passed point cloud +layout (points) in; + +// The output will consist of triangle strips with four vertices each +layout (triangle_strip, max_vertices = 4) out; + +// Output texture coordinates +out vec2 tex_coord; + +// Main entry point +void main() +{ + // Caculate the half width/height of the billboards + vec2 half_size = size / 2.f; + + // Scale the size based on resolution (1 would be full width/height) + half_size /= resolution; + + // Iterate over all vertices + for (int i = 0; i < gl_in.length(); i++) + { + // Retrieve the passed vertex position + vec2 pos = gl_in[i].gl_Position.xy; + + // Bottom left vertex + gl_Position = vec4(pos - half_size, 0.f, 1.f); + tex_coord = vec2(1.f, 1.f); + EmitVertex(); + + // Bottom right vertex + gl_Position = vec4(pos.x + half_size.x, pos.y - half_size.y, 0.f, 1.f); + tex_coord = vec2(0.f, 1.f); + EmitVertex(); + + // Top left vertex + gl_Position = vec4(pos.x - half_size.x, pos.y + half_size.y, 0.f, 1.f); + tex_coord = vec2(1.f, 0.f); + EmitVertex(); + + // Top right vertex + gl_Position = vec4(pos + half_size, 0.f, 1.f); + tex_coord = vec2(0.f, 0.f); + EmitVertex(); + + // And finalize the primitive + EndPrimitive(); + } +} diff --git a/examples/shader/resources/billboard.vert b/examples/shader/resources/billboard.vert new file mode 100644 index 00000000..3a899052 --- /dev/null +++ b/examples/shader/resources/billboard.vert @@ -0,0 +1,5 @@ +void main() +{ + // Transform the vertex position + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; +} diff --git a/examples/shader/resources/logo.png b/examples/shader/resources/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..29ba0102e52e1b094f1a31ecb321470e4e5ca725 GIT binary patch literal 8849 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