[ChunkRenderer] Added.
For now I just moved the code from ClientChunk::draw there, while trying to optimize a bit the OpenGL setup for each draw.
This commit is contained in:
parent
3b1855f10c
commit
475ff62018
68
source/client/graphics/ChunkRenderer.cpp
Normal file
68
source/client/graphics/ChunkRenderer.cpp
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* OpenMiner
|
||||||
|
*
|
||||||
|
* Copyright (C) 2018-2020 Unarelith, Quentin Bazin <openminer@unarelith.net>
|
||||||
|
* Copyright (C) 2019-2020 the OpenMiner contributors (see CONTRIBUTORS.md)
|
||||||
|
*
|
||||||
|
* This file is part of OpenMiner.
|
||||||
|
*
|
||||||
|
* OpenMiner is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* OpenMiner is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with OpenMiner; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
* =====================================================================================
|
||||||
|
*/
|
||||||
|
#include <gk/gl/GLCheck.hpp>
|
||||||
|
#include <gk/gl/Shader.hpp>
|
||||||
|
#include <gk/gl/Texture.hpp>
|
||||||
|
|
||||||
|
#include "ChunkRenderer.hpp"
|
||||||
|
#include "ClientChunk.hpp"
|
||||||
|
|
||||||
|
void ChunkRenderer::draw(gk::RenderTarget &target, gk::RenderStates states, const std::vector<std::pair<ClientChunk*, gk::Transform>> &chunks) {
|
||||||
|
if(Config::isWireframeModeEnabled) glCheck(glPolygonMode(GL_FRONT_AND_BACK, GL_LINE));
|
||||||
|
|
||||||
|
glCheck(glEnable(GL_DEPTH_TEST));
|
||||||
|
|
||||||
|
states.texture = &m_textureAtlas.texture();
|
||||||
|
target.beginSceneDraw(states);
|
||||||
|
|
||||||
|
for (u8 layer = 0 ; layer < ChunkMeshLayer::Count ; ++layer) {
|
||||||
|
// Disable mipmaps for specific layers
|
||||||
|
glCheck(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL,
|
||||||
|
(layer == ChunkMeshLayer::NoMipMap || layer == ChunkMeshLayer::Flora) ? 0 : Config::mipmapLevels));
|
||||||
|
|
||||||
|
if (layer == ChunkMeshLayer::Flora)
|
||||||
|
glCheck(glDisable(GL_CULL_FACE));
|
||||||
|
else
|
||||||
|
glCheck(glEnable(GL_CULL_FACE));
|
||||||
|
|
||||||
|
for (auto &it : chunks) {
|
||||||
|
states.shader->setUniform("u_modelMatrix", it.second);
|
||||||
|
|
||||||
|
std::size_t verticesCount = it.first->getVerticesCount(layer);
|
||||||
|
if (verticesCount == 0) continue;
|
||||||
|
|
||||||
|
target.drawVertexBuffer(it.first->getVBO(layer), GL_TRIANGLES, 0, (GLsizei)verticesCount, states);
|
||||||
|
|
||||||
|
it.first->setHasBeenDrawn(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
target.endSceneDraw(states);
|
||||||
|
|
||||||
|
if(Config::isWireframeModeEnabled) glCheck(glPolygonMode(GL_FRONT_AND_BACK, GL_FILL));
|
||||||
|
}
|
||||||
|
|
47
source/client/graphics/ChunkRenderer.hpp
Normal file
47
source/client/graphics/ChunkRenderer.hpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* =====================================================================================
|
||||||
|
*
|
||||||
|
* OpenMiner
|
||||||
|
*
|
||||||
|
* Copyright (C) 2018-2020 Unarelith, Quentin Bazin <openminer@unarelith.net>
|
||||||
|
* Copyright (C) 2019-2020 the OpenMiner contributors (see CONTRIBUTORS.md)
|
||||||
|
*
|
||||||
|
* This file is part of OpenMiner.
|
||||||
|
*
|
||||||
|
* OpenMiner is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* OpenMiner is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with OpenMiner; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
* =====================================================================================
|
||||||
|
*/
|
||||||
|
#ifndef CHUNKRENDERER_HPP_
|
||||||
|
#define CHUNKRENDERER_HPP_
|
||||||
|
|
||||||
|
#include <gk/gl/Transform.hpp>
|
||||||
|
#include <gk/gl/RenderTarget.hpp>
|
||||||
|
|
||||||
|
#include "TextureAtlas.hpp"
|
||||||
|
|
||||||
|
class ClientChunk;
|
||||||
|
|
||||||
|
class ChunkRenderer {
|
||||||
|
public:
|
||||||
|
ChunkRenderer(const TextureAtlas &textureAtlas) : m_textureAtlas(textureAtlas) {}
|
||||||
|
|
||||||
|
void draw(gk::RenderTarget &target, gk::RenderStates states, const std::vector<std::pair<ClientChunk*, gk::Transform>> &chunks);
|
||||||
|
|
||||||
|
public:
|
||||||
|
const TextureAtlas &m_textureAtlas;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CHUNKRENDERER_HPP_
|
@ -71,27 +71,6 @@ void ClientChunk::onBlockPlaced(int x, int y, int z, const Block &) {
|
|||||||
if(z == height - 1) addSurroundingChunkToProcess(Top);
|
if(z == height - 1) addSurroundingChunkToProcess(Top);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientChunk::drawLayer(gk::RenderTarget &target, gk::RenderStates states, u8 layer) const {
|
|
||||||
if (m_verticesCount.size() <= layer || m_verticesCount.at(layer) == 0) return;
|
|
||||||
|
|
||||||
states.texture = &m_textureAtlas.texture();
|
|
||||||
|
|
||||||
if (layer == ChunkMeshLayer::Flora || (layer == ChunkMeshLayer::Liquid && areAllNeighboursInitialized()))
|
|
||||||
glCheck(glDisable(GL_CULL_FACE));
|
|
||||||
else
|
|
||||||
glCheck(glEnable(GL_CULL_FACE));
|
|
||||||
|
|
||||||
gk::Texture::bind(states.texture);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, (layer == ChunkMeshLayer::NoMipMap || layer == ChunkMeshLayer::Flora) ? 0 : Config::mipmapLevels);
|
|
||||||
gk::Texture::bind(nullptr);
|
|
||||||
|
|
||||||
glCheck(glEnable(GL_DEPTH_TEST));
|
|
||||||
|
|
||||||
if(Config::isWireframeModeEnabled) glCheck(glPolygonMode(GL_FRONT_AND_BACK, GL_LINE));
|
|
||||||
target.draw(m_vbo.at(layer), GL_TRIANGLES, 0, (GLsizei)m_verticesCount.at(layer), states);
|
|
||||||
if(Config::isWireframeModeEnabled) glCheck(glPolygonMode(GL_FRONT_AND_BACK, GL_FILL));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ClientChunk::areAllNeighboursTooFar() const {
|
bool ClientChunk::areAllNeighboursTooFar() const {
|
||||||
return (!m_surroundingChunks[Chunk::West] || ((ClientChunk *)m_surroundingChunks[Chunk::West])->isTooFar())
|
return (!m_surroundingChunks[Chunk::West] || ((ClientChunk *)m_surroundingChunks[Chunk::West])->isTooFar())
|
||||||
&& (!m_surroundingChunks[Chunk::East] || ((ClientChunk *)m_surroundingChunks[Chunk::East])->isTooFar())
|
&& (!m_surroundingChunks[Chunk::East] || ((ClientChunk *)m_surroundingChunks[Chunk::East])->isTooFar())
|
||||||
|
@ -48,8 +48,6 @@ class ClientChunk : public Chunk {
|
|||||||
|
|
||||||
void onBlockPlaced(int x, int y, int z, const Block &block) override;
|
void onBlockPlaced(int x, int y, int z, const Block &block) override;
|
||||||
|
|
||||||
void drawLayer(gk::RenderTarget &target, gk::RenderStates states, u8 layer) const;
|
|
||||||
|
|
||||||
const Dimension &dimension() const { return m_dimension; }
|
const Dimension &dimension() const { return m_dimension; }
|
||||||
|
|
||||||
bool isReadyForMeshing() const { return m_isReadyForMeshing; }
|
bool isReadyForMeshing() const { return m_isReadyForMeshing; }
|
||||||
@ -65,8 +63,11 @@ class ClientChunk : public Chunk {
|
|||||||
|
|
||||||
const gk::VertexBuffer &getVertexBuffer(u8 layer) { return m_vbo[layer]; }
|
const gk::VertexBuffer &getVertexBuffer(u8 layer) { return m_vbo[layer]; }
|
||||||
|
|
||||||
|
std::size_t getVerticesCount(u8 layer) const { return m_verticesCount[layer]; }
|
||||||
void setVerticesCount(u8 layer, std::size_t count) { m_verticesCount[layer] = count; }
|
void setVerticesCount(u8 layer, std::size_t count) { m_verticesCount[layer] = count; }
|
||||||
|
|
||||||
|
const gk::VertexBuffer &getVBO(u8 layer) const { return m_vbo[layer]; }
|
||||||
|
|
||||||
int debugTimesReceived = 0; // Only used by Minimap
|
int debugTimesReceived = 0; // Only used by Minimap
|
||||||
|
|
||||||
static u32 chunkUpdatesPerSec;
|
static u32 chunkUpdatesPerSec;
|
||||||
|
@ -40,7 +40,9 @@
|
|||||||
#include "TextureAtlas.hpp"
|
#include "TextureAtlas.hpp"
|
||||||
#include "World.hpp"
|
#include "World.hpp"
|
||||||
|
|
||||||
ClientWorld::ClientWorld() : m_textureAtlas(gk::ResourceHandler::getInstance().get<TextureAtlas>("atlas-blocks"))
|
ClientWorld::ClientWorld()
|
||||||
|
: m_textureAtlas(gk::ResourceHandler::getInstance().get<TextureAtlas>("atlas-blocks")),
|
||||||
|
m_chunkRenderer(m_textureAtlas)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -345,14 +347,7 @@ void ClientWorld::draw(gk::RenderTarget &target, gk::RenderStates states) const
|
|||||||
chunks.emplace_back(it.second.get(), tf);
|
chunks.emplace_back(it.second.get(), tf);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u8 i = 0 ; i < ChunkMeshLayer::Count ; ++i) {
|
m_chunkRenderer.draw(target, states, chunks);
|
||||||
for (auto &it : chunks) {
|
|
||||||
states.transform = it.second;
|
|
||||||
it.first->drawLayer(target, states, i);
|
|
||||||
|
|
||||||
it.first->setHasBeenDrawn(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_camera->setDPosition(cameraPos); // Restore the camera to its original position
|
m_camera->setDPosition(cameraPos); // Restore the camera to its original position
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include <gk/gl/Camera.hpp>
|
#include <gk/gl/Camera.hpp>
|
||||||
|
|
||||||
#include "ChunkMeshBuilder.hpp"
|
#include "ChunkMeshBuilder.hpp"
|
||||||
|
#include "ChunkRenderer.hpp"
|
||||||
#include "ClientChunk.hpp"
|
#include "ClientChunk.hpp"
|
||||||
#include "ClientScene.hpp"
|
#include "ClientScene.hpp"
|
||||||
#include "Network.hpp"
|
#include "Network.hpp"
|
||||||
@ -102,6 +103,8 @@ class ClientWorld : public World, public gk::Drawable {
|
|||||||
mutable std::multimap<float, gk::Vector3i> m_chunksToMesh;
|
mutable std::multimap<float, gk::Vector3i> m_chunksToMesh;
|
||||||
|
|
||||||
ChunkMeshBuilder m_chunkMeshBuilder{*this};
|
ChunkMeshBuilder m_chunkMeshBuilder{*this};
|
||||||
|
|
||||||
|
mutable ChunkRenderer m_chunkRenderer;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CLIENTWORLD_HPP_
|
#endif // CLIENTWORLD_HPP_
|
||||||
|
Loading…
x
Reference in New Issue
Block a user