push progress (won't compile)
This commit is contained in:
@@ -468,7 +468,7 @@ set (_noggit_revision_script_file "${CMAKE_SOURCE_DIR}/cmake/GenerateRevision.cm
|
||||
include_directories ("${_noggit_revision_output_dir}")
|
||||
|
||||
find_package (Git)
|
||||
if (GIT_FOUND)
|
||||
if (FALSE) # GIT_FOUND
|
||||
add_custom_target (update_git_revision
|
||||
ALL
|
||||
DEPENDS "${_noggit_revision_template_file}"
|
||||
|
||||
@@ -194,7 +194,7 @@ void main()
|
||||
lDiffuse = DiffuseColor_FogStart.xyz * nDotL;
|
||||
|
||||
vec3 reflection = normalize(normalized_normal - (-LightDir_FogRate.xyz));
|
||||
float specularFactor = clamp(dot(reflection, normalize(camera - vary_position)), 0.0, 1.0);
|
||||
float specularFactor = max(dot(reflection, normalize(camera - vary_position)), 0.0);
|
||||
|
||||
// blend textures
|
||||
out_color = mix(vec4(1.0, 1.0, 1.0, 1.0), texture_blend(), int(instances[instanceID].ChunkHoles_DrawImpass_TexLayerCount_CantPaint.b > 0));
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#include <noggit/ChunkWater.hpp>
|
||||
#include <noggit/TileWater.hpp>
|
||||
#include <noggit/liquid_layer.hpp>
|
||||
#include <noggit/MPQ.h>
|
||||
#include <noggit/MapChunk.h>
|
||||
#include <noggit/Misc.h>
|
||||
|
||||
ChunkWater::ChunkWater(float x, float z, bool use_mclq_green_lava)
|
||||
ChunkWater::ChunkWater(MapChunk* chunk, TileWater* water_tile, float x, float z, bool use_mclq_green_lava)
|
||||
: xbase(x)
|
||||
, zbase(z)
|
||||
, vmin(x, 0.f, z)
|
||||
, vmax(x + CHUNKSIZE, 0.f, z + CHUNKSIZE)
|
||||
, _use_mclq_green_lava(use_mclq_green_lava)
|
||||
, _chunk(chunk)
|
||||
, _water_tile(water_tile)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -41,10 +44,10 @@ void ChunkWater::from_mclq(std::vector<mclq>& layers)
|
||||
|
||||
switch (mclq_liquid_type)
|
||||
{
|
||||
case 1:_layers.emplace_back(pos, liquid, 2); break;
|
||||
case 3:_layers.emplace_back(pos, liquid, 4); break;
|
||||
case 4:_layers.emplace_back(pos, liquid, 1); break;
|
||||
case 6:_layers.emplace_back(pos, liquid, (_use_mclq_green_lava ? 15 : 3)); break;
|
||||
case 1:_layers.emplace_back(this, pos, liquid, 2); break;
|
||||
case 3:_layers.emplace_back(this, pos, liquid, 4); break;
|
||||
case 4:_layers.emplace_back(this, pos, liquid, 1); break;
|
||||
case 6:_layers.emplace_back(this, pos, liquid, (_use_mclq_green_lava ? 15 : 3)); break;
|
||||
default:
|
||||
LogError << "Invalid/unhandled MCLQ liquid type" << std::endl;
|
||||
break;
|
||||
@@ -90,7 +93,7 @@ void ChunkWater::fromFile(MPQFile &f, size_t basePos)
|
||||
}
|
||||
|
||||
math::vector_3d pos(xbase, 0.0f, zbase);
|
||||
_layers.emplace_back(f, basePos, pos, info, infoMask);
|
||||
_layers.emplace_back(this, f, basePos, pos, info, infoMask);
|
||||
}
|
||||
|
||||
update_layers();
|
||||
@@ -253,7 +256,7 @@ void ChunkWater::paintLiquid( math::vector_3d const& pos
|
||||
|
||||
if (!layer_found)
|
||||
{
|
||||
liquid_layer layer(math::vector_3d(xbase, 0.0f, zbase), pos.y, liquid_id);
|
||||
liquid_layer layer(this, math::vector_3d(xbase, 0.0f, zbase), pos.y, liquid_id);
|
||||
copy_height_to_layer(layer, pos, radius);
|
||||
_layers.push_back(layer);
|
||||
}
|
||||
@@ -292,7 +295,7 @@ void ChunkWater::paintLiquid( math::vector_3d const& pos
|
||||
}
|
||||
else
|
||||
{
|
||||
liquid_layer layer(math::vector_3d(xbase, 0.0f, zbase), pos.y, liquid_id);
|
||||
liquid_layer layer(this, math::vector_3d(xbase, 0.0f, zbase), pos.y, liquid_id);
|
||||
layer.paintLiquid(pos, radius, true, angle, orientation, lock, origin, override_height, chunk, opacity_factor);
|
||||
_layers.push_back(layer);
|
||||
}
|
||||
|
||||
@@ -14,12 +14,13 @@
|
||||
class MPQFile;
|
||||
class sExtendableArray;
|
||||
class MapChunk;
|
||||
class TileWater;
|
||||
|
||||
class ChunkWater
|
||||
{
|
||||
public:
|
||||
ChunkWater() = delete;
|
||||
explicit ChunkWater(float x, float z, bool use_mclq_green_lava);
|
||||
explicit ChunkWater(MapChunk* chunk, TileWater* water_tile, float x, float z, bool use_mclq_green_lava);
|
||||
|
||||
ChunkWater (ChunkWater const&) = delete;
|
||||
ChunkWater (ChunkWater&&) = delete;
|
||||
@@ -75,6 +76,9 @@ public:
|
||||
|
||||
void unload();
|
||||
|
||||
MapChunk* getChunk() { return _chunk; };
|
||||
TileWater* getWaterTile() { return _water_tile; };
|
||||
|
||||
float xbase, zbase;
|
||||
|
||||
private:
|
||||
@@ -91,4 +95,6 @@ private:
|
||||
MH2O_Render Render;
|
||||
|
||||
std::vector<liquid_layer> _layers;
|
||||
MapChunk* _chunk;
|
||||
TileWater* _water_tile;
|
||||
};
|
||||
|
||||
@@ -36,29 +36,29 @@ public:
|
||||
class Record
|
||||
{
|
||||
public:
|
||||
float& getFloat(size_t field)
|
||||
const float& getFloat(size_t field) const
|
||||
{
|
||||
assert(field < file.fieldCount);
|
||||
return *reinterpret_cast<float*>(offset + field * 4);
|
||||
}
|
||||
unsigned int& getUInt(size_t field)
|
||||
const unsigned int& getUInt(size_t field) const
|
||||
{
|
||||
assert(field < file.fieldCount);
|
||||
return *reinterpret_cast<unsigned int*>(offset + field * 4);
|
||||
}
|
||||
int& getInt(size_t field)
|
||||
const int& getInt(size_t field) const
|
||||
{
|
||||
assert(field < file.fieldCount);
|
||||
return *reinterpret_cast<int*>(offset + field * 4);
|
||||
}
|
||||
char *getString(size_t field)
|
||||
const char *getString(size_t field) const
|
||||
{
|
||||
assert(field < file.fieldCount);
|
||||
size_t stringOffset = getUInt(field);
|
||||
assert(stringOffset < file.stringSize);
|
||||
return file.stringTable.data() + stringOffset;
|
||||
}
|
||||
char *getLocalizedString(size_t field, int locale = -1)
|
||||
const char *getLocalizedString(size_t field, int locale = -1) const
|
||||
{
|
||||
int loc = locale;
|
||||
if (locale == -1)
|
||||
|
||||
136
src/noggit/LiquidTextureManager.cpp
Normal file
136
src/noggit/LiquidTextureManager.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#include "LiquidTextureManager.hpp"
|
||||
|
||||
#include <opengl/context.inl>
|
||||
#include <noggit/DBC.h>
|
||||
#include <boost/format.hpp>
|
||||
|
||||
|
||||
LiquidTextureManager::LiquidTextureManager(noggit::NoggitRenderContext context)
|
||||
: _context(context)
|
||||
{
|
||||
}
|
||||
|
||||
void LiquidTextureManager::upload()
|
||||
{
|
||||
if (_uploaded)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < gLiquidTypeDB.getRecordCount(); ++i)
|
||||
{
|
||||
const DBCFile::Record record = gLiquidTypeDB.getRecord(i);
|
||||
unsigned liquid_type_id = record.getInt(LiquidTypeDB::ID);
|
||||
int type = record.getInt(LiquidTypeDB::Type);
|
||||
math::vector_2d anim = {record.getFloat(LiquidTypeDB::AnimationX), record.getFloat(LiquidTypeDB::AnimationY)};
|
||||
int shader_type = record.getInt(LiquidTypeDB::ShaderType);
|
||||
|
||||
std::string filename;
|
||||
|
||||
// procedural water hack fix
|
||||
if (shader_type == 3)
|
||||
{
|
||||
filename = "XTextures\\river\\lake_a.%d.blp";
|
||||
// default param for water
|
||||
anim = math::vector_2d(1.f, 0.f);
|
||||
}
|
||||
else
|
||||
[[likely]]
|
||||
{
|
||||
// TODO: why even try-catching there? empty string? BARE_EXCEPT_INV
|
||||
try
|
||||
{
|
||||
filename = record.getString(LiquidTypeDB::TextureFilenames);
|
||||
}
|
||||
catch (...) // fallback for malformed DBC
|
||||
{
|
||||
filename = "XTextures\\river\\lake_a.%d.blp";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GLuint array = 0;
|
||||
gl.genTextures(1, &array);
|
||||
gl.bindTexture(GL_TEXTURE_2D_ARRAY, array);
|
||||
|
||||
// init 2D texture array
|
||||
// loading a texture is required to get its dimensions and format
|
||||
blp_texture tex(boost::str(boost::format(filename) % i), _context);
|
||||
tex.finishLoading();
|
||||
|
||||
int width_ = tex.width();
|
||||
int height_ = tex.height();
|
||||
const unsigned mip_level = tex.mip_level();
|
||||
const bool is_uncompressed = !tex.compression_format();
|
||||
|
||||
constexpr unsigned N_FRAMES = 30;
|
||||
|
||||
if (is_uncompressed)
|
||||
{
|
||||
for (int j = 0; j < mip_level; ++j)
|
||||
{
|
||||
gl.texImage3D(GL_TEXTURE_2D_ARRAY, j, GL_RGBA8, width_, height_, N_FRAMES, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
nullptr);
|
||||
|
||||
width_ = std::max(width_ >> 1, 1);
|
||||
height_ = std::max(height_ >> 1, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
[[likely]]
|
||||
{
|
||||
for (int j = 0; j < mip_level; ++j)
|
||||
{
|
||||
gl.compressedTexImage3D(GL_TEXTURE_2D_ARRAY, j, tex.compression_format().get(), width_, height_, N_FRAMES,
|
||||
0, tex.compressed_data()[j].size() * N_FRAMES, nullptr);
|
||||
|
||||
width_ = std::max(width_ >> 1, 1);
|
||||
height_ = std::max(height_ >> 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, mip_level - 1);
|
||||
gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
for (int j = 0; j < N_FRAMES; ++j)
|
||||
{
|
||||
blp_texture tex_frame(boost::str(boost::format(filename) % j), _context);
|
||||
tex_frame.finishLoading();
|
||||
|
||||
// error checking
|
||||
if (tex_frame.height() != tex.height() || tex_frame.width() != tex.width())
|
||||
LogError << "Liquid texture resolution mismatch. Make sure all textures within a liquid type use identical format." << std::endl;
|
||||
else if (tex_frame.compression_format() != tex.compression_format())
|
||||
LogError << "Liquid texture compression mismatch. Make sure all textures within a liquid type use identical format." << std::endl;
|
||||
else if (tex_frame.mip_level() != tex.mip_level())
|
||||
LogError << "Liquid texture mip level mismatch. Make sure all textures within a liquid type use identical format." << std::endl;
|
||||
else
|
||||
[[likely]]
|
||||
{
|
||||
tex_frame.uploadToArray(j);
|
||||
continue;
|
||||
}
|
||||
|
||||
// use the first frame, the texture will end-up non-animated or skipping certain frames,
|
||||
// but that avoids OpenGL errors.
|
||||
tex.uploadToArray(j);
|
||||
}
|
||||
|
||||
_texture_frames_map[liquid_type_id] = std::make_tuple(array, anim, type);
|
||||
}
|
||||
|
||||
_uploaded = true;
|
||||
}
|
||||
|
||||
void LiquidTextureManager::unload()
|
||||
{
|
||||
for (auto& pair : _texture_frames_map)
|
||||
{
|
||||
GLuint array = std::get<0>(pair.second);
|
||||
gl.deleteTextures(1, &array);
|
||||
}
|
||||
|
||||
_texture_frames_map.clear();
|
||||
_uploaded = false;
|
||||
}
|
||||
36
src/noggit/LiquidTextureManager.hpp
Normal file
36
src/noggit/LiquidTextureManager.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
|
||||
|
||||
#ifndef NOGGIT_LIQUIDTEXTUREMANAGER_HPP
|
||||
#define NOGGIT_LIQUIDTEXTUREMANAGER_HPP
|
||||
|
||||
#include <noggit/TextureManager.h>
|
||||
#include <noggit/ContextObject.hpp>
|
||||
#include <math/vector_2d.hpp>
|
||||
#include <opengl/context.hpp>
|
||||
#include <opengl/scoped.hpp>
|
||||
#include <external/tsl/robin_map.h>
|
||||
|
||||
#include <tuple>
|
||||
|
||||
class LiquidTextureManager
|
||||
{
|
||||
public:
|
||||
|
||||
explicit LiquidTextureManager(noggit::NoggitRenderContext context);
|
||||
LiquidTextureManager() = delete;
|
||||
|
||||
void upload();
|
||||
void unload();
|
||||
|
||||
tsl::robin_map<unsigned, std::tuple<GLuint, math::vector_2d, int>> const& getTextureFrames() { return _texture_frames_map; };
|
||||
|
||||
private:
|
||||
bool _uploaded = false;
|
||||
|
||||
// liquidTypeRecID : (array, (animation_x, animation_y), liquid_type)
|
||||
tsl::robin_map<unsigned, std::tuple<GLuint, math::vector_2d, int>> _texture_frames_map;
|
||||
|
||||
noggit::NoggitRenderContext _context;
|
||||
};
|
||||
|
||||
#endif //NOGGIT_LIQUIDTEXTUREMANAGER_HPP
|
||||
@@ -153,6 +153,7 @@ public:
|
||||
void unload();
|
||||
|
||||
GLuint getAlphamapTextureHandle() { return _alphamap_tex; };
|
||||
World* getWorld() { return _world; };
|
||||
|
||||
private:
|
||||
|
||||
@@ -208,7 +209,6 @@ private:
|
||||
std::vector<uint32_t> uids;
|
||||
|
||||
std::unique_ptr<MapChunk> mChunks[16][16];
|
||||
std::vector<TileWater*> chunksLiquids; //map chunks liquids for old style water render!!! (Not MH2O)
|
||||
|
||||
bool _load_models;
|
||||
World* _world;
|
||||
|
||||
@@ -2522,7 +2522,7 @@ auto MapView::setBrushTexture(QImage const* img) -> void
|
||||
|
||||
makeCurrent();
|
||||
opengl::context::scoped_setter const _{gl, context()};
|
||||
opengl::texture::set_active_texture(5);
|
||||
opengl::texture::set_active_texture(4);
|
||||
_texBrush->bind();
|
||||
gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex.data());
|
||||
gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
@@ -3899,7 +3899,7 @@ void MapView::update_cursor_pos()
|
||||
{
|
||||
static bool buffer_switch = false;
|
||||
|
||||
if (terrainMode != editing_mode::holes)
|
||||
if (false && terrainMode != editing_mode::holes) // figure out why this does not work on every hardware.
|
||||
{
|
||||
float mx = _last_mouse_pos.x(), mz = _last_mouse_pos.y();
|
||||
|
||||
|
||||
@@ -32,6 +32,14 @@ void TextureManager::unload_all(noggit::NoggitRenderContext context)
|
||||
}
|
||||
, context
|
||||
);
|
||||
|
||||
// cleanup texture arrays
|
||||
auto& arrays_for_context = _tex_arrays[context];
|
||||
|
||||
for (auto& pair : arrays_for_context)
|
||||
{
|
||||
gl.deleteTextures(pair.second.arrays.size(), pair.second.arrays.data());
|
||||
}
|
||||
}
|
||||
|
||||
TexArrayParams& TextureManager::get_tex_array(int width, int height, int mip_level,
|
||||
@@ -161,6 +169,39 @@ void blp_texture::bind()
|
||||
gl.bindTexture(GL_TEXTURE_2D_ARRAY, _texture_array);
|
||||
}
|
||||
|
||||
void blp_texture::uploadToArray(unsigned layer)
|
||||
{
|
||||
int width = _width, height = _height;
|
||||
|
||||
if (!_compression_format)
|
||||
{
|
||||
|
||||
for (int i = 0; i < _data.size(); ++i)
|
||||
{
|
||||
gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, i, 0, 0, layer, width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE, _data[i].data());
|
||||
|
||||
width = std::max(width >> 1, 1);
|
||||
height = std::max(height >> 1, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < _compressed_data.size(); ++i)
|
||||
{
|
||||
gl.compressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, i, 0, 0, layer, width, height, 1, _compression_format.get(), _compressed_data[i].size(), _compressed_data[i].data());
|
||||
|
||||
width = std::max(width >> 1, 1);
|
||||
height = std::max(height >> 1, 1);
|
||||
}
|
||||
|
||||
gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, _compressed_data.size() - 1);
|
||||
_compressed_data.clear();
|
||||
}
|
||||
|
||||
gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
|
||||
void blp_texture::upload()
|
||||
{
|
||||
if (!finished)
|
||||
|
||||
@@ -57,11 +57,17 @@ struct blp_texture : public opengl::texture, AsyncObject
|
||||
|
||||
void bind();
|
||||
void upload();
|
||||
void uploadToArray(unsigned layer);
|
||||
void unload();
|
||||
bool is_uploaded() { return _uploaded; };
|
||||
GLuint texture_array() { return _texture_array; };
|
||||
int array_index() { return _array_index; };
|
||||
bool is_specular() { return _is_specular; };
|
||||
unsigned mip_level() { return !_compression_format ? _data.size() : _compressed_data.size(); };
|
||||
|
||||
std::map<int, std::vector<uint32_t>>& data() { return _data;};
|
||||
std::map<int, std::vector<uint8_t>>& compressed_data() { return _compressed_data; };
|
||||
boost::optional<GLint> const& compression_format() { return _compression_format; };
|
||||
|
||||
noggit::NoggitRenderContext getContext() { return _context; };
|
||||
|
||||
|
||||
@@ -5,17 +5,25 @@
|
||||
#include <noggit/MapTile.h>
|
||||
#include <noggit/Misc.h>
|
||||
#include <noggit/TileWater.hpp>
|
||||
#include <noggit/liquid_layer.hpp>
|
||||
#include <stdexcept>
|
||||
#include <noggit/World.h>
|
||||
#include <noggit/LiquidTextureManager.hpp>
|
||||
|
||||
TileWater::TileWater(MapTile *pTile, float pXbase, float pZbase, bool use_mclq_green_lava)
|
||||
: tile(pTile)
|
||||
, xbase(pXbase)
|
||||
, zbase(pZbase)
|
||||
{
|
||||
// by default we allocate space only for one liquid layer
|
||||
_chunk_instances.reserve(256);
|
||||
_chunk_layer_refs.reserve(256);
|
||||
|
||||
for (int z = 0; z < 16; ++z)
|
||||
{
|
||||
for (int x = 0; x < 16; ++x)
|
||||
{
|
||||
chunks[z][x] = std::make_unique<ChunkWater> (xbase + CHUNKSIZE * x, zbase + CHUNKSIZE * z, use_mclq_green_lava);
|
||||
chunks[z][x] = std::make_unique<ChunkWater> (tile->getChunk(z, x), this, xbase + CHUNKSIZE * x, zbase + CHUNKSIZE * z, use_mclq_green_lava);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -153,3 +161,65 @@ int TileWater::getType(size_t layer)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TileWater::registerChunkLayer(liquid_layer* layer)
|
||||
{
|
||||
if (_chunk_layer_refs.capacity() == _chunk_layer_refs.size())
|
||||
{
|
||||
_chunk_layer_refs.reserve(_chunk_layer_refs.capacity() + 256);
|
||||
}
|
||||
|
||||
if (_chunk_instances.capacity() == _chunk_instances.size())
|
||||
{
|
||||
_chunk_instances.reserve(_chunk_instances.capacity() + 256);
|
||||
}
|
||||
|
||||
_chunk_layer_refs.emplace_back(layer);
|
||||
|
||||
opengl::LiquidChunkInstanceDataUniformBlock chunk_instance{};
|
||||
MapChunk* chunk = layer->getChunk()->getChunk();
|
||||
chunk_instance.BaseHeight_ChunkXY_Pad1[1] = chunk->mt->xbase + (chunk->px * CHUNKSIZE);
|
||||
chunk_instance.BaseHeight_ChunkXY_Pad1[2] = chunk->mt->zbase + (chunk->py * CHUNKSIZE);
|
||||
|
||||
_chunk_instances.push_back(chunk_instance);
|
||||
|
||||
}
|
||||
|
||||
void TileWater::unregisterChunkLayer(liquid_layer* layer)
|
||||
{
|
||||
auto it = std::find(_chunk_layer_refs.begin(), _chunk_layer_refs.end(), layer);
|
||||
|
||||
if (it != _chunk_layer_refs.end())
|
||||
{
|
||||
|
||||
int index = it - _chunk_layer_refs.begin();
|
||||
_chunk_layer_refs.erase(it);
|
||||
_chunk_instances.erase(_chunk_instances.begin() + index);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::logic_error("Tried unregistering already freed liquid chunk");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void TileWater::updateChunkLayer(liquid_layer* layer)
|
||||
{
|
||||
auto it = std::find(_chunk_layer_refs.begin(), _chunk_layer_refs.end(), layer);
|
||||
|
||||
if (it != _chunk_layer_refs.end())
|
||||
{
|
||||
int index = it - _chunk_layer_refs.begin();
|
||||
|
||||
opengl::LiquidChunkInstanceDataUniformBlock& instance = _chunk_instances[index];
|
||||
auto const& texture_frames = tile->getWorld()->getLiquidTextureManager()->getTextureFrames();
|
||||
std::tuple<GLuint, math::vector_2d, int> const& lq_layer_texture_params = texture_frames.at(layer->liquidID());
|
||||
|
||||
instance.TextureArray_Pad3[0] = std::get<0>(lq_layer_texture_params);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::logic_error("Tried updating non-existing liquid chunk");
|
||||
}
|
||||
}
|
||||
@@ -7,10 +7,14 @@
|
||||
#include <noggit/MPQ.h>
|
||||
#include <noggit/MapHeaders.h>
|
||||
#include <noggit/tool_enums.hpp>
|
||||
#include <opengl/context.hpp>
|
||||
#include <opengl/types.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
class MapTile;
|
||||
class liquid_layer;
|
||||
class sExtendableArray;
|
||||
|
||||
class TileWater
|
||||
@@ -41,10 +45,16 @@ public:
|
||||
void setType(int type, size_t layer);
|
||||
int getType(size_t layer);
|
||||
|
||||
void registerChunkLayer(liquid_layer* layer);
|
||||
void unregisterChunkLayer(liquid_layer* layer);
|
||||
void updateChunkLayer(liquid_layer* layer);
|
||||
|
||||
private:
|
||||
|
||||
MapTile *tile;
|
||||
std::unique_ptr<ChunkWater> chunks[16][16];
|
||||
std::vector<opengl::LiquidChunkInstanceDataUniformBlock> _chunk_instances;
|
||||
std::vector<liquid_layer*> _chunk_layer_refs;
|
||||
|
||||
float xbase;
|
||||
float zbase;
|
||||
|
||||
@@ -124,6 +124,7 @@ World::World(const std::string& name, int map_id, noggit::NoggitRenderContext co
|
||||
, _settings (new QSettings())
|
||||
, _view_distance(_settings->value ("view_distance", 1000.f).toFloat())
|
||||
, _context(context)
|
||||
, _liquid_texture_manager(context)
|
||||
{
|
||||
LogDebug << "Loading world \"" << name << "\"." << std::endl;
|
||||
}
|
||||
@@ -873,6 +874,8 @@ void World::initShaders()
|
||||
);
|
||||
}
|
||||
|
||||
_liquid_texture_manager.upload();
|
||||
|
||||
{
|
||||
opengl::scoped::use_program m2_shader {*_m2_program.get()};
|
||||
m2_shader.uniform("tex1", 0);
|
||||
@@ -3682,6 +3685,7 @@ void World::unload_shaders()
|
||||
|
||||
_liquid_render = boost::none;
|
||||
_liquid_render_mini = boost::none;
|
||||
_liquid_texture_manager.unload();
|
||||
|
||||
skies->unload();
|
||||
|
||||
@@ -4368,3 +4372,42 @@ void World::setupChunkBuffers()
|
||||
|
||||
}
|
||||
|
||||
void World::setupLiquidChunkVAO(opengl::scoped::use_program& water_shader)
|
||||
{
|
||||
ZoneScoped;
|
||||
opengl::scoped::vao_binder const _ (_liquid_chunk_vao);
|
||||
|
||||
{
|
||||
opengl::scoped::buffer_binder<GL_ARRAY_BUFFER> const binder(_liquid_chunk_vertex);
|
||||
water_shader.attrib("position", 2, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void World::setupLiquidChunkBuffers()
|
||||
{
|
||||
ZoneScoped;
|
||||
|
||||
// vertices
|
||||
math::vector_2d vertices[768 / 2];
|
||||
math::vector_2d* vt = vertices;
|
||||
|
||||
for (int z = 0; z < 8; ++z)
|
||||
{
|
||||
for (int x = 0; x < 8; ++x)
|
||||
{
|
||||
// first triangle
|
||||
*vt++ = math::vector_2d(UNITSIZE * x, UNITSIZE * z);
|
||||
*vt++ = math::vector_2d(UNITSIZE * x, UNITSIZE * (z + 1));
|
||||
*vt++ = math::vector_2d(UNITSIZE * (x + 1), UNITSIZE * z);
|
||||
|
||||
// second triangle
|
||||
*vt++ = math::vector_2d(UNITSIZE * (x + 1), UNITSIZE * z);
|
||||
*vt++ = math::vector_2d(UNITSIZE * x, UNITSIZE * (z + 1));
|
||||
*vt++ = math::vector_2d(UNITSIZE * (x + 1), UNITSIZE * (z + 1));
|
||||
}
|
||||
}
|
||||
|
||||
gl.bufferData<GL_ARRAY_BUFFER> (_liquid_chunk_vertex, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <opengl/primitives.hpp>
|
||||
#include <opengl/shader.fwd.hpp>
|
||||
#include <opengl/types.hpp>
|
||||
#include <noggit/LiquidTextureManager.hpp>
|
||||
|
||||
#include <boost/optional/optional.hpp>
|
||||
|
||||
@@ -412,6 +413,8 @@ public:
|
||||
void updateTerrainParamsUniformBlock();
|
||||
void markTerrainParamsUniformBlockDirty() { _need_terrain_params_ubo_update = true; };
|
||||
|
||||
LiquidTextureManager* getLiquidTextureManager() { return &_liquid_texture_manager; };
|
||||
|
||||
private:
|
||||
void update_models_by_filename();
|
||||
|
||||
@@ -421,7 +424,9 @@ private:
|
||||
std::set<MapChunk*>& vertexBorderChunks();
|
||||
|
||||
void setupChunkVAO(opengl::scoped::use_program& mcnk_shader);
|
||||
void setupLiquidChunkVAO(opengl::scoped::use_program& water_shader);
|
||||
void setupChunkBuffers();
|
||||
void setupLiquidChunkBuffers();
|
||||
|
||||
std::set<MapTile*> _vertex_tiles;
|
||||
std::set<MapChunk*> _vertex_chunks;
|
||||
@@ -464,7 +469,7 @@ private:
|
||||
|
||||
noggit::NoggitRenderContext _context;
|
||||
|
||||
opengl::scoped::deferred_upload_buffers<6> _buffers;
|
||||
opengl::scoped::deferred_upload_buffers<7> _buffers;
|
||||
GLuint const& _mvp_ubo = _buffers[0];
|
||||
GLuint const& _lighting_ubo = _buffers[1];
|
||||
GLuint const& _terrain_params_ubo = _buffers[2];
|
||||
@@ -477,9 +482,14 @@ private:
|
||||
GLuint const& _mapchunk_index = _buffers[4];
|
||||
GLuint const& _mapchunk_texcoord = _buffers[5];
|
||||
|
||||
opengl::scoped::deferred_upload_vertex_arrays<1> _vertex_arrays;
|
||||
GLuint const& _mapchunk_vao = _vertex_arrays[0];
|
||||
GLuint const& _liquid_chunk_vertex = _buffers[6];
|
||||
|
||||
opengl::scoped::deferred_upload_vertex_arrays<2> _vertex_arrays;
|
||||
GLuint const& _mapchunk_vao = _vertex_arrays[0];
|
||||
GLuint const& _liquid_chunk_vao = _vertex_arrays[1];
|
||||
|
||||
LiquidTextureManager _liquid_texture_manager;
|
||||
|
||||
bool _need_terrain_params_ubo_update = false;
|
||||
|
||||
};
|
||||
|
||||
@@ -20,13 +20,14 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
liquid_layer::liquid_layer(math::vector_3d const& base, float height, int liquid_id)
|
||||
liquid_layer::liquid_layer(ChunkWater* chunk, math::vector_3d const& base, float height, int liquid_id)
|
||||
: _liquid_id(liquid_id)
|
||||
, _liquid_vertex_format(0)
|
||||
, _minimum(height)
|
||||
, _maximum(height)
|
||||
, _subchunks(0)
|
||||
, pos(base)
|
||||
, _chunk(chunk)
|
||||
{
|
||||
for (int z = 0; z < 9; ++z)
|
||||
{
|
||||
@@ -42,14 +43,16 @@ liquid_layer::liquid_layer(math::vector_3d const& base, float height, int liquid
|
||||
}
|
||||
|
||||
changeLiquidID(_liquid_id);
|
||||
chunk->getWaterTile()->registerChunkLayer(this);
|
||||
}
|
||||
|
||||
liquid_layer::liquid_layer(math::vector_3d const& base, mclq& liquid, int liquid_id)
|
||||
liquid_layer::liquid_layer(ChunkWater* chunk, math::vector_3d const& base, mclq& liquid, int liquid_id)
|
||||
: _liquid_id(liquid_id)
|
||||
, _minimum(liquid.min_height)
|
||||
, _maximum(liquid.max_height)
|
||||
, _subchunks(0)
|
||||
, pos(base)
|
||||
, _chunk(chunk)
|
||||
{
|
||||
changeLiquidID(_liquid_id);
|
||||
|
||||
@@ -85,15 +88,18 @@ liquid_layer::liquid_layer(math::vector_3d const& base, mclq& liquid, int liquid
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
chunk->getWaterTile()->registerChunkLayer(this);
|
||||
}
|
||||
|
||||
liquid_layer::liquid_layer(MPQFile &f, std::size_t base_pos, math::vector_3d const& base, MH2O_Information const& info, std::uint64_t infomask)
|
||||
liquid_layer::liquid_layer(ChunkWater* chunk, MPQFile &f, std::size_t base_pos, math::vector_3d const& base, MH2O_Information const& info, std::uint64_t infomask)
|
||||
: _liquid_id(info.liquid_id)
|
||||
, _liquid_vertex_format(info.liquid_vertex_format)
|
||||
, _minimum(info.minHeight)
|
||||
, _maximum(info.maxHeight)
|
||||
, _subchunks(0)
|
||||
, pos(base)
|
||||
, _chunk(chunk)
|
||||
{
|
||||
int offset = 0;
|
||||
for (int z = 0; z < info.height; ++z)
|
||||
@@ -164,6 +170,8 @@ liquid_layer::liquid_layer(MPQFile &f, std::size_t base_pos, math::vector_3d con
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
chunk->getWaterTile()->registerChunkLayer(this);
|
||||
}
|
||||
|
||||
liquid_layer::liquid_layer(liquid_layer&& other)
|
||||
@@ -178,8 +186,10 @@ liquid_layer::liquid_layer(liquid_layer&& other)
|
||||
, _indices_by_lod(other._indices_by_lod)
|
||||
, _need_buffer_update(true)
|
||||
, pos(other.pos)
|
||||
, _chunk(other._chunk)
|
||||
{
|
||||
changeLiquidID(_liquid_id);
|
||||
_chunk->getWaterTile()->registerChunkLayer(this);
|
||||
}
|
||||
|
||||
liquid_layer::liquid_layer(liquid_layer const& other)
|
||||
@@ -194,8 +204,10 @@ liquid_layer::liquid_layer(liquid_layer const& other)
|
||||
, _indices_by_lod(other._indices_by_lod)
|
||||
, _need_buffer_update(true)
|
||||
, pos(other.pos)
|
||||
, _chunk(other._chunk)
|
||||
{
|
||||
changeLiquidID(_liquid_id);
|
||||
_chunk->getWaterTile()->registerChunkLayer(this);
|
||||
}
|
||||
|
||||
liquid_layer& liquid_layer::operator= (liquid_layer&& other)
|
||||
@@ -210,6 +222,7 @@ liquid_layer& liquid_layer::operator= (liquid_layer&& other)
|
||||
std::swap(_tex_coords, other._tex_coords);
|
||||
std::swap(pos, other.pos);
|
||||
std::swap(_indices_by_lod, other._indices_by_lod);
|
||||
std::swap(_chunk, other._chunk);
|
||||
|
||||
_need_buffer_update = true;
|
||||
other._need_buffer_update = true;
|
||||
@@ -232,6 +245,7 @@ liquid_layer& liquid_layer::operator=(liquid_layer const& other)
|
||||
_tex_coords = other._tex_coords;
|
||||
pos = other.pos;
|
||||
_indices_by_lod = other._indices_by_lod;
|
||||
_chunk = other._chunk;
|
||||
_need_buffer_update = true;
|
||||
|
||||
return *this;
|
||||
@@ -705,3 +719,8 @@ void liquid_layer::set_lod_level(int lod_level)
|
||||
_current_lod_level = lod_level;
|
||||
_current_lod_indices_count = _indices_by_lod[lod_level].size();
|
||||
}
|
||||
|
||||
liquid_layer::~liquid_layer()
|
||||
{
|
||||
_chunk->getWaterTile()->unregisterChunkLayer(this);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
class MapChunk;
|
||||
class sExtendableArray;
|
||||
class ChunkWater;
|
||||
|
||||
|
||||
// handle liquids like oceans, lakes, rivers, slime, magma
|
||||
@@ -16,12 +17,13 @@ class liquid_layer
|
||||
{
|
||||
public:
|
||||
liquid_layer() = delete;
|
||||
liquid_layer(math::vector_3d const& base, float height, int liquid_id);
|
||||
liquid_layer(math::vector_3d const& base, mclq& liquid, int liquid_id);
|
||||
liquid_layer(MPQFile &f, std::size_t base_pos, math::vector_3d const& base, MH2O_Information const& info, std::uint64_t infomask);
|
||||
liquid_layer(ChunkWater* chunk, math::vector_3d const& base, float height, int liquid_id);
|
||||
liquid_layer(ChunkWater* chunk, math::vector_3d const& base, mclq& liquid, int liquid_id);
|
||||
liquid_layer(ChunkWater* chunk, MPQFile &f, std::size_t base_pos, math::vector_3d const& base, MH2O_Information const& info, std::uint64_t infomask);
|
||||
|
||||
liquid_layer(liquid_layer const& other);
|
||||
liquid_layer (liquid_layer&&);
|
||||
liquid_layer(liquid_layer&&);
|
||||
~liquid_layer();
|
||||
|
||||
liquid_layer& operator=(liquid_layer&&);
|
||||
liquid_layer& operator=(liquid_layer const& other);
|
||||
@@ -68,6 +70,8 @@ public:
|
||||
|
||||
void unload();
|
||||
|
||||
ChunkWater* getChunk() { return _chunk; };
|
||||
|
||||
private:
|
||||
void update_min_max();
|
||||
void update_vertex_opacity(int x, int z, MapChunk* chunk, float factor);
|
||||
@@ -107,4 +111,5 @@ private:
|
||||
|
||||
private:
|
||||
math::vector_3d pos;
|
||||
ChunkWater* _chunk;
|
||||
};
|
||||
|
||||
@@ -67,6 +67,7 @@ namespace noggit
|
||||
, _null_widget (new QWidget (this))
|
||||
{
|
||||
|
||||
/*
|
||||
auto socket = new QTcpSocket(this);
|
||||
socket->connectToHost("178.162.136.62", 5000);
|
||||
socket->waitForConnected();
|
||||
@@ -145,6 +146,8 @@ namespace noggit
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
std::stringstream title;
|
||||
title << "Noggit - " << STRPRODUCTVER;
|
||||
setWindowTitle (QString::fromStdString (title.str()));
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <QtOpenGLExtensions/QOpenGLExtensions>
|
||||
#include <QtGui/QOpenGLFunctions>
|
||||
#include <boost/current_function.hpp>
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace
|
||||
|
||||
@@ -66,4 +66,10 @@ namespace opengl
|
||||
int ChunkTexAnimDir[4];
|
||||
};
|
||||
|
||||
struct LiquidChunkInstanceDataUniformBlock
|
||||
{
|
||||
unsigned TextureArray_Pad3[4];
|
||||
float ChunkXY_Animation[4];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user