This commit is contained in:
milek7
2018-07-14 17:00:54 +02:00
parent a81499f7e5
commit 4566375faa
14 changed files with 157 additions and 75 deletions

View File

@@ -81,7 +81,6 @@ set(SOURCES
"uitranscripts.cpp"
"station.cpp"
"gl/shader.cpp"
"gl/shader_mvp.cpp"
"gl/vao.cpp"
"gl/ubo.cpp"
"gl/framebuffer.cpp"

View File

@@ -448,6 +448,7 @@ int main(int argc, char *argv[])
if (!World.Update())
break;
if (!GfxRenderer.Render())
break;

View File

@@ -106,6 +106,17 @@ void gl::program::init()
}
glUniform1i(glGetUniformLocation(*this, "shadowmap"), 10); //m7t: do something better
GLuint index;
if ((index = glGetUniformBlockIndex(*this, "scene_ubo")) != GL_INVALID_INDEX)
glUniformBlockBinding(*this, 0, index);
if ((index = glGetUniformBlockIndex(*this, "model_ubo")) != GL_INVALID_INDEX)
glUniformBlockBinding(*this, 1, index);
if ((index = glGetUniformBlockIndex(*this, "light_ubo")) != GL_INVALID_INDEX)
glUniformBlockBinding(*this, 2, index);
}
gl::program::program()

View File

@@ -33,6 +33,7 @@ namespace gl
void attach(const shader &);
void link();
virtual void init();
private:
void init();
};
}

View File

@@ -1,16 +0,0 @@
#include "stdafx.h"
#include "shader_mvp.h"
void gl::program_mvp::init()
{
GLuint index;
if ((index = glGetUniformBlockIndex(*this, "scene_ubo")) != GL_INVALID_INDEX)
glUniformBlockBinding(*this, 0, index);
if ((index = glGetUniformBlockIndex(*this, "model_ubo")) != GL_INVALID_INDEX)
glUniformBlockBinding(*this, 1, index);
if ((index = glGetUniformBlockIndex(*this, "light_ubo")) != GL_INVALID_INDEX)
glUniformBlockBinding(*this, 2, index);
}

View File

@@ -1,14 +0,0 @@
#pragma once
#include "shader.h"
namespace gl
{
class program_mvp : public program
{
public:
using program::program;
virtual void init() override;
};
}

View File

@@ -5,7 +5,7 @@ gl::ubo::ubo(int size, int index)
{
glGenBuffers(1, *this);
bind();
glBufferData(GL_UNIFORM_BUFFER, size, nullptr, GL_DYNAMIC_DRAW);
glBufferData(GL_UNIFORM_BUFFER, size, nullptr, GL_STREAM_DRAW);
glBindBufferBase(GL_UNIFORM_BUFFER, index, *this);
}

View File

@@ -87,7 +87,7 @@ namespace gl
static_assert(sizeof(light_element_ubs) == 64, "bad size of ubs");
const size_t MAX_LIGHTS = 16;
const size_t MAX_LIGHTS = 4;
struct light_ubs
{

View File

@@ -302,7 +302,7 @@ opengl_vbogeometrybank::draw_( gfx::geometry_handle const &Geometry) {
}
// actual draw procedure starts here
auto &chunkrecord = m_chunkrecords[ Geometry.chunk - 1 ];
auto &chunkrecord = m_chunkrecords.at(Geometry.chunk - 1);
auto const &chunk = gfx::geometry_bank::chunk( Geometry );
if( false == chunkrecord.is_good ) {
glBindBuffer( GL_ARRAY_BUFFER, m_buffer );

View File

@@ -139,38 +139,41 @@ bool opengl_renderer::Init(GLFWwindow *Window)
scene_ubo = std::make_unique<gl::ubo>(sizeof(gl::scene_ubs), 0);
model_ubo = std::make_unique<gl::ubo>(sizeof(gl::model_ubs), 1);
light_ubo = std::make_unique<gl::ubo>(sizeof(gl::light_ubs), 2);
memset(&light_ubs, 0, sizeof(light_ubs));
memset(&model_ubs, 0, sizeof(model_ubs));
memset(&scene_ubs, 0, sizeof(scene_ubs));
light_ubo->update(light_ubs);
model_ubo->update(model_ubs);
scene_ubo->update(scene_ubs);
// m7t: tbd: plug into material system?
{
gl::shader vert("traction.vert");
gl::shader frag("traction.frag");
gl::program *prog = new gl::program_mvp({vert, frag});
prog->init();
gl::program *prog = new gl::program({vert, frag});
m_line_shader = std::unique_ptr<gl::program>(prog);
}
{
gl::shader vert("freespot.vert");
gl::shader frag("freespot.frag");
gl::program *prog = new gl::program_mvp({vert, frag});
prog->init();
gl::program *prog = new gl::program({vert, frag});
m_freespot_shader = std::unique_ptr<gl::program>(prog);
}
{
gl::shader vert("shadowmap.vert");
gl::shader frag("shadowmap.frag");
gl::program *prog = new gl::program_mvp({vert, frag});
prog->init();
gl::program *prog = new gl::program({vert, frag});
m_shadow_shader = std::unique_ptr<gl::program>(prog);
}
{
gl::shader vert("pick.vert");
gl::shader frag("pick.frag");
gl::program *prog = new gl::program_mvp({vert, frag});
prog->init();
gl::program *prog = new gl::program({vert, frag});
m_pick_shader = std::unique_ptr<gl::program>(prog);
}
@@ -285,7 +288,6 @@ void opengl_renderer::SwapBuffers()
{
Timer::subsystem.gfx_swap.start();
glfwSwapBuffers(m_window);
glViewport(0, 0, Global.iWindowWidth, Global.iWindowHeight); // for apitrace
Timer::subsystem.gfx_swap.stop();
}
@@ -300,6 +302,11 @@ void opengl_renderer::Render_pass(rendermode const Mode)
{
glDebug("rendermode::color");
Update_Lights(simulation::Lights);
scene_ubs.time = Timer::GetTime();
scene_ubs.projection = OpenGLMatrices.data(GL_PROJECTION);
scene_ubo->update(scene_ubs);
{
setup_shadow_map(nullptr);
@@ -349,7 +356,6 @@ void opengl_renderer::Render_pass(rendermode const Mode)
glDebug("render environment");
scene_ubs.time = Timer::GetTime();
scene_ubs.projection = OpenGLMatrices.data(GL_PROJECTION);
scene_ubo->update(scene_ubs);
Render(&World.Environment);
@@ -363,7 +369,6 @@ void opengl_renderer::Render_pass(rendermode const Mode)
scene_ubs.lightview = coordmove * depthproj * depthcam * glm::inverse(worldcam);
}
scene_ubs.projection = OpenGLMatrices.data(GL_PROJECTION);
scene_ubo->update(scene_ubs);
// opaque parts...
setup_drawing(false);
@@ -444,7 +449,6 @@ void opengl_renderer::Render_pass(rendermode const Mode)
setup_matrices();
setup_drawing(false);
scene_ubs.time = Timer::GetTime();
scene_ubs.projection = OpenGLMatrices.data(GL_PROJECTION);
scene_ubo->update(scene_ubs);
Render(simulation::Region);
@@ -476,17 +480,18 @@ void opengl_renderer::Render_pass(rendermode const Mode)
glDebug("rendermode::pickcontrols");
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glViewport(0, 0, EU07_PICKBUFFERSIZE, EU07_PICKBUFFERSIZE);
m_pick_fb->bind();
m_pick_fb->clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
m_pickcontrolsitems.clear();
setup_matrices();
setup_drawing(false);
scene_ubs.projection = OpenGLMatrices.data(GL_PROJECTION);
scene_ubo->update(scene_ubs);
Render_cab(World.Train->Dynamic());
m_pick_fb->unbind();
@@ -497,6 +502,23 @@ void opengl_renderer::Render_pass(rendermode const Mode)
case rendermode::pickscenery:
{
if (!World.InitPerformed())
break;
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glViewport(0, 0, EU07_PICKBUFFERSIZE, EU07_PICKBUFFERSIZE);
m_pick_fb->bind();
m_pick_fb->clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_picksceneryitems.clear();
setup_matrices();
setup_drawing(false);
scene_ubs.projection = OpenGLMatrices.data(GL_PROJECTION);
scene_ubo->update(scene_ubs);
Render(simulation::Region);
break;
}
@@ -889,8 +911,7 @@ std::shared_ptr<gl::program> opengl_renderer::Fetch_Shader(const std::string &na
if (it == m_shaders.end())
{
gl::shader fragment("mat_" + name + ".frag");
gl::program *program = new gl::program_mvp({fragment, *m_vertex_shader.get()});
program->init();
gl::program *program = new gl::program({fragment, *m_vertex_shader.get()});
m_shaders.insert({name, std::shared_ptr<gl::program>(program)});
}
@@ -990,9 +1011,6 @@ void opengl_renderer::Render(scene::basic_region *Region)
{
case rendermode::color:
{
Update_Lights(simulation::Lights);
Render(std::begin(m_sectionqueue), std::end(m_sectionqueue));
// draw queue is filled while rendering sections
Render(std::begin(m_cellqueue), std::end(m_cellqueue));
@@ -1035,6 +1053,8 @@ void opengl_renderer::Render(section_sequence::iterator First, section_sequence:
}
case rendermode::pickscenery:
{
// non-interactive scenery elements get neutral colour
model_ubs.param[0] = colors::none;
break;
}
default:
@@ -1177,6 +1197,26 @@ void opengl_renderer::Render(cell_sequence::iterator First, cell_sequence::itera
break;
}
case rendermode::pickscenery:
{
// same procedure like with regular render, but editor-enabled nodes receive custom colour used for picking
// since all shapes of the section share center point we can optimize out a few calls here
::glPushMatrix();
auto const originoffset{cell->m_area.center - m_renderpass.camera.position()};
::glTranslated(originoffset.x, originoffset.y, originoffset.z);
// render
// opaque non-instanced shapes
// non-interactive scenery elements get neutral colour
model_ubs.param[0] = colors::none;
for (auto const &shape : cell->m_shapesopaque)
Render(shape, false);
// tracks
for (auto *path : cell->m_paths)
{
model_ubs.param[0] = glm::vec4(pick_color(m_picksceneryitems.size() + 1), 1.0f);
Render(path);
}
break;
}
case rendermode::reflections:
case rendermode::pickcontrols:
default:
@@ -1214,6 +1254,17 @@ void opengl_renderer::Render(cell_sequence::iterator First, cell_sequence::itera
break;
}
case rendermode::pickscenery:
{
// opaque parts of instanced models
// same procedure like with regular render, but each node receives custom colour used for picking
for (auto *instance : cell->m_instancesopaque)
{
model_ubs.param[0] = glm::vec4(pick_color(m_picksceneryitems.size() + 1), 1.0f);
Render(instance);
}
// vehicles aren't included in scenery picking for the time being
break;
}
case rendermode::reflections:
case rendermode::pickcontrols:
default:
@@ -1255,19 +1306,22 @@ void opengl_renderer::Render(scene::shape_node const &Shape, bool const Ignorera
}
// setup
Bind_Material(data.material);
switch (m_renderpass.draw_mode)
{
case rendermode::color:
Bind_Material(data.material);
break;
case rendermode::reflections:
// pick modes are painted with custom colours, and shadow pass doesn't use any
break;
case rendermode::shadows:
m_shadow_shader->bind();
break;
case rendermode::pickscenery:
case rendermode::pickcontrols:
default:
{
m_pick_shader->bind();
break;
default:
break;
}
}
// render
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
@@ -1311,6 +1365,8 @@ void opengl_renderer::Render(TAnimModel *Instance)
{
case rendermode::pickscenery:
{
// add the node to the pick list
m_picksceneryitems.emplace_back(Instance);
break;
}
default:
@@ -1583,6 +1639,9 @@ bool opengl_renderer::Render(TModel3d *Model, material_data const *Material, flo
void opengl_renderer::Render(TSubModel *Submodel)
{
// if (Submodel->m_geometry.bank == 5)
// return;
glDebug("Render TSubModel");
if ((Submodel->iVisible) && (TSubModel::fSquareDist >= Submodel->fSquareMinDist) && (TSubModel::fSquareDist < Submodel->fSquareMaxDist))
@@ -1699,7 +1758,13 @@ void opengl_renderer::Render(TSubModel *Submodel)
}
case rendermode::cabshadows:
case rendermode::pickscenery:
{
m_pick_shader->bind();
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
model_ubo->update(model_ubs);
m_geometry.draw(Submodel->m_geometry);
break;
}
case rendermode::pickcontrols:
{
m_pick_shader->bind();
@@ -1842,7 +1907,6 @@ void opengl_renderer::Render(TTrack *Track)
++m_debugstats.drawcalls;
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
model_ubo->update(model_ubs);
switch (m_renderpass.draw_mode)
{
@@ -1853,11 +1917,13 @@ void opengl_renderer::Render(TTrack *Track)
if (Track->m_material1 != 0)
{
Bind_Material(Track->m_material1);
model_ubo->update(model_ubs);
m_geometry.draw(std::begin(Track->Geometry1), std::end(Track->Geometry1));
}
if (Track->m_material2 != 0)
{
Bind_Material(Track->m_material2);
model_ubo->update(model_ubs);
m_geometry.draw(std::begin(Track->Geometry2), std::end(Track->Geometry2));
}
setup_environment_light();
@@ -1871,6 +1937,13 @@ void opengl_renderer::Render(TTrack *Track)
}
case rendermode::pickscenery:
{
m_picksceneryitems.emplace_back(Track);
model_ubs.param[0] = glm::vec4(pick_color(m_picksceneryitems.size() + 1), 1.0f);
model_ubo->update(model_ubs);
m_pick_shader->bind();
m_geometry.draw(std::begin(Track->Geometry1), std::end(Track->Geometry1));
m_geometry.draw(std::begin(Track->Geometry2), std::end(Track->Geometry2));
break;
}
case rendermode::pickcontrols:
@@ -1901,7 +1974,6 @@ void opengl_renderer::Render(scene::basic_cell::path_sequence::const_iterator Fi
}
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
model_ubo->update(model_ubs);
// first pass, material 1
for (auto first{First}; first != Last; ++first)
@@ -1931,6 +2003,7 @@ void opengl_renderer::Render(scene::basic_cell::path_sequence::const_iterator Fi
setup_environment_light(track->eEnvironment);
}
Bind_Material(track->m_material1);
model_ubo->update(model_ubs);
m_geometry.draw(std::begin(track->Geometry1), std::end(track->Geometry1));
if (track->eEnvironment != e_flat)
{
@@ -1947,6 +2020,7 @@ void opengl_renderer::Render(scene::basic_cell::path_sequence::const_iterator Fi
continue;
}
m_shadow_shader->bind();
model_ubo->update(model_ubs);
m_geometry.draw(std::begin(track->Geometry1), std::end(track->Geometry1));
break;
}
@@ -1983,6 +2057,7 @@ void opengl_renderer::Render(scene::basic_cell::path_sequence::const_iterator Fi
setup_environment_light(track->eEnvironment);
}
Bind_Material(track->m_material2);
model_ubo->update(model_ubs);
m_geometry.draw(std::begin(track->Geometry2), std::end(track->Geometry2));
if (track->eEnvironment != e_flat)
{
@@ -2218,12 +2293,13 @@ void opengl_renderer::Render_Alpha(TTraction *Traction)
}
// setup
auto const distance{static_cast<float>(std::sqrt(distancesquared))};
auto const linealpha{20.f * Traction->WireThickness / std::max(0.5f * Traction->radius() + 1.f, distance - (0.5f * Traction->radius()))};
auto const linealpha = glm::clamp(20.f * Traction->WireThickness / std::max(0.5f * Traction->radius() + 1.f, distance - (0.5f * Traction->radius())), 0.0f, 1.0f);
if (m_widelines_supported)
glLineWidth(clamp(0.5f * linealpha + Traction->WireThickness * Traction->radius() / 1000.f, 1.f, 1.5f));
// McZapkie-261102: kolor zalezy od materialu i zasniedzenia
// render
// McZapkie-261102: kolor zalezy od materialu i zasniedzenia
model_ubs.param[0] = glm::vec4(Traction->wire_color(), linealpha);
model_ubs.set_modelview(OpenGLMatrices.data(GL_MODELVIEW));
model_ubo->update(model_ubs);
@@ -2258,9 +2334,9 @@ void opengl_renderer::Render_Alpha(scene::lines_node const &Lines)
}
// setup
auto const distance{static_cast<float>(std::sqrt(distancesquared))};
auto const linealpha = (data.line_width > 0.f ? 10.f * data.line_width /
auto const linealpha = (data.line_width > 0.f ? glm::clamp(10.f * data.line_width /
std::max(0.5f * data.area.radius + 1.f,
distance - (0.5f * data.area.radius)) :
distance - (0.5f * data.area.radius)), 0.0f, 1.0f) :
1.f); // negative width means the lines are always opague
if (m_widelines_supported)
glLineWidth(clamp(0.5f * linealpha + data.line_width * data.area.radius / 1000.f, 1.f, 8.f));
@@ -2632,12 +2708,37 @@ TSubModel const *opengl_renderer::Update_Pick_Control()
scene::basic_node const *opengl_renderer::Update_Pick_Node()
{
return nullptr;
Render_pass(rendermode::pickscenery);
// determine point to examine
glm::dvec2 mousepos;
glfwGetCursorPos(m_window, &mousepos.x, &mousepos.y);
mousepos.y = Global.iWindowHeight - mousepos.y; // cursor coordinates are flipped compared to opengl
glm::ivec2 pickbufferpos;
pickbufferpos = glm::ivec2{mousepos.x * EU07_PICKBUFFERSIZE / std::max(1, Global.iWindowWidth), mousepos.y * EU07_PICKBUFFERSIZE / std::max(1, Global.iWindowHeight)};
unsigned char pickreadout[3];
// m7t: ! replace with PBO and wait frame or two to improve performance
// (and don't clash with control picking)
m_pick_fb->bind();
::glReadPixels(pickbufferpos.x, pickbufferpos.y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pickreadout);
m_pick_fb->unbind();
auto const nodeindex = pick_index(glm::ivec3{pickreadout[0], pickreadout[1], pickreadout[2]});
scene::basic_node const *node{nullptr};
if ((nodeindex > 0) && (nodeindex <= m_picksceneryitems.size()))
{
node = m_picksceneryitems[nodeindex - 1];
}
m_picksceneryitem = node;
return node;
}
void opengl_renderer::Update(double const Deltatime)
{
m_updateaccumulator += Deltatime;
if (m_updateaccumulator < 1.0)

View File

@@ -19,11 +19,11 @@ http://mozilla.org/MPL/2.0/.
#include "MemCell.h"
#include "scene.h"
#include "light.h"
#include "gl/shader_mvp.h"
#include "gl/ubo.h"
#include "gl/framebuffer.h"
#include "gl/renderbuffer.h"
#include "gl/postfx.h"
#include "gl/shader.h"
#define EU07_USE_PICKING_FRAMEBUFFER
//#define EU07_USE_DEBUG_SHADOWMAP

View File

@@ -121,8 +121,7 @@ void CSkyDome::Render() {
{
gl::shader vert("vbocolor.vert");
gl::shader frag("color.frag");
m_shader = std::make_unique<gl::program_mvp>(std::vector<std::reference_wrapper<const gl::shader>>({vert, frag}));
m_shader->init();
m_shader = std::make_unique<gl::program>(std::vector<std::reference_wrapper<const gl::shader>>({vert, frag}));
}
if( m_vertexbuffer == -1 ) {

View File

@@ -1,7 +1,7 @@
#pragma once
#include "gl/shader_mvp.h"
#include "gl/vao.h"
#include "gl/shader.h"
#include <memory>
// sky gradient based on "A practical analytic model for daylight"
@@ -65,6 +65,6 @@ private:
float PerezFunctionO1( float Perezcoeffs[ 5 ], const float Thetasun, const float Zenithval );
float PerezFunctionO2( float Perezcoeffs[ 5 ], const float Icostheta, const float Gamma, const float Cosgamma2, const float Zenithval );
std::unique_ptr<gl::program_mvp> m_shader;
std::unique_ptr<gl::program> m_shader;
std::unique_ptr<gl::vao> m_vao;
};

View File

@@ -176,8 +176,6 @@ ui_layer::render() {
render_progress();
render_tooltip();
//ImGui::ShowDemoWindow();
std::string uitextline1, uitextline2, uitextline3, uitextline4;
@@ -206,6 +204,8 @@ ui_layer::render() {
"" ) );
}
render_tooltip();
if (m_f1active)
{
ImGui::SetNextWindowSize(ImVec2(0, 0));