Added NzTexture
Added levelCount parameter to NzImageParams Added NzPixelFormat::HasAlpha Reformatted OpenGL debug messages
This commit is contained in:
@@ -31,7 +31,8 @@ namespace
|
||||
|
||||
NzStringStream ss;
|
||||
ss << "OpenGL debug message (ID: 0x" << NzString::Number(id, 16) << "):\n";
|
||||
ss << "-Source: ";
|
||||
ss << "Sent by context: " << userParam;
|
||||
ss << "\n-Source: ";
|
||||
switch (source)
|
||||
{
|
||||
case GL_DEBUG_SOURCE_API_ARB:
|
||||
@@ -121,8 +122,7 @@ namespace
|
||||
}
|
||||
ss << '\n';
|
||||
|
||||
ss << "Message: " << message;
|
||||
ss << "\n\nSent by context: " << userParam;
|
||||
ss << "Message: " << message << '\n';
|
||||
|
||||
NazaraNotice(ss);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include <Nazara/Renderer/GLSLShader.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/String.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <Nazara/Renderer/Texture.hpp>
|
||||
#include <Nazara/Renderer/VertexDeclaration.hpp>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
@@ -26,6 +28,9 @@ namespace
|
||||
GL_GEOMETRY_SHADER, // nzShaderType_Geometry
|
||||
GL_VERTEX_SHADER // nzShaderType_Vertex
|
||||
};
|
||||
|
||||
GLuint lockedPrevious = 0;
|
||||
nzUInt8 lockedLevel = 0;
|
||||
}
|
||||
|
||||
NzGLSLShader::NzGLSLShader(NzShader* parent) :
|
||||
@@ -39,9 +44,24 @@ NzGLSLShader::~NzGLSLShader()
|
||||
|
||||
bool NzGLSLShader::Bind()
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (lockedLevel > 0)
|
||||
{
|
||||
NazaraError("Cannot bind shader while a shader is locked");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
glUseProgram(m_program);
|
||||
|
||||
return true; ///FIXME: Comment détecter une erreur d'OpenGL sans ralentir le programme ?
|
||||
for (auto it = m_textures.begin(); it != m_textures.end(); ++it)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + it->second.unit);
|
||||
if (!it->second.texture->Bind())
|
||||
NazaraWarning("Failed to bind texture");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzGLSLShader::Compile()
|
||||
@@ -106,6 +126,8 @@ bool NzGLSLShader::Create()
|
||||
for (int i = 0; i < nzShaderType_Count; ++i)
|
||||
m_shaders[i] = 0;
|
||||
|
||||
m_textureFreeID = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -218,16 +240,16 @@ bool NzGLSLShader::Load(nzShaderType type, const NzString& source)
|
||||
}
|
||||
}
|
||||
|
||||
bool NzGLSLShader::Lock() const
|
||||
bool NzGLSLShader::Lock()
|
||||
{
|
||||
if (m_lockedLevel++ == 0)
|
||||
if (lockedLevel++ == 0)
|
||||
{
|
||||
GLint previous;
|
||||
glGetIntegerv(GL_CURRENT_PROGRAM, &previous);
|
||||
|
||||
m_lockedPrevious = previous;
|
||||
lockedPrevious = previous;
|
||||
|
||||
if (m_lockedPrevious != m_program)
|
||||
if (lockedPrevious != m_program)
|
||||
glUseProgram(m_program);
|
||||
}
|
||||
|
||||
@@ -288,19 +310,72 @@ bool NzGLSLShader::SendMatrix(const NzString& name, const NzMatrix4f& matrix)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzGLSLShader::SendTexture(const NzString& name, NzTexture* texture)
|
||||
{
|
||||
static const unsigned int maxUnits = NazaraRenderer->GetMaxTextureUnits();
|
||||
|
||||
unsigned int unitUsed = m_textures.size();
|
||||
if (unitUsed >= maxUnits)
|
||||
{
|
||||
NazaraError("Unable to use texture \"" + name + "\" for shader: all available texture units are used");
|
||||
return false;
|
||||
}
|
||||
|
||||
// À partir d'ici nous savons qu'il y a au moins un identifiant de texture libre
|
||||
GLint location = GetUniformLocation(name);
|
||||
if (location == -1)
|
||||
{
|
||||
NazaraError("Parameter name \"" + name + "\" not found in shader");
|
||||
return false;
|
||||
}
|
||||
|
||||
nzUInt8 unit;
|
||||
if (unitUsed == 0)
|
||||
// Pas d'unité utilisée, la tâche est simple
|
||||
unit = 0;
|
||||
else
|
||||
{
|
||||
auto it = m_textures.rbegin(); // Itérateur vers la fin de la map
|
||||
unit = it->second.unit;
|
||||
if (unit == maxUnits-1)
|
||||
{
|
||||
// Il y a une place libre, mais pas à la fin
|
||||
for (; it != m_textures.rend(); ++it)
|
||||
{
|
||||
if (unit - it->second.unit > 1) // Si l'espace entre les indices est supérieur à 1, alors il y a une place libre
|
||||
{
|
||||
unit--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
// Il y a une place libre à la fin
|
||||
unit++;
|
||||
}
|
||||
|
||||
m_textures[location] = TextureSlot{unit, texture};
|
||||
|
||||
Lock();
|
||||
glUniform1i(location, unit);
|
||||
Unlock();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzGLSLShader::Unbind()
|
||||
{
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
void NzGLSLShader::Unlock() const
|
||||
void NzGLSLShader::Unlock()
|
||||
{
|
||||
if (m_lockedLevel == 0)
|
||||
if (lockedLevel == 0)
|
||||
{
|
||||
NazaraWarning("Unlock called on non-locked texture");
|
||||
return;
|
||||
}
|
||||
|
||||
if (--m_lockedLevel == 0 && m_lockedPrevious != m_program)
|
||||
glUseProgram(m_lockedPrevious);
|
||||
if (--lockedLevel == 0 && lockedPrevious != m_program)
|
||||
glUseProgram(lockedPrevious);
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ class NzGLSLShader : public NzShaderImpl
|
||||
bool IsLoaded(nzShaderType type) const;
|
||||
|
||||
bool Load(nzShaderType type, const NzString& source);
|
||||
bool Lock() const;
|
||||
bool Lock();
|
||||
|
||||
bool SendBoolean(const NzString& name, bool value);
|
||||
bool SendDouble(const NzString& name, double value);
|
||||
@@ -42,16 +42,23 @@ class NzGLSLShader : public NzShaderImpl
|
||||
bool SendInteger(const NzString& name, int value);
|
||||
bool SendMatrix(const NzString& name, const NzMatrix4d& matrix);
|
||||
bool SendMatrix(const NzString& name, const NzMatrix4f& matrix);
|
||||
bool SendTexture(const NzString& name, NzTexture* texture);
|
||||
|
||||
void Unbind();
|
||||
void Unlock() const;
|
||||
void Unlock();
|
||||
|
||||
private:
|
||||
struct TextureSlot
|
||||
{
|
||||
nzUInt8 unit;
|
||||
NzTexture* texture;
|
||||
};
|
||||
|
||||
mutable std::map<NzString, GLint> m_idCache;
|
||||
mutable GLuint m_lockedPrevious;
|
||||
std::map<GLint, TextureSlot> m_textures;
|
||||
GLuint m_program;
|
||||
GLuint m_shaders[nzShaderType_Count];
|
||||
mutable nzUInt8 m_lockedLevel;
|
||||
nzUInt8 m_textureFreeID;
|
||||
NzShader* m_parent;
|
||||
NzString m_log;
|
||||
};
|
||||
|
||||
@@ -37,7 +37,10 @@ m_id(0)
|
||||
NzOcclusionQuery::~NzOcclusionQuery()
|
||||
{
|
||||
if (m_id)
|
||||
glDeleteQueries(1, reinterpret_cast<GLuint*>(&m_id));
|
||||
{
|
||||
GLuint query = static_cast<GLuint>(m_id);
|
||||
glDeleteQueries(1, &query);
|
||||
}
|
||||
}
|
||||
|
||||
void NzOcclusionQuery::Begin()
|
||||
|
||||
@@ -255,6 +255,8 @@ bool NzOpenGL::Initialize()
|
||||
glGetShaderiv = reinterpret_cast<PFNGLGETSHADERIVPROC>(LoadEntry("glGetShaderiv"));
|
||||
glGetShaderSource = reinterpret_cast<PFNGLGETSHADERSOURCEPROC>(LoadEntry("glGetShaderSource"));
|
||||
glGetTexImage = reinterpret_cast<PFNGLGETTEXIMAGEPROC>(LoadEntry("glGetTexImage"));
|
||||
glGetTexLevelParameterfv = reinterpret_cast<PFNGLGETTEXLEVELPARAMETERFVPROC>(LoadEntry("glGetTexLevelParameterfv"));
|
||||
glGetTexLevelParameteriv = reinterpret_cast<PFNGLGETTEXLEVELPARAMETERIVPROC>(LoadEntry("glGetTexLevelParameteriv"));
|
||||
glGetTexParameterfv = reinterpret_cast<PFNGLGETTEXPARAMETERFVPROC>(LoadEntry("glGetTexParameterfv"));
|
||||
glGetTexParameteriv = reinterpret_cast<PFNGLGETTEXPARAMETERIVPROC>(LoadEntry("glGetTexParameteriv"));
|
||||
glGetUniformLocation = reinterpret_cast<PFNGLGETUNIFORMLOCATIONPROC>(LoadEntry("glGetUniformLocation"));
|
||||
@@ -445,6 +447,9 @@ bool NzOpenGL::Initialize()
|
||||
}
|
||||
}
|
||||
|
||||
// TextureCompression_s3tc
|
||||
openGLextensions[NzOpenGL::TextureCompression_s3tc] = IsSupported("GL_EXT_texture_compression_s3tc");
|
||||
|
||||
// VertexArrayObject
|
||||
if (openGLversion >= 420 || IsSupported("GL_ARB_texture_storage"))
|
||||
{
|
||||
@@ -587,6 +592,8 @@ PFNGLGETSHADERSOURCEPROC glGetShaderSource = nullptr;
|
||||
PFNGLGETSTRINGPROC glGetString = nullptr;
|
||||
PFNGLGETSTRINGIPROC glGetStringi = nullptr;
|
||||
PFNGLGETTEXIMAGEPROC glGetTexImage = nullptr;
|
||||
PFNGLGETTEXLEVELPARAMETERFVPROC glGetTexLevelParameterfv = nullptr;
|
||||
PFNGLGETTEXLEVELPARAMETERIVPROC glGetTexLevelParameteriv = nullptr;
|
||||
PFNGLGETTEXPARAMETERFVPROC glGetTexParameterfv = nullptr;
|
||||
PFNGLGETTEXPARAMETERIVPROC glGetTexParameteriv = nullptr;
|
||||
PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation = nullptr;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <Nazara/Renderer/Config.hpp>
|
||||
#include <Nazara/Renderer/Context.hpp>
|
||||
#include <Nazara/Renderer/ContextParameters.hpp>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
namespace
|
||||
@@ -25,12 +26,28 @@ NzRenderWindow::NzRenderWindow(NzVideoMode mode, const NzString& title, nzUInt32
|
||||
m_context(nullptr)
|
||||
{
|
||||
Create(mode, title, style, parameters);
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Failed to create render window");
|
||||
throw std::runtime_error("Constructor failed");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
NzRenderWindow::NzRenderWindow(NzWindowHandle handle, const NzContextParameters& parameters) :
|
||||
m_context(nullptr)
|
||||
{
|
||||
Create(handle, parameters);
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Failed to create render window");
|
||||
throw std::runtime_error("Constructor failed");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
NzRenderWindow::~NzRenderWindow()
|
||||
|
||||
@@ -30,7 +30,8 @@ namespace
|
||||
4 // nzElementUsage_TexCoord
|
||||
};
|
||||
|
||||
const GLenum openglPrimitive[] = {
|
||||
const GLenum openglPrimitive[] =
|
||||
{
|
||||
GL_LINES, // nzPrimitiveType_LineList,
|
||||
GL_LINE_STRIP, // nzPrimitiveType_LineStrip,
|
||||
GL_POINTS, // nzPrimitiveType_PointList,
|
||||
@@ -310,6 +311,12 @@ bool NzRenderer::SetShader(NzShader* shader)
|
||||
if (shader == m_shader)
|
||||
return true;
|
||||
|
||||
if (m_shader)
|
||||
{
|
||||
m_shader->m_impl->Unbind();
|
||||
m_shader = nullptr;
|
||||
}
|
||||
|
||||
if (shader)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
@@ -328,11 +335,6 @@ bool NzRenderer::SetShader(NzShader* shader)
|
||||
|
||||
m_shader = shader;
|
||||
}
|
||||
else if (m_shader)
|
||||
{
|
||||
m_shader->m_impl->Unbind();
|
||||
m_shader = nullptr;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -408,7 +410,7 @@ void NzRenderer::Uninitialize()
|
||||
// Libération des VAOs
|
||||
for (auto it = m_vaos.begin(); it != m_vaos.end(); ++it)
|
||||
{
|
||||
GLuint vao = it->second;
|
||||
GLuint vao = static_cast<GLuint>(it->second);
|
||||
glDeleteVertexArrays(1, &vao);
|
||||
}
|
||||
|
||||
|
||||
@@ -371,6 +371,19 @@ bool NzShader::SendMatrix(const NzString& name, const NzMatrix4f& matrix)
|
||||
return m_impl->SendMatrix(name, matrix);
|
||||
}
|
||||
|
||||
bool NzShader::SendTexture(const NzString& name, NzTexture* texture)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Shader not created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->SendTexture(name, texture);
|
||||
}
|
||||
|
||||
void NzShader::Unlock()
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <Nazara/Renderer/Shader.hpp>
|
||||
|
||||
class NzRenderer;
|
||||
class NzTexture;
|
||||
class NzVertexBuffer;
|
||||
class NzVertexDeclaration;
|
||||
|
||||
@@ -36,7 +37,7 @@ class NzShaderImpl
|
||||
|
||||
virtual bool Load(nzShaderType type, const NzString& source) = 0;
|
||||
|
||||
virtual bool Lock() const = 0;
|
||||
virtual bool Lock() = 0;
|
||||
|
||||
virtual bool SendBoolean(const NzString& name, bool value) = 0;
|
||||
virtual bool SendDouble(const NzString& name, double value) = 0;
|
||||
@@ -44,9 +45,10 @@ class NzShaderImpl
|
||||
virtual bool SendInteger(const NzString& name, int value) = 0;
|
||||
virtual bool SendMatrix(const NzString& name, const NzMatrix4d& matrix) = 0;
|
||||
virtual bool SendMatrix(const NzString& name, const NzMatrix4f& matrix) = 0;
|
||||
virtual bool SendTexture(const NzString& name, NzTexture* texture) = 0;
|
||||
|
||||
virtual void Unbind() = 0;
|
||||
virtual void Unlock() const = 0;
|
||||
virtual void Unlock() = 0;
|
||||
};
|
||||
|
||||
#endif // NAZARA_SHADERIMPL_HPP
|
||||
|
||||
1485
src/Nazara/Renderer/Texture.cpp
Normal file
1485
src/Nazara/Renderer/Texture.cpp
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user