mirror of
https://github.com/SFML/SFML.git
synced 2024-11-24 20:31:05 +08:00
Added support for shaders written in non-legacy GLSL.
This commit is contained in:
parent
1dcad60878
commit
db7e683688
@ -115,6 +115,12 @@ int main()
|
||||
// Check whether the prerequisites are suppprted
|
||||
bool prerequisitesSupported = sf::VertexBuffer::isAvailable() && sf::Shader::isAvailable();
|
||||
|
||||
// Bind the shader to SFML's drawable interface
|
||||
terrainShader.setPositionAttribute ("positionAttribute")
|
||||
.setColorAttribute ("colorAttribute")
|
||||
.setTextureCoordinateAttribute("texCoordAttribute")
|
||||
.setModelViewProjectionMatrix ("modelViewProjectionMatrix");
|
||||
|
||||
// Set up our graphics resources and set the status text accordingly
|
||||
if (!prerequisitesSupported)
|
||||
{
|
||||
|
@ -1,3 +1,5 @@
|
||||
varying vec4 frontColor;
|
||||
|
||||
varying vec3 normal;
|
||||
uniform float lightFactor;
|
||||
|
||||
@ -7,5 +9,5 @@ void main()
|
||||
vec3 eyePosition = vec3(0.0, 0.0, 1.0);
|
||||
vec3 halfVector = normalize(lightPosition + eyePosition);
|
||||
float intensity = lightFactor + (1.0 - lightFactor) * dot(normalize(normal), normalize(halfVector));
|
||||
gl_FragColor = gl_Color * vec4(intensity, intensity, intensity, 1.0);
|
||||
gl_FragColor = frontColor * vec4(intensity, intensity, intensity, 1.0);
|
||||
}
|
||||
|
@ -1,8 +1,16 @@
|
||||
attribute vec2 positionAttribute;
|
||||
attribute vec4 colorAttribute;
|
||||
attribute vec2 texCoordAttribute;
|
||||
|
||||
uniform mat4 modelViewProjectionMatrix;
|
||||
|
||||
varying vec4 frontColor;
|
||||
|
||||
varying vec3 normal;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
gl_FrontColor = gl_Color;
|
||||
normal = vec3(gl_MultiTexCoord0.xy, 1.0);
|
||||
gl_Position = modelViewProjectionMatrix * vec4(positionAttribute, 0.0, 1.0);
|
||||
frontColor = colorAttribute;
|
||||
normal = vec3(texCoordAttribute, 1.0);
|
||||
}
|
||||
|
@ -28,8 +28,15 @@ public:
|
||||
return false;
|
||||
m_sprite.setTexture(m_texture);
|
||||
|
||||
// Bind the shader to SFML's drawable interface
|
||||
m_shader.setPositionAttribute ("positionAttribute")
|
||||
.setColorAttribute ("colorAttribute")
|
||||
.setTextureCoordinateAttribute("texCoordAttribute")
|
||||
.setModelViewProjectionMatrix ("modelViewProjectionMatrix")
|
||||
.setTextureMatrix ("textureMatrix");
|
||||
|
||||
// Load the shader
|
||||
if (!m_shader.loadFromFile("resources/pixelate.frag", sf::Shader::Fragment))
|
||||
if (!m_shader.loadFromFile("resources/pixelate.vert", "resources/pixelate.frag"))
|
||||
return false;
|
||||
m_shader.setUniform("texture", sf::Shader::CurrentTexture);
|
||||
|
||||
@ -92,6 +99,13 @@ public:
|
||||
m_text.setCharacterSize(22);
|
||||
m_text.setPosition(30, 20);
|
||||
|
||||
// Bind the shader to SFML's drawable interface
|
||||
m_shader.setPositionAttribute ("positionAttribute")
|
||||
.setColorAttribute ("colorAttribute")
|
||||
.setTextureCoordinateAttribute("texCoordAttribute")
|
||||
.setModelViewProjectionMatrix ("modelViewProjectionMatrix")
|
||||
.setTextureMatrix ("textureMatrix");
|
||||
|
||||
// Load the shader
|
||||
if (!m_shader.loadFromFile("resources/wave.vert", "resources/blur.frag"))
|
||||
return false;
|
||||
@ -145,6 +159,12 @@ public:
|
||||
m_points.append(sf::Vertex(sf::Vector2f(x, y), sf::Color(r, g, b)));
|
||||
}
|
||||
|
||||
// Bind the shader to SFML's drawable interface
|
||||
m_shader.setPositionAttribute("positionAttribute")
|
||||
.setColorAttribute ("colorAttribute")
|
||||
.setModelViewMatrix ("modelViewMatrix")
|
||||
.setProjectionMatrix ("projectionMatrix");
|
||||
|
||||
// Load the shader
|
||||
if (!m_shader.loadFromFile("resources/storm.vert", "resources/blink.frag"))
|
||||
return false;
|
||||
@ -212,8 +232,15 @@ public:
|
||||
m_entities.push_back(entity);
|
||||
}
|
||||
|
||||
// Bind the shader to SFML's drawable interface
|
||||
m_shader.setPositionAttribute ("positionAttribute")
|
||||
.setColorAttribute ("colorAttribute")
|
||||
.setTextureCoordinateAttribute("texCoordAttribute")
|
||||
.setModelViewProjectionMatrix ("modelViewProjectionMatrix")
|
||||
.setTextureMatrix ("textureMatrix");
|
||||
|
||||
// Load the shader
|
||||
if (!m_shader.loadFromFile("resources/edge.frag", sf::Shader::Fragment))
|
||||
if (!m_shader.loadFromFile("resources/edge.vert", "resources/edge.frag"))
|
||||
return false;
|
||||
m_shader.setUniform("texture", sf::Shader::CurrentTexture);
|
||||
|
||||
@ -290,6 +317,10 @@ public:
|
||||
if (!m_logoTexture.loadFromFile("resources/logo.png"))
|
||||
return false;
|
||||
|
||||
// Bind the shader to SFML's drawable interface
|
||||
m_shader.setPositionAttribute ("positionAttribute")
|
||||
.setModelViewProjectionMatrix("modelViewProjectionMatrix");
|
||||
|
||||
// Load the shader
|
||||
if (!m_shader.loadFromFile("resources/billboard.vert", "resources/billboard.geom", "resources/billboard.frag"))
|
||||
return false;
|
||||
|
@ -4,8 +4,10 @@ uniform sampler2D texture;
|
||||
|
||||
in vec2 tex_coord;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Read and apply a color from the texture
|
||||
gl_FragColor = texture2D(texture, tex_coord);
|
||||
fragColor = texture2D(texture, tex_coord);
|
||||
}
|
||||
|
@ -1,5 +1,11 @@
|
||||
#version 150
|
||||
|
||||
in vec2 positionAttribute;
|
||||
|
||||
uniform mat4 modelViewProjectionMatrix;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Transform the vertex position
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
gl_Position = modelViewProjectionMatrix * vec4(positionAttribute, 0.0, 1.0);
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
uniform sampler2D texture;
|
||||
uniform float blink_alpha;
|
||||
|
||||
varying vec4 frontColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 pixel = gl_Color;
|
||||
vec4 pixel = frontColor;
|
||||
pixel.a = blink_alpha;
|
||||
gl_FragColor = pixel;
|
||||
}
|
||||
|
@ -1,20 +1,23 @@
|
||||
uniform sampler2D texture;
|
||||
uniform float blur_radius;
|
||||
|
||||
varying vec4 texCoord;
|
||||
varying vec4 frontColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 offx = vec2(blur_radius, 0.0);
|
||||
vec2 offy = vec2(0.0, blur_radius);
|
||||
|
||||
vec4 pixel = texture2D(texture, gl_TexCoord[0].xy) * 4.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy - offx) * 2.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy + offx) * 2.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy - offy) * 2.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy + offy) * 2.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy - offx - offy) * 1.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy - offx + offy) * 1.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy + offx - offy) * 1.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy + offx + offy) * 1.0;
|
||||
vec4 pixel = texture2D(texture, texCoord.xy) * 4.0 +
|
||||
texture2D(texture, texCoord.xy - offx) * 2.0 +
|
||||
texture2D(texture, texCoord.xy + offx) * 2.0 +
|
||||
texture2D(texture, texCoord.xy - offy) * 2.0 +
|
||||
texture2D(texture, texCoord.xy + offy) * 2.0 +
|
||||
texture2D(texture, texCoord.xy - offx - offy) * 1.0 +
|
||||
texture2D(texture, texCoord.xy - offx + offy) * 1.0 +
|
||||
texture2D(texture, texCoord.xy + offx - offy) * 1.0 +
|
||||
texture2D(texture, texCoord.xy + offx + offy) * 1.0;
|
||||
|
||||
gl_FragColor = gl_Color * (pixel / 16.0);
|
||||
gl_FragColor = frontColor * (pixel / 16.0);
|
||||
}
|
||||
|
@ -1,29 +1,32 @@
|
||||
uniform sampler2D texture;
|
||||
uniform float edge_threshold;
|
||||
|
||||
varying vec4 texCoord;
|
||||
varying vec4 frontColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
const float offset = 1.0 / 512.0;
|
||||
vec2 offx = vec2(offset, 0.0);
|
||||
vec2 offy = vec2(0.0, offset);
|
||||
|
||||
vec4 hEdge = texture2D(texture, gl_TexCoord[0].xy - offy) * -2.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy + offy) * 2.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy - offx - offy) * -1.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy - offx + offy) * 1.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy + offx - offy) * -1.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy + offx + offy) * 1.0;
|
||||
vec4 hEdge = texture2D(texture, texCoord.xy - offy) * -2.0 +
|
||||
texture2D(texture, texCoord.xy + offy) * 2.0 +
|
||||
texture2D(texture, texCoord.xy - offx - offy) * -1.0 +
|
||||
texture2D(texture, texCoord.xy - offx + offy) * 1.0 +
|
||||
texture2D(texture, texCoord.xy + offx - offy) * -1.0 +
|
||||
texture2D(texture, texCoord.xy + offx + offy) * 1.0;
|
||||
|
||||
vec4 vEdge = texture2D(texture, gl_TexCoord[0].xy - offx) * 2.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy + offx) * -2.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy - offx - offy) * 1.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy - offx + offy) * -1.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy + offx - offy) * 1.0 +
|
||||
texture2D(texture, gl_TexCoord[0].xy + offx + offy) * -1.0;
|
||||
vec4 vEdge = texture2D(texture, texCoord.xy - offx) * 2.0 +
|
||||
texture2D(texture, texCoord.xy + offx) * -2.0 +
|
||||
texture2D(texture, texCoord.xy - offx - offy) * 1.0 +
|
||||
texture2D(texture, texCoord.xy - offx + offy) * -1.0 +
|
||||
texture2D(texture, texCoord.xy + offx - offy) * 1.0 +
|
||||
texture2D(texture, texCoord.xy + offx + offy) * -1.0;
|
||||
|
||||
vec3 result = sqrt(hEdge.rgb * hEdge.rgb + vEdge.rgb * vEdge.rgb);
|
||||
float edge = length(result);
|
||||
vec4 pixel = gl_Color * texture2D(texture, gl_TexCoord[0].xy);
|
||||
vec4 pixel = frontColor * texture2D(texture, texCoord.xy);
|
||||
if (edge > (edge_threshold * 8.0))
|
||||
pixel.rgb = vec3(0.0, 0.0, 0.0);
|
||||
else
|
||||
|
19
examples/shader/resources/edge.vert
Normal file
19
examples/shader/resources/edge.vert
Normal file
@ -0,0 +1,19 @@
|
||||
attribute vec2 positionAttribute;
|
||||
attribute vec4 colorAttribute;
|
||||
attribute vec2 texCoordAttribute;
|
||||
|
||||
uniform mat4 modelViewProjectionMatrix;
|
||||
uniform mat4 textureMatrix;
|
||||
|
||||
varying vec4 texCoord;
|
||||
varying vec4 frontColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Transform the vertex position
|
||||
gl_Position = modelViewProjectionMatrix * vec4(positionAttribute, 0.0, 1.0);
|
||||
|
||||
frontColor = colorAttribute;
|
||||
|
||||
texCoord = textureMatrix * vec4(texCoordAttribute, 0.0, 1.0);
|
||||
}
|
@ -1,9 +1,12 @@
|
||||
uniform sampler2D texture;
|
||||
uniform float pixel_threshold;
|
||||
|
||||
varying vec4 texCoord;
|
||||
varying vec4 frontColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
float factor = 1.0 / (pixel_threshold + 0.001);
|
||||
vec2 pos = floor(gl_TexCoord[0].xy * factor + 0.5) / factor;
|
||||
gl_FragColor = texture2D(texture, pos) * gl_Color;
|
||||
vec2 pos = floor(texCoord.xy * factor + 0.5) / factor;
|
||||
gl_FragColor = texture2D(texture, pos) * frontColor;
|
||||
}
|
||||
|
16
examples/shader/resources/pixelate.vert
Normal file
16
examples/shader/resources/pixelate.vert
Normal file
@ -0,0 +1,16 @@
|
||||
attribute vec2 positionAttribute;
|
||||
attribute vec4 colorAttribute;
|
||||
attribute vec2 texCoordAttribute;
|
||||
|
||||
uniform mat4 modelViewProjectionMatrix;
|
||||
uniform mat4 textureMatrix;
|
||||
|
||||
varying vec4 texCoord;
|
||||
varying vec4 frontColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = modelViewProjectionMatrix * vec4(positionAttribute, 0.0, 1.0);
|
||||
texCoord = textureMatrix * vec4(texCoordAttribute, 0.0, 1.0);
|
||||
frontColor = colorAttribute;
|
||||
}
|
@ -2,9 +2,17 @@ uniform vec2 storm_position;
|
||||
uniform float storm_total_radius;
|
||||
uniform float storm_inner_radius;
|
||||
|
||||
attribute vec2 positionAttribute;
|
||||
attribute vec4 colorAttribute;
|
||||
|
||||
uniform mat4 modelViewMatrix;
|
||||
uniform mat4 projectionMatrix;
|
||||
|
||||
varying vec4 frontColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 vertex = gl_ModelViewMatrix * gl_Vertex;
|
||||
vec4 vertex = modelViewMatrix * vec4(positionAttribute, 0.0, 1.0);
|
||||
vec2 offset = vertex.xy - storm_position;
|
||||
float len = length(offset);
|
||||
if (len < storm_total_radius)
|
||||
@ -13,7 +21,6 @@ void main()
|
||||
vertex.xy = storm_position + normalize(offset) * push_distance;
|
||||
}
|
||||
|
||||
gl_Position = gl_ProjectionMatrix * vertex;
|
||||
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
|
||||
gl_FrontColor = gl_Color;
|
||||
gl_Position = projectionMatrix * vertex;
|
||||
frontColor = colorAttribute;
|
||||
}
|
||||
|
@ -1,15 +1,25 @@
|
||||
uniform float wave_phase;
|
||||
uniform vec2 wave_amplitude;
|
||||
|
||||
attribute vec2 positionAttribute;
|
||||
attribute vec4 colorAttribute;
|
||||
attribute vec2 texCoordAttribute;
|
||||
|
||||
uniform mat4 modelViewProjectionMatrix;
|
||||
uniform mat4 textureMatrix;
|
||||
|
||||
varying vec4 texCoord;
|
||||
varying vec4 frontColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 vertex = gl_Vertex;
|
||||
vertex.x += cos(gl_Vertex.y * 0.02 + wave_phase * 3.8) * wave_amplitude.x
|
||||
+ sin(gl_Vertex.y * 0.02 + wave_phase * 6.3) * wave_amplitude.x * 0.3;
|
||||
vertex.y += sin(gl_Vertex.x * 0.02 + wave_phase * 2.4) * wave_amplitude.y
|
||||
+ cos(gl_Vertex.x * 0.02 + wave_phase * 5.2) * wave_amplitude.y * 0.3;
|
||||
vec4 vertex = vec4(positionAttribute, 0.0, 1.0);
|
||||
vertex.x += cos(positionAttribute.y * 0.02 + wave_phase * 3.8) * wave_amplitude.x
|
||||
+ sin(positionAttribute.y * 0.02 + wave_phase * 6.3) * wave_amplitude.x * 0.3;
|
||||
vertex.y += sin(positionAttribute.x * 0.02 + wave_phase * 2.4) * wave_amplitude.y
|
||||
+ cos(positionAttribute.x * 0.02 + wave_phase * 5.2) * wave_amplitude.y * 0.3;
|
||||
|
||||
gl_Position = gl_ModelViewProjectionMatrix * vertex;
|
||||
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
|
||||
gl_FrontColor = gl_Color;
|
||||
gl_Position = modelViewProjectionMatrix * vertex;
|
||||
texCoord = textureMatrix * vec4(texCoordAttribute, 0.0, 1.0);
|
||||
frontColor = colorAttribute;
|
||||
}
|
||||
|
@ -53,6 +53,17 @@ class SFML_GRAPHICS_API Shader : GlResource, NonCopyable
|
||||
{
|
||||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Vertex attribute indices
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
enum VertexAttributeIndices
|
||||
{
|
||||
PositionIndex = 0, ///< Position attribute index
|
||||
ColorIndex = 1, ///< Color attribute index
|
||||
TextureCoordinateIndex = 2 ///< Texture coordinate attribute index
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Types of shaders
|
||||
///
|
||||
@ -287,6 +298,118 @@ public:
|
||||
////////////////////////////////////////////////////////////
|
||||
bool loadFromStream(InputStream& vertexShaderStream, InputStream& geometryShaderStream, InputStream& fragmentShaderStream);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Specify the name of the position attribute in GLSL
|
||||
///
|
||||
/// This function returns a reference to *this, so that calls
|
||||
/// can be chained.
|
||||
///
|
||||
/// \param name Name of the position attribute in GLSL
|
||||
///
|
||||
/// \return Reference to *this
|
||||
///
|
||||
/// \see setColorAttribute, setTextureCoordinateAttribute, setModelViewMatrix,
|
||||
/// setProjectionMatrix, setModelViewProjectionMatrix, setTextureMatrix
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
Shader& setPositionAttribute(const std::string& name);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Specify the name of the color attribute in GLSL
|
||||
///
|
||||
/// This function returns a reference to *this, so that calls
|
||||
/// can be chained.
|
||||
///
|
||||
/// \param name Name of the color attribute in GLSL
|
||||
///
|
||||
/// \return Reference to *this
|
||||
///
|
||||
/// \see setPositionAttribute, setTextureCoordinateAttribute, setModelViewMatrix,
|
||||
/// setProjectionMatrix, setModelViewProjectionMatrix, setTextureMatrix
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
Shader& setColorAttribute(const std::string& name);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Specify the name of the texture coordinate attribute in GLSL
|
||||
///
|
||||
/// This function returns a reference to *this, so that calls
|
||||
/// can be chained.
|
||||
///
|
||||
/// \param name Name of the texture coordinate attribute in GLSL
|
||||
///
|
||||
/// \return Reference to *this
|
||||
///
|
||||
/// \see setPositionAttribute, setColorAttribute, setModelViewMatrix,
|
||||
/// setProjectionMatrix, setModelViewProjectionMatrix, setTextureMatrix
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
Shader& setTextureCoordinateAttribute(const std::string& name);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Specify the name of the modelview matrix uniform in GLSL
|
||||
///
|
||||
/// This function returns a reference to *this, so that calls
|
||||
/// can be chained.
|
||||
///
|
||||
/// \param name Name of the modelview matrix uniform in GLSL
|
||||
///
|
||||
/// \return Reference to *this
|
||||
///
|
||||
/// \see setPositionAttribute, setColorAttribute, setTextureCoordinateAttribute,
|
||||
/// setProjectionMatrix, setModelViewProjectionMatrix, setTextureMatrix
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
Shader& setModelViewMatrix(const std::string& name);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Specify the name of the projection matrix uniform in GLSL
|
||||
///
|
||||
/// This function returns a reference to *this, so that calls
|
||||
/// can be chained.
|
||||
///
|
||||
/// \param name Name of the projection matrix uniform in GLSL
|
||||
///
|
||||
/// \return Reference to *this
|
||||
///
|
||||
/// \see setPositionAttribute, setColorAttribute, setTextureCoordinateAttribute,
|
||||
/// setModelViewMatrix, setModelViewProjectionMatrix, setTextureMatrix
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
Shader& setProjectionMatrix(const std::string& name);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Specify the name of the pre-multiplied modelview-projection matrix uniform in GLSL
|
||||
///
|
||||
/// This function returns a reference to *this, so that calls
|
||||
/// can be chained.
|
||||
///
|
||||
/// \param name Name of the pre-multiplied modelview-projection matrix uniform in GLSL
|
||||
///
|
||||
/// \return Reference to *this
|
||||
///
|
||||
/// \see setPositionAttribute, setColorAttribute, setTextureCoordinateAttribute,
|
||||
/// setModelViewMatrix, setProjectionMatrix, setTextureMatrix
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
Shader& setModelViewProjectionMatrix(const std::string& name);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Specify the name of the texture matrix uniform in GLSL
|
||||
///
|
||||
/// This function returns a reference to *this, so that calls
|
||||
/// can be chained.
|
||||
///
|
||||
/// \param name Name of the texture matrix uniform in GLSL
|
||||
///
|
||||
/// \return Reference to *this
|
||||
///
|
||||
/// \see setPositionAttribute, setColorAttribute, setTextureCoordinateAttribute,
|
||||
/// setModelViewMatrix, setProjectionMatrix, setModelViewProjectionMatrix
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
Shader& setTextureMatrix(const std::string& name);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Specify value for \p float uniform
|
||||
///
|
||||
@ -693,6 +816,8 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
friend class RenderTarget;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Compile the shader(s) and create the program
|
||||
///
|
||||
@ -736,6 +861,14 @@ private:
|
||||
////////////////////////////////////////////////////////////
|
||||
struct UniformBinder;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Shader to Drawable interface specification
|
||||
///
|
||||
/// Implementation is private in the .cpp file.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
struct Interface;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Types
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -745,10 +878,15 @@ private:
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
unsigned int m_shaderProgram; ///< OpenGL identifier for the program
|
||||
int m_currentTexture; ///< Location of the current texture in the shader
|
||||
TextureTable m_textures; ///< Texture variables in the shader, mapped to their location
|
||||
UniformTable m_uniforms; ///< Parameters location cache
|
||||
unsigned int m_shaderProgram; ///< OpenGL identifier for the program
|
||||
int m_currentTexture; ///< Location of the current texture in the shader
|
||||
TextureTable m_textures; ///< Texture variables in the shader, mapped to their location
|
||||
UniformTable m_uniforms; ///< Parameters location cache
|
||||
int m_modelViewMatrixIndex; ///< Index of the modelview matrix
|
||||
int m_projectionMatrixIndex; ///< Index of the projection matrix
|
||||
int m_modelViewProjectionMatrixIndex; ///< Index of the modelview-projection matrix
|
||||
int m_textureMatrixIndex; ///< Index of the texture matrix
|
||||
Interface* m_interface; ///< Shader to drawable interface specification
|
||||
};
|
||||
|
||||
} // namespace sf
|
||||
|
@ -245,6 +245,11 @@
|
||||
|
||||
// Core since 2.0 - ARB_vertex_shader
|
||||
#define GLEXT_vertex_shader sfogl_ext_ARB_vertex_shader
|
||||
#define GLEXT_glVertexAttribPointer glVertexAttribPointerARB
|
||||
#define GLEXT_glEnableVertexAttribArray glEnableVertexAttribArrayARB
|
||||
#define GLEXT_glDisableVertexAttribArray glDisableVertexAttribArrayARB
|
||||
#define GLEXT_glBindAttribLocation glBindAttribLocationARB
|
||||
#define GLEXT_glGetAttribLocation glGetAttribLocationARB
|
||||
#define GLEXT_GL_VERTEX_SHADER GL_VERTEX_SHADER_ARB
|
||||
#define GLEXT_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB
|
||||
|
||||
|
@ -147,7 +147,19 @@ void RenderTarget::clear(const Color& color)
|
||||
if (isActive(m_id) || setActive(true))
|
||||
{
|
||||
// Unbind texture to fix RenderTexture preventing clear
|
||||
applyTexture(NULL);
|
||||
{
|
||||
// Bind no texture
|
||||
glCheck(glBindTexture(GL_TEXTURE_2D, 0));
|
||||
|
||||
// Reset the texture matrix
|
||||
glCheck(glMatrixMode(GL_TEXTURE));
|
||||
glCheck(glLoadIdentity());
|
||||
|
||||
// Go back to model-view mode
|
||||
glCheck(glMatrixMode(GL_MODELVIEW));
|
||||
|
||||
m_cache.lastTextureId = 0;
|
||||
}
|
||||
|
||||
glCheck(glClearColor(color.r / 255.f, color.g / 255.f, color.b / 255.f, color.a / 255.f));
|
||||
glCheck(glClear(GL_COLOR_BUFFER_BIT));
|
||||
@ -283,9 +295,19 @@ void RenderTarget::draw(const Vertex* vertices, std::size_t vertexCount,
|
||||
if (!m_cache.enable || (enableTexCoordsArray != m_cache.texCoordsArrayEnabled))
|
||||
{
|
||||
if (enableTexCoordsArray)
|
||||
{
|
||||
glCheck(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
|
||||
|
||||
if (Shader::isAvailable())
|
||||
glCheck(GLEXT_glEnableVertexAttribArray(Shader::TextureCoordinateIndex));
|
||||
}
|
||||
else
|
||||
{
|
||||
glCheck(glDisableClientState(GL_TEXTURE_COORD_ARRAY));
|
||||
|
||||
if (Shader::isAvailable())
|
||||
glCheck(GLEXT_glDisableVertexAttribArray(Shader::TextureCoordinateIndex));
|
||||
}
|
||||
}
|
||||
|
||||
// If we switch between non-cache and cache mode or enable texture
|
||||
@ -302,6 +324,15 @@ void RenderTarget::draw(const Vertex* vertices, std::size_t vertexCount,
|
||||
glCheck(glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), data + 8));
|
||||
if (enableTexCoordsArray)
|
||||
glCheck(glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), data + 12));
|
||||
|
||||
if (Shader::isAvailable())
|
||||
{
|
||||
glCheck(GLEXT_glVertexAttribPointer(Shader::PositionIndex, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), data + 0));
|
||||
glCheck(GLEXT_glVertexAttribPointer(Shader::ColorIndex, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), data + 8));
|
||||
|
||||
if (enableTexCoordsArray)
|
||||
glCheck(GLEXT_glVertexAttribPointer(Shader::TextureCoordinateIndex, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), data + 12));
|
||||
}
|
||||
}
|
||||
else if (enableTexCoordsArray && !m_cache.texCoordsArrayEnabled)
|
||||
{
|
||||
@ -309,6 +340,9 @@ void RenderTarget::draw(const Vertex* vertices, std::size_t vertexCount,
|
||||
const char* data = reinterpret_cast<const char*>(m_cache.vertexCache);
|
||||
|
||||
glCheck(glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), data + 12));
|
||||
|
||||
if (Shader::isAvailable())
|
||||
glCheck(GLEXT_glVertexAttribPointer(Shader::TextureCoordinateIndex, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), data + 12));
|
||||
}
|
||||
|
||||
drawPrimitives(type, 0, vertexCount);
|
||||
@ -368,12 +402,24 @@ void RenderTarget::draw(const VertexBuffer& vertexBuffer, std::size_t firstVerte
|
||||
|
||||
// Always enable texture coordinates
|
||||
if (!m_cache.enable || !m_cache.texCoordsArrayEnabled)
|
||||
{
|
||||
glCheck(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
|
||||
|
||||
if (Shader::isAvailable())
|
||||
glCheck(GLEXT_glEnableVertexAttribArray(Shader::TextureCoordinateIndex));
|
||||
}
|
||||
|
||||
glCheck(glVertexPointer(2, GL_FLOAT, sizeof(Vertex), reinterpret_cast<const void*>(0)));
|
||||
glCheck(glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), reinterpret_cast<const void*>(8)));
|
||||
glCheck(glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), reinterpret_cast<const void*>(12)));
|
||||
|
||||
if (Shader::isAvailable())
|
||||
{
|
||||
glCheck(GLEXT_glVertexAttribPointer(Shader::PositionIndex, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<const void*>(0)));
|
||||
glCheck(GLEXT_glVertexAttribPointer(Shader::ColorIndex, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), reinterpret_cast<const void*>(8)));
|
||||
glCheck(GLEXT_glVertexAttribPointer(Shader::TextureCoordinateIndex, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<const void*>(12)));
|
||||
}
|
||||
|
||||
drawPrimitives(vertexBuffer.getPrimitiveType(), firstVertex, vertexCount);
|
||||
|
||||
// Unbind vertex buffer
|
||||
@ -519,10 +565,29 @@ void RenderTarget::resetGLStates()
|
||||
|
||||
// Apply the default SFML states
|
||||
applyBlendMode(BlendAlpha);
|
||||
applyTexture(NULL);
|
||||
|
||||
// Bind no texture
|
||||
glCheck(glBindTexture(GL_TEXTURE_2D, 0));
|
||||
|
||||
// Reset the texture matrix
|
||||
glCheck(glMatrixMode(GL_TEXTURE));
|
||||
glCheck(glLoadIdentity());
|
||||
|
||||
// Go back to model-view mode
|
||||
glCheck(glMatrixMode(GL_MODELVIEW));
|
||||
|
||||
m_cache.lastTextureId = 0;
|
||||
|
||||
if (shaderAvailable)
|
||||
{
|
||||
applyShader(NULL);
|
||||
|
||||
// Enable all available vertex attribute arrays
|
||||
glCheck(GLEXT_glEnableVertexAttribArray(Shader::PositionIndex));
|
||||
glCheck(GLEXT_glEnableVertexAttribArray(Shader::ColorIndex));
|
||||
glCheck(GLEXT_glEnableVertexAttribArray(Shader::TextureCoordinateIndex));
|
||||
}
|
||||
|
||||
if (vertexBufferAvailable)
|
||||
glCheck(VertexBuffer::bind(NULL));
|
||||
|
||||
@ -622,23 +687,16 @@ void RenderTarget::applyBlendMode(const BlendMode& mode)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void RenderTarget::applyTransform(const Transform& transform)
|
||||
void RenderTarget::applyTransform(const Transform&)
|
||||
{
|
||||
// No need to call glMatrixMode(GL_MODELVIEW), it is always the
|
||||
// current mode (for optimization purpose, since it's the most used)
|
||||
if (transform == Transform::Identity)
|
||||
glCheck(glLoadIdentity());
|
||||
else
|
||||
glCheck(glLoadMatrixf(transform.getMatrix()));
|
||||
// Function kept for compatibility, no-op now
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void RenderTarget::applyTexture(const Texture* texture)
|
||||
void RenderTarget::applyTexture(const Texture*)
|
||||
{
|
||||
Texture::bind(texture, Texture::Pixels);
|
||||
|
||||
m_cache.lastTextureId = texture ? texture->m_cacheId : 0;
|
||||
// Function kept for compatibility, no-op now
|
||||
}
|
||||
|
||||
|
||||
@ -652,19 +710,45 @@ void RenderTarget::applyShader(const Shader* shader)
|
||||
////////////////////////////////////////////////////////////
|
||||
void RenderTarget::setupDraw(bool useVertexCache, const RenderStates& states)
|
||||
{
|
||||
static const GLfloat identityMatrix[] =
|
||||
{
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
// First set the persistent OpenGL states if it's the very first call
|
||||
if (!m_cache.glStatesSet)
|
||||
resetGLStates();
|
||||
|
||||
const GLfloat* modelViewMatrix = identityMatrix;
|
||||
|
||||
if (useVertexCache)
|
||||
{
|
||||
// Since vertices are transformed, we must use an identity transform to render them
|
||||
if (!m_cache.enable || !m_cache.useVertexCache)
|
||||
if (!m_cache.enable ||
|
||||
!m_cache.useVertexCache ||
|
||||
(states.shader && (states.shader->m_modelViewMatrixIndex >= 0)))
|
||||
{
|
||||
glCheck(glLoadIdentity());
|
||||
modelViewMatrix = identityMatrix;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
applyTransform(states.transform);
|
||||
// No need to call glMatrixMode(GL_MODELVIEW), it is always the
|
||||
// current mode (for optimization purpose, since it's the most used)
|
||||
if (states.transform == Transform::Identity)
|
||||
{
|
||||
glCheck(glLoadIdentity());
|
||||
modelViewMatrix = identityMatrix;
|
||||
}
|
||||
else
|
||||
{
|
||||
glCheck(glLoadMatrixf(states.transform.getMatrix()));
|
||||
modelViewMatrix = states.transform.getMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
// Apply the view
|
||||
@ -675,8 +759,12 @@ void RenderTarget::setupDraw(bool useVertexCache, const RenderStates& states)
|
||||
if (!m_cache.enable || (states.blendMode != m_cache.lastBlendMode))
|
||||
applyBlendMode(states.blendMode);
|
||||
|
||||
bool applyStatesTexture = false;
|
||||
|
||||
// Apply the texture
|
||||
if (!m_cache.enable || (states.texture && states.texture->m_fboAttachment))
|
||||
if (!m_cache.enable ||
|
||||
(states.texture && states.texture->m_fboAttachment) ||
|
||||
(states.shader && (states.shader->m_textureMatrixIndex >= 0)))
|
||||
{
|
||||
// If the texture is an FBO attachment, always rebind it
|
||||
// in order to inform the OpenGL driver that we want changes
|
||||
@ -684,18 +772,105 @@ void RenderTarget::setupDraw(bool useVertexCache, const RenderStates& states)
|
||||
// This saves us from having to call glFlush() in
|
||||
// RenderTextureImplFBO which can be quite costly
|
||||
// See: https://www.khronos.org/opengl/wiki/Memory_Model
|
||||
applyTexture(states.texture);
|
||||
applyStatesTexture = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Uint64 textureId = states.texture ? states.texture->m_cacheId : 0;
|
||||
if (textureId != m_cache.lastTextureId)
|
||||
applyTexture(states.texture);
|
||||
applyStatesTexture = true;
|
||||
}
|
||||
|
||||
// Temporary matrix we use to store both the texture matrix
|
||||
// and if required the pre-multiplied modelview-projection matrix
|
||||
GLfloat tempMatrix[16] =
|
||||
{
|
||||
1.f, 0.f, 0.f, 0.f,
|
||||
0.f, 1.f, 0.f, 0.f,
|
||||
0.f, 0.f, 1.f, 0.f,
|
||||
0.f, 0.f, 0.f, 1.f
|
||||
};
|
||||
|
||||
const GLfloat* textureMatrix = identityMatrix;
|
||||
|
||||
if (applyStatesTexture)
|
||||
{
|
||||
if (states.texture && states.texture->m_texture)
|
||||
{
|
||||
// Bind the texture
|
||||
glCheck(glBindTexture(GL_TEXTURE_2D, states.texture->m_texture));
|
||||
|
||||
// If non-normalized coordinates (= pixels) are requested, we need to
|
||||
// setup scale factors that convert the range [0 .. size] to [0 .. 1]
|
||||
tempMatrix[0] = 1.f / states.texture->m_actualSize.x;
|
||||
tempMatrix[5] = 1.f / states.texture->m_actualSize.y;
|
||||
|
||||
// If pixels are flipped we must invert the Y axis
|
||||
if (states.texture->m_pixelsFlipped)
|
||||
{
|
||||
tempMatrix[5] = -tempMatrix[5];
|
||||
tempMatrix[13] = static_cast<float>(states.texture->m_size.y) / states.texture->m_actualSize.y;
|
||||
}
|
||||
|
||||
// Load the matrix
|
||||
glCheck(glMatrixMode(GL_TEXTURE));
|
||||
glCheck(glLoadMatrixf(tempMatrix));
|
||||
textureMatrix = tempMatrix;
|
||||
|
||||
// Go back to model-view mode
|
||||
glCheck(glMatrixMode(GL_MODELVIEW));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Bind no texture
|
||||
glCheck(glBindTexture(GL_TEXTURE_2D, 0));
|
||||
|
||||
// Reset the texture matrix
|
||||
glCheck(glMatrixMode(GL_TEXTURE));
|
||||
glCheck(glLoadIdentity());
|
||||
textureMatrix = identityMatrix;
|
||||
|
||||
// Go back to model-view mode
|
||||
glCheck(glMatrixMode(GL_MODELVIEW));
|
||||
}
|
||||
|
||||
m_cache.lastTextureId = states.texture ? states.texture->m_cacheId : 0;
|
||||
}
|
||||
|
||||
// Apply the shader
|
||||
if (states.shader)
|
||||
{
|
||||
applyShader(states.shader);
|
||||
|
||||
// Set all available uniforms
|
||||
if (states.shader->m_modelViewMatrixIndex >= 0)
|
||||
glCheck(GLEXT_glUniformMatrix4fv(states.shader->m_modelViewMatrixIndex, 1, GL_FALSE, modelViewMatrix));
|
||||
|
||||
if (states.shader->m_projectionMatrixIndex >= 0)
|
||||
glCheck(GLEXT_glUniformMatrix4fv(states.shader->m_projectionMatrixIndex, 1, GL_FALSE, m_view.getTransform().getMatrix()));
|
||||
|
||||
if (states.shader->m_textureMatrixIndex >= 0)
|
||||
glCheck(GLEXT_glUniformMatrix4fv(states.shader->m_textureMatrixIndex, 1, GL_FALSE, textureMatrix));
|
||||
|
||||
if (states.shader->m_modelViewProjectionMatrixIndex >= 0)
|
||||
{
|
||||
const GLfloat* A = m_view.getTransform().getMatrix();
|
||||
const GLfloat* B = modelViewMatrix;
|
||||
|
||||
for (int i = 0; i < 4 * 4; i += 4)
|
||||
{
|
||||
for (int j = 0; j < 4; ++j)
|
||||
{
|
||||
tempMatrix[i + j] = A[4 * 0 + j] * B[i + 0] +
|
||||
A[4 * 1 + j] * B[i + 1] +
|
||||
A[4 * 2 + j] * B[i + 2] +
|
||||
A[4 * 3 + j] * B[i + 3];
|
||||
}
|
||||
}
|
||||
|
||||
glCheck(GLEXT_glUniformMatrix4fv(states.shader->m_modelViewProjectionMatrixIndex, 1, GL_FALSE, tempMatrix));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -722,7 +897,19 @@ void RenderTarget::cleanupDraw(const RenderStates& states)
|
||||
// If the texture we used to draw belonged to a RenderTexture, then forcibly unbind that texture.
|
||||
// This prevents a bug where some drivers do not clear RenderTextures properly.
|
||||
if (states.texture && states.texture->m_fboAttachment)
|
||||
applyTexture(NULL);
|
||||
{
|
||||
// Bind no texture
|
||||
glCheck(glBindTexture(GL_TEXTURE_2D, 0));
|
||||
|
||||
// Reset the texture matrix
|
||||
glCheck(glMatrixMode(GL_TEXTURE));
|
||||
glCheck(glLoadIdentity());
|
||||
|
||||
// Go back to model-view mode
|
||||
glCheck(glMatrixMode(GL_MODELVIEW));
|
||||
|
||||
m_cache.lastTextureId = 0;
|
||||
}
|
||||
|
||||
// Re-enable the cache at the end of the draw if it was disabled
|
||||
m_cache.enable = true;
|
||||
|
@ -218,12 +218,29 @@ struct Shader::UniformBinder : private NonCopyable
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
struct Shader::Interface
|
||||
{
|
||||
std::string positionAttribute;
|
||||
std::string colorAttribute;
|
||||
std::string texCoordAttribute;
|
||||
|
||||
std::string modelViewMatrix;
|
||||
std::string projectionMatrix;
|
||||
std::string modelViewProjectionMatrix;
|
||||
std::string textureMatrix;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Shader::Shader() :
|
||||
m_shaderProgram (0),
|
||||
m_currentTexture(-1),
|
||||
m_textures (),
|
||||
m_uniforms ()
|
||||
m_shaderProgram (0),
|
||||
m_currentTexture (-1),
|
||||
m_modelViewMatrixIndex (-1),
|
||||
m_projectionMatrixIndex (-1),
|
||||
m_modelViewProjectionMatrixIndex(-1),
|
||||
m_textureMatrixIndex (-1),
|
||||
m_interface (0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -231,6 +248,9 @@ m_uniforms ()
|
||||
////////////////////////////////////////////////////////////
|
||||
Shader::~Shader()
|
||||
{
|
||||
// Destroy the interface specification if we created one
|
||||
delete m_interface;
|
||||
|
||||
TransientContextLock lock;
|
||||
|
||||
// Destroy effect program
|
||||
@ -422,6 +442,90 @@ bool Shader::loadFromStream(InputStream& vertexShaderStream, InputStream& geomet
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Shader& Shader::setPositionAttribute(const std::string& positionAttribute)
|
||||
{
|
||||
if (!m_interface)
|
||||
m_interface = new Interface;
|
||||
|
||||
m_interface->positionAttribute = positionAttribute;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Shader& Shader::setColorAttribute(const std::string& name)
|
||||
{
|
||||
if (!m_interface)
|
||||
m_interface = new Interface;
|
||||
|
||||
m_interface->colorAttribute = name;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Shader& Shader::setTextureCoordinateAttribute(const std::string& name)
|
||||
{
|
||||
if (!m_interface)
|
||||
m_interface = new Interface;
|
||||
|
||||
m_interface->texCoordAttribute = name;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Shader& Shader::setModelViewMatrix(const std::string& name)
|
||||
{
|
||||
if (!m_interface)
|
||||
m_interface = new Interface;
|
||||
|
||||
m_interface->modelViewMatrix = name;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Shader& Shader::setProjectionMatrix(const std::string& name)
|
||||
{
|
||||
if (!m_interface)
|
||||
m_interface = new Interface;
|
||||
|
||||
m_interface->projectionMatrix = name;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Shader& Shader::setModelViewProjectionMatrix(const std::string& name)
|
||||
{
|
||||
if (!m_interface)
|
||||
m_interface = new Interface;
|
||||
|
||||
m_interface->modelViewProjectionMatrix = name;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Shader& Shader::setTextureMatrix(const std::string& name)
|
||||
{
|
||||
if (!m_interface)
|
||||
m_interface = new Interface;
|
||||
|
||||
m_interface->textureMatrix = name;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Shader::setUniform(const std::string& name, float x)
|
||||
{
|
||||
@ -855,6 +959,11 @@ bool Shader::compile(const char* vertexShaderCode, const char* geometryShaderCod
|
||||
m_textures.clear();
|
||||
m_uniforms.clear();
|
||||
|
||||
m_modelViewMatrixIndex = -1;
|
||||
m_projectionMatrixIndex = -1;
|
||||
m_modelViewProjectionMatrixIndex = -1;
|
||||
m_textureMatrixIndex = -1;
|
||||
|
||||
// Create the program
|
||||
GLEXT_GLhandle shaderProgram;
|
||||
glCheck(shaderProgram = GLEXT_glCreateProgramObject());
|
||||
@ -942,6 +1051,19 @@ bool Shader::compile(const char* vertexShaderCode, const char* geometryShaderCod
|
||||
glCheck(GLEXT_glDeleteObject(fragmentShader));
|
||||
}
|
||||
|
||||
// Bind all user-specified attributes to our pre-defined indices
|
||||
if (m_interface)
|
||||
{
|
||||
if (!m_interface->positionAttribute.empty())
|
||||
glCheck(GLEXT_glBindAttribLocation(shaderProgram, PositionIndex, m_interface->positionAttribute.c_str()));
|
||||
|
||||
if (!m_interface->colorAttribute.empty())
|
||||
glCheck(GLEXT_glBindAttribLocation(shaderProgram, ColorIndex, m_interface->colorAttribute.c_str()));
|
||||
|
||||
if (!m_interface->texCoordAttribute.empty())
|
||||
glCheck(GLEXT_glBindAttribLocation(shaderProgram, TextureCoordinateIndex, m_interface->texCoordAttribute.c_str()));
|
||||
}
|
||||
|
||||
// Link the program
|
||||
glCheck(GLEXT_glLinkProgram(shaderProgram));
|
||||
|
||||
@ -960,6 +1082,53 @@ bool Shader::compile(const char* vertexShaderCode, const char* geometryShaderCod
|
||||
|
||||
m_shaderProgram = castFromGlHandle(shaderProgram);
|
||||
|
||||
if (m_interface)
|
||||
{
|
||||
// Check if attribute binding resulted in the attributes having the indices we expect
|
||||
if (!m_interface->positionAttribute.empty())
|
||||
{
|
||||
int location = -1;
|
||||
|
||||
glCheck(location = GLEXT_glGetAttribLocation(shaderProgram, m_interface->positionAttribute.c_str()));
|
||||
|
||||
if (location != PositionIndex)
|
||||
err() << "Failed to bind vertex position attribute to index 0" << std::endl;
|
||||
}
|
||||
|
||||
if (!m_interface->colorAttribute.empty())
|
||||
{
|
||||
int location = -1;
|
||||
|
||||
glCheck(location = GLEXT_glGetAttribLocation(shaderProgram, m_interface->colorAttribute.c_str()));
|
||||
|
||||
if (location != ColorIndex)
|
||||
err() << "Failed to bind vertex color attribute to index 1" << std::endl;
|
||||
}
|
||||
|
||||
if (!m_interface->texCoordAttribute.empty())
|
||||
{
|
||||
int location = -1;
|
||||
|
||||
glCheck(location = GLEXT_glGetAttribLocation(shaderProgram, m_interface->texCoordAttribute.c_str()));
|
||||
|
||||
if (location != TextureCoordinateIndex)
|
||||
err() << "Failed to bind vertex texture coordinate attribute to index 2" << std::endl;
|
||||
}
|
||||
|
||||
// Populate the drawable interface uniform indices
|
||||
if (!m_interface->modelViewMatrix.empty())
|
||||
m_modelViewMatrixIndex = getUniformLocation(m_interface->modelViewMatrix);
|
||||
|
||||
if (!m_interface->projectionMatrix.empty())
|
||||
m_projectionMatrixIndex = getUniformLocation(m_interface->projectionMatrix);
|
||||
|
||||
if (!m_interface->modelViewProjectionMatrix.empty())
|
||||
m_modelViewProjectionMatrixIndex = getUniformLocation(m_interface->modelViewProjectionMatrix);
|
||||
|
||||
if (!m_interface->textureMatrix.empty())
|
||||
m_textureMatrixIndex = getUniformLocation(m_interface->textureMatrix);
|
||||
}
|
||||
|
||||
// Force an OpenGL flush, so that the shader will appear updated
|
||||
// in all contexts immediately (solves problems in multi-threaded apps)
|
||||
glCheck(glFlush());
|
||||
|
Loading…
Reference in New Issue
Block a user