Fixed rendering with OpenGL core profile
Added (automatic) support of Vertex Arrays Objects (VAO) to fix rendering with an OpenGL core profile (OpenGL 3.2 require the use of VAOs) Added level check to NzImage::GetDepth/Height/Size/Width Fixed occlussion query support not correctly setted
This commit is contained in:
@@ -6,14 +6,13 @@
|
||||
#include <Nazara/Renderer/GLSLShader.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Renderer/BufferImpl.hpp>
|
||||
#include <Nazara/Renderer/VertexBuffer.hpp>
|
||||
#include <Nazara/Renderer/VertexDeclaration.hpp>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
nzUInt8 attribIndex[] =
|
||||
///FIXME: Déclaré deux fois (ici et dans Renderer.cpp)
|
||||
const nzUInt8 attribIndex[] =
|
||||
{
|
||||
2, // nzElementUsage_Diffuse
|
||||
1, // nzElementUsage_Normal
|
||||
@@ -27,32 +26,6 @@ namespace
|
||||
GL_GEOMETRY_SHADER, // nzShaderType_Geometry
|
||||
GL_VERTEX_SHADER // nzShaderType_Vertex
|
||||
};
|
||||
|
||||
const nzUInt8 size[] =
|
||||
{
|
||||
4, // nzElementType_Color
|
||||
1, // nzElementType_Double1
|
||||
2, // nzElementType_Double2
|
||||
3, // nzElementType_Double3
|
||||
4, // nzElementType_Double4
|
||||
1, // nzElementType_Float1
|
||||
2, // nzElementType_Float2
|
||||
3, // nzElementType_Float3
|
||||
4 // nzElementType_Float4
|
||||
};
|
||||
|
||||
const GLenum type[] =
|
||||
{
|
||||
GL_UNSIGNED_BYTE, // nzElementType_Color
|
||||
GL_DOUBLE, // nzElementType_Double1
|
||||
GL_DOUBLE, // nzElementType_Double2
|
||||
GL_DOUBLE, // nzElementType_Double3
|
||||
GL_DOUBLE, // nzElementType_Double4
|
||||
GL_FLOAT, // nzElementType_Float1
|
||||
GL_FLOAT, // nzElementType_Float2
|
||||
GL_FLOAT, // nzElementType_Float3
|
||||
GL_FLOAT // nzElementType_Float4
|
||||
};
|
||||
}
|
||||
|
||||
NzGLSLShader::NzGLSLShader(NzShader* parent) :
|
||||
@@ -331,29 +304,3 @@ void NzGLSLShader::Unlock() const
|
||||
if (--m_lockedLevel == 0 && m_lockedPrevious != m_program)
|
||||
glUseProgram(m_lockedPrevious);
|
||||
}
|
||||
|
||||
bool NzGLSLShader::UpdateVertexBuffer(const NzVertexBuffer* vertexBuffer, const NzVertexDeclaration* vertexDeclaration)
|
||||
{
|
||||
vertexBuffer->GetBuffer()->GetImpl()->Bind();
|
||||
const nzUInt8* buffer = reinterpret_cast<const nzUInt8*>(vertexBuffer->GetBufferPtr());
|
||||
|
||||
///FIXME: Améliorer les déclarations pour permettre de faire ça plus simplement
|
||||
for (int i = 0; i < 12; ++i) // Solution temporaire, à virer
|
||||
glDisableVertexAttribArray(i); // Chaque itération tue un chaton :(
|
||||
|
||||
unsigned int stride = vertexDeclaration->GetStride();
|
||||
unsigned int elementCount = vertexDeclaration->GetElementCount();
|
||||
for (unsigned int i = 0; i < elementCount; ++i)
|
||||
{
|
||||
const NzVertexDeclaration::Element* element = vertexDeclaration->GetElement(i);
|
||||
glEnableVertexAttribArray(attribIndex[element->usage]+element->usageIndex);
|
||||
glVertexAttribPointer(attribIndex[element->usage]+element->usageIndex,
|
||||
size[element->type],
|
||||
type[element->type],
|
||||
(element->type == nzElementType_Color) ? GL_TRUE : GL_FALSE,
|
||||
stride,
|
||||
&buffer[element->offset]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -47,8 +47,6 @@ class NzGLSLShader : public NzShaderImpl
|
||||
void Unlock() const;
|
||||
|
||||
private:
|
||||
bool UpdateVertexBuffer(const NzVertexBuffer* vertexBuffer, const NzVertexDeclaration* vertexDeclaration);
|
||||
|
||||
mutable std::map<NzString, GLint> m_idCache;
|
||||
mutable GLuint m_lockedPrevious;
|
||||
GLuint m_program;
|
||||
|
||||
@@ -314,7 +314,7 @@ bool NzOpenGL::Initialize()
|
||||
}
|
||||
}
|
||||
|
||||
// Framebuffer_Object
|
||||
// FrameBufferObject
|
||||
try
|
||||
{
|
||||
glBindFramebuffer = reinterpret_cast<PFNGLBINDFRAMEBUFFERPROC>(LoadEntry("glBindFramebuffer"));
|
||||
@@ -329,7 +329,7 @@ bool NzOpenGL::Initialize()
|
||||
glGenRenderbuffers = reinterpret_cast<PFNGLGENRENDERBUFFERSPROC>(LoadEntry("glGenRenderbuffers"));
|
||||
glRenderbufferStorage = reinterpret_cast<PFNGLRENDERBUFFERSTORAGEPROC>(LoadEntry("glRenderbufferStorage"));
|
||||
|
||||
openGLextensions[NzOpenGL::Framebuffer_Object] = true;
|
||||
openGLextensions[NzOpenGL::FrameBufferObject] = true;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
@@ -352,7 +352,7 @@ bool NzOpenGL::Initialize()
|
||||
glGenRenderbuffers = reinterpret_cast<PFNGLGENRENDERBUFFERSEXTPROC>(LoadEntry("glGenRenderbuffersEXT"));
|
||||
glRenderbufferStorage = reinterpret_cast<PFNGLRENDERBUFFERSTORAGEEXTPROC>(LoadEntry("glRenderbufferStorageEXT"));
|
||||
|
||||
openGLextensions[NzOpenGL::Framebuffer_Object] = true;
|
||||
openGLextensions[NzOpenGL::FrameBufferObject] = true;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
@@ -377,8 +377,24 @@ bool NzOpenGL::Initialize()
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************Contextes****************************************/
|
||||
// VertexArrayObject
|
||||
if (openGLversion >= 300 || IsSupported("GL_ARB_vertex_array_object"))
|
||||
{
|
||||
try
|
||||
{
|
||||
glBindVertexArray = reinterpret_cast<PFNGLBINDVERTEXARRAYPROC>(LoadEntry("glBindVertexArray", false));
|
||||
glDeleteVertexArrays = reinterpret_cast<PFNGLDELETEVERTEXARRAYSPROC>(LoadEntry("glDeleteVertexArrays", false));
|
||||
glGenVertexArrays = reinterpret_cast<PFNGLGENVERTEXARRAYSPROC>(LoadEntry("glGenVertexArrays", false));
|
||||
|
||||
openGLextensions[NzOpenGL::VertexArrayObject] = true;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
NazaraError("Failed to load ARB_vertex_array_object: " + NzString(e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************Contextes****************************************/
|
||||
|
||||
NzContextParameters::defaultMajorVersion = openGLversion/100;
|
||||
NzContextParameters::defaultMinorVersion = (openGLversion%100)/10;
|
||||
@@ -427,6 +443,7 @@ PFNGLBINDBUFFERPROC glBindBuffer = nullptr;
|
||||
PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer = nullptr;
|
||||
PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer = nullptr;
|
||||
PFNGLBINDTEXTUREPROC glBindTexture = nullptr;
|
||||
PFNGLBINDVERTEXARRAYPROC glBindVertexArray = nullptr;
|
||||
PFNGLBLENDFUNCPROC glBlendFunc = nullptr;
|
||||
PFNGLBUFFERDATAPROC glBufferData = nullptr;
|
||||
PFNGLBUFFERSUBDATAPROC glBufferSubData = nullptr;
|
||||
@@ -447,6 +464,7 @@ PFNGLDELETEQUERIESPROC glDeleteQueries = nullptr;
|
||||
PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers = nullptr;
|
||||
PFNGLDELETESHADERPROC glDeleteShader = nullptr;
|
||||
PFNGLDELETETEXTURESPROC glDeleteTextures = nullptr;
|
||||
PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays = nullptr;
|
||||
PFNGLDEPTHFUNCPROC glDepthFunc = nullptr;
|
||||
PFNGLDEPTHMASKPROC glDepthMask = nullptr;
|
||||
PFNGLDISABLEPROC glDisable = nullptr;
|
||||
@@ -467,6 +485,7 @@ PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers = nullptr;
|
||||
PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers = nullptr;
|
||||
PFNGLGENQUERIESPROC glGenQueries = nullptr;
|
||||
PFNGLGENTEXTURESPROC glGenTextures = nullptr;
|
||||
PFNGLGENVERTEXARRAYSPROC glGenVertexArrays = nullptr;
|
||||
PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv = nullptr;
|
||||
PFNGLGETERRORPROC glGetError = nullptr;
|
||||
PFNGLGETINTEGERVPROC glGetIntegerv = nullptr;
|
||||
|
||||
@@ -14,13 +14,23 @@
|
||||
#include <Nazara/Renderer/Shader.hpp>
|
||||
#include <Nazara/Renderer/ShaderImpl.hpp>
|
||||
#include <Nazara/Renderer/VertexBuffer.hpp>
|
||||
#include <Nazara/Renderer/VertexDeclaration.hpp>
|
||||
#include <Nazara/Utility/Utility.hpp>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
GLenum openglPrimitive[] = {
|
||||
const nzUInt8 attribIndex[] =
|
||||
{
|
||||
2, // nzElementUsage_Diffuse
|
||||
1, // nzElementUsage_Normal
|
||||
0, // nzElementUsage_Position
|
||||
3, // nzElementUsage_Tangent
|
||||
4 // nzElementUsage_TexCoord
|
||||
};
|
||||
|
||||
const GLenum openglPrimitive[] = {
|
||||
GL_LINES, // nzPrimitiveType_LineList,
|
||||
GL_LINE_STRIP, // nzPrimitiveType_LineStrip,
|
||||
GL_POINTS, // nzPrimitiveType_PointList,
|
||||
@@ -28,6 +38,32 @@ namespace
|
||||
GL_TRIANGLE_STRIP, // nzPrimitiveType_TriangleStrip,
|
||||
GL_TRIANGLE_FAN // nzPrimitiveType_TriangleFan
|
||||
};
|
||||
|
||||
const nzUInt8 openglSize[] =
|
||||
{
|
||||
4, // nzElementType_Color
|
||||
1, // nzElementType_Double1
|
||||
2, // nzElementType_Double2
|
||||
3, // nzElementType_Double3
|
||||
4, // nzElementType_Double4
|
||||
1, // nzElementType_Float1
|
||||
2, // nzElementType_Float2
|
||||
3, // nzElementType_Float3
|
||||
4 // nzElementType_Float4
|
||||
};
|
||||
|
||||
const GLenum openglType[] =
|
||||
{
|
||||
GL_UNSIGNED_BYTE, // nzElementType_Color
|
||||
GL_DOUBLE, // nzElementType_Double1
|
||||
GL_DOUBLE, // nzElementType_Double2
|
||||
GL_DOUBLE, // nzElementType_Double3
|
||||
GL_DOUBLE, // nzElementType_Double4
|
||||
GL_FLOAT, // nzElementType_Float1
|
||||
GL_FLOAT, // nzElementType_Float2
|
||||
GL_FLOAT, // nzElementType_Float3
|
||||
GL_FLOAT // nzElementType_Float4
|
||||
};
|
||||
}
|
||||
|
||||
NzRenderer::NzRenderer() :
|
||||
@@ -36,7 +72,7 @@ m_target(nullptr),
|
||||
m_shader(nullptr),
|
||||
m_vertexBuffer(nullptr),
|
||||
m_vertexDeclaration(nullptr),
|
||||
m_vertexBufferUpdated(false)
|
||||
m_statesUpdated(false)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (s_instance)
|
||||
@@ -91,11 +127,11 @@ void NzRenderer::DrawIndexedPrimitives(nzPrimitiveType primitive, unsigned int f
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!m_vertexBufferUpdated)
|
||||
if (!m_statesUpdated)
|
||||
{
|
||||
if (!UpdateVertexBuffer())
|
||||
if (!UpdateStates())
|
||||
{
|
||||
NazaraError("Failed to update vertex buffer");
|
||||
NazaraError("Failed to update states");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -127,11 +163,11 @@ void NzRenderer::DrawIndexedPrimitives(nzPrimitiveType primitive, unsigned int f
|
||||
|
||||
void NzRenderer::DrawPrimitives(nzPrimitiveType primitive, unsigned int firstVertex, unsigned int vertexCount)
|
||||
{
|
||||
if (!m_vertexBufferUpdated)
|
||||
if (!m_statesUpdated)
|
||||
{
|
||||
if (!UpdateVertexBuffer())
|
||||
if (!UpdateStates())
|
||||
{
|
||||
NazaraError("Failed to update vertex buffer");
|
||||
NazaraError("Failed to update states");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -191,7 +227,7 @@ bool NzRenderer::Initialize()
|
||||
m_capabilities[nzRendererCap_FP64] = NzOpenGL::IsSupported(NzOpenGL::FP64);
|
||||
m_capabilities[nzRendererCap_HardwareBuffer] = true; // Natif depuis OpenGL 1.5
|
||||
m_capabilities[nzRendererCap_MultipleRenderTargets] = true; // Natif depuis OpenGL 2.0
|
||||
m_capabilities[nzRendererCap_OcclusionQuery] = // Natif depuis OpenGL 1.5
|
||||
m_capabilities[nzRendererCap_OcclusionQuery] = true; // Natif depuis OpenGL 1.5
|
||||
m_capabilities[nzRendererCap_SoftwareBuffer] = NzOpenGL::GetVersion() <= 300; // Déprécié en OpenGL 3
|
||||
m_capabilities[nzRendererCap_Texture3D] = NzOpenGL::IsSupported(NzOpenGL::Texture3D);
|
||||
m_capabilities[nzRendererCap_TextureCubemap] = true; // Natif depuis OpenGL 1.3
|
||||
@@ -260,12 +296,11 @@ void NzRenderer::SetClearStencil(unsigned int value)
|
||||
|
||||
bool NzRenderer::SetIndexBuffer(const NzIndexBuffer* indexBuffer)
|
||||
{
|
||||
if (indexBuffer == m_indexBuffer)
|
||||
return true;
|
||||
|
||||
// OpenGL ne nécessite pas de débinder un index buffer pour ne pas l'utiliser
|
||||
if (indexBuffer)
|
||||
indexBuffer->GetBuffer()->m_impl->Bind();
|
||||
if (indexBuffer != m_indexBuffer)
|
||||
{
|
||||
m_indexBuffer = indexBuffer;
|
||||
m_statesUpdated = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -292,7 +327,6 @@ bool NzRenderer::SetShader(NzShader* shader)
|
||||
}
|
||||
|
||||
m_shader = shader;
|
||||
m_vertexBufferUpdated = false;
|
||||
}
|
||||
else if (m_shader)
|
||||
{
|
||||
@@ -339,24 +373,22 @@ bool NzRenderer::SetTarget(NzRenderTarget* target)
|
||||
|
||||
bool NzRenderer::SetVertexBuffer(const NzVertexBuffer* vertexBuffer)
|
||||
{
|
||||
if (m_vertexBuffer == vertexBuffer)
|
||||
return true;
|
||||
|
||||
if (m_vertexBuffer && vertexBuffer)
|
||||
if (m_vertexBuffer != vertexBuffer)
|
||||
{
|
||||
// Si l'ancien buffer et le nouveau sont hardware, pas besoin de mettre à jour la déclaration
|
||||
if (!m_vertexBuffer->IsHardware() || !vertexBuffer->IsHardware())
|
||||
m_vertexBufferUpdated = false;
|
||||
m_vertexBuffer = vertexBuffer;
|
||||
m_statesUpdated = false;
|
||||
}
|
||||
m_vertexBuffer = vertexBuffer;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzRenderer::SetVertexDeclaration(const NzVertexDeclaration* vertexDeclaration)
|
||||
{
|
||||
m_vertexDeclaration = vertexDeclaration;
|
||||
m_vertexBufferUpdated = false;
|
||||
if (m_vertexDeclaration != vertexDeclaration)
|
||||
{
|
||||
m_vertexDeclaration = vertexDeclaration;
|
||||
m_statesUpdated = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -371,10 +403,17 @@ void NzRenderer::Uninitialize()
|
||||
}
|
||||
#endif
|
||||
|
||||
NzOpenGL::Uninitialize();
|
||||
|
||||
s_initialized = false;
|
||||
|
||||
// Libération des VAOs
|
||||
for (auto it = m_vaos.begin(); it != m_vaos.end(); ++it)
|
||||
{
|
||||
GLuint vao = it->second;
|
||||
glDeleteVertexArrays(1, &vao);
|
||||
}
|
||||
|
||||
NzOpenGL::Uninitialize();
|
||||
|
||||
if (m_utilityModule)
|
||||
{
|
||||
delete m_utilityModule;
|
||||
@@ -397,15 +436,9 @@ bool NzRenderer::IsInitialized()
|
||||
return s_initialized;
|
||||
}
|
||||
|
||||
bool NzRenderer::UpdateVertexBuffer()
|
||||
bool NzRenderer::UpdateStates()
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (!m_shader)
|
||||
{
|
||||
NazaraError("No shader");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_vertexBuffer)
|
||||
{
|
||||
NazaraError("No vertex buffer");
|
||||
@@ -419,10 +452,78 @@ bool NzRenderer::UpdateVertexBuffer()
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!m_shader->m_impl->UpdateVertexBuffer(m_vertexBuffer, m_vertexDeclaration))
|
||||
return false;
|
||||
static const bool vaoSupported = NzOpenGL::IsSupported(NzOpenGL::VertexArrayObject);
|
||||
bool update;
|
||||
GLuint vao;
|
||||
|
||||
m_vertexBufferUpdated = true;
|
||||
// Si les VAOs sont supportés, on entoure nos appels par ceux-ci
|
||||
if (vaoSupported)
|
||||
{
|
||||
// On recherche si un VAO existe déjà avec notre configuration
|
||||
// Note: Les VAOs ne sont pas partagés entre les contextes, ils font donc partie de notre configuration
|
||||
|
||||
auto key = std::make_tuple(NzContext::GetCurrent(), m_indexBuffer, m_vertexBuffer, m_vertexDeclaration);
|
||||
auto it = m_vaos.find(key);
|
||||
if (it == m_vaos.end())
|
||||
{
|
||||
glGenVertexArrays(1, &vao);
|
||||
glBindVertexArray(vao);
|
||||
|
||||
m_vaos.insert(std::make_pair(key, static_cast<unsigned int>(vao)));
|
||||
|
||||
update = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Notre VAO existe déjà, il est donc inutile de le reprogrammer
|
||||
vao = it->second;
|
||||
|
||||
update = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
update = true; // Fallback si les VAOs ne sont pas supportés
|
||||
|
||||
if (update)
|
||||
{
|
||||
m_vertexBuffer->GetBuffer()->GetImpl()->Bind();
|
||||
|
||||
const nzUInt8* buffer = reinterpret_cast<const nzUInt8*>(m_vertexBuffer->GetBufferPtr());
|
||||
|
||||
///FIXME: Améliorer les déclarations pour permettre de faire ça plus simplement
|
||||
for (int i = 0; i < 12; ++i) // Solution temporaire, à virer
|
||||
glDisableVertexAttribArray(i); // Chaque itération tue un chaton :(
|
||||
|
||||
unsigned int stride = m_vertexDeclaration->GetStride();
|
||||
unsigned int elementCount = m_vertexDeclaration->GetElementCount();
|
||||
for (unsigned int i = 0; i < elementCount; ++i)
|
||||
{
|
||||
const NzVertexDeclaration::Element* element = m_vertexDeclaration->GetElement(i);
|
||||
|
||||
glEnableVertexAttribArray(attribIndex[element->usage]+element->usageIndex);
|
||||
glVertexAttribPointer(attribIndex[element->usage]+element->usageIndex,
|
||||
openglSize[element->type],
|
||||
openglType[element->type],
|
||||
(element->type == nzElementType_Color) ? GL_TRUE : GL_FALSE,
|
||||
stride,
|
||||
&buffer[element->offset]);
|
||||
}
|
||||
|
||||
if (m_indexBuffer)
|
||||
m_indexBuffer->GetBuffer()->GetImpl()->Bind();
|
||||
}
|
||||
|
||||
if (vaoSupported)
|
||||
{
|
||||
// Si nous venons de définir notre VAO, nous devons le débinder pour indiquer la fin de sa construction
|
||||
if (update)
|
||||
glBindVertexArray(0);
|
||||
|
||||
// Nous (re)bindons le VAO pour définir les attributs de vertice
|
||||
glBindVertexArray(vao);
|
||||
}
|
||||
|
||||
m_statesUpdated = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -47,9 +47,6 @@ class NzShaderImpl
|
||||
|
||||
virtual void Unbind() = 0;
|
||||
virtual void Unlock() const = 0;
|
||||
|
||||
protected:
|
||||
virtual bool UpdateVertexBuffer(const NzVertexBuffer* vertexBuffer, const NzVertexDeclaration* vertexDeclaration) = 0;
|
||||
};
|
||||
|
||||
#endif // NAZARA_SHADERIMPL_HPP
|
||||
|
||||
@@ -271,6 +271,14 @@ const nzUInt8* NzImage::GetConstPixels(nzUInt8 level) const
|
||||
|
||||
unsigned int NzImage::GetDepth(nzUInt8 level) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (level >= m_sharedImage->levelCount)
|
||||
{
|
||||
NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levelCount) + ')');
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return std::max(m_sharedImage->depth/(1 << level), 1U);
|
||||
}
|
||||
|
||||
@@ -281,6 +289,14 @@ nzPixelFormat NzImage::GetFormat() const
|
||||
|
||||
unsigned int NzImage::GetHeight(nzUInt8 level) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (level >= m_sharedImage->levelCount)
|
||||
{
|
||||
NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levelCount) + ')');
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return std::max(m_sharedImage->height/(1 << level), 1U);
|
||||
}
|
||||
|
||||
@@ -422,6 +438,14 @@ unsigned int NzImage::GetSize() const
|
||||
|
||||
unsigned int NzImage::GetSize(nzUInt8 level) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (level >= m_sharedImage->levelCount)
|
||||
{
|
||||
NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levelCount) + ')');
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return (std::max(m_sharedImage->width/(1 << level), 1U)) *
|
||||
(std::max(m_sharedImage->height/(1 << level), 1U)) *
|
||||
((m_sharedImage->type == nzImageType_Cubemap) ? 6 : std::min(m_sharedImage->depth/(1 << level), 1U)) *
|
||||
@@ -435,6 +459,14 @@ nzImageType NzImage::GetType() const
|
||||
|
||||
unsigned int NzImage::GetWidth(nzUInt8 level) const
|
||||
{
|
||||
#if NAZARA_UTILITY_SAFE
|
||||
if (level >= m_sharedImage->levelCount)
|
||||
{
|
||||
NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levelCount) + ')');
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return std::max(m_sharedImage->width/(1 << level), 1U);
|
||||
}
|
||||
|
||||
@@ -905,4 +937,4 @@ void NzImage::ReleaseImage()
|
||||
m_sharedImage = &emptyImage;
|
||||
}
|
||||
|
||||
NzImage::SharedImage NzImage::emptyImage(0, nzImageType_2D, nzPixelFormat_Undefined, 0, nullptr, 0, 0, 0);
|
||||
NzImage::SharedImage NzImage::emptyImage(0, nzImageType_2D, nzPixelFormat_Undefined, 1, nullptr, 0, 0, 0);
|
||||
|
||||
Reference in New Issue
Block a user