Drawing a vertex buffer right after a call to DebugDrawer::Draw causes said vertex buffer to be corrupted.
Drawing the vertex buffer before DebugDrawer::Drawer does not show the issue.
Here is the test code (sorry for the *DampedString" function could have removed it)
#include <Nazara/Core/Clock.hpp>
#include <Nazara/Graphics.hpp>
#include <Nazara/Renderer.hpp>
#include <Nazara/Utility.hpp>
#include <iostream>
NzVector3f DampedString(const NzVector3f& currentPos, const NzVector3f& targetPos, float frametime, float springStrength = 3.f);
int main()
{
NzInitializer<NzGraphics> nazara;
if (!nazara)
{
std::cout << "Failed to initialize Nazara, see NazaraLog.log for further informations" << std::endl;
std::getchar();
return EXIT_FAILURE;
}
NzDebugDrawer::Initialize();
NzScene scene;
NzEulerAnglesf camAngles(0.f, -20.f, 0.f);
NzCamera camera;
camera.SetPosition(0.f, 0.25f, 2.f);
camera.SetRotation(camAngles);
camera.SetParent(scene);
camera.SetZFar(5000.f);
camera.SetZNear(0.1f);
NzVideoMode mode = NzVideoMode::GetDesktopMode();
mode.width *= 3.f/4.f;
mode.height *= 3.f/4.f;
NzString windowTitle = "Nazara Demo - DebugDrawer bug";
nzWindowStyleFlags style = nzWindowStyle_Default;
NzRenderWindow window(mode, windowTitle, style);
if (!window.IsValid())
{
std::cout << "Failed to create render window" << std::endl;
std::getchar();
return EXIT_FAILURE;
}
window.SetCursor(nzWindowCursor_None);
camera.SetTarget(window);
NzClock secondClock, updateClock;
unsigned int fps = 0;
bool smoothMovement = true;
NzVector3f targetPos = camera.GetPosition();
/// Le vertex buffer testé
std::array<float,75> data;
int index = 0;
NzVertexBuffer buf(NzVertexDeclaration::Get(nzVertexLayout_XYZ),25,nzBufferStorage_Hardware,nzBufferUsage_Static);
for(int y(0) ; y < 5 ; ++y)
for(int x(0) ; x < 5 ; ++x)
{
index = (x + 5 * y)*3;
//On génère une grille
data.at(index) = x * 100.f;
data.at(index + 1) = 0.f;
data.at(index + 2) = y * 100.f;
}
buf.Fill(data.data(),0,25);
//On affiche le contenu du vertex buffer
NzBufferMapper<NzVertexBuffer> mapper(buf,nzBufferAccess_ReadOnly);
const float* vertices = reinterpret_cast<const float*>(mapper.GetPointer());
std::cout<<"Avant Rendu---------------------"<<std::endl;
for(int i(0) ; i < 25 ; ++i)
std::cout<<vertices[i*3]<<" ; "<<vertices[i*3+1]<<" ; "<<vertices[i*3+2]<<std::endl;
mapper.Unmap();
while (window.IsOpen())
{
NzEvent event;
while (window.PollEvent(&event))
{
switch (event.type)
{
case nzEventType_MouseMoved:
{
float sensitivity = 0.3f;
camAngles.yaw = NzNormalizeAngle(camAngles.yaw - event.mouseMove.deltaX*sensitivity);
camAngles.pitch = NzClamp(camAngles.pitch - event.mouseMove.deltaY*sensitivity, -89.f, 89.f);
camera.SetRotation(camAngles);
NzMouse::SetPosition(window.GetWidth()/2, window.GetHeight()/2, window);
break;
}
case nzEventType_Quit:
window.Close();
break;
case nzEventType_KeyPressed:
if (event.key.code == NzKeyboard::Key::Escape)
window.Close();
else if (event.key.code == NzKeyboard::F1)
{
if (smoothMovement)
{
targetPos = camera.GetPosition();
smoothMovement = false;
}
else
smoothMovement = true;
}
break;
default:
break;
}
}
if (updateClock.GetMilliseconds() >= 1000/60)
{
float elapsedTime = updateClock.GetSeconds();
float cameraSpeed = 3.f * elapsedTime;
if (NzKeyboard::IsKeyPressed(NzKeyboard::Space))
cameraSpeed *= 2.f;
if (NzKeyboard::IsKeyPressed(NzKeyboard::Up) || NzKeyboard::IsKeyPressed(NzKeyboard::Z))
targetPos += camera.GetForward() * cameraSpeed;
if (NzKeyboard::IsKeyPressed(NzKeyboard::Down) || NzKeyboard::IsKeyPressed(NzKeyboard::S))
targetPos += camera.GetBackward() * cameraSpeed;
if (NzKeyboard::IsKeyPressed(NzKeyboard::Left) || NzKeyboard::IsKeyPressed(NzKeyboard::Q))
targetPos += camera.GetLeft() * cameraSpeed;
if (NzKeyboard::IsKeyPressed(NzKeyboard::Right) || NzKeyboard::IsKeyPressed(NzKeyboard::D))
targetPos += camera.GetRight() * cameraSpeed;
if (NzKeyboard::IsKeyPressed(NzKeyboard::LShift) || NzKeyboard::IsKeyPressed(NzKeyboard::RShift))
targetPos += NzVector3f::Up() * cameraSpeed;
if (NzKeyboard::IsKeyPressed(NzKeyboard::LControl) || NzKeyboard::IsKeyPressed(NzKeyboard::RControl))
targetPos += NzVector3f::Down() * cameraSpeed;
camera.SetPosition((smoothMovement) ? DampedString(camera.GetPosition(), targetPos, elapsedTime) : targetPos, nzCoordSys_Global);
updateClock.Restart();
}
camera.Activate();
scene.Update();
scene.Cull();
scene.UpdateVisible();
scene.Draw();
NzRenderer::SetMatrix(nzMatrixType_World, NzMatrix4f::Identity());
NzBoxf bbox(0.f,-1.f,0.f,1.f,1.f,1.f);
NzDebugDrawer::Draw(bbox);
//Attention, le fait de commenter NzDebugDrawer::Draw enlève la déclaration d'un shader, normal que rien ne s'affiche ici alors
NzRenderer::SetVertexBuffer(&buf);
NzRenderer::DrawPrimitives(nzPrimitiveMode_LineStrip,0,25);
window.Display();
fps++;
if (secondClock.GetMilliseconds() >= 1000)
{
window.SetTitle(windowTitle + " - " + NzString::Number(fps) + " FPS");
fps = 0;
secondClock.Restart();
}
}
//On affiche le contenu du vertex buffer
NzBufferMapper<NzVertexBuffer> mapper2(buf,nzBufferAccess_ReadOnly);
const float* vertices2 = reinterpret_cast<const float*>(mapper2.GetPointer());
std::cout<<"Apres Rendu-------------------------------"<<std::endl;
for(int i(0) ; i < 25 ; ++i)
std::cout<<vertices2[i*3]<<" ; "<<vertices2[i*3+1]<<" ; "<<vertices2[i*3+2]<<std::endl;
mapper2.Unmap();
NzDebugDrawer::Uninitialize();
return EXIT_SUCCESS;
}
NzVector3f DampedString(const NzVector3f& currentPos, const NzVector3f& targetPos, float frametime, float springStrength)
{
// Je ne suis pas l'auteur de cette fonction
// Je l'ai reprise du programme "Floaty Camera Example" et adaptée au C++
// Trouvé ici: http://nccastaff.bournemouth.ac.uk/jmacey/RobTheBloke/www/opengl_programming.html#4
// Tout le mérite revient à l'auteur (Qui me permettra ainsi d'améliorer les démos, voire même le moteur)
// calculate the displacement between the target and the current position
NzVector3f displacement = targetPos - currentPos;
// whats the distance between them?
float displacementLength = displacement.GetLength();
// Stops small position fluctuations (integration errors probably - since only using euler)
if (NzNumberEquals(displacementLength, 0.f))
return currentPos;
float invDisplacementLength = 1.f/displacementLength;
const float dampConstant = 0.000065f; // Something v.small to offset 1/ displacement length
// the strength of the spring increases the further away the camera is from the target.
float springMagitude = springStrength*displacementLength + dampConstant*invDisplacementLength;
// Normalise the displacement and scale by the spring magnitude
// and the amount of time passed
float scalar = std::min(invDisplacementLength * springMagitude * frametime, 1.f);
displacement *= scalar;
// move the camera a bit towards the target
return currentPos + displacement;
}