mirror of
https://github.com/SFML/SFML.git
synced 2024-11-28 22:31:09 +08:00
Added support for geometry shaders
This commit is contained in:
parent
1217699fe0
commit
1763861b26
@ -46,7 +46,7 @@ class Texture;
|
||||
class Transform;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Shader class (vertex and fragment)
|
||||
/// \brief Shader class (vertex, geometry and fragment)
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
class SFML_GRAPHICS_API Shader : GlResource, NonCopyable
|
||||
@ -59,8 +59,9 @@ public:
|
||||
////////////////////////////////////////////////////////////
|
||||
enum Type
|
||||
{
|
||||
Vertex, ///< %Vertex shader
|
||||
Fragment ///< Fragment (pixel) shader
|
||||
Vertex, ///< %Vertex shader
|
||||
Geometry, ///< Geometry shader
|
||||
Fragment ///< Fragment (pixel) shader
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -97,9 +98,9 @@ public:
|
||||
~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.
|
||||
/// The source must be a text file containing a valid
|
||||
/// shader in GLSL language. GLSL is a C-like language
|
||||
@ -107,8 +108,8 @@ public:
|
||||
/// read a good documentation for it before writing your
|
||||
/// own shaders.
|
||||
///
|
||||
/// \param filename Path of the vertex or fragment shader file to load
|
||||
/// \param type Type of shader (vertex or fragment)
|
||||
/// \param filename Path of the vertex, geometry or fragment shader file to load
|
||||
/// \param type Type of shader (vertex, geometry or fragment)
|
||||
///
|
||||
/// \return True if loading succeeded, false if it failed
|
||||
///
|
||||
@ -139,17 +140,39 @@ public:
|
||||
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
|
||||
/// fragment, identified by the second argument.
|
||||
/// 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 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.
|
||||
/// 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 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
|
||||
///
|
||||
@ -180,17 +203,39 @@ public:
|
||||
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
|
||||
/// fragment, identified by the second argument.
|
||||
/// 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 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.
|
||||
/// 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 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
|
||||
///
|
||||
@ -220,6 +265,28 @@ public:
|
||||
////////////////////////////////////////////////////////////
|
||||
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
|
||||
///
|
||||
@ -605,6 +672,25 @@ public:
|
||||
////////////////////////////////////////////////////////////
|
||||
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:
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -614,12 +700,13 @@ private:
|
||||
/// is not created.
|
||||
///
|
||||
/// \param vertexShaderCode Source code of the vertex shader
|
||||
/// \param geometryShaderCode Source code of the geometry shader
|
||||
/// \param fragmentShaderCode Source code of the fragment shader
|
||||
///
|
||||
/// \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
|
||||
@ -678,13 +765,15 @@ private:
|
||||
/// executed directly by the graphics card and allowing
|
||||
/// 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 Geometry shaders, that process primitives
|
||||
/// \li Fragment (pixel) shaders, that process pixels
|
||||
///
|
||||
/// A sf::Shader can be composed of either a vertex shader
|
||||
/// alone, a fragment shader alone, or both combined
|
||||
/// (see the variants of the load functions).
|
||||
/// alone, a geometry shader alone, a fragment shader alone,
|
||||
/// or any combination of them. (see the variants of the
|
||||
/// load functions).
|
||||
///
|
||||
/// Shaders are written in GLSL, which is a C-like
|
||||
/// language dedicated to OpenGL shaders. You'll probably
|
||||
|
@ -228,6 +228,10 @@
|
||||
#define GLEXT_GL_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING_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
|
||||
|
||||
namespace sf
|
||||
|
@ -14,3 +14,4 @@ ARB_fragment_shader
|
||||
ARB_texture_non_power_of_two
|
||||
EXT_blend_equation_separate
|
||||
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_EXT_blend_equation_separate = 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;
|
||||
|
||||
@ -798,6 +799,34 @@ static int Load_EXT_framebuffer_object()
|
||||
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 struct sfogl_StrToExtMap_s
|
||||
{
|
||||
@ -806,7 +835,7 @@ typedef struct sfogl_StrToExtMap_s
|
||||
PFN_LOADFUNCPOINTERS LoadExtension;
|
||||
} 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_EXT_texture_edge_clamp", &sfogl_ext_EXT_texture_edge_clamp, NULL},
|
||||
{"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_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_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()
|
||||
@ -840,6 +870,7 @@ static void ClearExtensionVars()
|
||||
sfogl_ext_ARB_texture_non_power_of_two = sfogl_LOAD_FAILED;
|
||||
sfogl_ext_EXT_blend_equation_separate = 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_EXT_blend_equation_separate;
|
||||
extern int sfogl_ext_EXT_framebuffer_object;
|
||||
extern int sfogl_ext_ARB_geometry_shader4;
|
||||
|
||||
#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_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_2_BYTES 0x1407
|
||||
#define GL_3D 0x0601
|
||||
@ -1201,6 +1223,18 @@ extern void (GL_FUNCPTR *sf_ptrc_glRenderbufferStorageEXT)(GLenum, GLenum, GLsiz
|
||||
#define glRenderbufferStorageEXT sf_ptrc_glRenderbufferStorageEXT
|
||||
#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 glAlphaFunc(GLenum, GLfloat);
|
||||
GLAPI void APIENTRY glBegin(GLenum);
|
||||
|
@ -148,6 +148,20 @@ namespace
|
||||
|
||||
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
|
||||
template <typename T>
|
||||
@ -285,9 +299,11 @@ bool Shader::loadFromFile(const std::string& filename, Type type)
|
||||
|
||||
// Compile the shader program
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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)
|
||||
{
|
||||
// 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
|
||||
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
|
||||
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
|
||||
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();
|
||||
|
||||
@ -750,6 +854,14 @@ bool Shader::compile(const char* vertexShaderCode, const char* fragmentShaderCod
|
||||
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
|
||||
if (m_shaderProgram)
|
||||
{
|
||||
@ -794,6 +906,33 @@ bool Shader::compile(const char* vertexShaderCode, const char* fragmentShaderCod
|
||||
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
|
||||
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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user