test speed up rendering

This commit is contained in:
sshumakov3
2021-08-01 17:32:28 +03:00
parent 0e76a00402
commit 0df885e5a0
35 changed files with 661 additions and 359 deletions

View File

@@ -2,19 +2,23 @@
#version 330 core
uniform sampler2D tex;
uniform vec4 ocean_color_light;
uniform vec4 ocean_color_dark;
uniform vec4 river_color_light;
uniform vec4 river_color_dark;
uniform vec3 fog_color;
uniform float fog_start;
uniform float fog_end;
layout (std140) uniform lighting
{
vec4 DiffuseColor_FogStart;
vec4 AmbientColor_FogEnd;
vec4 FogColor_FogOn;
vec4 LightDir_FogRate;
vec4 OceanColorLight;
vec4 OceanColorDark;
vec4 RiverColorLight;
vec4 RiverColorDark;
};
uniform int type;
uniform float animtime;
uniform vec2 param;
uniform bool draw_fog;
in float depth_;
in vec2 tex_coord_;
@@ -40,22 +44,22 @@ void main()
vec2 uv = rot2(tex_coord_ * param.x, param.y);
vec4 texel = texture(tex, uv);
vec4 lerp = (type == 1)
? mix (ocean_color_light, ocean_color_dark, depth_)
: mix (river_color_light, river_color_dark, depth_)
? mix (OceanColorLight, OceanColorDark, depth_)
: mix (RiverColorLight, RiverColorDark, depth_)
;
//clamp shouldn't be needed
out_color = vec4 (clamp(texel + lerp, 0.0, 1.0).rgb, lerp.a);
}
if (draw_fog)
if (FogColor_FogOn.w != 0)
{
float start = fog_end * fog_start;
float start = AmbientColor_FogEnd.w * DiffuseColor_FogStart.w;
vec3 fogParams;
fogParams.x = -(1.0 / (fog_end - start));
fogParams.y = (1.0 / (fog_end - start)) * fog_end;
fogParams.z = 1.0;
fogParams.x = -(1.0 / (AmbientColor_FogEnd.w - start));
fogParams.y = (1.0 / (AmbientColor_FogEnd.w - start)) * AmbientColor_FogEnd.w;
fogParams.z = LightDir_FogRate.w;
float f1 = (dist_from_camera_ * fogParams.x) + fogParams.y;
float f2 = max(f1, 0.0);
@@ -64,6 +68,6 @@ void main()
float fogFactor = 1.0 - f4;
out_color.rgb = mix(out_color.rgb, fog_color.rgb, fogFactor);
out_color.rgb = mix(out_color.rgb, FogColor_FogOn.rgb, fogFactor);
}
}

View File

@@ -7,8 +7,12 @@ in float depth;
uniform vec3 camera;
uniform mat4 model_view;
uniform mat4 projection;
layout (std140) uniform matrices
{
mat4 model_view;
mat4 projection;
};
uniform mat4 transform;
uniform int use_transform = int(0);

View File

