[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);
|
||||
}
|
||||
|
||||
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 {
|
||||
return (!m_surroundingChunks[Chunk::West] || ((ClientChunk *)m_surroundingChunks[Chunk::West])->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 drawLayer(gk::RenderTarget &target, gk::RenderStates states, u8 layer) const;
|
||||
|
||||
const Dimension &dimension() const { return m_dimension; }
|
||||
|
||||
bool isReadyForMeshing() const { return m_isReadyForMeshing; }
|
||||
@ -65,8 +63,11 @@ class ClientChunk : public Chunk {
|
||||
|
||||
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; }
|
||||
|
||||
const gk::VertexBuffer &getVBO(u8 layer) const { return m_vbo[layer]; }
|
||||
|
||||
int debugTimesReceived = 0; // Only used by Minimap
|
||||
|
||||
static u32 chunkUpdatesPerSec;
|
||||
|
@ -40,7 +40,9 @@
|
||||
#include "TextureAtlas.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);
|
||||
}
|
||||
|
||||
for (u8 i = 0 ; i < ChunkMeshLayer::Count ; ++i) {
|
||||
for (auto &it : chunks) {
|
||||
states.transform = it.second;
|
||||
it.first->drawLayer(target, states, i);
|
||||
|
||||
it.first->setHasBeenDrawn(true);
|
||||
}
|
||||
}
|
||||
m_chunkRenderer.draw(target, states, chunks);
|
||||
|
||||
m_camera->setDPosition(cameraPos); // Restore the camera to its original position
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <gk/gl/Camera.hpp>
|
||||
|
||||
#include "ChunkMeshBuilder.hpp"
|
||||
#include "ChunkRenderer.hpp"
|
||||
#include "ClientChunk.hpp"
|
||||
#include "ClientScene.hpp"
|
||||
#include "Network.hpp"
|
||||
@ -102,6 +103,8 @@ class ClientWorld : public World, public gk::Drawable {
|
||||
mutable std::multimap<float, gk::Vector3i> m_chunksToMesh;
|
||||
|
||||
ChunkMeshBuilder m_chunkMeshBuilder{*this};
|
||||
|
||||
mutable ChunkRenderer m_chunkRenderer;
|
||||
};
|
||||
|
||||
#endif // CLIENTWORLD_HPP_
|
||||
|
Loading…
x
Reference in New Issue
Block a user