mirror of
https://github.com/SFML/SFML.git
synced 2024-12-01 15:51:04 +08:00
Added support for geometry shaders
This commit is contained in:
parent
1217699fe0
commit
1763861b26
@ -46,7 +46,7 @@ class Texture;
|
|||||||
class Transform;
|
class Transform;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Shader class (vertex and fragment)
|
/// \brief Shader class (vertex, geometry and fragment)
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
class SFML_GRAPHICS_API Shader : GlResource, NonCopyable
|
class SFML_GRAPHICS_API Shader : GlResource, NonCopyable
|
||||||
@ -60,6 +60,7 @@ public:
|
|||||||
enum Type
|
enum Type
|
||||||
{
|
{
|
||||||
Vertex, ///< %Vertex shader
|
Vertex, ///< %Vertex shader
|
||||||
|
Geometry, ///< Geometry shader
|
||||||
Fragment ///< Fragment (pixel) shader
|
Fragment ///< Fragment (pixel) shader
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -97,9 +98,9 @@ public:
|
|||||||
~Shader();
|
~Shader();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Load either the vertex or fragment shader from a file
|
/// \brief Load the vertex, geometry or fragment shader from a file
|
||||||
///
|
///
|
||||||
/// This function loads a single shader, either vertex or
|
/// This function loads a single shader, vertex, geometry or
|
||||||
/// fragment, identified by the second argument.
|
/// fragment, identified by the second argument.
|
||||||
/// The source must be a text file containing a valid
|
/// The source must be a text file containing a valid
|
||||||
/// shader in GLSL language. GLSL is a C-like language
|
/// shader in GLSL language. GLSL is a C-like language
|
||||||
@ -107,8 +108,8 @@ public:
|
|||||||
/// read a good documentation for it before writing your
|
/// read a good documentation for it before writing your
|
||||||
/// own shaders.
|
/// own shaders.
|
||||||
///
|
///
|
||||||
/// \param filename Path of the vertex or fragment shader file to load
|
/// \param filename Path of the vertex, geometry or fragment shader file to load
|
||||||
/// \param type Type of shader (vertex or fragment)
|
/// \param type Type of shader (vertex, geometry or fragment)
|
||||||
///
|
///
|
||||||
/// \return True if loading succeeded, false if it failed
|
/// \return True if loading succeeded, false if it failed
|
||||||
///
|
///
|
||||||
@ -139,17 +140,39 @@ public:
|
|||||||
bool loadFromFile(const std::string& vertexShaderFilename, const std::string& fragmentShaderFilename);
|
bool loadFromFile(const std::string& vertexShaderFilename, const std::string& fragmentShaderFilename);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Load either the vertex or fragment shader from a source code in memory
|
/// \brief Load the vertex, geometry and fragment shaders from files
|
||||||
///
|
///
|
||||||
/// This function loads a single shader, either vertex or
|
/// This function loads the vertex, geometry and fragment
|
||||||
/// fragment, identified by the second argument.
|
/// shaders. If one of them fails to load, the shader is left
|
||||||
|
/// empty (the valid shader is unloaded).
|
||||||
|
/// The sources must be text files containing valid shaders
|
||||||
|
/// in GLSL language. GLSL is a C-like language dedicated to
|
||||||
|
/// OpenGL shaders; you'll probably need to read a good documentation
|
||||||
|
/// for it before writing your own shaders.
|
||||||
|
///
|
||||||
|
/// \param vertexShaderFilename Path of the vertex shader file to load
|
||||||
|
/// \param geometryShaderFilename Path of the geometry shader file to load
|
||||||
|
/// \param fragmentShaderFilename Path of the fragment shader file to load
|
||||||
|
///
|
||||||
|
/// \return True if loading succeeded, false if it failed
|
||||||
|
///
|
||||||
|
/// \see loadFromMemory, loadFromStream
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
bool loadFromFile(const std::string& vertexShaderFilename, const std::string& geometryShaderFilename, const std::string& fragmentShaderFilename);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Load the vertex, geometry or fragment shader from a source code in memory
|
||||||
|
///
|
||||||
|
/// This function loads a single shader, vertex, geometry
|
||||||
|
/// or fragment, identified by the second argument.
|
||||||
/// The source code must be a valid shader in GLSL language.
|
/// The source code must be a valid shader in GLSL language.
|
||||||
/// GLSL is a C-like language dedicated to OpenGL shaders;
|
/// GLSL is a C-like language dedicated to OpenGL shaders;
|
||||||
/// you'll probably need to read a good documentation for
|
/// you'll probably need to read a good documentation for
|
||||||
/// it before writing your own shaders.
|
/// it before writing your own shaders.
|
||||||
///
|
///
|
||||||
/// \param shader String containing the source code of the shader
|
/// \param shader String containing the source code of the shader
|
||||||
/// \param type Type of shader (vertex or fragment)
|
/// \param type Type of shader (vertex, geometry or fragment)
|
||||||
///
|
///
|
||||||
/// \return True if loading succeeded, false if it failed
|
/// \return True if loading succeeded, false if it failed
|
||||||
///
|
///
|
||||||
@ -180,17 +203,39 @@ public:
|
|||||||
bool loadFromMemory(const std::string& vertexShader, const std::string& fragmentShader);
|
bool loadFromMemory(const std::string& vertexShader, const std::string& fragmentShader);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Load either the vertex or fragment shader from a custom stream
|
/// \brief Load the vertex, geometry and fragment shaders from source codes in memory
|
||||||
///
|
///
|
||||||
/// This function loads a single shader, either vertex or
|
/// This function loads the vertex, geometry and fragment
|
||||||
/// fragment, identified by the second argument.
|
/// shaders. If one of them fails to load, the shader is left
|
||||||
|
/// empty (the valid shader is unloaded).
|
||||||
|
/// The sources must be valid shaders in GLSL language. GLSL is
|
||||||
|
/// a C-like language dedicated to OpenGL shaders; you'll
|
||||||
|
/// probably need to read a good documentation for it before
|
||||||
|
/// writing your own shaders.
|
||||||
|
///
|
||||||
|
/// \param vertexShader String containing the source code of the vertex shader
|
||||||
|
/// \param geometryShader String containing the source code of the geometry shader
|
||||||
|
/// \param fragmentShader String containing the source code of the fragment shader
|
||||||
|
///
|
||||||
|
/// \return True if loading succeeded, false if it failed
|
||||||
|
///
|
||||||
|
/// \see loadFromFile, loadFromStream
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
bool loadFromMemory(const std::string& vertexShader, const std::string& geometryShader, const std::string& fragmentShader);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Load the vertex, geometry or fragment shader from a custom stream
|
||||||
|
///
|
||||||
|
/// This function loads a single shader, vertex, geometry
|
||||||
|
/// or fragment, identified by the second argument.
|
||||||
/// The source code must be a valid shader in GLSL language.
|
/// The source code must be a valid shader in GLSL language.
|
||||||
/// GLSL is a C-like language dedicated to OpenGL shaders;
|
/// GLSL is a C-like language dedicated to OpenGL shaders;
|
||||||
/// you'll probably need to read a good documentation for it
|
/// you'll probably need to read a good documentation for it
|
||||||
/// before writing your own shaders.
|
/// before writing your own shaders.
|
||||||
///
|
///
|
||||||
/// \param stream Source stream to read from
|
/// \param stream Source stream to read from
|
||||||
/// \param type Type of shader (vertex or fragment)
|
/// \param type Type of shader (vertex, geometry or fragment)
|
||||||
///
|
///
|
||||||
/// \return True if loading succeeded, false if it failed
|
/// \return True if loading succeeded, false if it failed
|
||||||
///
|
///
|
||||||
@ -220,6 +265,28 @@ public:
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
bool loadFromStream(InputStream& vertexShaderStream, InputStream& fragmentShaderStream);
|
bool loadFromStream(InputStream& vertexShaderStream, InputStream& fragmentShaderStream);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Load the vertex, geometry and fragment shaders from custom streams
|
||||||
|
///
|
||||||
|
/// This function loads the vertex, geometry and fragment
|
||||||
|
/// shaders. If one of them fails to load, the shader is left
|
||||||
|
/// empty (the valid shader is unloaded).
|
||||||
|
/// The source codes must be valid shaders in GLSL language.
|
||||||
|
/// GLSL is a C-like language dedicated to OpenGL shaders;
|
||||||
|
/// you'll probably need to read a good documentation for
|
||||||
|
/// it before writing your own shaders.
|
||||||
|
///
|
||||||
|
/// \param vertexShaderStream Source stream to read the vertex shader from
|
||||||
|
/// \param geometryShaderStream Source stream to read the geometry shader from
|
||||||
|
/// \param fragmentShaderStream Source stream to read the fragment shader from
|
||||||
|
///
|
||||||
|
/// \return True if loading succeeded, false if it failed
|
||||||
|
///
|
||||||
|
/// \see loadFromFile, loadFromMemory
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
bool loadFromStream(InputStream& vertexShaderStream, InputStream& geometryShaderStream, InputStream& fragmentShaderStream);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Specify value for \p float uniform
|
/// \brief Specify value for \p float uniform
|
||||||
///
|
///
|
||||||
@ -605,6 +672,25 @@ public:
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
static bool isAvailable();
|
static bool isAvailable();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Tell whether or not the system supports geometry shaders
|
||||||
|
///
|
||||||
|
/// This function should always be called before using
|
||||||
|
/// the geometry shader features. If it returns false, then
|
||||||
|
/// any attempt to use sf::Shader geometry shader features will fail.
|
||||||
|
///
|
||||||
|
/// This function can only return true if isAvailable() would also
|
||||||
|
/// return true, since shaders in general have to be supported in
|
||||||
|
/// order for geometry shaders to be supported as well.
|
||||||
|
///
|
||||||
|
/// Note: The first call to this function, whether by your
|
||||||
|
/// code or SFML will result in a context switch.
|
||||||
|
///
|
||||||
|
/// \return True if geometry shaders are supported, false otherwise
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
static bool isGeometryAvailable();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@ -614,12 +700,13 @@ private:
|
|||||||
/// is not created.
|
/// is not created.
|
||||||
///
|
///
|
||||||
/// \param vertexShaderCode Source code of the vertex shader
|
/// \param vertexShaderCode Source code of the vertex shader
|
||||||
|
/// \param geometryShaderCode Source code of the geometry shader
|
||||||
/// \param fragmentShaderCode Source code of the fragment shader
|
/// \param fragmentShaderCode Source code of the fragment shader
|
||||||
///
|
///
|
||||||
/// \return True on success, false if any error happened
|
/// \return True on success, false if any error happened
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
bool compile(const char* vertexShaderCode, const char* fragmentShaderCode);
|
bool compile(const char* vertexShaderCode, const char* geometryShaderCode, const char* fragmentShaderCode);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Bind all the textures used by the shader
|
/// \brief Bind all the textures used by the shader
|
||||||
@ -678,13 +765,15 @@ private:
|
|||||||
/// executed directly by the graphics card and allowing
|
/// executed directly by the graphics card and allowing
|
||||||
/// to apply real-time operations to the rendered entities.
|
/// to apply real-time operations to the rendered entities.
|
||||||
///
|
///
|
||||||
/// There are two kinds of shaders:
|
/// There are three kinds of shaders:
|
||||||
/// \li %Vertex shaders, that process vertices
|
/// \li %Vertex shaders, that process vertices
|
||||||
|
/// \li Geometry shaders, that process primitives
|
||||||
/// \li Fragment (pixel) shaders, that process pixels
|
/// \li Fragment (pixel) shaders, that process pixels
|
||||||
///
|
///
|
||||||
/// A sf::Shader can be composed of either a vertex shader
|
/// A sf::Shader can be composed of either a vertex shader
|
||||||
/// alone, a fragment shader alone, or both combined
|
/// alone, a geometry shader alone, a fragment shader alone,
|
||||||
/// (see the variants of the load functions).
|
/// or any combination of them. (see the variants of the
|
||||||
|
/// load functions).
|
||||||
///
|
///
|
||||||
/// Shaders are written in GLSL, which is a C-like
|
/// Shaders are written in GLSL, which is a C-like
|
||||||
/// language dedicated to OpenGL shaders. You'll probably
|
/// language dedicated to OpenGL shaders. You'll probably
|
||||||
|
@ -228,6 +228,10 @@
|
|||||||
#define GLEXT_GL_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING_EXT
|
#define GLEXT_GL_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING_EXT
|
||||||
#define GLEXT_GL_INVALID_FRAMEBUFFER_OPERATION GL_INVALID_FRAMEBUFFER_OPERATION_EXT
|
#define GLEXT_GL_INVALID_FRAMEBUFFER_OPERATION GL_INVALID_FRAMEBUFFER_OPERATION_EXT
|
||||||
|
|
||||||
|
// Core since 3.2 - ARB_geometry_shader4
|
||||||
|
#define GLEXT_geometry_shader4 sfogl_ext_ARB_geometry_shader4
|
||||||
|
#define GLEXT_GL_GEOMETRY_SHADER GL_GEOMETRY_SHADER_ARB
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace sf
|
namespace sf
|
||||||
|
@ -14,3 +14,4 @@ ARB_fragment_shader
|
|||||||
ARB_texture_non_power_of_two
|
ARB_texture_non_power_of_two
|
||||||
EXT_blend_equation_separate
|
EXT_blend_equation_separate
|
||||||
EXT_framebuffer_object
|
EXT_framebuffer_object
|
||||||
|
ARB_geometry_shader4
|
||||||
|
@ -46,6 +46,7 @@ int sfogl_ext_ARB_fragment_shader = sfogl_LOAD_FAILED;
|
|||||||
int sfogl_ext_ARB_texture_non_power_of_two = sfogl_LOAD_FAILED;
|
int sfogl_ext_ARB_texture_non_power_of_two = sfogl_LOAD_FAILED;
|
||||||
int sfogl_ext_EXT_blend_equation_separate = sfogl_LOAD_FAILED;
|
int sfogl_ext_EXT_blend_equation_separate = sfogl_LOAD_FAILED;
|
||||||
int sfogl_ext_EXT_framebuffer_object = sfogl_LOAD_FAILED;
|
int sfogl_ext_EXT_framebuffer_object = sfogl_LOAD_FAILED;
|
||||||
|
int sfogl_ext_ARB_geometry_shader4 = sfogl_LOAD_FAILED;
|
||||||
|
|
||||||
void (GL_FUNCPTR *sf_ptrc_glBlendEquationEXT)(GLenum) = NULL;
|
void (GL_FUNCPTR *sf_ptrc_glBlendEquationEXT)(GLenum) = NULL;
|
||||||
|
|
||||||
@ -798,6 +799,34 @@ static int Load_EXT_framebuffer_object()
|
|||||||
return numFailed;
|
return numFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void (GL_FUNCPTR *sf_ptrc_glFramebufferTextureARB)(GLenum, GLenum, GLuint, GLint) = NULL;
|
||||||
|
void (GL_FUNCPTR *sf_ptrc_glFramebufferTextureFaceARB)(GLenum, GLenum, GLuint, GLint, GLenum) = NULL;
|
||||||
|
void (GL_FUNCPTR *sf_ptrc_glFramebufferTextureLayerARB)(GLenum, GLenum, GLuint, GLint, GLint) = NULL;
|
||||||
|
void (GL_FUNCPTR *sf_ptrc_glProgramParameteriARB)(GLuint, GLenum, GLint) = NULL;
|
||||||
|
|
||||||
|
static int Load_ARB_geometry_shader4()
|
||||||
|
{
|
||||||
|
int numFailed = 0;
|
||||||
|
|
||||||
|
sf_ptrc_glFramebufferTextureARB = reinterpret_cast<void (GL_FUNCPTR *)(GLenum, GLenum, GLuint, GLint)>(glLoaderGetProcAddress("glFramebufferTextureARB"));
|
||||||
|
if (!sf_ptrc_glFramebufferTextureARB)
|
||||||
|
numFailed++;
|
||||||
|
|
||||||
|
sf_ptrc_glFramebufferTextureFaceARB = reinterpret_cast<void (GL_FUNCPTR *)(GLenum, GLenum, GLuint, GLint, GLenum)>(glLoaderGetProcAddress("glFramebufferTextureFaceARB"));
|
||||||
|
if (!sf_ptrc_glFramebufferTextureFaceARB)
|
||||||
|
numFailed++;
|
||||||
|
|
||||||
|
sf_ptrc_glFramebufferTextureLayerARB = reinterpret_cast<void (GL_FUNCPTR *)(GLenum, GLenum, GLuint, GLint, GLint)>(glLoaderGetProcAddress("glFramebufferTextureLayerARB"));
|
||||||
|
if (!sf_ptrc_glFramebufferTextureLayerARB)
|
||||||
|
numFailed++;
|
||||||
|
|
||||||
|
sf_ptrc_glProgramParameteriARB = reinterpret_cast<void (GL_FUNCPTR *)(GLuint, GLenum, GLint)>(glLoaderGetProcAddress("glProgramParameteriARB"));
|
||||||
|
if (!sf_ptrc_glProgramParameteriARB)
|
||||||
|
numFailed++;
|
||||||
|
|
||||||
|
return numFailed;
|
||||||
|
}
|
||||||
|
|
||||||
typedef int (*PFN_LOADFUNCPOINTERS)();
|
typedef int (*PFN_LOADFUNCPOINTERS)();
|
||||||
typedef struct sfogl_StrToExtMap_s
|
typedef struct sfogl_StrToExtMap_s
|
||||||
{
|
{
|
||||||
@ -806,7 +835,7 @@ typedef struct sfogl_StrToExtMap_s
|
|||||||
PFN_LOADFUNCPOINTERS LoadExtension;
|
PFN_LOADFUNCPOINTERS LoadExtension;
|
||||||
} sfogl_StrToExtMap;
|
} sfogl_StrToExtMap;
|
||||||
|
|
||||||
static sfogl_StrToExtMap ExtensionMap[13] = {
|
static sfogl_StrToExtMap ExtensionMap[14] = {
|
||||||
{"GL_SGIS_texture_edge_clamp", &sfogl_ext_SGIS_texture_edge_clamp, NULL},
|
{"GL_SGIS_texture_edge_clamp", &sfogl_ext_SGIS_texture_edge_clamp, NULL},
|
||||||
{"GL_EXT_texture_edge_clamp", &sfogl_ext_EXT_texture_edge_clamp, NULL},
|
{"GL_EXT_texture_edge_clamp", &sfogl_ext_EXT_texture_edge_clamp, NULL},
|
||||||
{"GL_EXT_blend_minmax", &sfogl_ext_EXT_blend_minmax, Load_EXT_blend_minmax},
|
{"GL_EXT_blend_minmax", &sfogl_ext_EXT_blend_minmax, Load_EXT_blend_minmax},
|
||||||
@ -819,10 +848,11 @@ static sfogl_StrToExtMap ExtensionMap[13] = {
|
|||||||
{"GL_ARB_fragment_shader", &sfogl_ext_ARB_fragment_shader, NULL},
|
{"GL_ARB_fragment_shader", &sfogl_ext_ARB_fragment_shader, NULL},
|
||||||
{"GL_ARB_texture_non_power_of_two", &sfogl_ext_ARB_texture_non_power_of_two, NULL},
|
{"GL_ARB_texture_non_power_of_two", &sfogl_ext_ARB_texture_non_power_of_two, NULL},
|
||||||
{"GL_EXT_blend_equation_separate", &sfogl_ext_EXT_blend_equation_separate, Load_EXT_blend_equation_separate},
|
{"GL_EXT_blend_equation_separate", &sfogl_ext_EXT_blend_equation_separate, Load_EXT_blend_equation_separate},
|
||||||
{"GL_EXT_framebuffer_object", &sfogl_ext_EXT_framebuffer_object, Load_EXT_framebuffer_object}
|
{"GL_EXT_framebuffer_object", &sfogl_ext_EXT_framebuffer_object, Load_EXT_framebuffer_object},
|
||||||
|
{"GL_ARB_geometry_shader4", &sfogl_ext_ARB_geometry_shader4, Load_ARB_geometry_shader4}
|
||||||
};
|
};
|
||||||
|
|
||||||
static int g_extensionMapSize = 13;
|
static int g_extensionMapSize = 14;
|
||||||
|
|
||||||
|
|
||||||
static void ClearExtensionVars()
|
static void ClearExtensionVars()
|
||||||
@ -840,6 +870,7 @@ static void ClearExtensionVars()
|
|||||||
sfogl_ext_ARB_texture_non_power_of_two = sfogl_LOAD_FAILED;
|
sfogl_ext_ARB_texture_non_power_of_two = sfogl_LOAD_FAILED;
|
||||||
sfogl_ext_EXT_blend_equation_separate = sfogl_LOAD_FAILED;
|
sfogl_ext_EXT_blend_equation_separate = sfogl_LOAD_FAILED;
|
||||||
sfogl_ext_EXT_framebuffer_object = sfogl_LOAD_FAILED;
|
sfogl_ext_EXT_framebuffer_object = sfogl_LOAD_FAILED;
|
||||||
|
sfogl_ext_ARB_geometry_shader4 = sfogl_LOAD_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -183,6 +183,7 @@ extern int sfogl_ext_ARB_fragment_shader;
|
|||||||
extern int sfogl_ext_ARB_texture_non_power_of_two;
|
extern int sfogl_ext_ARB_texture_non_power_of_two;
|
||||||
extern int sfogl_ext_EXT_blend_equation_separate;
|
extern int sfogl_ext_EXT_blend_equation_separate;
|
||||||
extern int sfogl_ext_EXT_framebuffer_object;
|
extern int sfogl_ext_EXT_framebuffer_object;
|
||||||
|
extern int sfogl_ext_ARB_geometry_shader4;
|
||||||
|
|
||||||
#define GL_CLAMP_TO_EDGE_SGIS 0x812F
|
#define GL_CLAMP_TO_EDGE_SGIS 0x812F
|
||||||
|
|
||||||
@ -360,6 +361,27 @@ extern int sfogl_ext_EXT_framebuffer_object;
|
|||||||
#define GL_STENCIL_INDEX4_EXT 0x8D47
|
#define GL_STENCIL_INDEX4_EXT 0x8D47
|
||||||
#define GL_STENCIL_INDEX8_EXT 0x8D48
|
#define GL_STENCIL_INDEX8_EXT 0x8D48
|
||||||
|
|
||||||
|
#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7
|
||||||
|
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4
|
||||||
|
#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9
|
||||||
|
#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8
|
||||||
|
#define GL_GEOMETRY_INPUT_TYPE_ARB 0x8DDB
|
||||||
|
#define GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8DDC
|
||||||
|
#define GL_GEOMETRY_SHADER_ARB 0x8DD9
|
||||||
|
#define GL_GEOMETRY_VERTICES_OUT_ARB 0x8DDA
|
||||||
|
#define GL_LINES_ADJACENCY_ARB 0x000A
|
||||||
|
#define GL_LINE_STRIP_ADJACENCY_ARB 0x000B
|
||||||
|
#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0
|
||||||
|
#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29
|
||||||
|
#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1
|
||||||
|
#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF
|
||||||
|
#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD
|
||||||
|
#define GL_MAX_VARYING_COMPONENTS 0x8B4B
|
||||||
|
#define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE
|
||||||
|
#define GL_PROGRAM_POINT_SIZE_ARB 0x8642
|
||||||
|
#define GL_TRIANGLES_ADJACENCY_ARB 0x000C
|
||||||
|
#define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0x000D
|
||||||
|
|
||||||
#define GL_2D 0x0600
|
#define GL_2D 0x0600
|
||||||
#define GL_2_BYTES 0x1407
|
#define GL_2_BYTES 0x1407
|
||||||
#define GL_3D 0x0601
|
#define GL_3D 0x0601
|
||||||
@ -1201,6 +1223,18 @@ extern void (GL_FUNCPTR *sf_ptrc_glRenderbufferStorageEXT)(GLenum, GLenum, GLsiz
|
|||||||
#define glRenderbufferStorageEXT sf_ptrc_glRenderbufferStorageEXT
|
#define glRenderbufferStorageEXT sf_ptrc_glRenderbufferStorageEXT
|
||||||
#endif // GL_EXT_framebuffer_object
|
#endif // GL_EXT_framebuffer_object
|
||||||
|
|
||||||
|
#ifndef GL_ARB_geometry_shader4
|
||||||
|
#define GL_ARB_geometry_shader4 1
|
||||||
|
extern void (GL_FUNCPTR *sf_ptrc_glFramebufferTextureARB)(GLenum, GLenum, GLuint, GLint);
|
||||||
|
#define glFramebufferTextureARB sf_ptrc_glFramebufferTextureARB
|
||||||
|
extern void (GL_FUNCPTR *sf_ptrc_glFramebufferTextureFaceARB)(GLenum, GLenum, GLuint, GLint, GLenum);
|
||||||
|
#define glFramebufferTextureFaceARB sf_ptrc_glFramebufferTextureFaceARB
|
||||||
|
extern void (GL_FUNCPTR *sf_ptrc_glFramebufferTextureLayerARB)(GLenum, GLenum, GLuint, GLint, GLint);
|
||||||
|
#define glFramebufferTextureLayerARB sf_ptrc_glFramebufferTextureLayerARB
|
||||||
|
extern void (GL_FUNCPTR *sf_ptrc_glProgramParameteriARB)(GLuint, GLenum, GLint);
|
||||||
|
#define glProgramParameteriARB sf_ptrc_glProgramParameteriARB
|
||||||
|
#endif // GL_ARB_geometry_shader4
|
||||||
|
|
||||||
GLAPI void APIENTRY glAccum(GLenum, GLfloat);
|
GLAPI void APIENTRY glAccum(GLenum, GLfloat);
|
||||||
GLAPI void APIENTRY glAlphaFunc(GLenum, GLfloat);
|
GLAPI void APIENTRY glAlphaFunc(GLenum, GLfloat);
|
||||||
GLAPI void APIENTRY glBegin(GLenum);
|
GLAPI void APIENTRY glBegin(GLenum);
|
||||||
|
@ -148,6 +148,20 @@ namespace
|
|||||||
|
|
||||||
return available;
|
return available;
|
||||||
}
|
}
|
||||||
|
bool checkGeometryShadersAvailable()
|
||||||
|
{
|
||||||
|
// Create a temporary context in case the user checks
|
||||||
|
// before a GlResource is created, thus initializing
|
||||||
|
// the shared context
|
||||||
|
sf::Context context;
|
||||||
|
|
||||||
|
// Make sure that extensions are initialized
|
||||||
|
sf::priv::ensureExtensionsInit();
|
||||||
|
|
||||||
|
bool available = checkShadersAvailable() && GLEXT_geometry_shader4;
|
||||||
|
|
||||||
|
return available;
|
||||||
|
}
|
||||||
|
|
||||||
// Transforms an array of 2D vectors into a contiguous array of scalars
|
// Transforms an array of 2D vectors into a contiguous array of scalars
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -285,9 +299,11 @@ bool Shader::loadFromFile(const std::string& filename, Type type)
|
|||||||
|
|
||||||
// Compile the shader program
|
// Compile the shader program
|
||||||
if (type == Vertex)
|
if (type == Vertex)
|
||||||
return compile(&shader[0], NULL);
|
return compile(&shader[0], NULL, NULL);
|
||||||
|
else if (type == Geometry)
|
||||||
|
return compile(NULL, &shader[0], NULL);
|
||||||
else
|
else
|
||||||
return compile(NULL, &shader[0]);
|
return compile(NULL, NULL, &shader[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -311,7 +327,39 @@ bool Shader::loadFromFile(const std::string& vertexShaderFilename, const std::st
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Compile the shader program
|
// Compile the shader program
|
||||||
return compile(&vertexShader[0], &fragmentShader[0]);
|
return compile(&vertexShader[0], NULL, &fragmentShader[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
bool Shader::loadFromFile(const std::string& vertexShaderFilename, const std::string& geometryShaderFilename, const std::string& fragmentShaderFilename)
|
||||||
|
{
|
||||||
|
// Read the vertex shader file
|
||||||
|
std::vector<char> vertexShader;
|
||||||
|
if (!getFileContents(vertexShaderFilename, vertexShader))
|
||||||
|
{
|
||||||
|
err() << "Failed to open vertex shader file \"" << vertexShaderFilename << "\"" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the geometry shader file
|
||||||
|
std::vector<char> geometryShader;
|
||||||
|
if (!getFileContents(geometryShaderFilename, geometryShader))
|
||||||
|
{
|
||||||
|
err() << "Failed to open geometry shader file \"" << geometryShaderFilename << "\"" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the fragment shader file
|
||||||
|
std::vector<char> fragmentShader;
|
||||||
|
if (!getFileContents(fragmentShaderFilename, fragmentShader))
|
||||||
|
{
|
||||||
|
err() << "Failed to open fragment shader file \"" << fragmentShaderFilename << "\"" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compile the shader program
|
||||||
|
return compile(&vertexShader[0], &geometryShader[0], &fragmentShader[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -320,9 +368,11 @@ bool Shader::loadFromMemory(const std::string& shader, Type type)
|
|||||||
{
|
{
|
||||||
// Compile the shader program
|
// Compile the shader program
|
||||||
if (type == Vertex)
|
if (type == Vertex)
|
||||||
return compile(shader.c_str(), NULL);
|
return compile(shader.c_str(), NULL, NULL);
|
||||||
|
else if (type == Geometry)
|
||||||
|
return compile(NULL, shader.c_str(), NULL);
|
||||||
else
|
else
|
||||||
return compile(NULL, shader.c_str());
|
return compile(NULL, NULL, shader.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -330,7 +380,15 @@ bool Shader::loadFromMemory(const std::string& shader, Type type)
|
|||||||
bool Shader::loadFromMemory(const std::string& vertexShader, const std::string& fragmentShader)
|
bool Shader::loadFromMemory(const std::string& vertexShader, const std::string& fragmentShader)
|
||||||
{
|
{
|
||||||
// Compile the shader program
|
// Compile the shader program
|
||||||
return compile(vertexShader.c_str(), fragmentShader.c_str());
|
return compile(vertexShader.c_str(), NULL, fragmentShader.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
bool Shader::loadFromMemory(const std::string& vertexShader, const std::string& geometryShader, const std::string& fragmentShader)
|
||||||
|
{
|
||||||
|
// Compile the shader program
|
||||||
|
return compile(vertexShader.c_str(), geometryShader.c_str(), fragmentShader.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -347,9 +405,11 @@ bool Shader::loadFromStream(InputStream& stream, Type type)
|
|||||||
|
|
||||||
// Compile the shader program
|
// Compile the shader program
|
||||||
if (type == Vertex)
|
if (type == Vertex)
|
||||||
return compile(&shader[0], NULL);
|
return compile(&shader[0], NULL, NULL);
|
||||||
|
else if (type == Geometry)
|
||||||
|
return compile(NULL, &shader[0], NULL);
|
||||||
else
|
else
|
||||||
return compile(NULL, &shader[0]);
|
return compile(NULL, NULL, &shader[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -373,7 +433,39 @@ bool Shader::loadFromStream(InputStream& vertexShaderStream, InputStream& fragme
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Compile the shader program
|
// Compile the shader program
|
||||||
return compile(&vertexShader[0], &fragmentShader[0]);
|
return compile(&vertexShader[0], NULL, &fragmentShader[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
bool Shader::loadFromStream(InputStream& vertexShaderStream, InputStream& geometryShaderStream, InputStream& fragmentShaderStream)
|
||||||
|
{
|
||||||
|
// Read the vertex shader code from the stream
|
||||||
|
std::vector<char> vertexShader;
|
||||||
|
if (!getStreamContents(vertexShaderStream, vertexShader))
|
||||||
|
{
|
||||||
|
err() << "Failed to read vertex shader from stream" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the geometry shader code from the stream
|
||||||
|
std::vector<char> geometryShader;
|
||||||
|
if (!getStreamContents(geometryShaderStream, geometryShader))
|
||||||
|
{
|
||||||
|
err() << "Failed to read geometry shader from stream" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the fragment shader code from the stream
|
||||||
|
std::vector<char> fragmentShader;
|
||||||
|
if (!getStreamContents(fragmentShaderStream, fragmentShader))
|
||||||
|
{
|
||||||
|
err() << "Failed to read fragment shader from stream" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compile the shader program
|
||||||
|
return compile(&vertexShader[0], &geometryShader[0], &fragmentShader[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -738,7 +830,19 @@ bool Shader::isAvailable()
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
bool Shader::compile(const char* vertexShaderCode, const char* fragmentShaderCode)
|
bool Shader::isGeometryAvailable()
|
||||||
|
{
|
||||||
|
// TODO: Remove this lock when it becomes unnecessary in C++11
|
||||||
|
Lock lock(mutex);
|
||||||
|
|
||||||
|
static bool available = checkGeometryShadersAvailable();
|
||||||
|
|
||||||
|
return available;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
bool Shader::compile(const char* vertexShaderCode, const char* geometryShaderCode, const char* fragmentShaderCode)
|
||||||
{
|
{
|
||||||
ensureGlContext();
|
ensureGlContext();
|
||||||
|
|
||||||
@ -750,6 +854,14 @@ bool Shader::compile(const char* vertexShaderCode, const char* fragmentShaderCod
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure we can use geometry shaders
|
||||||
|
if (geometryShaderCode && !isGeometryAvailable())
|
||||||
|
{
|
||||||
|
err() << "Failed to create a shader: your system doesn't support geometry shaders "
|
||||||
|
<< "(you should test Shader::isGeometryAvailable() before trying to use geometry shaders)" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Destroy the shader if it was already created
|
// Destroy the shader if it was already created
|
||||||
if (m_shaderProgram)
|
if (m_shaderProgram)
|
||||||
{
|
{
|
||||||
@ -794,6 +906,33 @@ bool Shader::compile(const char* vertexShaderCode, const char* fragmentShaderCod
|
|||||||
glCheck(GLEXT_glDeleteObject(vertexShader));
|
glCheck(GLEXT_glDeleteObject(vertexShader));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create the geometry shader if needed
|
||||||
|
if (geometryShaderCode)
|
||||||
|
{
|
||||||
|
// Create and compile the shader
|
||||||
|
GLEXT_GLhandle geometryShader = GLEXT_glCreateShaderObject(GLEXT_GL_GEOMETRY_SHADER);
|
||||||
|
glCheck(GLEXT_glShaderSource(geometryShader, 1, &geometryShaderCode, NULL));
|
||||||
|
glCheck(GLEXT_glCompileShader(geometryShader));
|
||||||
|
|
||||||
|
// Check the compile log
|
||||||
|
GLint success;
|
||||||
|
glCheck(GLEXT_glGetObjectParameteriv(geometryShader, GLEXT_GL_OBJECT_COMPILE_STATUS, &success));
|
||||||
|
if (success == GL_FALSE)
|
||||||
|
{
|
||||||
|
char log[1024];
|
||||||
|
glCheck(GLEXT_glGetInfoLog(geometryShader, sizeof(log), 0, log));
|
||||||
|
err() << "Failed to compile geometry shader:" << std::endl
|
||||||
|
<< log << std::endl;
|
||||||
|
glCheck(GLEXT_glDeleteObject(geometryShader));
|
||||||
|
glCheck(GLEXT_glDeleteObject(shaderProgram));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attach the shader to the program, and delete it (not needed anymore)
|
||||||
|
glCheck(GLEXT_glAttachObject(shaderProgram, geometryShader));
|
||||||
|
glCheck(GLEXT_glDeleteObject(geometryShader));
|
||||||
|
}
|
||||||
|
|
||||||
// Create the fragment shader if needed
|
// Create the fragment shader if needed
|
||||||
if (fragmentShaderCode)
|
if (fragmentShaderCode)
|
||||||
{
|
{
|
||||||
@ -929,6 +1068,13 @@ bool Shader::loadFromFile(const std::string& vertexShaderFilename, const std::st
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
bool Shader::loadFromFile(const std::string& vertexShaderFilename, const std::string& geometryShaderFilename, const std::string& fragmentShaderFilename)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
bool Shader::loadFromMemory(const std::string& shader, Type type)
|
bool Shader::loadFromMemory(const std::string& shader, Type type)
|
||||||
{
|
{
|
||||||
@ -943,6 +1089,13 @@ bool Shader::loadFromMemory(const std::string& vertexShader, const std::string&
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
bool Shader::loadFromMemory(const std::string& vertexShader, const std::string& geometryShader, const std::string& fragmentShader)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
bool Shader::loadFromStream(InputStream& stream, Type type)
|
bool Shader::loadFromStream(InputStream& stream, Type type)
|
||||||
{
|
{
|
||||||
@ -957,6 +1110,13 @@ bool Shader::loadFromStream(InputStream& vertexShaderStream, InputStream& fragme
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
bool Shader::loadFromStream(InputStream& vertexShaderStream, InputStream& geometryShaderStream, InputStream& fragmentShaderStream)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void Shader::setUniform(const std::string& name, float x)
|
void Shader::setUniform(const std::string& name, float x)
|
||||||
{
|
{
|
||||||
@ -1170,7 +1330,14 @@ bool Shader::isAvailable()
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
bool Shader::compile(const char* vertexShaderCode, const char* fragmentShaderCode)
|
bool Shader::isGeometryAvailable()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
bool Shader::compile(const char* vertexShaderCode, const char* geometryShaderCode, const char* fragmentShaderCode)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user