@@ -4,8 +4,11 @@
in mat4 transform;
in vec4 position;
uniform mat4 model_view;
uniform mat4 projection;
layout (std140) uniform matrices
{
mat4 model_view;
mat4 projection;
};
void main()
{

View File

@@ -8,23 +8,27 @@ in vec3 norm;
out vec4 out_color;
layout (std140) uniform lighting
{
vec4 DiffuseColor_FogStart;
vec4 AmbientColor_FogEnd;
vec4 FogColor_FogOn;
vec4 LightDir_FogRate;
vec4 OceanColorLight;
vec4 OceanColorDark;
vec4 RiverColorLight;
vec4 RiverColorDark;
};
uniform vec4 mesh_color;
uniform sampler2D tex1;
uniform sampler2D tex2;
uniform vec4 fog_color;
uniform float fog_start;
uniform float fog_end;
uniform int draw_fog;
uniform int fog_mode;
uniform int unfogged;
uniform int unlit;
uniform vec3 light_dir;
uniform vec3 diffuse_color;
uniform vec3 ambient_color;
uniform float alpha_test;
uniform int pixel_shader;
@@ -162,32 +166,32 @@ void main()
if(unlit == 0)
{
float nDotL = clamp(dot(normalize(norm), -normalize(light_dir)), 0.0, 1.0);
float nDotL = clamp(dot(normalize(norm), -normalize(vec3(-LightDir_FogRate.x, LightDir_FogRate.z, -LightDir_FogRate.y))), 0.0, 1.0);
vec3 ambientColor = ambient_color;
vec3 ambientColor = AmbientColor_FogEnd.xyz;
vec3 skyColor = (ambientColor * 1.10000002);
vec3 groundColor = (ambientColor * 0.699999988);
currColor = mix(groundColor, skyColor, 0.5 + (0.5 * nDotL));
lDiffuse = diffuse_color * nDotL;
lDiffuse = DiffuseColor_FogStart.xyz * nDotL;
}
else
{
currColor = ambient_color;
currColor = AmbientColor_FogEnd.xyz;
accumlatedLight = vec3(0.0f, 0.0f, 0.0f);
}
color.rgb = clamp(color.rgb * (currColor + lDiffuse), 0.0, 1.0);
if(draw_fog == 1 && unfogged == 0)
if(FogColor_FogOn.w != 0 && unfogged == 0)
{
float start = fog_end * fog_start;
float start = AmbientColor_FogEnd.w * DiffuseColor_FogStart.w;
vec3 fogParams;
fogParams.x = -(1.0 / (fog_end - start));
fogParams.y = (1.0 / (fog_end - start)) * fog_end;
fogParams.z = 1.0;
fogParams.x = -(1.0 / (AmbientColor_FogEnd.w - start));
fogParams.y = (1.0 / (AmbientColor_FogEnd.w - start)) * AmbientColor_FogEnd.w;
fogParams.z = LightDir_FogRate.w;
float f1 = (camera_dist * fogParams.x) + fogParams.y;
float f2 = max(f1, 0.0);
@@ -201,7 +205,7 @@ void main()
// see https://wowdev.wiki/M2/Rendering#Fog_Modes
if(fog_mode == 1)
{
fog = fog_color.rgb;
fog = FogColor_FogOn.rgb;
}
else if(fog_mode == 2)
{
@@ -216,7 +220,7 @@ void main()
fog = vec3(0.5);
}
color.rgb = mix(color.rgb, fog.rgb, fogFactor);
color.rgb = mix(color.rgb, FogColor_FogOn.rgb, fogFactor);
}
out_color = color;

View File

@@ -17,8 +17,11 @@ out vec2 uv2;
out float camera_dist;
out vec3 norm;
uniform mat4 model_view;
uniform mat4 projection;
layout (std140) uniform matrices
{
mat4 model_view;
mat4 projection;
};
uniform int tex_unit_lookup_1;
uniform int tex_unit_lookup_2;

View File

@@ -3,9 +3,13 @@
in vec4 position;
uniform mat4 model_view_projection;
layout (std140) uniform matrices
{
mat4 model_view;
mat4 projection;
};
void main()
{
gl_Position = model_view_projection * position;
gl_Position = (model_view * projection) * position;
}

View File

@@ -1,6 +1,32 @@
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
#version 330 core
layout (std140) uniform lighting
{
vec4 DiffuseColor_FogStart;
vec4 AmbientColor_FogEnd;
vec4 FogColor_FogOn;
vec4 LightDir_FogRate;
vec4 OceanColorLight;
vec4 OceanColorDark;
vec4 RiverColorLight;
vec4 RiverColorDark;
};
layout (std140) uniform overlay_params
{
int draw_shadows;
int draw_lines;
int draw_hole_lines;
int draw_areaid_overlay;
int draw_terrain_height_contour;
int draw_wireframe;
int wireframe_type;
float wireframe_radius;
float wireframe_width;
vec4 wireframe_color;
};
uniform sampler2D shadow_map;
uniform sampler2D tex0;
uniform sampler2D tex1;
@@ -15,28 +41,13 @@ uniform sampler2D alphamap;
uniform int layer_count;
uniform bool has_mccv;
uniform bool cant_paint;
uniform bool draw_areaid_overlay;
uniform vec4 areaid_color;
uniform bool draw_impassible_flag;
uniform bool draw_terrain_height_contour;
uniform bool draw_lines;
uniform bool draw_hole_lines;
uniform bool draw_selection;
uniform bool draw_shadows;
uniform bool draw_wireframe;
uniform int wireframe_type;
uniform float wireframe_radius;
uniform float wireframe_width;
uniform vec4 wireframe_color;
uniform bool rainbow_wireframe;
uniform bool draw_selection;
uniform vec3 camera;
uniform bool draw_fog;
uniform vec4 fog_color;
uniform float fog_start;
uniform float fog_end;
uniform float fog_rate;
uniform int draw_cursor_circle;
uniform vec3 cursor_position;
@@ -45,10 +56,6 @@ uniform float outer_cursor_radius;
uniform float inner_cursor_ratio;
uniform vec4 cursor_color;
uniform vec3 light_dir;
uniform vec3 diffuse_color;
uniform vec3 ambient_color;
in vec3 vary_position;
in vec2 vary_texcoord;
in vec3 vary_normal;
@@ -64,9 +71,6 @@ const float PI = 3.14159265358979323846;
vec4 texture_blend()
{
if(layer_count == 0)
return vec4 (1.0, 1.0, 1.0, 1.0);
vec3 alpha = texture(alphamap, vary_texcoord / 8.0).rgb;
float a0 = alpha.r;
float a1 = alpha.g;
@@ -77,7 +81,7 @@ vec4 texture_blend()
vec3 t2 = texture(tex2, vary_texcoord + tex_anim_2).rgb;
vec3 t3 = texture(tex3, vary_texcoord + tex_anim_3).rgb;
return vec4 (t0 * (1.0 - (a0 + a1 + a2)) + t1 * a0 + t2 * a1 + t3 * a2, 1.0);
return mix(vec4 (1.0, 1.0, 1.0, 1.0), vec4 (t0 * (1.0 - (a0 + a1 + a2)) + t1 * a0 + t2 * a1 + t3 * a2, 1.0), int(layer_count > 0));
}
float contour_alpha(float unit_size, float pos, float line_width)
@@ -109,15 +113,13 @@ void main()
vec3 lDiffuse = vec3(0.0, 0.0, 0.0);
vec3 accumlatedLight = vec3(1.0, 1.0, 1.0);
float nDotL = clamp(dot(normalize(vary_normal), -normalize(light_dir)), 0.0, 1.0);
float nDotL = clamp(dot(normalize(vary_normal), -normalize(LightDir_FogRate.xyz)), 0.0, 1.0);
vec3 ambientColor = ambient_color;
vec3 skyColor = (ambientColor * 1.10000002);
vec3 groundColor = (ambientColor * 0.699999988);
vec3 skyColor = (AmbientColor_FogEnd.xyz * 1.10000002);
vec3 groundColor = (AmbientColor_FogEnd.xyz * 0.699999988);
currColor = mix(groundColor, skyColor, 0.5 + (0.5 * nDotL));
lDiffuse = diffuse_color * nDotL;
lDiffuse = DiffuseColor_FogStart.xyz * nDotL;
out_color.rgb = clamp(out_color.rgb * (currColor + lDiffuse), 0.0, 1.0);
@@ -127,7 +129,7 @@ void main()
out_color *= vec4(1.0, 0.0, 0.0, 1.0);
}
if(draw_areaid_overlay)
if(draw_areaid_overlay != 0)
{
out_color = out_color * 0.3 + areaid_color;
}
@@ -142,19 +144,19 @@ void main()
out_color.rgb = mix(vec3(1.0), out_color.rgb, 0.5);
}
if (draw_shadows)
if (draw_shadows != 0)
{
float shadow_alpha = texture(shadow_map, vary_texcoord / 8.0).r;
out_color = vec4 (out_color.rgb * (1.0 - shadow_alpha), 1.0);
}
if (draw_terrain_height_contour)
if (draw_terrain_height_contour != 0)
{
out_color = vec4(out_color.rgb * contour_alpha(4.0, vary_position.y+0.1, fw.y), 1.0);
}
bool lines_drawn = false;
if(draw_lines)
if(draw_lines != 0)
{
vec4 color = vec4(0.0, 0.0, 0.0, 0.0);
@@ -166,7 +168,7 @@ void main()
color.a = contour_alpha(CHUNKSIZE, vary_position.xz, fw.xz);
color.r = color.a > 0.0 ? 0.8 : 0.0;
}
if(draw_hole_lines && color.a == 0.0)
if(draw_hole_lines != 0 && color.a == 0.0)
{
color.a = contour_alpha(HOLESIZE, vary_position.xz, fw.xz * 0.75);
color.b = 0.8;
@@ -176,14 +178,14 @@ void main()
out_color.rgb = mix(out_color.rgb, color.rgb, color.a);
}
if(draw_fog)
if(FogColor_FogOn.w != 0)
{
float start = fog_end * fog_start; // 0
float start = AmbientColor_FogEnd.w * DiffuseColor_FogStart.w; // 0
vec3 fogParams;
fogParams.x = -(1.0 / (fog_end - start)); // - 1 / 338
fogParams.y = (1.0 / (fog_end - start)) * fog_end; // 1 / 338 * 338
fogParams.z = fog_rate; // 2.7
fogParams.x = -(1.0 / (AmbientColor_FogEnd.w - start)); // - 1 / 338
fogParams.y = (1.0 / (AmbientColor_FogEnd.w - start)) * AmbientColor_FogEnd.w; // 1 / 338 * 338
fogParams.z = LightDir_FogRate.w; // 2.7
float f1 = (dist_from_camera * fogParams.x) + fogParams.y; // 1.0029
float f2 = max(f1, 0.0);
@@ -192,12 +194,12 @@ void main()
float fogFactor = 1.0 - f4;
float alpha = clamp((dist_from_camera - start) / (fog_end - start), 0.0, 1.0);
float alpha = clamp((dist_from_camera - start) / (AmbientColor_FogEnd.w - start), 0.0, 1.0);
out_color.rgb = mix(out_color.rgb, fog_color.rgb, alpha);
out_color.rgb = mix(out_color.rgb, FogColor_FogOn.rgb, alpha);
}
if(draw_wireframe && !lines_drawn)
if(draw_wireframe != 0 && !lines_drawn)
{
// true by default => type 0
bool draw_wire = true;

View File

@@ -6,8 +6,11 @@ in vec3 normal;
in vec3 mccv;
in vec2 texcoord;
uniform mat4 model_view;
uniform mat4 projection;
layout (std140) uniform matrices
{
mat4 model_view;
mat4 projection;
};
out vec3 vary_position;
out vec2 vary_texcoord;

View File

@@ -1,23 +1,28 @@
// This file is part of Noggit3, licensed under GNU General Public License (version 3).
#version 330 core
layout (std140) uniform lighting
{
vec4 DiffuseColor_FogStart;
vec4 AmbientColor_FogEnd;
vec4 FogColor_FogOn;
vec4 LightDir_FogRate;
vec4 OceanColorLight;
vec4 OceanColorDark;
vec4 RiverColorLight;
vec4 RiverColorDark;
};
uniform sampler2D tex1;
uniform sampler2D tex2;
uniform bool use_vertex_color;
uniform bool draw_fog;
uniform bool unfogged;
uniform float fog_start;
uniform float fog_end;
uniform vec3 fog_color;
uniform vec3 camera;
uniform bool unlit;
uniform bool exterior_lit;
uniform vec3 exterior_light_dir;
uniform vec3 exterior_diffuse_color;
uniform vec3 exterior_ambient_color;
uniform vec3 ambient_color;
uniform float alpha_test;
@@ -32,7 +37,7 @@ in vec4 f_vertex_color;
out vec4 out_color;
vec3 lighting(vec3 material)
vec3 apply_lighting(vec3 material)
{
vec3 ambient_term;
vec3 diffuse_term;
@@ -45,8 +50,8 @@ vec3 lighting(vec3 material)
}
else if(exterior_lit)
{
ambient_term = exterior_ambient_color;
diffuse_term = exterior_diffuse_color;
ambient_term = AmbientColor_FogEnd.xyz;
diffuse_term = DiffuseColor_FogStart.xyz;
}
else
{
@@ -61,7 +66,7 @@ vec3 lighting(vec3 material)
if(!unlit)
{
float nDotL = clamp(dot(normalize(f_normal), -normalize(exterior_light_dir)), 0.0, 1.0);
float nDotL = clamp(dot(normalize(f_normal), -normalize(vec3(-LightDir_FogRate.x, LightDir_FogRate.z, -LightDir_FogRate.y))), 0.0, 1.0);
vec3 ambientColor = ambient_term + vertex_color;
@@ -83,7 +88,7 @@ vec3 lighting(vec3 material)
void main()
{
float dist_from_camera = distance(camera, f_position);
bool fog = draw_fog && !unfogged;
bool fog = FogColor_FogOn.w != 0 && !unfogged;
vec4 tex = texture(tex1, f_texcoord);
vec4 tex_2 = texture(tex2, f_texcoord_2);
@@ -106,31 +111,31 @@ void main()
if(shader_id == 3) // Env
{
vec3 env = tex_2.rgb * tex.rgb;
out_color = vec4(lighting(tex.rgb) + env, 1.);
out_color = vec4(apply_lighting(tex.rgb) + env, 1.);
}
else if(shader_id == 5) // EnvMetal
{
vec3 env = tex_2.rgb * tex.rgb * tex.a;
out_color = vec4(lighting(tex.rgb) + env, 1.);
out_color = vec4(apply_lighting(tex.rgb) + env, 1.);
}
else if(shader_id == 6) // TwoLayerDiffuse
{
vec3 layer2 = mix(tex.rgb, tex_2.rgb, tex_2.a);
out_color = vec4(lighting(mix(layer2, tex.rgb, vertex_color.a)), 1.);
out_color = vec4(apply_lighting(mix(layer2, tex.rgb, vertex_color.a)), 1.);
}
else // default shader, used for shader_id 0,1,2,4 (Diffuse, Specular, Metal, Opaque)
{
out_color = vec4(lighting(tex.rgb), 1.);
out_color = vec4(apply_lighting(tex.rgb), 1.);
}
if(fog)
{
float start = fog_end * fog_start;
float start = AmbientColor_FogEnd.w * DiffuseColor_FogStart.w;
vec3 fogParams;
fogParams.x = -(1.0 / (fog_end - start));
fogParams.y = (1.0 / (fog_end - start)) * fog_end;
fogParams.z = 1.0;
fogParams.x = -(1.0 / (AmbientColor_FogEnd.w - start));
fogParams.y = (1.0 / (AmbientColor_FogEnd.w - start)) * AmbientColor_FogEnd.w;
fogParams.z = LightDir_FogRate.w;
float f1 = (dist_from_camera * fogParams.x) + fogParams.y;
float f2 = max(f1, 0.0);
@@ -139,7 +144,7 @@ void main()
float fogFactor = 1.0 - f4;
out_color.rgb = mix(out_color.rgb, fog_color.rgb, fogFactor);
out_color.rgb = mix(out_color.rgb, FogColor_FogOn.rgb, fogFactor);
}
if(out_color.a < alpha_test)

View File

@@ -13,8 +13,12 @@ out vec2 f_texcoord;
out vec2 f_texcoord_2;
out vec4 f_vertex_color;
uniform mat4 model_view;
uniform mat4 projection;
layout (std140) uniform matrices
{
mat4 model_view;
mat4 projection;
};
uniform mat4 transform;
uniform int shader_id;

View File

@@ -14,6 +14,8 @@ namespace math
struct matrix_4x4
{
public:
matrix_4x4 () {}
static struct uninitialized_t {} uninitialized;
matrix_4x4 (uninitialized_t) {}

View File

@@ -601,7 +601,7 @@ void MapChunk::draw ( math::frustum const& frustum
, std::map<int, misc::random_color>& area_id_colors
, int animtime
, display_mode display
, std::vector<int>& textures_bound
, std::array<int, 4>& textures_bound
)
{
@@ -629,10 +629,10 @@ void MapChunk::draw ( math::frustum const& frustum
update_vao(mcnk_shader, tex_coord_vbo);
}
bool cantPaint = noggit::ui::selected_texture::get()
&& !canPaintTexture(*noggit::ui::selected_texture::get())
&& show_unpaintable_chunks
&& draw_paintability_overlay;
bool cantPaint = show_unpaintable_chunks
&& draw_paintability_overlay
&& noggit::ui::selected_texture::get()
&& !canPaintTexture(*noggit::ui::selected_texture::get());
if (texture_set->num())
{

View File

@@ -18,6 +18,7 @@
#include <map>
#include <memory>
#include <array>
#include <QImage>
class MPQFile;
@@ -146,7 +147,7 @@ public:
, std::map<int, misc::random_color>& area_id_colors
, int animtime
, display_mode display
, std::vector<int>& textures_bound
, std::array<int, 4>& textures_bound
);
//! \todo only this function should be public, all others should be called from it

View File

@@ -375,7 +375,7 @@ void MapTile::draw ( math::frustum const& frustum
, std::map<int, misc::random_color>& area_id_colors
, int animtime
, display_mode display
, std::vector<int>& textures_bound
, std::array<int, 4>& textures_bound
)
{
if (!finished)

View File

@@ -17,6 +17,7 @@
#include <map>
#include <string>
#include <vector>
#include <array>
namespace math
{
@@ -88,7 +89,7 @@ public:
, std::map<int, misc::random_color>& area_id_colors
, int animtime
, display_mode display
, std::vector<int>& textures_bound
, std::array<int, 4>& textures_bound
);
void intersect (math::ray const&, selection_result*) const;
void drawWater ( math::frustum const& frustum

View File

@@ -34,7 +34,6 @@
#include <noggit/ui/texture_palette_small.hpp>
#include <noggit/ui/MinimapCreator.hpp>
#include <opengl/scoped.hpp>
#include <noggit/Red/StampMode/Ui/PaletteMain.hpp>
#include <noggit/Red/ViewToolbar/Ui/ViewToolbar.hpp>
#include <noggit/Red/AssetBrowser/Ui/AssetBrowser.hpp>
#include <noggit/Red/PresetEditor/Ui/PresetEditor.hpp>
@@ -44,7 +43,8 @@
#include <noggit/Red/LightEditor/LightEditor.hpp>
#include <external/imguipiemenu/PieMenu.hpp>
#include <noggit/ui/object_palette.hpp>
#include <noggit/Red/UiCommon/ImageMaskSelector.hpp>
#include <opengl/types.hpp>
#include <noggit/ActionManager.hpp>
#include <noggit/Action.hpp>
@@ -136,6 +136,52 @@ ACTION_CODE
while (false)
#define ADD_TOGGLE_POST(menu_, name_, shortcut_, property_, post_)\
do \
{ \
QAction* action (new QAction (name_, this)); \
action->setShortcut (QKeySequence (shortcut_)); \
action->setCheckable (true); \
action->setChecked (property_.get()); \
menu_->addAction (action); \
connect ( action, &QAction::toggled \
, &property_, &noggit::bool_toggle_property::set \
); \
connect ( &property_, &noggit::bool_toggle_property::changed \
, action, &QAction::setChecked \
); \
connect ( action, &QAction::toggled, post_); \
connect ( &property_, &noggit::bool_toggle_property::changed, \
post_); \
} \
while (false)
#define ADD_TOGGLE_NS_POST(menu_, name_, property_, code_) \
do \
{ \
QAction* action (new QAction (name_, this)); \
action->setCheckable (true); \
action->setChecked (property_.get()); \
menu_->addAction (action); \
connect ( action, &QAction::toggled \
, &property_, &noggit::bool_toggle_property::set \
); \
connect ( &property_, &noggit::bool_toggle_property::changed \
, action, &QAction::setChecked \
); \
connect ( action, &QAction::toggled \
, code_ \
); \
connect ( &property_, &noggit::bool_toggle_property::changed \
, code_ \
); \
} \
while (false)
#define ADD_ACTION(menu, name, shortcut, on_action) \
{ \
auto action (menu->addAction (name)); \
@@ -175,6 +221,8 @@ void MapView::set_editing_mode (editing_mode mode)
if (context() && context()->isValid())
{
_world->getTerrainParamsUniformBlock()->draw_areaid_overlay = false;
switch (mode)
{
case editing_mode::ground:
@@ -201,6 +249,9 @@ void MapView::set_editing_mode (editing_mode mode)
stampTool->getActiveBrushItem()->updateMask();
}
break;
case editing_mode::areaid:
_world->getTerrainParamsUniformBlock()->draw_areaid_overlay = true;
break;
default:
break;
}
@@ -218,6 +269,8 @@ void MapView::set_editing_mode (editing_mode mode)
terrainMode = mode;
_toolbar->check_tool (mode);
this->activateWindow();
_world->markTerrainParamsUniformBlockDirty();
}
void MapView::setToolPropertyWidgetVisibility(editing_mode mode)
@@ -1628,13 +1681,39 @@ void MapView::setupViewMenu()
ADD_TOGGLE (view_menu, "Terrain", Qt::Key_F3, _draw_terrain);
ADD_TOGGLE (view_menu, "Water", Qt::Key_F4, _draw_water);
ADD_TOGGLE (view_menu, "WMOs", Qt::Key_F6, _draw_wmo);
ADD_TOGGLE (view_menu, "Lines", Qt::Key_F7, _draw_lines);
ADD_TOGGLE (view_menu, "Contours", Qt::Key_F9, _draw_contour);
ADD_TOGGLE (view_menu, "Wireframe", Qt::Key_F10, _draw_wireframe);
ADD_TOGGLE_POST (view_menu, "Lines", Qt::Key_F7, _draw_lines,
[=]
{
_world->getTerrainParamsUniformBlock()->draw_lines = _draw_lines.get();
_world->markTerrainParamsUniformBlockDirty();
});
ADD_TOGGLE_POST (view_menu, "Contours", Qt::Key_F9, _draw_contour,
[=]
{
_world->getTerrainParamsUniformBlock()->draw_terrain_height_contour = _draw_contour.get();
_world->markTerrainParamsUniformBlockDirty();
});
ADD_TOGGLE_POST (view_menu, "Wireframe", Qt::Key_F10, _draw_wireframe,
[=]
{
_world->getTerrainParamsUniformBlock()->draw_wireframe = _draw_wireframe.get();
_world->markTerrainParamsUniformBlockDirty();
});
ADD_TOGGLE (view_menu, "Toggle Animation", Qt::Key_F11, _draw_model_animations);
ADD_TOGGLE (view_menu, "Draw fog", Qt::Key_F12, _draw_fog);
ADD_TOGGLE_NS (view_menu, "Flight Bounds", _draw_mfbo);
ADD_TOGGLE (view_menu, "Hole lines", "Shift+F7", _draw_hole_lines);
ADD_TOGGLE_POST (view_menu, "Hole lines", "Shift+F7", _draw_hole_lines,
[=]
{
_world->getTerrainParamsUniformBlock()->draw_hole_lines = _draw_hole_lines.get();
_world->markTerrainParamsUniformBlockDirty();
});
ADD_TOGGLE_NS (view_menu, "Models with box", _draw_models_with_box);
//! \todo space+h in object mode
ADD_TOGGLE_NS (view_menu, "Hidden models", _draw_hidden_models);
@@ -2392,8 +2471,6 @@ MapView::MapView( math::degrees camera_yaw0
, [=] { _main_window->statusBar()->removeWidget (_status_fps); }
);
moving = strafing = updown = lookat = turn = 0.0f;
freelook = false;
@@ -4859,3 +4936,17 @@ QWidget* MapView::getActiveStampModeItem()
else
return nullptr;
}
void MapView::onSettingsSave()
{
opengl::TerrainParamsUniformBlock* params = _world->getTerrainParamsUniformBlock();
params->wireframe_type = _settings->value("wireframe/type", 0).toInt();
params->wireframe_radius = _settings->value("wireframe/radius", 1.5f).toFloat();
params->wireframe_width = _settings->value ("wireframe/width", 1.f).toFloat();
QColor c = _settings->value("wireframe/color").value<QColor>();
math::vector_4d wireframe_color(c.redF(), c.greenF(), c.blueF(), c.alphaF());
params->wireframe_color = wireframe_color;
_world->markTerrainParamsUniformBlockDirty();
}

View File

@@ -245,6 +245,7 @@ public:
void randomizeTexturingRotation();
void randomizeShaderRotation();
void randomizeStampRotation();
void onSettingsSave();
void set_editing_mode (editing_mode);
editing_mode get_editing_mode() { return terrainMode; };

View File

@@ -1428,7 +1428,7 @@ void Model::draw( math::matrix_4x4 const& model_view
}
void Model::draw ( math::matrix_4x4 const& model_view
, std::vector<ModelInstance*> instances
, std::vector<ModelInstance*>& instances
, opengl::scoped::use_program& m2_shader
, math::frustum const& frustum
, const float& cull_distance
@@ -1459,17 +1459,19 @@ void Model::draw ( math::matrix_4x4 const& model_view
animcalc = true;
}
std::vector<math::matrix_4x4> transform_matrix;
static std::array<math::matrix_4x4, 10000> transform_matrix;
int n_visible_instances = 0;
for (ModelInstance* mi : instances)
{
if (no_cull || mi->is_visible(frustum, cull_distance, camera, display))
{
transform_matrix.push_back(mi->transformMatrixTransposed());
transform_matrix[n_visible_instances] = (mi->transformMatrixTransposed());
n_visible_instances++;
}
}
if (transform_matrix.empty())
if (!n_visible_instances)
{
return;
}
@@ -1477,18 +1479,18 @@ void Model::draw ( math::matrix_4x4 const& model_view
// store the model count to draw the bounding boxes later
if (all_boxes || _hidden)
{
model_boxes_to_draw.emplace(this, transform_matrix.size());
model_boxes_to_draw.emplace(this, n_visible_instances);
}
if (draw_particles && (!_particles.empty() || !_ribbons.empty()))
{
models_with_particles.emplace(this, transform_matrix.size());
models_with_particles.emplace(this, n_visible_instances);
}
opengl::scoped::vao_binder const _ (_vao);
{
opengl::scoped::buffer_binder<GL_ARRAY_BUFFER> const transform_binder (_transform_buffer);
gl.bufferData(GL_ARRAY_BUFFER, transform_matrix.size() * sizeof(::math::matrix_4x4), transform_matrix.data(), GL_DYNAMIC_DRAW);
gl.bufferData(GL_ARRAY_BUFFER, n_visible_instances * sizeof(::math::matrix_4x4), transform_matrix.data(), GL_DYNAMIC_DRAW);
m2_shader.attrib("transform", 0, 1);
}
@@ -1508,7 +1510,7 @@ void Model::draw ( math::matrix_4x4 const& model_view
{
if (p.prepare_draw(m2_shader, this))
{
gl.drawElementsInstanced(GL_TRIANGLES, p.index_count, GL_UNSIGNED_SHORT, reinterpret_cast<void*>(p.index_start * sizeof(GLushort)), transform_matrix.size());
gl.drawElementsInstanced(GL_TRIANGLES, p.index_count, GL_UNSIGNED_SHORT, reinterpret_cast<void*>(p.index_start * sizeof(GLushort)), n_visible_instances);
p.after_draw();
}
}

View File

@@ -227,7 +227,7 @@ public:
, bool no_cull = false
);
void draw ( math::matrix_4x4 const& model_view
, std::vector<ModelInstance*> instances
, std::vector<ModelInstance*>& instances
, opengl::scoped::use_program& m2_shader
, math::frustum const& frustum
, const float& cull_distance

View File

@@ -211,34 +211,34 @@ void PreviewRenderer::draw()
opengl::scoped::use_program water_shader {_liquid_render->shader_program()};
water_shader.uniform("animtime", _animtime / 2880.f);
water_shader.uniform("model_view", model_view().transposed());
water_shader.uniform("projection", projection().transposed());
//water_shader.uniform("model_view", model_view().transposed());
//water_shader.uniform("projection", projection().transposed());
math::vector_4d ocean_color_light(math::vector_3d(1.0f, 1.0f, 1.0f), 1.f);
math::vector_4d ocean_color_dark(math::vector_3d(1.0f, 1.0f, 1.0f), 1.f);
math::vector_4d river_color_light(math::vector_3d(1.0f, 1.0f, 1.0f), 1.f);
math::vector_4d river_color_dark(math::vector_3d(1.0f, 1.0f, 1.0f), 1.f);
water_shader.uniform("ocean_color_light", ocean_color_light);
water_shader.uniform("ocean_color_dark", ocean_color_dark);
water_shader.uniform("river_color_light", river_color_light);
water_shader.uniform("river_color_dark", river_color_dark);
water_shader.uniform("use_transform", 1);
//water_shader.uniform("ocean_color_light", ocean_color_light);
//water_shader.uniform("ocean_color_dark", ocean_color_dark);
//water_shader.uniform("river_color_light", river_color_light);
//water_shader.uniform("river_color_dark", river_color_dark);
//water_shader.uniform("use_transform", 1);
}
{
opengl::scoped::use_program wmo_program{*_wmo_program.get()};
wmo_program.uniform("model_view", model_view().transposed());
wmo_program.uniform("projection", projection().transposed());
//wmo_program.uniform("model_view", model_view().transposed());
//wmo_program.uniform("projection", projection().transposed());
wmo_program.uniform("tex1", 0);
wmo_program.uniform("tex2", 1);
wmo_program.uniform("draw_fog", 0);
//wmo_program.uniform("draw_fog", 0);
wmo_program.uniform("exterior_light_dir", _light_dir);
wmo_program.uniform("exterior_diffuse_color", _diffuse_light);
wmo_program.uniform("exterior_ambient_color", _ambient_light);
//wmo_program.uniform("exterior_light_dir", _light_dir);
//wmo_program.uniform("exterior_diffuse_color", _diffuse_light);
//wmo_program.uniform("exterior_ambient_color", _ambient_light);
for (auto& wmo_instance : _wmo_instances)
{
@@ -274,21 +274,22 @@ void PreviewRenderer::draw()
opengl::scoped::use_program m2_shader {*_m2_instanced_program.get()};
m2_shader.uniform("model_view", model_view().transposed());
m2_shader.uniform("projection", projection().transposed());
//m2_shader.uniform("model_view", model_view().transposed());
//m2_shader.uniform("projection", projection().transposed());
m2_shader.uniform("tex1", 0);
m2_shader.uniform("tex2", 1);
m2_shader.uniform("draw_fog", 0);
//m2_shader.uniform("draw_fog", 0);
m2_shader.uniform("light_dir", _light_dir);
m2_shader.uniform("diffuse_color", _diffuse_light);
m2_shader.uniform("ambient_color", _ambient_light);
//m2_shader.uniform("light_dir", _light_dir);
//m2_shader.uniform("diffuse_color", _diffuse_light);
//m2_shader.uniform("ambient_color", _ambient_light);
for (auto& model_instance : _model_instances)
{
std::vector<ModelInstance*> instance{&model_instance};
model_instance.model->draw(
model_view().transposed()
, std::vector<ModelInstance*>{&model_instance}
, instance
, m2_shader
, frustum
, culldistance

View File

@@ -253,3 +253,37 @@ std::vector<wmo_doodad_instance*> WMOInstance::get_visible_doodads
return doodads;
}
std::map<uint32_t, std::vector<wmo_doodad_instance>>* WMOInstance::get_doodads(bool draw_hidden_models)
{
if (!wmo->finishedLoading() || wmo->loading_failed())
{
return nullptr;
}
if (_need_doodadset_update)
{
change_doodadset(_doodadset);
}
if (wmo->is_hidden() && !draw_hidden_models)
{
return nullptr;
}
else
{
for (int i = 0; i < wmo->groups.size(); ++i)
{
for (auto& doodad : _doodads_per_group[i])
{
if (doodad.need_matrix_update())
{
doodad.update_transform_matrix_wmo(this);
}
}
}
}
return &_doodads_per_group;
}

View File

@@ -112,4 +112,6 @@ public:
, bool draw_hidden_models
, display_mode display
);
std::map<uint32_t, std::vector<wmo_doodad_instance>>* get_doodads(bool draw_hidden_models);
};

View File

@@ -888,22 +888,48 @@ void World::initShaders()
}
);
}
{
opengl::scoped::use_program m2_shader {*_m2_program.get()};
m2_shader.uniform("tex1", 0);
m2_shader.uniform("tex2", 1);
_buffers.upload();
m2_shader.bind_uniform_block("matrices", 0);
gl.bindBuffer(GL_UNIFORM_BUFFER, _mvp_ubo);
gl.bufferData(GL_UNIFORM_BUFFER, sizeof(opengl::MVPUniformBlock), NULL, GL_DYNAMIC_DRAW);
gl.bindBufferRange(GL_UNIFORM_BUFFER, opengl::ubo_targets::MVP, _mvp_ubo, 0, sizeof(opengl::MVPUniformBlock));
gl.bindBuffer(GL_UNIFORM_BUFFER, 0);
m2_shader.bind_uniform_block("lighting", 1);
gl.bindBuffer(GL_UNIFORM_BUFFER, _lighting_ubo);
gl.bufferData(GL_UNIFORM_BUFFER, sizeof(opengl::LightingUniformBlock), NULL, GL_DYNAMIC_DRAW);
gl.bindBufferRange(GL_UNIFORM_BUFFER, opengl::ubo_targets::LIGHTING, _lighting_ubo, 0, sizeof(opengl::LightingUniformBlock));
gl.bindBuffer(GL_UNIFORM_BUFFER, 0);
}
{
opengl::scoped::use_program wmo_program {*_wmo_program.get()};
wmo_program.uniform("tex1", 0);
wmo_program.uniform("tex2", 1);
wmo_program.uniform("fog_end", fogdistance);
wmo_program.uniform("fog_start", 0.5f);
wmo_program.bind_uniform_block("matrices", 0);
wmo_program.bind_uniform_block("lighting", 1);
}
{
opengl::scoped::use_program mcnk_shader {*_mcnk_program.get()};
mcnk_shader.bind_uniform_block("matrices", 0);
mcnk_shader.bind_uniform_block("lighting", 1);
mcnk_shader.bind_uniform_block("overlay_params", 2);
gl.bindBuffer(GL_UNIFORM_BUFFER, _terrain_params_ubo);
gl.bufferData(GL_UNIFORM_BUFFER, sizeof(opengl::TerrainParamsUniformBlock), NULL, GL_STATIC_DRAW);
gl.bindBufferRange(GL_UNIFORM_BUFFER, opengl::ubo_targets::TERRAIN_OVERLAYS, _terrain_params_ubo, 0, sizeof(opengl::TerrainParamsUniformBlock));
gl.bindBuffer(GL_UNIFORM_BUFFER, 0);
mcnk_shader.uniform("alphamap", 0);
mcnk_shader.uniform("tex0", 1);
mcnk_shader.uniform("tex1", 2);
@@ -912,23 +938,17 @@ void World::initShaders()
mcnk_shader.uniform("stampBrush", 6);
mcnk_shader.uniform("draw_shadows", 1);
mcnk_shader.uniform("shadow_map", 5);
mcnk_shader.uniform ("fog_start", 0.5f);
mcnk_shader.uniform ("fog_end", fogdistance);
mcnk_shader.uniform ("wireframe_type", 0);
mcnk_shader.uniform ("wireframe_width", 1.0f);
mcnk_shader.uniform ("wireframe_radius", 1.5f);
}
{
opengl::scoped::use_program m2_shader_instanced {*_m2_instanced_program.get()};
m2_shader_instanced.bind_uniform_block("matrices", 0);
m2_shader_instanced.bind_uniform_block("lighting", 1);
m2_shader_instanced.uniform("tex1", 0);
m2_shader_instanced.uniform("tex2", 1);
m2_shader_instanced.uniform("fog_end", fogdistance);
m2_shader_instanced.uniform("fog_start", 0.5f);
}
/*
{
opengl::scoped::use_program particles_shader {*_m2_particles_program.get()};
particles_shader.uniform("tex", 0);
@@ -939,6 +959,24 @@ void World::initShaders()
ribbon_shader.uniform("tex", 0);
}
*/
{
opengl::scoped::use_program liquid_render {_liquid_render.get().shader_program()};
liquid_render.bind_uniform_block("matrices", 0);
liquid_render.bind_uniform_block("lighting", 1);
}
{
opengl::scoped::use_program mfbo_shader {*_mfbo_program.get()};
mfbo_shader.bind_uniform_block("matrices", 0);
}
{
opengl::scoped::use_program m2_box_shader {*_m2_box_program.get()};
m2_box_shader.bind_uniform_block("matrices", 0);
}
}
void World::draw ( math::matrix_4x4 const& model_view
@@ -986,37 +1024,22 @@ void World::draw ( math::matrix_4x4 const& model_view
math::matrix_4x4 const mvp(model_view * projection);
math::frustum const frustum (mvp);
if (camera_moved)
updateMVPUniformBlock(model_view, projection);
gl.disable(GL_DEPTH_TEST);
int daytime = static_cast<int>(time) % 2880;
updateLightingUniformBlock(draw_fog, camera_pos);
skies->update_sky_colors(camera_pos, daytime);
outdoorLightStats = ol->getLightStats(static_cast<int>(time));
if (_need_terrain_params_ubo_update)
updateTerrainParamsUniformBlock();
math::vector_3d light_dir = outdoorLightStats.dayDir;
light_dir = {-light_dir.x, light_dir.z, -light_dir.y};
// todo: figure out why I need to use a different light vector for the terrain
math::vector_3d terrain_light_dir = outdoorLightStats.dayDir;
math::vector_3d diffuse_color(skies->color_set[LIGHT_GLOBAL_DIFFUSE]);
math::vector_3d ambient_color(skies->color_set[LIGHT_GLOBAL_AMBIENT]);
// only draw the sky in 3D
if(display == display_mode::in_3D)
{
opengl::scoped::use_program m2_shader {*_m2_program.get()};
m2_shader.uniform("model_view", model_view);
m2_shader.uniform("projection", projection);
m2_shader.uniform_cached("draw_fog", 0);
m2_shader.uniform("fog_end", skies->fog_distance_end());
m2_shader.uniform("fog_start", skies->fog_distance_start());
m2_shader.uniform("light_dir", light_dir);
m2_shader.uniform("diffuse_color", diffuse_color);
m2_shader.uniform("ambient_color", ambient_color);
bool hadSky = false;
if (draw_wmo || mapIndex.hasAGlobalWMO())
@@ -1052,8 +1075,6 @@ void World::draw ( math::matrix_4x4 const& model_view
if (!hadSky)
{
m2_shader.uniform("diffuse_color", math::vector_3d{0.0f, 0.0f, 0.0f});
m2_shader.uniform("ambient_color", math::vector_3d{1.f, 1.f, 1.f});
skies->draw( model_view
, projection
, camera_pos
@@ -1085,56 +1106,14 @@ void World::draw ( math::matrix_4x4 const& model_view
{
opengl::scoped::use_program mcnk_shader{ *_mcnk_program.get() };
mcnk_shader.uniform("model_view", model_view);
mcnk_shader.uniform("projection", projection);
mcnk_shader.uniform_cached("draw_lines", draw_lines);
mcnk_shader.uniform_cached("draw_hole_lines", draw_hole_lines);
mcnk_shader.uniform_cached("draw_areaid_overlay", draw_areaid_overlay);
mcnk_shader.uniform_cached("draw_terrain_height_contour", draw_contour);
// the flag stays on if the last chunk drawn before leaving the editing tool has it
if (!draw_chunk_flag_overlay)
{
mcnk_shader.uniform_cached("draw_impassible_flag", 0);
}
mcnk_shader.uniform_cached("draw_wireframe", draw_wireframe);
int wireframe_type = _settings->value("wireframe/type", 0).toInt();
mcnk_shader.uniform_cached("wireframe_type", wireframe_type);
float wireframe_radius = _settings->value("wireframe/radius", 1.5f).toFloat();
mcnk_shader.uniform_cached("wireframe_radius", wireframe_radius);
float wireframe_width = _settings->value ("wireframe/width", 1.f).toFloat();
mcnk_shader.uniform_cached ("wireframe_width", wireframe_width);
// !\ todo store the color somewhere ?
QColor c = _settings->value("wireframe/color").value<QColor>();
math::vector_4d wireframe_color(c.redF(), c.greenF(), c.blueF(), c.alphaF());
mcnk_shader.uniform ("wireframe_color", wireframe_color);
mcnk_shader.uniform_cached ("draw_fog", draw_fog);
if (draw_fog)
{
mcnk_shader.uniform("fog_end", skies->fog_distance_end());
mcnk_shader.uniform("fog_start", skies->fog_distance_start());
mcnk_shader.uniform("fog_rate", skies->fogRate());
mcnk_shader.uniform ("fog_color", math::vector_4d(skies->color_set[FOG_COLOR], 1));
}
mcnk_shader.uniform ("camera", camera_pos);
mcnk_shader.uniform("light_dir", terrain_light_dir);
mcnk_shader.uniform("diffuse_color", diffuse_color);
mcnk_shader.uniform("ambient_color", ambient_color);
if (cursor_type != CursorType::NONE)
{
@@ -1155,7 +1134,7 @@ void World::draw ( math::matrix_4x4 const& model_view
mcnk_shader.uniform("tex_anim_2", math::vector_2d());
mcnk_shader.uniform("tex_anim_3", math::vector_2d());
std::vector<int> textures_bound = { -1, -1, -1, -1 };
std::array<int, 4> textures_bound = { -1, -1, -1, -1 };
for (MapTile* tile : mapIndex.loaded_tiles())
{
@@ -1218,20 +1197,6 @@ void World::draw ( math::matrix_4x4 const& model_view
_sphere_render.draw(mvp, vertexCenter(), cursor_color, 2.f);
}
std::unordered_map<std::string, std::vector<ModelInstance*>> _wmo_doodads;
bool draw_doodads_wmo = draw_wmo && draw_wmo_doodads;
if (draw_doodads_wmo)
{
_model_instance_storage.for_each_wmo_instance([&] (WMOInstance& wmo)
{
for (auto& doodad : wmo.get_visible_doodads(frustum, culldistance, camera_pos, draw_hidden_models, display))
{
_wmo_doodads[doodad->model->filename].push_back(doodad);
}
});
}
std::unordered_map<Model*, std::size_t> model_with_particles;
// WMOs / map objects
@@ -1240,22 +1205,7 @@ void World::draw ( math::matrix_4x4 const& model_view
{
opengl::scoped::use_program wmo_program {*_wmo_program.get()};
wmo_program.uniform("model_view", model_view);
wmo_program.uniform("projection", projection);
wmo_program.uniform_cached("draw_fog", draw_fog);
if (draw_fog)
{
wmo_program.uniform("fog_color", skies->color_set[FOG_COLOR]);
wmo_program.uniform("fog_end", skies->fog_distance_end());
wmo_program.uniform("fog_start", skies->fog_distance_start());
wmo_program.uniform("camera", camera_pos);
}
wmo_program.uniform("exterior_light_dir", light_dir);
wmo_program.uniform("exterior_diffuse_color", diffuse_color);
wmo_program.uniform("exterior_ambient_color", ambient_color);
wmo_program.uniform("camera", camera_pos);
_model_instance_storage.for_each_wmo_instance([&] (WMOInstance& wmo)
{
@@ -1286,6 +1236,8 @@ void World::draw ( math::matrix_4x4 const& model_view
}
}
bool draw_doodads_wmo = draw_wmo && draw_wmo_doodads;
// M2s / models
if (draw_models || draw_doodads_wmo)
{
@@ -1302,24 +1254,11 @@ void World::draw ( math::matrix_4x4 const& model_view
std::unordered_map<Model*, std::size_t> model_boxes_to_draw;
{
opengl::scoped::use_program m2_shader {*_m2_instanced_program.get()};
m2_shader.uniform("model_view", model_view);
m2_shader.uniform("projection", projection);
m2_shader.uniform("fog_color", math::vector_4d(skies->color_set[FOG_COLOR], 1));
// !\ todo use light dbcs values
m2_shader.uniform_cached("draw_fog", draw_fog);
m2_shader.uniform("fog_end", skies->fog_distance_end());
m2_shader.uniform("fog_start", skies->fog_distance_start());
m2_shader.uniform("light_dir", light_dir);
m2_shader.uniform("diffuse_color", diffuse_color);
m2_shader.uniform("ambient_color", ambient_color);
if (draw_models)
{
opengl::scoped::use_program m2_shader {*_m2_instanced_program.get()};
for (auto& it : _models_by_filename)
{
if (draw_hidden_models || !it.second[0]->model->is_hidden())
@@ -1340,37 +1279,49 @@ void World::draw ( math::matrix_4x4 const& model_view
);
}
}
/*
if (draw_doodads_wmo)
{
_model_instance_storage.for_each_wmo_instance([&] (WMOInstance& wmo)
{
auto doodads = wmo.get_doodads(draw_hidden_models);
if (!doodads)
return;
for (auto& pair : *doodads)
{
for (auto& doodad : pair.second)
{
doodad->model->draw( model_view
, m2_shader
, frustum
, culldistance
, camera_pos
, false
, animtime
, draw_model_animations
, draw_models_with_box
, model_with_particles
, model_boxes_to_draw
, display
);
}
}
});
}
*/
}
if (draw_doodads_wmo)
{
for (auto& it : _wmo_doodads)
{
it.second[0]->model->draw( model_view
, it.second
, m2_shader
, frustum
, culldistance
, camera_pos
, false
, animtime
, draw_model_animations
, draw_models_with_box
, model_with_particles
, model_boxes_to_draw
, display
);
}
}
}
if(draw_models_with_box || (draw_hidden_models && !model_boxes_to_draw.empty()))
{
opengl::scoped::use_program m2_box_shader{ *_m2_box_program.get() };
m2_box_shader.uniform ("model_view", model_view);
m2_box_shader.uniform ("projection", projection);
opengl::scoped::bool_setter<GL_LINE_SMOOTH, GL_TRUE> const line_smooth;
gl.hint (GL_LINE_SMOOTH_HINT, GL_NICEST);
@@ -1412,35 +1363,15 @@ void World::draw ( math::matrix_4x4 const& model_view
opengl::scoped::use_program water_shader {_liquid_render->shader_program()};
water_shader.uniform("animtime", static_cast<float>(animtime) / 2880.f);
water_shader.uniform("model_view", model_view);
water_shader.uniform("projection", projection);
water_shader.uniform("camera", camera_pos);
water_shader.uniform_cached("draw_fog", draw_fog);
if (draw_fog)
{
water_shader.uniform("fog_color", skies->color_set[FOG_COLOR]);
water_shader.uniform("fog_start", skies->fog_distance_start());
water_shader.uniform("fog_end", skies->fog_distance_end());
}
math::vector_4d ocean_color_light(skies->color_set[OCEAN_COLOR_LIGHT], skies->ocean_shallow_alpha());
math::vector_4d ocean_color_dark(skies->color_set[OCEAN_COLOR_DARK], skies->ocean_deep_alpha());
math::vector_4d river_color_light(skies->color_set[RIVER_COLOR_LIGHT], skies->river_shallow_alpha());
math::vector_4d river_color_dark(skies->color_set[RIVER_COLOR_DARK], skies->river_deep_alpha());
water_shader.uniform("ocean_color_light", ocean_color_light);
water_shader.uniform("ocean_color_dark", ocean_color_dark);
water_shader.uniform("river_color_light", river_color_light);
water_shader.uniform("river_color_dark", river_color_dark);
if (draw_wmo || mapIndex.hasAGlobalWMO())
{
water_shader.uniform("use_transform", 1);
}
}
/*
// model particles
if (draw_model_animations && !model_with_particles.empty())
{
@@ -1458,6 +1389,7 @@ void World::draw ( math::matrix_4x4 const& model_view
}
}
if (draw_model_animations && !model_with_particles.empty())
{
opengl::scoped::bool_setter<GL_CULL_FACE, GL_FALSE> const cull;
@@ -1475,6 +1407,8 @@ void World::draw ( math::matrix_4x4 const& model_view
}
}
*/
gl.enable(GL_BLEND);
gl.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -1560,8 +1494,6 @@ void World::draw ( math::matrix_4x4 const& model_view
opengl::scoped::use_program mfbo_shader {*_mfbo_program.get()};
mfbo_shader.uniform("model_view_projection", model_view * projection);
for (MapTile* tile : mapIndex.loaded_tiles())
{
tile->drawMFBO(mfbo_shader);
@@ -2160,7 +2092,7 @@ void World::drawMinimap ( MapTile *tile
mcnk_shader.uniform("tex_anim_2", math::vector_2d());
mcnk_shader.uniform("tex_anim_3", math::vector_2d());
std::vector<int> textures_bound = { -1, -1, -1, -1 };
std::array<int, 4> textures_bound = { -1, -1, -1, -1 };
std::map<int, misc::random_color> area_id_colors;
tile->draw(frustum, mcnk_shader, detailtexcoords, culldistance, camera_pos, true, false,
@@ -3657,6 +3589,8 @@ void World::unload_shaders()
detailtexcoords = 0;
alphatexcoords = 0;
_buffers.unload();
_global_vbos_initialized = false;
_display_initialized = false;
}
@@ -4112,3 +4046,44 @@ void World::ensureAllTilesetsAllADTs()
}
}
void World::updateMVPUniformBlock(const math::matrix_4x4& model_view, const math::matrix_4x4& projection)
{
_mvp_ubo_data.model_view = model_view;
_mvp_ubo_data.projection = projection;
gl.bindBuffer(GL_UNIFORM_BUFFER, _mvp_ubo);
gl.bufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(opengl::MVPUniformBlock), &_mvp_ubo_data);
}
void World::updateLightingUniformBlock(bool draw_fog, math::vector_3d const& camera_pos)
{
int daytime = static_cast<int>(time) % 2880;
skies->update_sky_colors(camera_pos, daytime);
outdoorLightStats = ol->getLightStats(static_cast<int>(time));
math::vector_3d diffuse = skies->color_set[LIGHT_GLOBAL_DIFFUSE];
math::vector_3d ambient = skies->color_set[LIGHT_GLOBAL_AMBIENT];
math::vector_3d fog_color = skies->color_set[FOG_COLOR];
_lighting_ubo_data.DiffuseColor_FogStart = {diffuse, skies->fog_distance_start()};
_lighting_ubo_data.AmbientColor_FogEnd = {ambient, skies->fog_distance_end()};
_lighting_ubo_data.FogColor_FogOn = {fog_color, static_cast<float>(draw_fog)};
_lighting_ubo_data.LightDir_FogRate = {outdoorLightStats.dayDir.x, outdoorLightStats.dayDir.y, outdoorLightStats.dayDir.z, skies->fogRate()};
_lighting_ubo_data.OceanColorLight = {skies->color_set[OCEAN_COLOR_LIGHT], skies->ocean_shallow_alpha()};
_lighting_ubo_data.OceanColorDark = {skies->color_set[OCEAN_COLOR_DARK], skies->ocean_deep_alpha()};
_lighting_ubo_data.RiverColorLight = {skies->color_set[RIVER_COLOR_LIGHT], skies->river_shallow_alpha()};
_lighting_ubo_data.RiverColorDark = {skies->color_set[RIVER_COLOR_DARK], skies->river_deep_alpha()};
gl.bindBuffer(GL_UNIFORM_BUFFER, _lighting_ubo);
gl.bufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(opengl::LightingUniformBlock), &_lighting_ubo_data);
}
void World::updateTerrainParamsUniformBlock()
{
gl.bindBuffer(GL_UNIFORM_BUFFER, _terrain_params_ubo);
gl.bufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(opengl::TerrainParamsUniformBlock), &_terrain_params_ubo_data);
_need_terrain_params_ubo_update = false;
}

View File

@@ -20,6 +20,7 @@
#include <noggit/ContextObject.hpp>
#include <opengl/primitives.hpp>
#include <opengl/shader.fwd.hpp>
#include <opengl/types.hpp>
#include <boost/optional/optional.hpp>
@@ -408,9 +409,16 @@ public:
bool need_model_updates = false;
opengl::TerrainParamsUniformBlock* getTerrainParamsUniformBlock() { return &_terrain_params_ubo_data; };
void updateTerrainParamsUniformBlock();
void markTerrainParamsUniformBlockDirty() { _need_terrain_params_ubo_update = true; };
private:
void update_models_by_filename();
void updateMVPUniformBlock(const math::matrix_4x4& model_view, const math::matrix_4x4& projection);
void updateLightingUniformBlock(bool draw_fog, math::vector_3d const& camera_pos);
std::set<MapChunk*>& vertexBorderChunks();
std::set<MapTile*> _vertex_tiles;
@@ -454,17 +462,15 @@ private:
noggit::NoggitRenderContext _context;
bool _draw_lines_old = false;
bool _draw_hole_lines_old = false;
bool _draw_areaid_overlay_old = false;
bool _draw_terrain_height_contour_old = false;
bool _draw_wireframe_old = false;
int _wireframe_type_old = 0;
float _wireframe_radius_old = 1.5f;
float _wireframe_width_old = 1.f;
bool _draw_fog_old = false;
CursorType _cursor_type_old = CursorType::NONE;
bool _draw_selection_old = false;
opengl::scoped::deferred_upload_buffers<3> _buffers;
GLuint const& _mvp_ubo = _buffers[0];
GLuint const& _lighting_ubo = _buffers[1];
GLuint const& _terrain_params_ubo = _buffers[2];
opengl::MVPUniformBlock _mvp_ubo_data;
opengl::LightingUniformBlock _lighting_ubo_data;
opengl::TerrainParamsUniformBlock _terrain_params_ubo_data;
bool _need_terrain_params_ubo_update = false;
};

View File

@@ -260,7 +260,7 @@ const std::string& TextureSet::filename(size_t id)
return textures[id]->filename;
}
void TextureSet::bindTexture(size_t id, size_t activeTexture, std::vector<int>& textures_bound)
void TextureSet::bindTexture(size_t id, size_t activeTexture, std::array<int, 4>& textures_bound)
{
if (textures_bound[id] != textures[id]->id())
{

View File

@@ -35,7 +35,7 @@ public:
math::vector_2d anim_uv_offset(int id, int animtime) const;
void bindTexture(size_t id, size_t activeTexture, std::vector<int>& textures_bound);
void bindTexture(size_t id, size_t activeTexture, std::array<int, 4>& textures_bound);
int addTexture(scoped_blp_texture_reference texture);
void eraseTexture(size_t id);

View File

@@ -300,6 +300,8 @@ namespace noggit
_settings->setValue("assetBrowser/render_asset_preview", ui->assetBrowserRenderAssetPreview->isChecked());
_settings->sync();
emit saved();
}
}
}

View File

@@ -15,12 +15,16 @@ namespace noggit
{
class settings : public QMainWindow
{
Q_OBJECT
QSettings* _settings;
Ui::SettingsPanel* ui;
public:
settings(QWidget* parent = nullptr);
void discard_changes();
void save_changes();
signals:
void saved();
};
}
}

View File

@@ -231,7 +231,7 @@ namespace noggit
boost::optional<scoped_blp_texture_reference> selected_texture::get()
{
return selected_texture::texture;
return selected_texture::texture; // TODO: something performance-hungry is going on here
}
void selected_texture::set (scoped_blp_texture_reference t)

View File

@@ -162,7 +162,7 @@ namespace noggit
QSettings settings;
if (!settings.value("systemWindowFrame", false).toBool())
if (!settings.value("systemWindowFrame", true).toBool())
{
QWidget *widget = new QWidget(this);
Ui::TitleBar* titleBarWidget = setupFramelessWindow(widget, this, minimumSize(), maximumSize(), true);
@@ -266,6 +266,7 @@ namespace noggit
_map_creation_wizard->destroyFakeWorld();
_map_view = (new MapView (camera_yaw, camera_pitch, pos, this, std::move (_world), uid_fix, from_bookmark));
connect(_map_view, &MapView::uid_fix_failed, [this]() { prompt_uid_fix_failure(); });
connect(_settings, &settings::saved, [this]() { if (_map_view) _map_view->onSettingsSave(); });
_stack_widget->addWidget(_map_view);
_stack_widget->setCurrentIndex(1);

View File

@@ -93,6 +93,7 @@ namespace opengl
BOOST_FORCEINLINE void genBuffers (GLuint, GLuint*);
BOOST_FORCEINLINE void deleteBuffers (GLuint, GLuint*);
BOOST_FORCEINLINE void bindBuffer (GLenum, GLuint);
BOOST_FORCEINLINE void bindBufferRange (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr);
BOOST_FORCEINLINE void bufferData (GLenum target, GLsizeiptr size, GLvoid const* data, GLenum usage);
BOOST_FORCEINLINE GLvoid* mapBuffer (GLenum target, GLenum access);
BOOST_FORCEINLINE GLboolean unmapBuffer (GLenum);
@@ -137,6 +138,10 @@ namespace opengl
BOOST_FORCEINLINE void disableVertexAttribArray (GLuint index);
BOOST_FORCEINLINE GLint getUniformLocation (GLuint program, GLchar const* name);
BOOST_FORCEINLINE GLint getUniformBlockIndex (GLuint program, GLchar const* name);
BOOST_FORCEINLINE void uniformBlockBinding (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
BOOST_FORCEINLINE void uniform1i (GLint location, GLint value);
BOOST_FORCEINLINE void uniform1f (GLint location, GLfloat value);
BOOST_FORCEINLINE void uniform1iv (GLint location, GLsizei count, GLint const* value);

View File

@@ -11,7 +11,6 @@
#include <QtOpenGLExtensions/QOpenGLExtensions>
#include <QtGui/QOpenGLFunctions>
#include <QOpenGLExtensions>
#include <boost/current_function.hpp>
@@ -390,6 +389,13 @@ void opengl::context::bindBuffer (GLenum target, GLuint buffer)
#endif
return _current_context->functions()->glBindBuffer (target, buffer);
}
void opengl::context::bindBufferRange (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)
{
#ifndef NOGGIT_DO_NOT_CHECK_FOR_OPENGL_ERRORS
verify_context_and_check_for_gl_errors const _ (_current_context, BOOST_CURRENT_FUNCTION);
#endif
return _4_1_core_func->glBindBufferRange (target, index, buffer, offset, size);
}
GLvoid* opengl::context::mapBuffer (GLenum target, GLenum access)
{
#ifndef NOGGIT_DO_NOT_CHECK_FOR_OPENGL_ERRORS
@@ -692,14 +698,31 @@ GLint opengl::context::getUniformLocation (GLuint program, GLchar const* name)
#ifndef NOGGIT_DO_NOT_CHECK_FOR_OPENGL_ERRORS
verify_context_and_check_for_gl_errors const _ (_current_context, BOOST_CURRENT_FUNCTION);
#endif
auto val (_current_context->functions()->glGetUniformLocation (program, name));
return (_current_context->functions()->glGetUniformLocation (program, name));
}
GLint opengl::context::getUniformBlockIndex (GLuint program, GLchar const* name)
{
#ifndef NOGGIT_DO_NOT_CHECK_FOR_OPENGL_ERRORS
verify_context_and_check_for_gl_errors const _ (_current_context, BOOST_CURRENT_FUNCTION);
#endif
auto val (_4_1_core_func->glGetUniformBlockIndex(program, name));
if (val == -1)
{
throw std::logic_error ("unknown uniform " + std::string (name));
throw std::logic_error ("unknown uniform block " + std::string (name));
}
return val;
}
void opengl::context::uniformBlockBinding (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding)
{
#ifndef NOGGIT_DO_NOT_CHECK_FOR_OPENGL_ERRORS
verify_context_and_check_for_gl_errors const _ (_current_context, BOOST_CURRENT_FUNCTION);
#endif
return _4_1_core_func->glUniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding);
}
void opengl::context::uniform1i (GLint location, GLint value)
{
#ifndef NOGGIT_DO_NOT_CHECK_FOR_OPENGL_ERRORS

View File

@@ -130,11 +130,14 @@ namespace opengl
}
}
//! \todo _cache lookups?
GLuint program::uniform_location (std::string const& name) const
{
return gl.getUniformLocation (*_handle, name.c_str());
}
GLuint program::uniform_block_location (std::string const& name) const
{
return gl.getUniformBlockIndex(*_handle, name.c_str());
}
GLuint program::attrib_location (std::string const& name) const
{
return gl.getAttribLocation (*_handle, name.c_str());
@@ -164,19 +167,34 @@ namespace opengl
void use_program::uniform (std::string const& name, GLint value)
{
gl.uniform1i (uniform_location (name), value);
GLuint loc = uniform_location (name);
if (loc < 0)
return;
gl.uniform1i (loc, value);
}
void use_program::uniform (std::string const& name, GLfloat value)
{
gl.uniform1f (uniform_location (name), value);
GLuint loc = uniform_location (name);
if (loc < 0)
return;
gl.uniform1f (loc, value);
}
void use_program::uniform (std::string const& name, bool value)
{
gl.uniform1i (uniform_location (name), static_cast<int>(value));
GLuint loc = uniform_location (name);
if (loc < 0)
return;
gl.uniform1i (loc, static_cast<int>(value));
}
void use_program::uniform_cached(std::string const& name, GLint value)
{
GLuint loc = uniform_location(name);
GLuint loc = uniform_location (name);
if (loc < 0)
return;
auto cache = _program.getUniformsIntCache();
auto it = cache->find(loc);
if (it == cache->end() || it->second != value)
@@ -187,7 +205,10 @@ namespace opengl
}
void use_program::uniform_cached(std::string const& name, GLfloat value)
{
GLuint loc = uniform_location(name);
GLuint loc = uniform_location (name);
if (loc < 0)
return;
auto cache = _program.getUniformsFloatCache();
auto it = cache->find(loc);
if (it == cache->end() || !misc::float_equals(it->second, value))
@@ -198,7 +219,10 @@ namespace opengl
}
void use_program::uniform_cached(std::string const& name, bool value)
{
GLuint loc = uniform_location(name);
GLuint loc = uniform_location (name);
if (loc < 0)
return;
auto cache = _program.getUniformsBoolCache();
auto it = cache->find(loc);
if (it == cache->end() || it->second != value)
@@ -207,29 +231,58 @@ namespace opengl
gl.uniform1i(loc, static_cast<int>(value));
}
}
void use_program::bind_uniform_block(std::string const& name, unsigned target)
{
gl.uniformBlockBinding(_program._handle.get(), uniform_block_location(name), target);
}
void use_program::uniform (std::string const& name, std::vector<int> const& value)
{
gl.uniform1iv (uniform_location(name), value.size(), value.data());
GLuint loc = uniform_location (name);
if (loc < 0)
return;
gl.uniform1iv (loc, value.size(), value.data());
}
void use_program::uniform (std::string const& name, std::vector<math::vector_3d> const& value)
{
gl.uniform3fv (uniform_location(name), value.size(), reinterpret_cast<const GLfloat*>(value.data()));
GLuint loc = uniform_location (name);
if (loc < 0)
return;
gl.uniform3fv (loc, value.size(), reinterpret_cast<const GLfloat*>(value.data()));
}
void use_program::uniform (std::string const& name, math::vector_2d const& value)
{
gl.uniform2fv (uniform_location (name), 1, value);
GLuint loc = uniform_location (name);
if (loc < 0)
return;
gl.uniform2fv (loc, 1, value);
}
void use_program::uniform (std::string const& name, math::vector_3d const& value)
{
gl.uniform3fv (uniform_location (name), 1, value);
GLuint loc = uniform_location (name);
if (loc < 0)
return;
gl.uniform3fv (loc, 1, value);
}
void use_program::uniform (std::string const& name, math::vector_4d const& value)
{
gl.uniform4fv (uniform_location (name), 1, value);
GLuint loc = uniform_location (name);
if (loc < 0)
return;
gl.uniform4fv (loc, 1, value);
}
void use_program::uniform (std::string const& name, math::matrix_4x4 const& value)
{
gl.uniformMatrix4fv (uniform_location (name), 1, GL_FALSE, value);
GLuint loc = uniform_location (name);
if (loc < 0)
return;
gl.uniformMatrix4fv (loc, 1, GL_FALSE, value);
}
void use_program::sampler (std::string const& name, GLenum texture_slot, texture* tex)
@@ -317,7 +370,25 @@ namespace opengl
GLuint loc = _program.uniform_location(name);
if (loc == -1)
{
throw std::invalid_argument ("uniform " + name + " does not exist in shader\n");
LogError << "uniform " + name + " does not exist in shader\n" << std::endl;
}
(*const_cast<tsl::robin_map<std::string, GLuint>*>(uniforms))[name] = loc;
return loc;
}
GLuint use_program::uniform_block_location (std::string const& name)
{
auto uniforms = _program.getUniforms();
auto it = uniforms->find(name);
if (it != uniforms->end())
{
return it->second;
}
GLuint loc = _program.uniform_block_location(name);
if (loc == -1)
{
throw std::invalid_argument ("uniform block " + name + " does not exist in shader\n");
}
(*const_cast<tsl::robin_map<std::string, GLuint>*>(uniforms))[name] = loc;
return loc;

View File

@@ -62,6 +62,7 @@ namespace opengl
private:
inline GLuint uniform_location (std::string const& name) const;
inline GLuint uniform_block_location (std::string const& name) const;
inline GLuint attrib_location (std::string const& name) const;
friend struct scoped::use_program;
@@ -88,6 +89,7 @@ namespace opengl
use_program& operator= (use_program const&) = delete;
use_program& operator= (use_program&&) = delete;
void bind_uniform_block(std::string const& name, unsigned);
void uniform (std::string const& name, std::vector<int> const&);
void uniform (std::string const& name, GLint);
void uniform (std::string const& name, GLfloat);
@@ -117,6 +119,7 @@ namespace opengl
private:
GLuint uniform_location (std::string const& name);
GLuint uniform_block_location (std::string const& name);
GLuint attrib_location (std::string const& name);
program const& _program;

View File

@@ -3,8 +3,49 @@
#pragma once
#include <QtGui/QOpenGLContext>
#include <math/matrix_4x4.hpp>
#include <math/vector_4d.hpp>
namespace opengl
{
typedef GLuint light;
enum ubo_targets
{
MVP,
LIGHTING,
TERRAIN_OVERLAYS
};
struct MVPUniformBlock
{
math::matrix_4x4 model_view;
math::matrix_4x4 projection;
};
struct LightingUniformBlock
{
math::vector_4d DiffuseColor_FogStart;
math::vector_4d AmbientColor_FogEnd;
math::vector_4d FogColor_FogOn;
math::vector_4d LightDir_FogRate;
math::vector_4d OceanColorLight;
math::vector_4d OceanColorDark;
math::vector_4d RiverColorLight;
math::vector_4d RiverColorDark;
};
struct TerrainParamsUniformBlock
{
int draw_shadows = true;
int draw_lines = false;
int draw_hole_lines = false;
int draw_areaid_overlay = false;
int draw_terrain_height_contour = false;
int draw_wireframe = false;
int wireframe_type;
float wireframe_radius;
float wireframe_width;
math::vector_4d wireframe_color;
};
}