Merge branch 'master' into NDK-ShadowMapping
Former-commit-id: e2be28b65207dfbb81efe58f31ca31548afecee7
This commit is contained in:
@@ -120,7 +120,7 @@ namespace Nz
|
||||
|
||||
for (unsigned int i = 0; i < 3; ++i)
|
||||
m_GBuffer[i] = Texture::New();
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
ErrorFlags errFlags(ErrorFlag_ThrowException);
|
||||
@@ -204,6 +204,11 @@ namespace Nz
|
||||
|
||||
DeferredRenderTechnique::~DeferredRenderTechnique() = default;
|
||||
|
||||
void DeferredRenderTechnique::Clear(const SceneData& sceneData) const
|
||||
{
|
||||
NazaraUnused(sceneData);
|
||||
}
|
||||
|
||||
bool DeferredRenderTechnique::Draw(const SceneData& sceneData) const
|
||||
{
|
||||
NazaraAssert(sceneData.viewer, "Invalid viewer");
|
||||
|
||||
@@ -17,7 +17,10 @@ namespace Nz
|
||||
Ternary CheckStatic(Stream& stream, const ModelParameters& parameters)
|
||||
{
|
||||
NazaraUnused(stream);
|
||||
NazaraUnused(parameters);
|
||||
|
||||
bool skip;
|
||||
if (parameters.custom.GetBooleanParameter("SkipNativeMeshLoader", &skip) && skip)
|
||||
return Ternary_False;
|
||||
|
||||
return Ternary_Unknown;
|
||||
}
|
||||
@@ -66,7 +69,10 @@ namespace Nz
|
||||
Ternary CheckAnimated(Stream& stream, const SkeletalModelParameters& parameters)
|
||||
{
|
||||
NazaraUnused(stream);
|
||||
NazaraUnused(parameters);
|
||||
|
||||
bool skip;
|
||||
if (parameters.custom.GetBooleanParameter("SkipNativeAnimatedMeshLoader", &skip) && skip)
|
||||
return Ternary_False;
|
||||
|
||||
return Ternary_Unknown;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <Nazara/Utility/StaticMesh.hpp>
|
||||
#include <Nazara/Utility/Formats/MTLParser.hpp>
|
||||
#include <Nazara/Utility/Formats/OBJParser.hpp>
|
||||
#include <cstdio>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
@@ -32,7 +33,10 @@ namespace Nz
|
||||
Ternary Check(Stream& stream, const ModelParameters& parameters)
|
||||
{
|
||||
NazaraUnused(stream);
|
||||
NazaraUnused(parameters);
|
||||
|
||||
bool skip;
|
||||
if (parameters.custom.GetBooleanParameter("SkipNativeOBJLoader", &skip) && skip)
|
||||
return Ternary_False;
|
||||
|
||||
return Ternary_Unknown;
|
||||
}
|
||||
@@ -129,8 +133,12 @@ namespace Nz
|
||||
|
||||
bool Load(Model* model, Stream& stream, const ModelParameters& parameters)
|
||||
{
|
||||
int reservedVertexCount;
|
||||
if (!parameters.custom.GetIntegerParameter("NativeOBJLoader_VertexCount", &reservedVertexCount))
|
||||
reservedVertexCount = 100;
|
||||
|
||||
OBJParser parser(stream);
|
||||
if (!parser.Parse())
|
||||
if (!parser.Parse(reservedVertexCount))
|
||||
{
|
||||
NazaraError("OBJ parser failed");
|
||||
return false;
|
||||
|
||||
@@ -15,7 +15,10 @@ namespace Nz
|
||||
Ternary Check(Stream& stream, const MaterialParams& parameters)
|
||||
{
|
||||
NazaraUnused(stream);
|
||||
NazaraUnused(parameters);
|
||||
|
||||
bool skip;
|
||||
if (parameters.custom.GetBooleanParameter("SkipNativeTextureLoader", &skip) && skip)
|
||||
return Ternary_False;
|
||||
|
||||
return Ternary_Unknown;
|
||||
}
|
||||
|
||||
@@ -502,16 +502,17 @@ namespace Nz
|
||||
layers.clear();
|
||||
else
|
||||
{
|
||||
for (auto it = layers.begin(); it != layers.end(); ++it)
|
||||
for (auto it = layers.begin(); it != layers.end();)
|
||||
{
|
||||
Layer& layer = it->second;
|
||||
if (layer.clearCount++ >= 100)
|
||||
it = layers.erase(it);
|
||||
layers.erase(it++);
|
||||
else
|
||||
{
|
||||
layer.otherDrawables.clear();
|
||||
layer.transparentModels.clear();
|
||||
layer.transparentModelData.clear();
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,18 +49,21 @@ namespace Nz
|
||||
m_spriteBuffer.Reset(VertexDeclaration::Get(VertexLayout_XYZ_Color_UV), &m_vertexBuffer);
|
||||
}
|
||||
|
||||
bool ForwardRenderTechnique::Draw(const SceneData& sceneData) const
|
||||
void ForwardRenderTechnique::Clear(const SceneData& sceneData) const
|
||||
{
|
||||
NazaraAssert(sceneData.viewer, "Invalid viewer");
|
||||
|
||||
m_renderQueue.Sort(sceneData.viewer);
|
||||
|
||||
Renderer::Enable(RendererParameter_DepthBuffer, true);
|
||||
Renderer::Enable(RendererParameter_DepthWrite, true);
|
||||
Renderer::Clear(RendererBuffer_Depth);
|
||||
|
||||
if (sceneData.background)
|
||||
sceneData.background->Draw(sceneData.viewer);
|
||||
}
|
||||
|
||||
bool ForwardRenderTechnique::Draw(const SceneData& sceneData) const
|
||||
{
|
||||
NazaraAssert(sceneData.viewer, "Invalid viewer");
|
||||
|
||||
m_renderQueue.Sort(sceneData.viewer);
|
||||
|
||||
for (auto& pair : m_renderQueue.layers)
|
||||
{
|
||||
@@ -275,7 +278,7 @@ namespace Nz
|
||||
{
|
||||
// On ouvre le buffer en écriture
|
||||
BufferMapper<VertexBuffer> vertexMapper(m_spriteBuffer, BufferAccess_DiscardAndWrite);
|
||||
VertexStruct_XYZ_Color_UV* vertices = reinterpret_cast<VertexStruct_XYZ_Color_UV*>(vertexMapper.GetPointer());
|
||||
VertexStruct_XYZ_Color_UV* vertices = static_cast<VertexStruct_XYZ_Color_UV*>(vertexMapper.GetPointer());
|
||||
|
||||
unsigned int spriteCount = 0;
|
||||
unsigned int maxSpriteCount = std::min(s_maxQuads, m_spriteBuffer.GetVertexCount()/4);
|
||||
@@ -414,7 +417,7 @@ namespace Nz
|
||||
billboardCount -= renderedBillboardCount;
|
||||
|
||||
BufferMapper<VertexBuffer> vertexMapper(m_billboardPointBuffer, BufferAccess_DiscardAndWrite, 0, renderedBillboardCount*4);
|
||||
BillboardPoint* vertices = reinterpret_cast<BillboardPoint*>(vertexMapper.GetPointer());
|
||||
BillboardPoint* vertices = static_cast<BillboardPoint*>(vertexMapper.GetPointer());
|
||||
|
||||
for (unsigned int i = 0; i < renderedBillboardCount; ++i)
|
||||
{
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <Nazara/Graphics/RenderTechniques.hpp>
|
||||
#include <Nazara/Graphics/SkinningManager.hpp>
|
||||
#include <Nazara/Graphics/SkyboxBackground.hpp>
|
||||
#include <Nazara/Graphics/Sprite.hpp>
|
||||
#include <Nazara/Graphics/Formats/MeshLoader.hpp>
|
||||
#include <Nazara/Graphics/Formats/OBJLoader.hpp>
|
||||
#include <Nazara/Graphics/Formats/TextureLoader.hpp>
|
||||
@@ -90,6 +91,12 @@ namespace Nz
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Sprite::Initialize())
|
||||
{
|
||||
NazaraError("Failed to initialize sprites");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Loaders
|
||||
Loaders::RegisterOBJ();
|
||||
|
||||
@@ -189,6 +196,7 @@ namespace Nz
|
||||
ParticleController::Uninitialize();
|
||||
Material::Uninitialize();
|
||||
SkyboxBackground::Uninitialize();
|
||||
Sprite::Uninitialize();
|
||||
|
||||
NazaraNotice("Uninitialized: Graphics module");
|
||||
|
||||
|
||||
@@ -208,7 +208,7 @@ namespace Nz
|
||||
flags & ShaderFlags_TextureOverlay);
|
||||
list.SetParameter("TRANSFORM", m_transformEnabled);
|
||||
|
||||
list.SetParameter("FLAG_BILLBOARD", static_cast<bool>(flags & ShaderFlags_Billboard));
|
||||
list.SetParameter("FLAG_BILLBOARD", static_cast<bool>((flags & ShaderFlags_Billboard) != 0));
|
||||
list.SetParameter("FLAG_DEFERRED", static_cast<bool>((flags & ShaderFlags_Deferred) != 0));
|
||||
list.SetParameter("FLAG_INSTANCING", static_cast<bool>((flags & ShaderFlags_Instancing) != 0));
|
||||
list.SetParameter("FLAG_TEXTUREOVERLAY", static_cast<bool>((flags & ShaderFlags_TextureOverlay) != 0));
|
||||
|
||||
@@ -22,9 +22,11 @@ namespace Nz
|
||||
static VertexBufferRef s_vertexBuffer;
|
||||
}
|
||||
|
||||
SkyboxBackground::SkyboxBackground(TextureRef cubemapTexture)
|
||||
SkyboxBackground::SkyboxBackground(TextureRef cubemapTexture) :
|
||||
m_movementOffset(Vector3f::Zero()),
|
||||
m_movementScale(0.f)
|
||||
{
|
||||
m_sampler.SetWrapMode(SamplerWrap_Clamp); // Nécessaire pour ne pas voir les côtés
|
||||
m_sampler.SetWrapMode(SamplerWrap_Clamp); // We don't want to see any beam
|
||||
|
||||
SetTexture(std::move(cubemapTexture));
|
||||
}
|
||||
@@ -34,9 +36,24 @@ namespace Nz
|
||||
Matrix4f skyboxMatrix(viewer->GetViewMatrix());
|
||||
skyboxMatrix.SetTranslation(Vector3f::Zero());
|
||||
|
||||
float zNear = viewer->GetZNear();
|
||||
|
||||
constexpr float movementLimit = 0.05f;
|
||||
|
||||
Vector3f offset = (viewer->GetEyePosition() - m_movementOffset) * -m_movementScale;
|
||||
offset.x = Clamp(offset.x, -movementLimit, movementLimit);
|
||||
offset.y = Clamp(offset.y, -movementLimit, movementLimit);
|
||||
offset.z = Clamp(offset.z, -movementLimit, movementLimit);
|
||||
offset *= zNear;
|
||||
|
||||
Matrix4f world;
|
||||
world.MakeIdentity();
|
||||
world.SetScale(Vector3f(zNear));
|
||||
world.SetTranslation(offset);
|
||||
|
||||
Renderer::SetIndexBuffer(s_indexBuffer);
|
||||
Renderer::SetMatrix(MatrixType_View, skyboxMatrix);
|
||||
Renderer::SetMatrix(MatrixType_World, Matrix4f::Scale(Vector3f(viewer->GetZNear())));
|
||||
Renderer::SetMatrix(MatrixType_World, world);
|
||||
Renderer::SetRenderStates(s_renderStates);
|
||||
Renderer::SetShader(s_shader);
|
||||
Renderer::SetTexture(0, m_texture);
|
||||
|
||||
@@ -51,5 +51,21 @@ namespace Nz
|
||||
*texCoordPtr++ = m_textureCoords.GetCorner(RectCorner_RightBottom);
|
||||
}
|
||||
|
||||
bool Sprite::Initialize()
|
||||
{
|
||||
if (!SpriteLibrary::Initialize())
|
||||
{
|
||||
NazaraError("Failed to initialise library");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Sprite::Uninitialize()
|
||||
{
|
||||
SpriteLibrary::Uninitialize();
|
||||
}
|
||||
|
||||
SpriteLibrary::LibraryMap Sprite::s_library;
|
||||
}
|
||||
|
||||
@@ -33,13 +33,16 @@ namespace Nz
|
||||
|
||||
void TextSprite::Update(const AbstractTextDrawer& drawer)
|
||||
{
|
||||
m_atlases.clear();
|
||||
|
||||
CallOnExit clearOnFail([this]()
|
||||
{
|
||||
Clear();
|
||||
});
|
||||
|
||||
// Mark every atlas as unused...
|
||||
for (auto& pair : m_atlases)
|
||||
pair.second.used = false;
|
||||
|
||||
// ... until they are marked as used by the drawer
|
||||
unsigned int fontCount = drawer.GetFontCount();
|
||||
for (unsigned int i = 0; i < fontCount; ++i)
|
||||
{
|
||||
@@ -47,19 +50,38 @@ namespace Nz
|
||||
const AbstractAtlas* atlas = font->GetAtlas().get();
|
||||
NazaraAssert(atlas->GetStorage() & DataStorage_Hardware, "Font uses a non-hardware atlas which cannot be used by text sprites");
|
||||
|
||||
if (m_atlases.find(atlas) == m_atlases.end())
|
||||
auto it = m_atlases.find(atlas);
|
||||
if (it == m_atlases.end())
|
||||
{
|
||||
AtlasSlots& atlasSlots = m_atlases[atlas];
|
||||
it = m_atlases.insert(std::make_pair(atlas, AtlasSlots())).first;
|
||||
AtlasSlots& atlasSlots = it->second;
|
||||
|
||||
atlasSlots.clearSlot.Connect(atlas->OnAtlasCleared, this, &TextSprite::OnAtlasInvalidated);
|
||||
atlasSlots.layerChangeSlot.Connect(atlas->OnAtlasLayerChange, this, &TextSprite::OnAtlasLayerChange);
|
||||
atlasSlots.releaseSlot.Connect(atlas->OnAtlasRelease, this, &TextSprite::OnAtlasInvalidated);
|
||||
}
|
||||
|
||||
it->second.used = true;
|
||||
}
|
||||
|
||||
// Remove unused atlas slots
|
||||
auto atlasIt = m_atlases.begin();
|
||||
while (atlasIt != m_atlases.end())
|
||||
{
|
||||
if (!atlasIt->second.used)
|
||||
m_atlases.erase(atlasIt++);
|
||||
else
|
||||
++atlasIt;
|
||||
}
|
||||
|
||||
unsigned int glyphCount = drawer.GetGlyphCount();
|
||||
m_localVertices.resize(glyphCount * 4);
|
||||
|
||||
// Reset glyph count for every texture to zero
|
||||
for (auto& pair : m_renderInfos)
|
||||
pair.second.count = 0;
|
||||
|
||||
// Count glyph count for each texture
|
||||
Texture* lastTexture = nullptr;
|
||||
unsigned int* count = nullptr;
|
||||
for (unsigned int i = 0; i < glyphCount; ++i)
|
||||
@@ -69,25 +91,36 @@ namespace Nz
|
||||
Texture* texture = static_cast<Texture*>(glyph.atlas);
|
||||
if (lastTexture != texture)
|
||||
{
|
||||
auto pair = m_renderInfos.insert(std::make_pair(texture, RenderIndices{0U, 0U}));
|
||||
auto it = m_renderInfos.find(texture);
|
||||
if (it == m_renderInfos.end())
|
||||
it = m_renderInfos.insert(std::make_pair(texture, RenderIndices{0U, 0U})).first;
|
||||
|
||||
count = &pair.first->second.count;
|
||||
count = &it->second.count;
|
||||
lastTexture = texture;
|
||||
}
|
||||
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
// Attribution des indices
|
||||
// Attributes indices and reinitialize glyph count to zero to use it as a counter in the next loop
|
||||
// This is because the 1st glyph can use texture A, the 2nd glyph can use texture B and the 3th glyph C can use texture A again
|
||||
// so we need a counter to know where to write informations
|
||||
// also remove unused render infos
|
||||
unsigned int index = 0;
|
||||
for (auto& pair : m_renderInfos)
|
||||
auto infoIt = m_renderInfos.begin();
|
||||
while (infoIt != m_renderInfos.end())
|
||||
{
|
||||
RenderIndices& indices = pair.second;
|
||||
RenderIndices& indices = infoIt->second;
|
||||
if (indices.count == 0)
|
||||
m_renderInfos.erase(infoIt++); //< No glyph uses this texture, remove from indices
|
||||
else
|
||||
{
|
||||
indices.first = index;
|
||||
|
||||
indices.first = index;
|
||||
|
||||
index += indices.count;
|
||||
indices.count = 0; // On réinitialise count à zéro (on va s'en servir comme compteur dans la boucle suivante)
|
||||
index += indices.count;
|
||||
indices.count = 0;
|
||||
++infoIt;
|
||||
}
|
||||
}
|
||||
|
||||
lastTexture = nullptr;
|
||||
@@ -99,11 +132,11 @@ namespace Nz
|
||||
Texture* texture = static_cast<Texture*>(glyph.atlas);
|
||||
if (lastTexture != texture)
|
||||
{
|
||||
indices = &m_renderInfos[texture]; // On a changé de texture, on ajuste le pointeur
|
||||
indices = &m_renderInfos[texture]; //< We changed texture, adjust the pointer
|
||||
lastTexture = texture;
|
||||
}
|
||||
|
||||
// On commence par transformer les coordonnées entières en flottantes:
|
||||
// First, compute the uv coordinates from our atlas rect
|
||||
Vector2ui size(texture->GetSize());
|
||||
float invWidth = 1.f/size.x;
|
||||
float invHeight = 1.f/size.y;
|
||||
@@ -114,10 +147,11 @@ namespace Nz
|
||||
uvRect.width *= invWidth;
|
||||
uvRect.height *= invHeight;
|
||||
|
||||
static RectCorner normalCorners[4] = {RectCorner_LeftTop, RectCorner_RightTop, RectCorner_LeftBottom, RectCorner_RightBottom};
|
||||
static RectCorner flippedCorners[4] = {RectCorner_LeftBottom, RectCorner_LeftTop, RectCorner_RightBottom, RectCorner_RightTop};
|
||||
// Our glyph may be flipped in the atlas, to render it correctly we need to change the uv coordinates accordingly
|
||||
const RectCorner normalCorners[4] = {RectCorner_LeftTop, RectCorner_RightTop, RectCorner_LeftBottom, RectCorner_RightBottom};
|
||||
const RectCorner flippedCorners[4] = {RectCorner_LeftBottom, RectCorner_LeftTop, RectCorner_RightBottom, RectCorner_RightTop};
|
||||
|
||||
// Affectation des positions, couleurs, coordonnées de textures
|
||||
// Set the position, color and UV of our vertices
|
||||
for (unsigned int j = 0; j < 4; ++j)
|
||||
{
|
||||
// Remember that indices->count is a counter here, not a count value
|
||||
@@ -126,7 +160,7 @@ namespace Nz
|
||||
m_localVertices[indices->count*4 + j].uv.Set(uvRect.GetCorner((glyph.flipped) ? flippedCorners[j] : normalCorners[j]));
|
||||
}
|
||||
|
||||
// Et on passe au prochain sommet
|
||||
// Increment the counter, go to next glyph
|
||||
indices->count++;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user