mirror of
https://github.com/SFML/SFML.git
synced 2024-11-25 04:41:05 +08:00
Change glCheck macro to be usable as an expression
This commit is contained in:
parent
c8cf84511d
commit
0d33ddeccf
@ -31,31 +31,10 @@
|
|||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
namespace sf::priv
|
namespace sf::priv
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// Let's define a macro to quickly check every OpenGL API call
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
#ifdef SFML_DEBUG
|
|
||||||
|
|
||||||
// In debug mode, perform a test on every OpenGL call
|
|
||||||
// The do-while loop is needed so that glCheck can be used as a single statement in if/else branches
|
|
||||||
#define glCheck(expr) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
expr; \
|
|
||||||
sf::priv::glCheckError(__FILE__, __LINE__, #expr); \
|
|
||||||
} while (false)
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
// Else, we don't add any overhead
|
|
||||||
#define glCheck(expr) (expr)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Check the last OpenGL error
|
/// \brief Check the last OpenGL error
|
||||||
///
|
///
|
||||||
@ -68,4 +47,32 @@ namespace sf::priv
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
bool glCheckError(const std::filesystem::path& file, unsigned int line, std::string_view expression);
|
bool glCheckError(const std::filesystem::path& file, unsigned int line, std::string_view expression);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Let's define a macro to quickly check every OpenGL API call
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
#ifdef SFML_DEBUG
|
||||||
|
// In debug mode, perform a test on every OpenGL call
|
||||||
|
// The lamdba allows us to call glCheck as an expression and acts as a single statement perfect for if/else statements
|
||||||
|
#define glCheck(...) \
|
||||||
|
[](auto&& glCheckInternalFunction) \
|
||||||
|
{ \
|
||||||
|
if constexpr (!std::is_void_v<decltype(glCheckInternalFunction())>) \
|
||||||
|
{ \
|
||||||
|
const auto glCheckInternalReturnValue = glCheckInternalFunction(); \
|
||||||
|
sf::priv::glCheckError(__FILE__, static_cast<unsigned int>(__LINE__), #__VA_ARGS__); \
|
||||||
|
return glCheckInternalReturnValue; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
glCheckInternalFunction(); \
|
||||||
|
sf::priv::glCheckError(__FILE__, static_cast<unsigned int>(__LINE__), #__VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
}([&]() { return __VA_ARGS__; })
|
||||||
|
#else
|
||||||
|
|
||||||
|
// Else, we don't add any overhead
|
||||||
|
#define glCheck(...) (__VA_ARGS__)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace sf::priv
|
} // namespace sf::priv
|
||||||
|
@ -430,9 +430,7 @@ bool RenderTextureImplFBO::createFrameBuffer()
|
|||||||
glCheck(GLEXT_glFramebufferTexture2D(GLEXT_GL_FRAMEBUFFER, GLEXT_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_textureId, 0));
|
glCheck(GLEXT_glFramebufferTexture2D(GLEXT_GL_FRAMEBUFFER, GLEXT_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_textureId, 0));
|
||||||
|
|
||||||
// A final check, just to be sure...
|
// A final check, just to be sure...
|
||||||
GLenum status = 0;
|
if (glCheck(GLEXT_glCheckFramebufferStatus(GLEXT_GL_FRAMEBUFFER)) != GLEXT_GL_FRAMEBUFFER_COMPLETE)
|
||||||
glCheck(status = GLEXT_glCheckFramebufferStatus(GLEXT_GL_FRAMEBUFFER));
|
|
||||||
if (status != GLEXT_GL_FRAMEBUFFER_COMPLETE)
|
|
||||||
{
|
{
|
||||||
glCheck(GLEXT_glBindFramebuffer(GLEXT_GL_FRAMEBUFFER, 0));
|
glCheck(GLEXT_glBindFramebuffer(GLEXT_GL_FRAMEBUFFER, 0));
|
||||||
err() << "Impossible to create render texture (failed to link the target texture to the frame buffer)" << std::endl;
|
err() << "Impossible to create render texture (failed to link the target texture to the frame buffer)" << std::endl;
|
||||||
@ -486,8 +484,7 @@ bool RenderTextureImplFBO::createFrameBuffer()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// A final check, just to be sure...
|
// A final check, just to be sure...
|
||||||
glCheck(status = GLEXT_glCheckFramebufferStatus(GLEXT_GL_FRAMEBUFFER));
|
if (glCheck(GLEXT_glCheckFramebufferStatus(GLEXT_GL_FRAMEBUFFER)) != GLEXT_GL_FRAMEBUFFER_COMPLETE)
|
||||||
if (status != GLEXT_GL_FRAMEBUFFER_COMPLETE)
|
|
||||||
{
|
{
|
||||||
glCheck(GLEXT_glBindFramebuffer(GLEXT_GL_FRAMEBUFFER, 0));
|
glCheck(GLEXT_glBindFramebuffer(GLEXT_GL_FRAMEBUFFER, 0));
|
||||||
err() << "Impossible to create render texture (failed to link the render buffers to the multisample frame "
|
err() << "Impossible to create render texture (failed to link the render buffers to the multisample frame "
|
||||||
|
@ -185,7 +185,7 @@ struct Shader::UniformBinder
|
|||||||
if (currentProgram)
|
if (currentProgram)
|
||||||
{
|
{
|
||||||
// Enable program object
|
// Enable program object
|
||||||
glCheck(savedProgram = GLEXT_glGetHandle(GLEXT_GL_PROGRAM_OBJECT));
|
savedProgram = glCheck(GLEXT_glGetHandle(GLEXT_GL_PROGRAM_OBJECT));
|
||||||
if (currentProgram != savedProgram)
|
if (currentProgram != savedProgram)
|
||||||
glCheck(GLEXT_glUseProgramObject(currentProgram));
|
glCheck(GLEXT_glUseProgramObject(currentProgram));
|
||||||
|
|
||||||
@ -865,15 +865,13 @@ bool Shader::compile(std::string_view vertexShaderCode, std::string_view geometr
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the program
|
// Create the program
|
||||||
GLEXT_GLhandle shaderProgram{};
|
const GLEXT_GLhandle shaderProgram = glCheck(GLEXT_glCreateProgramObject());
|
||||||
glCheck(shaderProgram = GLEXT_glCreateProgramObject());
|
|
||||||
|
|
||||||
// Create the vertex shader if needed
|
// Create the vertex shader if needed
|
||||||
if (!vertexShaderCode.empty())
|
if (!vertexShaderCode.empty())
|
||||||
{
|
{
|
||||||
// Create and compile the shader
|
// Create and compile the shader
|
||||||
GLEXT_GLhandle vertexShader{};
|
const GLEXT_GLhandle vertexShader = glCheck(GLEXT_glCreateShaderObject(GLEXT_GL_VERTEX_SHADER));
|
||||||
glCheck(vertexShader = GLEXT_glCreateShaderObject(GLEXT_GL_VERTEX_SHADER));
|
|
||||||
const GLcharARB* sourceCode = vertexShaderCode.data();
|
const GLcharARB* sourceCode = vertexShaderCode.data();
|
||||||
const auto sourceCodeLength = static_cast<GLint>(vertexShaderCode.length());
|
const auto sourceCodeLength = static_cast<GLint>(vertexShaderCode.length());
|
||||||
glCheck(GLEXT_glShaderSource(vertexShader, 1, &sourceCode, &sourceCodeLength));
|
glCheck(GLEXT_glShaderSource(vertexShader, 1, &sourceCode, &sourceCodeLength));
|
||||||
@ -929,8 +927,7 @@ bool Shader::compile(std::string_view vertexShaderCode, std::string_view geometr
|
|||||||
if (!fragmentShaderCode.empty())
|
if (!fragmentShaderCode.empty())
|
||||||
{
|
{
|
||||||
// Create and compile the shader
|
// Create and compile the shader
|
||||||
GLEXT_GLhandle fragmentShader{};
|
const GLEXT_GLhandle fragmentShader = glCheck(GLEXT_glCreateShaderObject(GLEXT_GL_FRAGMENT_SHADER));
|
||||||
glCheck(fragmentShader = GLEXT_glCreateShaderObject(GLEXT_GL_FRAGMENT_SHADER));
|
|
||||||
const GLcharARB* sourceCode = fragmentShaderCode.data();
|
const GLcharARB* sourceCode = fragmentShaderCode.data();
|
||||||
const auto sourceCodeLength = static_cast<GLint>(fragmentShaderCode.length());
|
const auto sourceCodeLength = static_cast<GLint>(fragmentShaderCode.length());
|
||||||
glCheck(GLEXT_glShaderSource(fragmentShader, 1, &sourceCode, &sourceCodeLength));
|
glCheck(GLEXT_glShaderSource(fragmentShader, 1, &sourceCode, &sourceCodeLength));
|
||||||
|
@ -648,11 +648,9 @@ void Texture::update(const Texture& texture, Vector2u dest)
|
|||||||
GLEXT_glFramebufferTexture2D(GLEXT_GL_DRAW_FRAMEBUFFER, GLEXT_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0));
|
GLEXT_glFramebufferTexture2D(GLEXT_GL_DRAW_FRAMEBUFFER, GLEXT_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0));
|
||||||
|
|
||||||
// A final check, just to be sure...
|
// A final check, just to be sure...
|
||||||
GLenum sourceStatus = 0;
|
const GLenum sourceStatus = glCheck(GLEXT_glCheckFramebufferStatus(GLEXT_GL_READ_FRAMEBUFFER));
|
||||||
glCheck(sourceStatus = GLEXT_glCheckFramebufferStatus(GLEXT_GL_READ_FRAMEBUFFER));
|
|
||||||
|
|
||||||
GLenum destStatus = 0;
|
const GLenum destStatus = glCheck(GLEXT_glCheckFramebufferStatus(GLEXT_GL_DRAW_FRAMEBUFFER));
|
||||||
glCheck(destStatus = GLEXT_glCheckFramebufferStatus(GLEXT_GL_DRAW_FRAMEBUFFER));
|
|
||||||
|
|
||||||
if ((sourceStatus == GLEXT_GL_FRAMEBUFFER_COMPLETE) && (destStatus == GLEXT_GL_FRAMEBUFFER_COMPLETE))
|
if ((sourceStatus == GLEXT_GL_FRAMEBUFFER_COMPLETE) && (destStatus == GLEXT_GL_FRAMEBUFFER_COMPLETE))
|
||||||
{
|
{
|
||||||
|
@ -236,23 +236,19 @@ bool VertexBuffer::update([[maybe_unused]] const VertexBuffer& vertexBuffer)
|
|||||||
nullptr,
|
nullptr,
|
||||||
VertexBufferImpl::usageToGlEnum(m_usage)));
|
VertexBufferImpl::usageToGlEnum(m_usage)));
|
||||||
|
|
||||||
void* destination = nullptr;
|
void* const destination = glCheck(GLEXT_glMapBuffer(GLEXT_GL_ARRAY_BUFFER, GLEXT_GL_WRITE_ONLY));
|
||||||
glCheck(destination = GLEXT_glMapBuffer(GLEXT_GL_ARRAY_BUFFER, GLEXT_GL_WRITE_ONLY));
|
|
||||||
|
|
||||||
glCheck(GLEXT_glBindBuffer(GLEXT_GL_ARRAY_BUFFER, vertexBuffer.m_buffer));
|
glCheck(GLEXT_glBindBuffer(GLEXT_GL_ARRAY_BUFFER, vertexBuffer.m_buffer));
|
||||||
|
|
||||||
void* source = nullptr;
|
const void* const source = glCheck(GLEXT_glMapBuffer(GLEXT_GL_ARRAY_BUFFER, GLEXT_GL_READ_ONLY));
|
||||||
glCheck(source = GLEXT_glMapBuffer(GLEXT_GL_ARRAY_BUFFER, GLEXT_GL_READ_ONLY));
|
|
||||||
|
|
||||||
std::memcpy(destination, source, sizeof(Vertex) * vertexBuffer.m_size);
|
std::memcpy(destination, source, sizeof(Vertex) * vertexBuffer.m_size);
|
||||||
|
|
||||||
GLboolean sourceResult = GL_FALSE;
|
const GLboolean sourceResult = glCheck(GLEXT_glUnmapBuffer(GLEXT_GL_ARRAY_BUFFER));
|
||||||
glCheck(sourceResult = GLEXT_glUnmapBuffer(GLEXT_GL_ARRAY_BUFFER));
|
|
||||||
|
|
||||||
glCheck(GLEXT_glBindBuffer(GLEXT_GL_ARRAY_BUFFER, m_buffer));
|
glCheck(GLEXT_glBindBuffer(GLEXT_GL_ARRAY_BUFFER, m_buffer));
|
||||||
|
|
||||||
GLboolean destinationResult = GL_FALSE;
|
const GLboolean destinationResult = glCheck(GLEXT_glUnmapBuffer(GLEXT_GL_ARRAY_BUFFER));
|
||||||
glCheck(destinationResult = GLEXT_glUnmapBuffer(GLEXT_GL_ARRAY_BUFFER));
|
|
||||||
|
|
||||||
glCheck(GLEXT_glBindBuffer(GLEXT_GL_ARRAY_BUFFER, 0));
|
glCheck(GLEXT_glBindBuffer(GLEXT_GL_ARRAY_BUFFER, 0));
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ bool eglCheckError(const std::filesystem::path& file, unsigned int line, std::st
|
|||||||
{
|
{
|
||||||
const auto logError = [&](const char* error, const char* description)
|
const auto logError = [&](const char* error, const char* description)
|
||||||
{
|
{
|
||||||
err() << "An internal EGL call failed in " << file.filename() << " (" << line << ") : "
|
err() << "An internal EGL call failed in " << file.filename() << "(" << line << ")."
|
||||||
<< "\nExpression:\n " << expression << "\nError description:\n " << error << "\n " << description << '\n'
|
<< "\nExpression:\n " << expression << "\nError description:\n " << error << "\n " << description << '\n'
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
|
@ -35,27 +35,6 @@
|
|||||||
|
|
||||||
namespace sf::priv
|
namespace sf::priv
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// Let's define a macro to quickly check every EGL API call
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
#ifdef SFML_DEBUG
|
|
||||||
|
|
||||||
// In debug mode, perform a test on every EGL call
|
|
||||||
// The do-while loop is needed so that glCheck can be used as a single statement in if/else branches
|
|
||||||
#define eglCheck(expr) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
expr; \
|
|
||||||
sf::priv::eglCheckError(__FILE__, __LINE__, #expr); \
|
|
||||||
} while (false)
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
// Else, we don't add any overhead
|
|
||||||
#define eglCheck(x) (x)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Check the last EGL error
|
/// \brief Check the last EGL error
|
||||||
///
|
///
|
||||||
@ -68,4 +47,35 @@ namespace sf::priv
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
bool eglCheckError(const std::filesystem::path& file, unsigned int line, std::string_view expression);
|
bool eglCheckError(const std::filesystem::path& file, unsigned int line, std::string_view expression);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Let's define a macro to quickly check every EGL API call
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
#ifdef SFML_DEBUG
|
||||||
|
|
||||||
|
// In debug mode, perform a test on every EGL call
|
||||||
|
// The lamdba allows us to call eglCheck as an expression and acts as a single statement perfect for if/else statements
|
||||||
|
#define eglCheck(...) \
|
||||||
|
[](auto&& eglCheckInternalFunction) \
|
||||||
|
{ \
|
||||||
|
if constexpr (!std::is_void_v<decltype(eglCheckInternalFunction())>) \
|
||||||
|
{ \
|
||||||
|
const auto eglCheckInternalReturnValue = eglCheckInternalFunction(); \
|
||||||
|
sf::priv::eglCheckError(__FILE__, static_cast<unsigned int>(__LINE__), #__VA_ARGS__); \
|
||||||
|
return eglCheckInternalReturnValue; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
eglCheckInternalFunction(); \
|
||||||
|
sf::priv::eglCheckError(__FILE__, static_cast<unsigned int>(__LINE__), #__VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
}([&]() { return __VA_ARGS__; })
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// Else, we don't add any overhead
|
||||||
|
#define eglCheck(...) (__VA_ARGS__)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
} // namespace sf::priv
|
} // namespace sf::priv
|
||||||
|
Loading…
Reference in New Issue
Block a user