Added conditional rendering

Former-commit-id: 30c062a469ad5f534b95a33c07c92c89036aacf7
This commit is contained in:
Lynix 2013-09-06 17:38:34 +02:00
parent e60b1c010e
commit 10f7d185a6
5 changed files with 121 additions and 15 deletions

View File

@ -51,6 +51,16 @@ enum nzFaceFilling
nzFaceFilling_Max = nzFaceFilling_Fill nzFaceFilling_Max = nzFaceFilling_Fill
}; };
enum nzGpuQueryCondition
{
nzGpuQueryCondition_Region_NoWait,
nzGpuQueryCondition_Region_Wait,
nzGpuQueryCondition_NoWait,
nzGpuQueryCondition_Wait,
nzGpuQueryCondition_Max = nzGpuQueryCondition_Wait
};
enum nzGpuQueryMode enum nzGpuQueryMode
{ {
nzGpuQueryMode_AnySamplesPassed, nzGpuQueryMode_AnySamplesPassed,
@ -97,6 +107,7 @@ enum nzPixelBufferType
enum nzRendererCap enum nzRendererCap
{ {
nzRendererCap_AnisotropicFilter, nzRendererCap_AnisotropicFilter,
nzRendererCap_ConditionalRendering,
nzRendererCap_FP64, nzRendererCap_FP64,
nzRendererCap_HardwareBuffer, nzRendererCap_HardwareBuffer,
nzRendererCap_Instancing, nzRendererCap_Instancing,

View File

@ -29,6 +29,7 @@
enum nzOpenGLExtension enum nzOpenGLExtension
{ {
nzOpenGLExtension_AnisotropicFilter, nzOpenGLExtension_AnisotropicFilter,
nzOpenGLExtension_ConditionalRender,
nzOpenGLExtension_DebugOutput, nzOpenGLExtension_DebugOutput,
nzOpenGLExtension_DrawInstanced, nzOpenGLExtension_DrawInstanced,
nzOpenGLExtension_FP64, nzOpenGLExtension_FP64,
@ -90,8 +91,8 @@ class NAZARA_API NzOpenGL
static GLuint GetCurrentBuffer(nzBufferType type); static GLuint GetCurrentBuffer(nzBufferType type);
static GLuint GetCurrentProgram(); static GLuint GetCurrentProgram();
static const NzRenderTarget* GetCurrentTarget();
static NzRecti GetCurrentScissorBox(); static NzRecti GetCurrentScissorBox();
static const NzRenderTarget* GetCurrentTarget();
static GLuint GetCurrentTexture(); static GLuint GetCurrentTexture();
static GLuint GetCurrentTexture(unsigned int textureUnit); static GLuint GetCurrentTexture(unsigned int textureUnit);
static unsigned int GetCurrentTextureUnit(); static unsigned int GetCurrentTextureUnit();
@ -110,8 +111,8 @@ class NAZARA_API NzOpenGL
static bool IsSupported(const NzString& string); static bool IsSupported(const NzString& string);
static void SetBuffer(nzBufferType type, GLuint id); static void SetBuffer(nzBufferType type, GLuint id);
static void SetScissorBox(const NzRecti& scissorBox);
static void SetProgram(GLuint id); static void SetProgram(GLuint id);
static void SetScissorBox(const NzRecti& scissorBox);
static void SetTarget(const NzRenderTarget* renderTarget); static void SetTarget(const NzRenderTarget* renderTarget);
static void SetTexture(GLuint id); static void SetTexture(GLuint id);
static void SetTexture(unsigned int textureUnit, GLuint id); static void SetTexture(unsigned int textureUnit, GLuint id);
@ -135,6 +136,7 @@ class NAZARA_API NzOpenGL
static GLenum FaceCulling[nzFaceCulling_Max+1]; static GLenum FaceCulling[nzFaceCulling_Max+1];
static GLenum FaceFilling[nzFaceFilling_Max+1]; static GLenum FaceFilling[nzFaceFilling_Max+1];
static GLenum PrimitiveMode[nzPrimitiveMode_Max+1]; static GLenum PrimitiveMode[nzPrimitiveMode_Max+1];
static GLenum QueryCondition[nzGpuQueryCondition_Max+1];
static GLenum QueryMode[nzGpuQueryMode_Max+1]; static GLenum QueryMode[nzGpuQueryMode_Max+1];
static GLenum RendererComparison[nzRendererComparison_Max+1]; static GLenum RendererComparison[nzRendererComparison_Max+1];
static GLenum RendererParameter[nzRendererParameter_Max+1]; static GLenum RendererParameter[nzRendererParameter_Max+1];
@ -152,6 +154,7 @@ class NAZARA_API NzOpenGL
NAZARA_API extern PFNGLACTIVETEXTUREPROC glActiveTexture; NAZARA_API extern PFNGLACTIVETEXTUREPROC glActiveTexture;
NAZARA_API extern PFNGLATTACHSHADERPROC glAttachShader; NAZARA_API extern PFNGLATTACHSHADERPROC glAttachShader;
NAZARA_API extern PFNGLBEGINCONDITIONALRENDERPROC glBeginConditionalRender;
NAZARA_API extern PFNGLBEGINQUERYPROC glBeginQuery; NAZARA_API extern PFNGLBEGINQUERYPROC glBeginQuery;
NAZARA_API extern PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation; NAZARA_API extern PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation;
NAZARA_API extern PFNGLBINDBUFFERPROC glBindBuffer; NAZARA_API extern PFNGLBINDBUFFERPROC glBindBuffer;
@ -201,6 +204,7 @@ NAZARA_API extern PFNGLDRAWELEMENTSINSTANCEDPROC glDrawElementsInstanced;
NAZARA_API extern PFNGLDRAWTEXTURENVPROC glDrawTexture; NAZARA_API extern PFNGLDRAWTEXTURENVPROC glDrawTexture;
NAZARA_API extern PFNGLENABLEPROC glEnable; NAZARA_API extern PFNGLENABLEPROC glEnable;
NAZARA_API extern PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; NAZARA_API extern PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
NAZARA_API extern PFNGLENDCONDITIONALRENDERPROC glEndConditionalRender;
NAZARA_API extern PFNGLENDQUERYPROC glEndQuery; NAZARA_API extern PFNGLENDQUERYPROC glEndQuery;
NAZARA_API extern PFNGLFLUSHPROC glFlush; NAZARA_API extern PFNGLFLUSHPROC glFlush;
NAZARA_API extern PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer; NAZARA_API extern PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer;

View File

@ -12,6 +12,7 @@
#include <Nazara/Math/Matrix4.hpp> #include <Nazara/Math/Matrix4.hpp>
#include <Nazara/Math/Rect.hpp> #include <Nazara/Math/Rect.hpp>
#include <Nazara/Renderer/Enums.hpp> #include <Nazara/Renderer/Enums.hpp>
#include <Nazara/Renderer/GpuQuery.hpp>
#include <Nazara/Renderer/RenderStates.hpp> #include <Nazara/Renderer/RenderStates.hpp>
#include <Nazara/Renderer/TextureSampler.hpp> #include <Nazara/Renderer/TextureSampler.hpp>
#include <Nazara/Utility/Enums.hpp> #include <Nazara/Utility/Enums.hpp>
@ -35,6 +36,8 @@ class NAZARA_API NzRenderer
NzRenderer() = delete; NzRenderer() = delete;
~NzRenderer() = delete; ~NzRenderer() = delete;
static void BeginCondition(const NzGpuQuery& query, nzGpuQueryCondition condition);
static void Clear(nzUInt32 flags = nzRendererClear_Color | nzRendererClear_Depth); static void Clear(nzUInt32 flags = nzRendererClear_Color | nzRendererClear_Depth);
static void DrawFullscreenQuad(); static void DrawFullscreenQuad();
@ -45,6 +48,8 @@ class NAZARA_API NzRenderer
static void Enable(nzRendererParameter parameter, bool enable); static void Enable(nzRendererParameter parameter, bool enable);
static void EndCondition();
static void Flush(); static void Flush();
static NzVertexBuffer* GetInstanceBuffer(); static NzVertexBuffer* GetInstanceBuffer();

View File

@ -923,6 +923,37 @@ bool NzOpenGL::Initialize()
// AnisotropicFilter // AnisotropicFilter
s_openGLextensions[nzOpenGLExtension_AnisotropicFilter] = IsSupported("GL_EXT_texture_filter_anisotropic"); s_openGLextensions[nzOpenGLExtension_AnisotropicFilter] = IsSupported("GL_EXT_texture_filter_anisotropic");
// ConditionalRender
if (s_openglVersion >= 300)
{
try
{
glBeginConditionalRender = reinterpret_cast<PFNGLBEGINCONDITIONALRENDERPROC>(LoadEntry("glBeginConditionalRender"));
glEndConditionalRender = reinterpret_cast<PFNGLENDCONDITIONALRENDERPROC>(LoadEntry("glEndConditionalRender"));
s_openGLextensions[nzOpenGLExtension_ConditionalRender] = true;
}
catch (const std::exception& e)
{
NazaraWarning("Failed to load Conditional Render: " + NzString(e.what()));
}
}
if (!s_openGLextensions[nzOpenGLExtension_ConditionalRender] && IsSupported("GL_NV_conditional_render"))
{
try
{
glBeginConditionalRender = reinterpret_cast<PFNGLBEGINCONDITIONALRENDERPROC>(LoadEntry("glBeginConditionalRenderNV"));
glEndConditionalRender = reinterpret_cast<PFNGLENDCONDITIONALRENDERPROC>(LoadEntry("glEndConditionalRenderNV"));
s_openGLextensions[nzOpenGLExtension_ConditionalRender] = true;
}
catch (const std::exception& e)
{
NazaraWarning("Failed to load GL_NV_conditional_render: " + NzString(e.what()));
}
}
// DebugOutput // DebugOutput
if (s_openglVersion >= 430 || IsSupported("GL_KHR_debug")) if (s_openglVersion >= 430 || IsSupported("GL_KHR_debug"))
{ {
@ -1228,19 +1259,6 @@ void NzOpenGL::SetBuffer(nzBufferType type, GLuint id)
s_contextStates->buffersBinding[type] = id; s_contextStates->buffersBinding[type] = id;
} }
void NzOpenGL::SetScissorBox(const NzRecti& scissorBox)
{
#ifdef NAZARA_DEBUG
if (!s_contextStates)
{
NazaraError("No context activated");
return;
}
#endif
s_contextStates->currentScissorBox = scissorBox;
}
void NzOpenGL::SetProgram(GLuint id) void NzOpenGL::SetProgram(GLuint id)
{ {
#ifdef NAZARA_DEBUG #ifdef NAZARA_DEBUG
@ -1254,6 +1272,19 @@ void NzOpenGL::SetProgram(GLuint id)
s_contextStates->currentProgram = id; s_contextStates->currentProgram = id;
} }
void NzOpenGL::SetScissorBox(const NzRecti& scissorBox)
{
#ifdef NAZARA_DEBUG
if (!s_contextStates)
{
NazaraError("No context activated");
return;
}
#endif
s_contextStates->currentScissorBox = scissorBox;
}
void NzOpenGL::SetTarget(const NzRenderTarget* renderTarget) void NzOpenGL::SetTarget(const NzRenderTarget* renderTarget)
{ {
#ifdef NAZARA_DEBUG #ifdef NAZARA_DEBUG
@ -1855,6 +1886,16 @@ GLenum NzOpenGL::PrimitiveMode[nzPrimitiveMode_Max+1] =
static_assert(sizeof(NzOpenGL::PrimitiveMode)/sizeof(GLenum) == nzPrimitiveMode_Max+1, "Primitive mode array is incomplete"); static_assert(sizeof(NzOpenGL::PrimitiveMode)/sizeof(GLenum) == nzPrimitiveMode_Max+1, "Primitive mode array is incomplete");
GLenum NzOpenGL::QueryCondition[nzGpuQueryCondition_Max+1] =
{
GL_QUERY_WAIT, // nzGpuQueryCondition_NoWait
GL_QUERY_BY_REGION_NO_WAIT, // nzGpuQueryCondition_Region_NoWait
GL_QUERY_BY_REGION_WAIT, // nzGpuQueryCondition_Region_Wait
GL_QUERY_WAIT // nzGpuQueryCondition_Wait
};
static_assert(sizeof(NzOpenGL::QueryCondition)/sizeof(GLenum) == nzGpuQueryCondition_Max+1, "Query condition array is incomplete");
GLenum NzOpenGL::QueryMode[nzGpuQueryMode_Max+1] = GLenum NzOpenGL::QueryMode[nzGpuQueryMode_Max+1] =
{ {
GL_ANY_SAMPLES_PASSED, // nzGpuQueryMode_AnySamplesPassed GL_ANY_SAMPLES_PASSED, // nzGpuQueryMode_AnySamplesPassed
@ -1963,6 +2004,7 @@ static_assert(sizeof(NzOpenGL::TextureTargetProxy)/sizeof(GLenum) == nzImageType
PFNGLACTIVETEXTUREPROC glActiveTexture = nullptr; PFNGLACTIVETEXTUREPROC glActiveTexture = nullptr;
PFNGLATTACHSHADERPROC glAttachShader = nullptr; PFNGLATTACHSHADERPROC glAttachShader = nullptr;
PFNGLBEGINCONDITIONALRENDERPROC glBeginConditionalRender = nullptr;
PFNGLBEGINQUERYPROC glBeginQuery = nullptr; PFNGLBEGINQUERYPROC glBeginQuery = nullptr;
PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation = nullptr; PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation = nullptr;
PFNGLBINDBUFFERPROC glBindBuffer = nullptr; PFNGLBINDBUFFERPROC glBindBuffer = nullptr;
@ -2012,6 +2054,7 @@ PFNGLDRAWELEMENTSINSTANCEDPROC glDrawElementsInstanced = nullptr;
PFNGLDRAWTEXTURENVPROC glDrawTexture = nullptr; PFNGLDRAWTEXTURENVPROC glDrawTexture = nullptr;
PFNGLENABLEPROC glEnable = nullptr; PFNGLENABLEPROC glEnable = nullptr;
PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray = nullptr; PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray = nullptr;
PFNGLENDCONDITIONALRENDERPROC glEndConditionalRender = nullptr;
PFNGLENDQUERYPROC glEndQuery = nullptr; PFNGLENDQUERYPROC glEndQuery = nullptr;
PFNGLFLUSHPROC glFlush = nullptr; PFNGLFLUSHPROC glFlush = nullptr;
PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer = nullptr; PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer = nullptr;

View File

@ -184,6 +184,27 @@ namespace
ResourceListener s_listener; ResourceListener s_listener;
} }
void NzRenderer::BeginCondition(const NzGpuQuery& query, nzGpuQueryCondition condition)
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
#if NAZARA_RENDERER_SAFE
if (!s_capabilities[nzRendererCap_ConditionalRendering])
{
NazaraError("Conditional rendering is not supported");
return;
}
#endif
glBeginConditionalRender(query.GetOpenGLID(), NzOpenGL::QueryCondition[condition]);
}
void NzRenderer::Clear(nzUInt32 flags) void NzRenderer::Clear(nzUInt32 flags)
{ {
#ifdef NAZARA_DEBUG #ifdef NAZARA_DEBUG
@ -463,6 +484,27 @@ void NzRenderer::Enable(nzRendererParameter parameter, bool enable)
s_states.parameters[parameter] = enable; s_states.parameters[parameter] = enable;
} }
void NzRenderer::EndCondition()
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
#if NAZARA_RENDERER_SAFE
if (!s_capabilities[nzRendererCap_ConditionalRendering])
{
NazaraError("Conditional rendering is not supported");
return;
}
#endif
glEndConditionalRender();
}
void NzRenderer::Flush() void NzRenderer::Flush()
{ {
#ifdef NAZARA_DEBUG #ifdef NAZARA_DEBUG
@ -617,6 +659,7 @@ bool NzRenderer::Initialize()
// Récupération des capacités d'OpenGL // Récupération des capacités d'OpenGL
s_capabilities[nzRendererCap_AnisotropicFilter] = NzOpenGL::IsSupported(nzOpenGLExtension_AnisotropicFilter); s_capabilities[nzRendererCap_AnisotropicFilter] = NzOpenGL::IsSupported(nzOpenGLExtension_AnisotropicFilter);
s_capabilities[nzRendererCap_ConditionalRendering] = NzOpenGL::IsSupported(nzOpenGLExtension_ConditionalRender);
s_capabilities[nzRendererCap_FP64] = NzOpenGL::IsSupported(nzOpenGLExtension_FP64); s_capabilities[nzRendererCap_FP64] = NzOpenGL::IsSupported(nzOpenGLExtension_FP64);
s_capabilities[nzRendererCap_HardwareBuffer] = true; // Natif depuis OpenGL 1.5 s_capabilities[nzRendererCap_HardwareBuffer] = true; // Natif depuis OpenGL 1.5
s_capabilities[nzRendererCap_Instancing] = NzOpenGL::IsSupported(nzOpenGLExtension_DrawInstanced) && NzOpenGL::IsSupported(nzOpenGLExtension_InstancedArray); s_capabilities[nzRendererCap_Instancing] = NzOpenGL::IsSupported(nzOpenGLExtension_DrawInstanced) && NzOpenGL::IsSupported(nzOpenGLExtension_InstancedArray);