mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
restore depth based world mouse position
This commit is contained in:
@@ -55,26 +55,34 @@ void gl::framebuffer::clear(GLbitfield mask)
|
||||
glClear(mask);
|
||||
}
|
||||
|
||||
void gl::framebuffer::blit_to(framebuffer &other, int w, int h, GLbitfield mask, GLenum attachment)
|
||||
void gl::framebuffer::blit_to(framebuffer *other, int w, int h, GLbitfield mask, GLenum attachment)
|
||||
{
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, *this);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, other);
|
||||
|
||||
int attachment_n = attachment - GL_COLOR_ATTACHMENT0;
|
||||
|
||||
GLenum outputs[8] = { GL_NONE };
|
||||
outputs[attachment_n] = attachment;
|
||||
|
||||
glReadBuffer(attachment);
|
||||
glDrawBuffers(attachment_n + 1, outputs);
|
||||
|
||||
glBlitFramebuffer(0, 0, w, h, 0, 0, w, h, mask, GL_NEAREST);
|
||||
unbind();
|
||||
blit(this, other, 0, 0, w, h, mask, attachment);
|
||||
}
|
||||
|
||||
void gl::framebuffer::blit_from(framebuffer &other, int w, int h, GLbitfield mask, GLenum attachment)
|
||||
void gl::framebuffer::blit_from(framebuffer *other, int w, int h, GLbitfield mask, GLenum attachment)
|
||||
{
|
||||
other.blit_to(*this, w, h, mask, attachment);
|
||||
blit(other, this, 0, 0, w, h, mask, attachment);
|
||||
}
|
||||
|
||||
void gl::framebuffer::blit(framebuffer *src, framebuffer *dst, int sx, int sy, int w, int h, GLbitfield mask, GLenum attachment)
|
||||
{
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, src ? *src : 0);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dst ? *dst : 0);
|
||||
|
||||
if (mask & GL_COLOR_BUFFER_BIT)
|
||||
{
|
||||
int attachment_n = attachment - GL_COLOR_ATTACHMENT0;
|
||||
|
||||
GLenum outputs[8] = { GL_NONE };
|
||||
outputs[attachment_n] = attachment;
|
||||
|
||||
glReadBuffer(attachment);
|
||||
glDrawBuffers(attachment_n + 1, outputs);
|
||||
}
|
||||
|
||||
glBlitFramebuffer(sx, sy, sx + w, sy + h, 0, 0, w, h, mask, GL_NEAREST);
|
||||
unbind();
|
||||
}
|
||||
|
||||
void gl::framebuffer::setup_drawing(int attachments)
|
||||
|
||||
@@ -22,8 +22,10 @@ namespace gl
|
||||
void clear(GLbitfield mask);
|
||||
|
||||
bool is_complete();
|
||||
void blit_to(framebuffer &other, int w, int h, GLbitfield mask, GLenum attachment);
|
||||
void blit_from(framebuffer &other, int w, int h, GLbitfield mask, GLenum attachment);
|
||||
void blit_to(framebuffer *other, int w, int h, GLbitfield mask, GLenum attachment);
|
||||
void blit_from(framebuffer *other, int w, int h, GLbitfield mask, GLenum attachment);
|
||||
|
||||
static void blit(framebuffer *src, framebuffer *dst, int sx, int sy, int w, int h, GLbitfield mask, GLenum attachment);
|
||||
|
||||
using bindable::bind;
|
||||
static void bind(GLuint id);
|
||||
|
||||
10
gl/pbo.cpp
10
gl/pbo.cpp
@@ -1,8 +1,8 @@
|
||||
#include "pbo.h"
|
||||
|
||||
void gl::pbo::request_read(int x, int y, int lx, int ly)
|
||||
void gl::pbo::request_read(int x, int y, int lx, int ly, int pixsize, GLenum format, GLenum type)
|
||||
{
|
||||
int s = lx * ly * 4;
|
||||
int s = lx * ly * pixsize;
|
||||
if (s != size)
|
||||
allocate(PIXEL_PACK_BUFFER, s, GL_STREAM_DRAW);
|
||||
size = s;
|
||||
@@ -11,20 +11,20 @@ void gl::pbo::request_read(int x, int y, int lx, int ly)
|
||||
sync.reset();
|
||||
|
||||
bind(PIXEL_PACK_BUFFER);
|
||||
glReadPixels(x, y, lx, ly, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
glReadPixels(x, y, lx, ly, format, type, 0);
|
||||
unbind(PIXEL_PACK_BUFFER);
|
||||
|
||||
sync.emplace();
|
||||
}
|
||||
|
||||
bool gl::pbo::read_data(int lx, int ly, uint8_t *data)
|
||||
bool gl::pbo::read_data(int lx, int ly, void *data, int pixsize)
|
||||
{
|
||||
is_busy();
|
||||
|
||||
if (!data_ready)
|
||||
return false;
|
||||
|
||||
int s = lx * ly * 4;
|
||||
int s = lx * ly * pixsize;
|
||||
if (s != size)
|
||||
return false;
|
||||
|
||||
|
||||
4
gl/pbo.h
4
gl/pbo.h
@@ -10,8 +10,8 @@ namespace gl {
|
||||
bool data_ready;
|
||||
|
||||
public:
|
||||
void request_read(int x, int y, int lx, int ly);
|
||||
bool read_data(int lx, int ly, uint8_t *data);
|
||||
void request_read(int x, int y, int lx, int ly, int pixsize = 4, GLenum format = GL_RGBA, GLenum type = GL_UNSIGNED_BYTE);
|
||||
bool read_data(int lx, int ly, void *data, int pixsize = 4);
|
||||
bool is_busy();
|
||||
};
|
||||
}
|
||||
|
||||
2
map.cpp
2
map.cpp
@@ -166,7 +166,7 @@ void map::render(scene::basic_region *Region)
|
||||
GfxRenderer.Draw_Geometry(m_section_handles.begin(), m_section_handles.end());
|
||||
|
||||
if (Global.iMultisampling)
|
||||
m_fb->blit_from(*m_msaa_fb, size.x, size.y, GL_COLOR_BUFFER_BIT, GL_COLOR_ATTACHMENT0);
|
||||
m_fb->blit_from(m_msaa_fb.get(), size.x, size.y, GL_COLOR_BUFFER_BIT, GL_COLOR_ATTACHMENT0);
|
||||
|
||||
gl::framebuffer::unbind();
|
||||
m_shader->unbind();
|
||||
|
||||
175
renderer.cpp
175
renderer.cpp
@@ -161,6 +161,8 @@ bool opengl_renderer::Init(GLFWwindow *Window)
|
||||
m_pick_shader = make_shader("vertexonly.vert", "pick.frag");
|
||||
m_billboard_shader = make_shader("simpleuv.vert", "billboard.frag");
|
||||
m_celestial_shader = make_shader("celestial.vert", "celestial.frag");
|
||||
if (Global.gfx_usegles)
|
||||
m_depth_pointer_shader = make_shader("quad.vert", "gles_depthpointer.frag");
|
||||
m_invalid_material = Fetch_Material("invalid");
|
||||
}
|
||||
catch (gl::shader_exception const &e)
|
||||
@@ -296,7 +298,59 @@ bool opengl_renderer::Init(GLFWwindow *Window)
|
||||
|
||||
m_picking_pbo = std::make_unique<gl::pbo>();
|
||||
m_picking_node_pbo = std::make_unique<gl::pbo>();
|
||||
WriteLog("picking pbos created");
|
||||
|
||||
m_depth_pointer_pbo = std::make_unique<gl::pbo>();
|
||||
if (!Global.gfx_usegles && Global.iMultisampling)
|
||||
{
|
||||
m_depth_pointer_rb = std::make_unique<gl::renderbuffer>();
|
||||
m_depth_pointer_rb->alloc(Global.gfx_format_depth, 1, 1);
|
||||
|
||||
m_depth_pointer_fb = std::make_unique<gl::framebuffer>();
|
||||
m_depth_pointer_fb->attach(*m_depth_pointer_rb, GL_DEPTH_ATTACHMENT);
|
||||
|
||||
if (!m_depth_pointer_fb->is_complete())
|
||||
return false;
|
||||
}
|
||||
else if (Global.gfx_usegles)
|
||||
{
|
||||
m_depth_pointer_tex = std::make_unique<opengl_texture>();
|
||||
|
||||
GLenum format = Global.gfx_format_depth;
|
||||
if (Global.gfx_skippipeline)
|
||||
{
|
||||
gl::framebuffer::unbind();
|
||||
GLint bits, type;
|
||||
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH, GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, &bits);
|
||||
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH, GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, &type);
|
||||
if (type == GL_FLOAT && bits == 32)
|
||||
format = GL_DEPTH_COMPONENT32F;
|
||||
else if (bits == 16)
|
||||
format = GL_DEPTH_COMPONENT16;
|
||||
else if (bits == 24)
|
||||
format = GL_DEPTH_COMPONENT24;
|
||||
else if (bits == 32)
|
||||
format = GL_DEPTH_COMPONENT32;
|
||||
}
|
||||
|
||||
m_depth_pointer_tex->alloc_rendertarget(format, GL_DEPTH_COMPONENT, Global.gfx_framebuffer_width, Global.gfx_framebuffer_height);
|
||||
|
||||
m_depth_pointer_rb = std::make_unique<gl::renderbuffer>();
|
||||
m_depth_pointer_rb->alloc(GL_R16UI, Global.gfx_framebuffer_width, Global.gfx_framebuffer_height);
|
||||
|
||||
m_depth_pointer_fb = std::make_unique<gl::framebuffer>();
|
||||
m_depth_pointer_fb->attach(*m_depth_pointer_tex, GL_DEPTH_ATTACHMENT);
|
||||
|
||||
m_depth_pointer_fb2 = std::make_unique<gl::framebuffer>();
|
||||
m_depth_pointer_fb2->attach(*m_depth_pointer_rb, GL_COLOR_ATTACHMENT0);
|
||||
|
||||
if (!m_depth_pointer_fb->is_complete())
|
||||
return false;
|
||||
|
||||
if (!m_depth_pointer_fb2->is_complete())
|
||||
return false;
|
||||
}
|
||||
|
||||
WriteLog("picking objects created");
|
||||
|
||||
WriteLog("renderer initialization finished!");
|
||||
|
||||
@@ -555,8 +609,8 @@ void opengl_renderer::Render_pass(rendermode const Mode)
|
||||
if (Global.gfx_postfx_motionblur_enabled)
|
||||
{
|
||||
m_main_fb->clear(GL_COLOR_BUFFER_BIT);
|
||||
m_msaa_fb->blit_to(*m_main_fb.get(), Global.gfx_framebuffer_width, Global.gfx_framebuffer_height, GL_COLOR_BUFFER_BIT, GL_COLOR_ATTACHMENT0);
|
||||
m_msaa_fb->blit_to(*m_main_fb.get(), Global.gfx_framebuffer_width, Global.gfx_framebuffer_height, GL_COLOR_BUFFER_BIT, GL_COLOR_ATTACHMENT1);
|
||||
m_msaa_fb->blit_to(m_main_fb.get(), Global.gfx_framebuffer_width, Global.gfx_framebuffer_height, GL_COLOR_BUFFER_BIT, GL_COLOR_ATTACHMENT0);
|
||||
m_msaa_fb->blit_to(m_main_fb.get(), Global.gfx_framebuffer_width, Global.gfx_framebuffer_height, GL_COLOR_BUFFER_BIT, GL_COLOR_ATTACHMENT1);
|
||||
|
||||
model_ubs.param[0].x = m_framerate / (1.0 / Global.gfx_postfx_motionblur_shutter);
|
||||
model_ubo->update(model_ubs);
|
||||
@@ -565,7 +619,7 @@ void opengl_renderer::Render_pass(rendermode const Mode)
|
||||
else
|
||||
{
|
||||
m_main2_fb->clear(GL_COLOR_BUFFER_BIT);
|
||||
m_msaa_fb->blit_to(*m_main2_fb.get(), Global.gfx_framebuffer_width, Global.gfx_framebuffer_height, GL_COLOR_BUFFER_BIT, GL_COLOR_ATTACHMENT0);
|
||||
m_msaa_fb->blit_to(m_main2_fb.get(), Global.gfx_framebuffer_width, Global.gfx_framebuffer_height, GL_COLOR_BUFFER_BIT, GL_COLOR_ATTACHMENT0);
|
||||
}
|
||||
|
||||
if (!Global.gfx_usegles && !Global.gfx_shadergamma)
|
||||
@@ -1587,7 +1641,7 @@ void opengl_renderer::Render(scene::basic_region *Region)
|
||||
{
|
||||
// when editor mode is active calculate world position of the cursor
|
||||
// at this stage the z-buffer is filled with only ground geometry
|
||||
Update_Mouse_Position();
|
||||
get_mouse_depth();
|
||||
}
|
||||
Render(std::begin(m_cellqueue), std::end(m_cellqueue));
|
||||
break;
|
||||
@@ -3411,7 +3465,7 @@ void opengl_renderer::Update_Pick_Node()
|
||||
m_node_pick_requests.clear();
|
||||
}
|
||||
|
||||
if (!m_picking_node_pbo->is_busy())
|
||||
if (!m_node_pick_requests.empty())
|
||||
{
|
||||
// determine point to examine
|
||||
glm::dvec2 mousepos = Application.get_cursor_pos();
|
||||
@@ -3439,29 +3493,100 @@ void opengl_renderer::pick_node(std::function<void(scene::basic_node *)> callbac
|
||||
m_node_pick_requests.push_back(callback);
|
||||
}
|
||||
|
||||
glm::dvec3 opengl_renderer::Update_Mouse_Position()
|
||||
glm::dvec3 opengl_renderer::get_mouse_depth()
|
||||
{
|
||||
// m7t: we need to blit multisampled framebuffer into regular one
|
||||
// and better to use PBO and wait frame or two to improve performance
|
||||
/*
|
||||
glm::dvec2 mousepos;
|
||||
glfwGetCursorPos( m_window, &mousepos.x, &mousepos.y );
|
||||
mousepos = glm::ivec2{mousepos.x * Global.render_width / std::max(1, Global.iWindowWidth), mousepos.y * Global.render_height / std::max(1, Global.iWindowHeight)};
|
||||
GLfloat pointdepth;
|
||||
::glReadPixels( mousepos.x, mousepos.y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &pointdepth );
|
||||
if (!m_depth_pointer_pbo->is_busy())
|
||||
{
|
||||
// determine point to examine
|
||||
glm::dvec2 mousepos = Application.get_cursor_pos();
|
||||
mousepos.y = Global.iWindowHeight - mousepos.y; // cursor coordinates are flipped compared to opengl
|
||||
|
||||
if( pointdepth < 1.0 ) {
|
||||
m_worldmousecoordinates =
|
||||
glm::unProject(
|
||||
glm::vec3{ mousepos, pointdepth },
|
||||
glm::mat4{ glm::mat3{ m_colorpass.camera.modelview() } },
|
||||
m_colorpass.camera.projection(),
|
||||
glm::vec4{ 0, 0, Global.render_width, Global.render_height } );
|
||||
glm::ivec2 bufferpos;
|
||||
bufferpos = glm::ivec2{mousepos.x * Global.gfx_framebuffer_width / std::max(1, Global.iWindowWidth),
|
||||
mousepos.y * Global.gfx_framebuffer_height / std::max(1, Global.iWindowHeight)};
|
||||
bufferpos = glm::clamp(bufferpos, glm::ivec2(0, 0), glm::ivec2(Global.gfx_framebuffer_width - 1, Global.gfx_framebuffer_height - 1));
|
||||
|
||||
float pointdepth = std::numeric_limits<float>::max();
|
||||
|
||||
if (!Global.gfx_usegles)
|
||||
{
|
||||
m_depth_pointer_pbo->read_data(1, 1, &pointdepth, 4);
|
||||
|
||||
if (!Global.iMultisampling)
|
||||
{
|
||||
m_depth_pointer_pbo->request_read(bufferpos.x, bufferpos.y, 1, 1, 4, GL_DEPTH_COMPONENT, GL_FLOAT);
|
||||
}
|
||||
else if (Global.gfx_skippipeline)
|
||||
{
|
||||
gl::framebuffer::blit(nullptr, m_depth_pointer_fb.get(), bufferpos.x, bufferpos.y, 1, 1, GL_DEPTH_BUFFER_BIT, 0);
|
||||
|
||||
m_depth_pointer_fb->bind();
|
||||
m_depth_pointer_pbo->request_read(0, 0, 1, 1, 4, GL_DEPTH_COMPONENT, GL_FLOAT);
|
||||
m_depth_pointer_fb->unbind();
|
||||
}
|
||||
else
|
||||
{
|
||||
gl::framebuffer::blit(m_msaa_fb.get(), m_depth_pointer_fb.get(), bufferpos.x, bufferpos.y, 1, 1, GL_DEPTH_BUFFER_BIT, 0);
|
||||
|
||||
m_depth_pointer_fb->bind();
|
||||
m_depth_pointer_pbo->request_read(0, 0, 1, 1, 4, GL_DEPTH_COMPONENT, GL_FLOAT);
|
||||
m_msaa_fb->bind();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int data[4];
|
||||
if (m_depth_pointer_pbo->read_data(1, 1, data, 16))
|
||||
pointdepth = (double)data[0] / 65535.0;
|
||||
|
||||
if (Global.gfx_skippipeline)
|
||||
{
|
||||
gl::framebuffer::blit(nullptr, m_depth_pointer_fb.get(), 0, 0, Global.gfx_framebuffer_width, Global.gfx_framebuffer_height, GL_DEPTH_BUFFER_BIT, 0);
|
||||
|
||||
m_empty_vao->bind();
|
||||
m_depth_pointer_tex->bind(0);
|
||||
m_depth_pointer_shader->bind();
|
||||
m_depth_pointer_fb2->bind();
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
m_depth_pointer_pbo->request_read(bufferpos.x, bufferpos.y, 1, 1, 16, GL_RGBA_INTEGER, GL_UNSIGNED_INT);
|
||||
m_depth_pointer_shader->unbind();
|
||||
m_empty_vao->unbind();
|
||||
m_depth_pointer_fb2->unbind();
|
||||
}
|
||||
else
|
||||
{
|
||||
gl::framebuffer::blit(m_msaa_fb.get(), m_depth_pointer_fb.get(), 0, 0, Global.gfx_framebuffer_width, Global.gfx_framebuffer_height, GL_DEPTH_BUFFER_BIT, 0);
|
||||
|
||||
m_empty_vao->bind();
|
||||
m_depth_pointer_tex->bind(0);
|
||||
m_depth_pointer_shader->bind();
|
||||
m_depth_pointer_fb2->bind();
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
m_depth_pointer_pbo->request_read(bufferpos.x, bufferpos.y, 1, 1, 16, GL_RGBA_INTEGER, GL_UNSIGNED_INT);
|
||||
m_depth_pointer_shader->unbind();
|
||||
m_empty_vao->unbind();
|
||||
m_msaa_fb->bind();
|
||||
}
|
||||
}
|
||||
|
||||
return m_colorpass.camera.position() + glm::dvec3{ m_worldmousecoordinates };
|
||||
*/
|
||||
return glm::dvec3();
|
||||
if (pointdepth != std::numeric_limits<float>::max())
|
||||
{
|
||||
if (GLAD_GL_ARB_clip_control || GLAD_GL_EXT_clip_control)
|
||||
m_worldmousecoordinates = glm::unProjectZO(
|
||||
glm::vec3(bufferpos, pointdepth),
|
||||
glm::mat4(glm::mat3(m_colorpass.camera.modelview())),
|
||||
m_colorpass.camera.projection(),
|
||||
glm::vec4(0, 0, Global.gfx_framebuffer_width, Global.gfx_framebuffer_height));
|
||||
else
|
||||
m_worldmousecoordinates = glm::unProjectNO(
|
||||
glm::vec3(bufferpos, pointdepth),
|
||||
glm::mat4(glm::mat3(m_colorpass.camera.modelview())),
|
||||
m_colorpass.camera.projection(),
|
||||
glm::vec4(0, 0, Global.gfx_framebuffer_width, Global.gfx_framebuffer_height));
|
||||
}
|
||||
}
|
||||
|
||||
return m_colorpass.camera.position() + glm::dvec3{ m_worldmousecoordinates };
|
||||
}
|
||||
|
||||
void opengl_renderer::Update(double const Deltatime)
|
||||
|
||||
@@ -182,7 +182,7 @@ class opengl_renderer
|
||||
void Update(double const Deltatime);
|
||||
void Update_Pick_Control();
|
||||
void Update_Pick_Node();
|
||||
glm::dvec3 Update_Mouse_Position();
|
||||
glm::dvec3 get_mouse_depth();
|
||||
// debug methods
|
||||
std::string const &info_times() const;
|
||||
std::string const &info_stats() const;
|
||||
@@ -399,6 +399,13 @@ class opengl_renderer
|
||||
std::unique_ptr<gl::pbo> m_picking_pbo;
|
||||
std::unique_ptr<gl::pbo> m_picking_node_pbo;
|
||||
|
||||
std::unique_ptr<gl::pbo> m_depth_pointer_pbo;
|
||||
std::unique_ptr<gl::framebuffer> m_depth_pointer_fb;
|
||||
std::unique_ptr<gl::framebuffer> m_depth_pointer_fb2;
|
||||
std::unique_ptr<gl::renderbuffer> m_depth_pointer_rb;
|
||||
std::unique_ptr<opengl_texture> m_depth_pointer_tex;
|
||||
std::unique_ptr<gl::program> m_depth_pointer_shader;
|
||||
|
||||
material_handle m_invalid_material;
|
||||
|
||||
bool m_blendingenabled;
|
||||
|
||||
11
shaders/gles_depthpointer.frag
Normal file
11
shaders/gles_depthpointer.frag
Normal file
@@ -0,0 +1,11 @@
|
||||
in vec2 f_coords;
|
||||
|
||||
#texture (tex1, 0, R)
|
||||
uniform sampler2D tex1;
|
||||
|
||||
layout(location = 0) out uvec4 out_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
out_color = uvec4(uint(texture(tex1, f_coords).r * 65535.0), 0, 0, 0xFFFF);
|
||||
}
|
||||
Reference in New Issue
Block a user