Added a geometry shader effect to the Shader example

This commit is contained in:
Mario Liebisch 2014-05-15 15:29:23 +02:00 committed by Lukas Dürrenberger
parent 1763861b26
commit 146f63874a
5 changed files with 152 additions and 0 deletions

View File

@ -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 /// Entry point of application
/// ///
@ -283,6 +362,7 @@ int main()
effects.push_back(new WaveBlur); effects.push_back(new WaveBlur);
effects.push_back(new StormBlink); effects.push_back(new StormBlink);
effects.push_back(new Edge); effects.push_back(new Edge);
effects.push_back(new Geometry);
std::size_t current = 0; std::size_t current = 0;
// Initialize them // Initialize them

View File

@ -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);
}

View File

@ -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();
}
}

View File

@ -0,0 +1,5 @@
void main()
{
// Transform the vertex position
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB