[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.
master
Quentin Bazin 2021-06-09 18:39:30 +02:00
parent 3b1855f10c
commit 475ff62018
6 changed files with 125 additions and 32 deletions

View 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));
}

View 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_

View File

@ -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())

View File

@ -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;

View File

@ -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

View File

@ -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_