mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-05 07:34:27 +01:00
Require OpenGL 4.6 core context and regenerate glad
This commit is contained in:
@@ -1201,6 +1201,33 @@ int eu07_application::init_locale()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the context of the required version couldn't be created. a context with default settings tells which version the
|
||||||
|
// driver does provide, so the user can be told what is missing
|
||||||
|
static std::string describe_gl_driver()
|
||||||
|
{
|
||||||
|
glfwDefaultWindowHints();
|
||||||
|
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
||||||
|
auto *probe = glfwCreateWindow(64, 64, "eu07 opengl probe", nullptr, nullptr);
|
||||||
|
if (probe == nullptr)
|
||||||
|
return "no OpenGL context";
|
||||||
|
|
||||||
|
glfwMakeContextCurrent(probe);
|
||||||
|
std::string description;
|
||||||
|
auto const getstring = reinterpret_cast<PFNGLGETSTRINGPROC>(glfwGetProcAddress("glGetString"));
|
||||||
|
if (getstring != nullptr)
|
||||||
|
{
|
||||||
|
auto const text = [&](GLenum const Name) {
|
||||||
|
auto const *value = reinterpret_cast<char const *>(getstring(Name));
|
||||||
|
return std::string(value != nullptr ? value : "?");
|
||||||
|
};
|
||||||
|
description = "OpenGL " + text(GL_VERSION) + ", " + text(GL_RENDERER) + " (" + text(GL_VENDOR) + ")";
|
||||||
|
}
|
||||||
|
glfwMakeContextCurrent(nullptr);
|
||||||
|
glfwDestroyWindow(probe);
|
||||||
|
|
||||||
|
return description.empty() ? "unknown OpenGL version" : description;
|
||||||
|
}
|
||||||
|
|
||||||
int eu07_application::init_glfw()
|
int eu07_application::init_glfw()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
@@ -1244,11 +1271,12 @@ int eu07_application::init_glfw()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// activate core profile for opengl 3.3 renderer
|
// activate core profile for opengl 4.6 renderer
|
||||||
|
// NOTE: the hints stay in effect for the additional windows and shared contexts created later through window()
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
|
||||||
|
|
||||||
if (Global.gfx_gldebug)
|
if (Global.gfx_gldebug)
|
||||||
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);
|
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);
|
||||||
@@ -1268,6 +1296,21 @@ int eu07_application::init_glfw()
|
|||||||
|
|
||||||
if (mainwindow == nullptr)
|
if (mainwindow == nullptr)
|
||||||
{
|
{
|
||||||
|
if (needs_ogl())
|
||||||
|
{
|
||||||
|
char const *glfwerror = nullptr;
|
||||||
|
glfwGetError(&glfwerror);
|
||||||
|
std::string const reason = (glfwerror != nullptr ? glfwerror : "unknown error");
|
||||||
|
auto const driver = describe_gl_driver();
|
||||||
|
ErrorLog("Bad init: failed to create OpenGL 4.6 core profile context (" + reason + "); the graphics card/driver provides: " + driver);
|
||||||
|
#ifdef _WIN32
|
||||||
|
auto const message = "MaSzyna requires OpenGL 4.6 (core profile), but the OpenGL 4.6 context could not be created.\n\n"
|
||||||
|
"Your graphics card/driver provides:\n" + driver + "\n\n"
|
||||||
|
"Details: " + reason + "\n\n"
|
||||||
|
"Update the graphics driver or use a graphics card with OpenGL 4.6 support.";
|
||||||
|
MessageBoxA(nullptr, message.c_str(), "MaSzyna", MB_ICONERROR | MB_OK);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
ErrorLog("Bad init: failed to create glfw window");
|
ErrorLog("Bad init: failed to create glfw window");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,16 +81,7 @@ void gl::buffer::upload(targets target, const void *data, int offset, GLsizeiptr
|
|||||||
void gl::buffer::download(targets target, void *data, int offset, GLsizeiptr size)
|
void gl::buffer::download(targets target, void *data, int offset, GLsizeiptr size)
|
||||||
{
|
{
|
||||||
bind(target);
|
bind(target);
|
||||||
if (GLAD_GL_VERSION_3_3)
|
glGetBufferSubData(glenum_target(target), offset, size, data);
|
||||||
{
|
|
||||||
glGetBufferSubData(glenum_target(target), offset, size, data);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
void const *glbuf = glMapBufferRange(glenum_target(target), offset, size, GL_MAP_READ_BIT);
|
|
||||||
memcpy(data, glbuf, size);
|
|
||||||
glUnmapBuffer(glenum_target(target));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_local GLuint gl::buffer::binding_points[13];
|
thread_local GLuint gl::buffer::binding_points[13];
|
||||||
|
|||||||
@@ -14,44 +14,6 @@ inline bool strcend(std::string_view value, std::string_view ending)
|
|||||||
return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
|
return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
// The project's glad config only generates GLAD_GL_ARB_texture_filter_anisotropic
|
|
||||||
// among the ARB/EXT extension flags -- GL_ARB_texture_gather (desktop) and
|
|
||||||
// GL_EXT_gpu_shader5 (GLES 3.1) aren't compiled in, so we can't gate the
|
|
||||||
// shadow textureGather() optimisation on a GLAD constant. Query the live
|
|
||||||
// extension string instead. The first call walks the extension list once
|
|
||||||
// (no extension count in the dozens is large enough to matter here) and
|
|
||||||
// the result is cached in the static bool inside has_gl_extension(), so
|
|
||||||
// every subsequent shader compile is a plain bool read.
|
|
||||||
//
|
|
||||||
// SHADERVALIDATOR_STANDALONE gates out the GL queries because the offline
|
|
||||||
// shader validator tool links glad.c but never calls gladLoadGL(); the
|
|
||||||
// function pointers stay null and a real call would crash. Returning
|
|
||||||
// false there means the standalone validator simply compiles the original
|
|
||||||
// 16-tap PCF fallback path in light_common.glsl, which is what we want.
|
|
||||||
bool has_gl_extension(char const *name) {
|
|
||||||
#ifdef SHADERVALIDATOR_STANDALONE
|
|
||||||
(void)name;
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
if (!glGetIntegerv || !glGetStringi) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
GLint count = 0;
|
|
||||||
glGetIntegerv(GL_NUM_EXTENSIONS, &count);
|
|
||||||
for (GLint i = 0; i < count; ++i) {
|
|
||||||
auto ext = reinterpret_cast<char const *>(glGetStringi(GL_EXTENSIONS, i));
|
|
||||||
if (ext != nullptr && std::strcmp(ext, name) == 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
} // anonymous namespace
|
|
||||||
|
|
||||||
std::string gl::shader::read_file(const std::string &filename) const
|
std::string gl::shader::read_file(const std::string &filename) const
|
||||||
{
|
{
|
||||||
std::stringstream stream;
|
std::stringstream stream;
|
||||||
@@ -127,21 +89,7 @@ std::pair<GLuint, std::string> gl::shader::process_source(const std::string &fil
|
|||||||
else
|
else
|
||||||
throw shader_exception("unknown shader " + filename);
|
throw shader_exception("unknown shader " + filename);
|
||||||
|
|
||||||
str += "#version 330 core\n";
|
str += "#version 460 core\n";
|
||||||
// textureGather() on sampler2DArrayShadow is core in GLSL 4.0. On 3.30
|
|
||||||
// desktop it requires GL_ARB_gpu_shader5 -- the older
|
|
||||||
// GL_ARB_texture_gather (2010) only adds the non-shadow and the plain
|
|
||||||
// sampler2DShadow overloads, NOT the sampler2DArrayShadow one we need
|
|
||||||
// for cascaded shadow PCF. Some drivers advertise texture_gather but
|
|
||||||
// reject the shadow-array overload because the spec for it lives in
|
|
||||||
// gpu_shader5; so emit only when gpu_shader5 is advertised. When the
|
|
||||||
// extension is missing, calc_shadow() in light_common.glsl falls back
|
|
||||||
// to the original 16-tap hardware-PCF loop via #ifndef.
|
|
||||||
// (Project's glad config doesn't generate GLAD_GL_ARB_gpu_shader5,
|
|
||||||
// so we query the live extension list -- see has_gl_extension above.)
|
|
||||||
static bool const have_gpu_shader5 = has_gl_extension("GL_ARB_gpu_shader5");
|
|
||||||
if (have_gpu_shader5)
|
|
||||||
str += "#extension GL_ARB_gpu_shader5 : enable\n";
|
|
||||||
// expose the shader stage to glsl_common so vertex-only built-ins
|
// expose the shader stage to glsl_common so vertex-only built-ins
|
||||||
// (gl_InstanceID, effective_modelview, etc.) can be guarded out of
|
// (gl_InstanceID, effective_modelview, etc.) can be guarded out of
|
||||||
// fragment/geometry compilations.
|
// fragment/geometry compilations.
|
||||||
|
|||||||
@@ -424,8 +424,6 @@ void opengl_texture::update_from_memory(size_t width, size_t height, const uint8
|
|||||||
set_filtering();
|
set_filtering();
|
||||||
glTexParameteri(target, GL_TEXTURE_WRAP_S, wrap_mode_s);
|
glTexParameteri(target, GL_TEXTURE_WRAP_S, wrap_mode_s);
|
||||||
glTexParameteri(target, GL_TEXTURE_WRAP_T, wrap_mode_t);
|
glTexParameteri(target, GL_TEXTURE_WRAP_T, wrap_mode_t);
|
||||||
if (!glGenerateMipmap)
|
|
||||||
glTexParameteri(target, GL_GENERATE_MIPMAP, GL_TRUE);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -925,19 +923,7 @@ opengl_texture::bind(size_t unit) {
|
|||||||
|
|
||||||
if (units[unit] == id)
|
if (units[unit] == id)
|
||||||
return true;
|
return true;
|
||||||
if (GLAD_GL_ARB_direct_state_access)
|
glBindTextureUnit(unit, id);
|
||||||
{
|
|
||||||
glBindTextureUnit(unit, id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (unit != m_activeunit)
|
|
||||||
{
|
|
||||||
glActiveTexture(GL_TEXTURE0 + unit);
|
|
||||||
m_activeunit = unit;
|
|
||||||
}
|
|
||||||
glBindTexture(target, id);
|
|
||||||
}
|
|
||||||
units[unit] = id;
|
units[unit] = id;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -946,20 +932,7 @@ opengl_texture::bind(size_t unit) {
|
|||||||
void
|
void
|
||||||
opengl_texture::unbind(size_t unit)
|
opengl_texture::unbind(size_t unit)
|
||||||
{
|
{
|
||||||
if (GLAD_GL_ARB_direct_state_access)
|
glBindTextureUnit(unit, 0);
|
||||||
{
|
|
||||||
glBindTextureUnit(unit, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (unit != m_activeunit)
|
|
||||||
{
|
|
||||||
glActiveTexture(GL_TEXTURE0 + unit);
|
|
||||||
m_activeunit = unit;
|
|
||||||
}
|
|
||||||
//todo: for other targets
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
}
|
|
||||||
units[unit] = 0;
|
units[unit] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1053,10 +1026,6 @@ opengl_texture::create( bool const Static ) {
|
|||||||
|
|
||||||
auto blocksize_it = precompressed_formats.find(internal_format);
|
auto blocksize_it = precompressed_formats.find(internal_format);
|
||||||
|
|
||||||
if ( data_mapcount == 1 && !glGenerateMipmap ) {
|
|
||||||
glTexParameteri(target, GL_GENERATE_MIPMAP, GL_TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
for( int maplevel = 0; maplevel < data_mapcount; ++maplevel ) {
|
for( int maplevel = 0; maplevel < data_mapcount; ++maplevel ) {
|
||||||
|
|
||||||
if (blocksize_it != precompressed_formats.end())
|
if (blocksize_it != precompressed_formats.end())
|
||||||
@@ -1228,8 +1197,7 @@ opengl_texture::set_filtering() const
|
|||||||
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||||
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
|
::glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
|
||||||
|
|
||||||
if (Global.AnisotropicFiltering >= 0
|
if (Global.AnisotropicFiltering >= 0) {
|
||||||
&& ( GLAD_GL_EXT_texture_filter_anisotropic || GLAD_GL_ARB_texture_filter_anisotropic) ) {
|
|
||||||
// anisotropic filtering
|
// anisotropic filtering
|
||||||
::glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, Global.AnisotropicFiltering );
|
::glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, Global.AnisotropicFiltering );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,8 +141,9 @@ std::vector<std::string> nodebank_entries()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// creates the hidden window with the gl context for the renderer. on a computer without a graphics driver able to provide
|
// creates the hidden window with the gl context for the renderer. on a computer without a graphics driver able to provide
|
||||||
// gl 3.3 the software rasterizer of mesa can take over: on linux mesa picks it by itself, on windows its opengl32.dll
|
// gl 4.6 the software rasterizer of mesa can take over: on linux mesa picks it by itself, on windows its opengl32.dll
|
||||||
// (with the libraries it needs) is looked for in the mesa folder
|
// (with the libraries it needs) is looked for in the mesa folder.
|
||||||
|
// llvmpipe implements everything gl 4.6 adds, but reports 4.5 (no formal 4.6 conformance), hence the version override
|
||||||
GLFWwindow *create_context(bool const Software)
|
GLFWwindow *create_context(bool const Software)
|
||||||
{
|
{
|
||||||
if (Software)
|
if (Software)
|
||||||
@@ -150,8 +151,12 @@ GLFWwindow *create_context(bool const Software)
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
auto const folder{std::filesystem::absolute("mesa")};
|
auto const folder{std::filesystem::absolute("mesa")};
|
||||||
::SetDllDirectoryW(folder.wstring().c_str());
|
::SetDllDirectoryW(folder.wstring().c_str());
|
||||||
|
::_putenv_s("MESA_GL_VERSION_OVERRIDE", "4.6");
|
||||||
|
::_putenv_s("MESA_GLSL_VERSION_OVERRIDE", "460");
|
||||||
#else
|
#else
|
||||||
::setenv("LIBGL_ALWAYS_SOFTWARE", "1", 1);
|
::setenv("LIBGL_ALWAYS_SOFTWARE", "1", 1);
|
||||||
|
::setenv("MESA_GL_VERSION_OVERRIDE", "4.6", 1);
|
||||||
|
::setenv("MESA_GLSL_VERSION_OVERRIDE", "460", 1);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (glfwInit() == GLFW_FALSE)
|
if (glfwInit() == GLFW_FALSE)
|
||||||
@@ -162,8 +167,8 @@ GLFWwindow *create_context(bool const Software)
|
|||||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
|
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
|
||||||
if (Global.gfx_gldebug)
|
if (Global.gfx_gldebug)
|
||||||
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);
|
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);
|
||||||
auto *window{glfwCreateWindow(64, 64, "eu07 previews", nullptr, nullptr)};
|
auto *window{glfwCreateWindow(64, 64, "eu07 previews", nullptr, nullptr)};
|
||||||
@@ -332,16 +337,16 @@ int generate_nodebank_previews(int Argc, char *Argv[])
|
|||||||
auto *window{create_context(settings.software)};
|
auto *window{create_context(settings.software)};
|
||||||
if ((window == nullptr) && (false == settings.software))
|
if ((window == nullptr) && (false == settings.software))
|
||||||
{
|
{
|
||||||
report("no gl 3.3 context from the graphics driver, trying the software renderer");
|
report("no gl 4.6 context from the graphics driver, trying the software renderer");
|
||||||
settings.software = true;
|
settings.software = true;
|
||||||
window = create_context(true);
|
window = create_context(true);
|
||||||
}
|
}
|
||||||
if (window == nullptr)
|
if (window == nullptr)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
report("failed to create gl 3.3 context. for computers without a capable graphics driver put opengl32.dll of mesa (with the libraries it comes with) in the mesa folder", true);
|
report("failed to create gl 4.6 context. for computers without a capable graphics driver put opengl32.dll of mesa (with the libraries it comes with) in the mesa folder", true);
|
||||||
#else
|
#else
|
||||||
report("failed to create gl 3.3 context. without a display run it through xvfb-run", true);
|
report("failed to create gl 4.6 context. without a display run it through xvfb-run", true);
|
||||||
#endif
|
#endif
|
||||||
return finish(1);
|
return finish(1);
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
1864
ref/glad/src/glad.c
1864
ref/glad/src/glad.c
File diff suppressed because it is too large
Load Diff
@@ -148,22 +148,12 @@ opengl46_vaogeometrybank::draw_( gfx::geometry_handle const &Geometry, gfx::stre
|
|||||||
}
|
}
|
||||||
// render
|
// render
|
||||||
if( chunkrecord.index_count > 0 ) {
|
if( chunkrecord.index_count > 0 ) {
|
||||||
if (glDrawRangeElementsBaseVertex) {
|
m_vao->bind();
|
||||||
m_vao->bind();
|
::glDrawRangeElementsBaseVertex(
|
||||||
::glDrawRangeElementsBaseVertex(
|
chunk.type,
|
||||||
chunk.type,
|
0, chunkrecord.vertex_count,
|
||||||
0, chunkrecord.vertex_count,
|
chunkrecord.index_count, GL_UNSIGNED_INT, reinterpret_cast<void const *>( chunkrecord.index_offset * sizeof( gfx::basic_index ) ),
|
||||||
chunkrecord.index_count, GL_UNSIGNED_INT, reinterpret_cast<void const *>( chunkrecord.index_offset * sizeof( gfx::basic_index ) ),
|
chunkrecord.vertex_offset );
|
||||||
chunkrecord.vertex_offset );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
setup_attrib(chunkrecord.vertex_offset);
|
|
||||||
m_vao->bind();
|
|
||||||
::glDrawRangeElements(
|
|
||||||
chunk.type,
|
|
||||||
0, chunkrecord.vertex_count,
|
|
||||||
chunkrecord.index_count, GL_UNSIGNED_INT, reinterpret_cast<void const *>( chunkrecord.index_offset * sizeof( gfx::basic_index ) ) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_vao->bind();
|
m_vao->bind();
|
||||||
@@ -208,25 +198,13 @@ opengl46_vaogeometrybank::draw_instanced_( gfx::geometry_handle const &Geometry,
|
|||||||
GLsizei const inst_count = static_cast<GLsizei>(InstanceCount);
|
GLsizei const inst_count = static_cast<GLsizei>(InstanceCount);
|
||||||
|
|
||||||
if( chunkrecord.index_count > 0 ) {
|
if( chunkrecord.index_count > 0 ) {
|
||||||
// GLES 3.0 context doesn't provide the base vertex variant, same fallbacks as in draw_()
|
m_vao->bind();
|
||||||
if( glDrawElementsInstancedBaseVertex ) {
|
::glDrawElementsInstancedBaseVertex(
|
||||||
m_vao->bind();
|
chunk.type,
|
||||||
::glDrawElementsInstancedBaseVertex(
|
chunkrecord.index_count, GL_UNSIGNED_INT,
|
||||||
chunk.type,
|
reinterpret_cast<void const *>( chunkrecord.index_offset * sizeof( gfx::basic_index ) ),
|
||||||
chunkrecord.index_count, GL_UNSIGNED_INT,
|
inst_count,
|
||||||
reinterpret_cast<void const *>( chunkrecord.index_offset * sizeof( gfx::basic_index ) ),
|
chunkrecord.vertex_offset );
|
||||||
inst_count,
|
|
||||||
chunkrecord.vertex_offset );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
setup_attrib( chunkrecord.vertex_offset );
|
|
||||||
m_vao->bind();
|
|
||||||
::glDrawElementsInstanced(
|
|
||||||
chunk.type,
|
|
||||||
chunkrecord.index_count, GL_UNSIGNED_INT,
|
|
||||||
reinterpret_cast<void const *>( chunkrecord.index_offset * sizeof( gfx::basic_index ) ),
|
|
||||||
inst_count );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_vao->bind();
|
m_vao->bind();
|
||||||
@@ -250,12 +228,6 @@ opengl46_vaogeometrybank::draw_batch_( gfx::geometry_handle const *First, gfx::g
|
|||||||
{
|
{
|
||||||
std::size_t count { 0 };
|
std::size_t count { 0 };
|
||||||
|
|
||||||
if( !glMultiDrawArrays ) {
|
|
||||||
// GLES context doesn't provide the call
|
|
||||||
for( ; First != Last; ++First ) { count += draw_( *First, Units, Streams ); }
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
setup_buffer();
|
setup_buffer();
|
||||||
|
|
||||||
std::array<GLint, 64> offsets;
|
std::array<GLint, 64> offsets;
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ ErrorCallback( GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei l
|
|||||||
|
|
||||||
bool opengl46_renderer::Init(GLFWwindow *Window)
|
bool opengl46_renderer::Init(GLFWwindow *Window)
|
||||||
{
|
{
|
||||||
if (Global.gfx_gldebug && GLAD_GL_KHR_debug) {
|
if (Global.gfx_gldebug) {
|
||||||
glEnable( GL_DEBUG_OUTPUT );
|
glEnable( GL_DEBUG_OUTPUT );
|
||||||
glEnable( GL_DEBUG_OUTPUT_SYNCHRONOUS );
|
glEnable( GL_DEBUG_OUTPUT_SYNCHRONOUS );
|
||||||
glDebugMessageControl( GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, nullptr, GL_FALSE );
|
glDebugMessageControl( GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, nullptr, GL_FALSE );
|
||||||
@@ -438,10 +438,7 @@ bool opengl46_renderer::init_viewport(viewport_config &vp)
|
|||||||
|
|
||||||
glDepthFunc(GL_GEQUAL);
|
glDepthFunc(GL_GEQUAL);
|
||||||
|
|
||||||
if (GLAD_GL_ARB_clip_control)
|
glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
|
||||||
glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
|
|
||||||
else if (GLAD_GL_EXT_clip_control)
|
|
||||||
glClipControlEXT(GL_LOWER_LEFT_EXT, GL_ZERO_TO_ONE_EXT);
|
|
||||||
|
|
||||||
glEnable(GL_PROGRAM_POINT_SIZE);
|
glEnable(GL_PROGRAM_POINT_SIZE);
|
||||||
|
|
||||||
@@ -1459,78 +1456,43 @@ glm::mat4 opengl46_renderer::perspective_projection(const viewport_proj_config &
|
|||||||
glm::mat4 R = frustum;
|
glm::mat4 R = frustum;
|
||||||
frustum = glm::translate(frustum * M, -c.pe);
|
frustum = glm::translate(frustum * M, -c.pe);
|
||||||
|
|
||||||
if (GLAD_GL_ARB_clip_control || GLAD_GL_EXT_clip_control) {
|
// clip_control: projection matrix with 1..0 Z range and infinite zfar
|
||||||
// when clip_control available, use projection matrix with 1..0 Z range and infinite zfar
|
R[2][2] = -1.0f;
|
||||||
R[2][2] = -1.0f;
|
R[3][2] = -2.0f * n;
|
||||||
R[3][2] = -2.0f * n;
|
R = glm::mat4( //
|
||||||
R = glm::mat4( //
|
1.0f, 0.0f, 0.0f, 0.0f, //
|
||||||
1.0f, 0.0f, 0.0f, 0.0f, //
|
0.0f, 1.0f, 0.0f, 0.0f, //
|
||||||
0.0f, 1.0f, 0.0f, 0.0f, //
|
0.0f, 0.0f, -0.5f, 0.0f, //
|
||||||
0.0f, 0.0f, -0.5f, 0.0f, //
|
0.0f, 0.0f, 0.5f, 1.0f //
|
||||||
0.0f, 0.0f, 0.5f, 1.0f //
|
) * R;
|
||||||
) * R;
|
|
||||||
} else {
|
|
||||||
// or use standard matrix but with 1..-1 Z range
|
|
||||||
// (reverse Z don't give any extra precision without clip_control, but it is used anyway for consistency)
|
|
||||||
R = glm::mat4(
|
|
||||||
1.0f, 0.0f, 0.0f, 0.0f, //
|
|
||||||
0.0f, 1.0f, 0.0f, 0.0f, //
|
|
||||||
0.0f, 0.0f, -1.0f, 0.0f, //
|
|
||||||
0.0f, 0.0f, 0.0f, 1.0f //
|
|
||||||
) * R;
|
|
||||||
}
|
|
||||||
|
|
||||||
return glm::translate(R * M, -c.pe);
|
return glm::translate(R * M, -c.pe);
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 opengl46_renderer::perspective_projection_raw(float fovy, float aspect, float znear, float zfar)
|
glm::mat4 opengl46_renderer::perspective_projection_raw(float fovy, float aspect, float znear, float zfar)
|
||||||
{
|
{
|
||||||
if (GLAD_GL_ARB_clip_control || GLAD_GL_EXT_clip_control)
|
const float f = 1.0f / std::tan(fovy / 2.0f);
|
||||||
{
|
|
||||||
const float f = 1.0f / std::tan(fovy / 2.0f);
|
|
||||||
|
|
||||||
// when clip_control available, use projection matrix with 1..0 Z range and infinite zfar
|
// clip_control: projection matrix with 1..0 Z range and infinite zfar
|
||||||
return glm::mat4( //
|
return glm::mat4( //
|
||||||
f / aspect, 0.0f, 0.0f, 0.0f, //
|
f / aspect, 0.0f, 0.0f, 0.0f, //
|
||||||
0.0f, f, 0.0f, 0.0f, //
|
0.0f, f, 0.0f, 0.0f, //
|
||||||
0.0f, 0.0f, 0.0f, -1.0f, //
|
0.0f, 0.0f, 0.0f, -1.0f, //
|
||||||
0.0f, 0.0f, znear, 0.0f //
|
0.0f, 0.0f, znear, 0.0f //
|
||||||
);
|
);
|
||||||
}
|
|
||||||
else
|
|
||||||
// or use standard matrix but with 1..-1 Z range
|
|
||||||
// (reverse Z don't give any extra precision without clip_control, but it is used anyway for consistency)
|
|
||||||
return glm::mat4( //
|
|
||||||
1.0f, 0.0f, 0.0f, 0.0f, //
|
|
||||||
0.0f, 1.0f, 0.0f, 0.0f, //
|
|
||||||
0.0f, 0.0f, -1.0f, 0.0f, //
|
|
||||||
0.0f, 0.0f, 0.0f, 1.0f //
|
|
||||||
) *
|
|
||||||
glm::perspective(fovy, aspect, znear, zfar);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 opengl46_renderer::ortho_projection(float l, float r, float b, float t, float znear, float zfar)
|
glm::mat4 opengl46_renderer::ortho_projection(float l, float r, float b, float t, float znear, float zfar)
|
||||||
{
|
{
|
||||||
glm::mat4 proj = glm::ortho(l, r, b, t, znear, zfar);
|
glm::mat4 proj = glm::ortho(l, r, b, t, znear, zfar);
|
||||||
if (GLAD_GL_ARB_clip_control || GLAD_GL_EXT_clip_control)
|
// clip_control: projection matrix with 1..0 Z range
|
||||||
// when clip_control available, use projection matrix with 1..0 Z range
|
return glm::mat4( //
|
||||||
return glm::mat4( //
|
1.0f, 0.0f, 0.0f, 0.0f, //
|
||||||
1.0f, 0.0f, 0.0f, 0.0f, //
|
0.0f, 1.0f, 0.0f, 0.0f, //
|
||||||
0.0f, 1.0f, 0.0f, 0.0f, //
|
0.0f, 0.0f, -0.5f, 0.0f, //
|
||||||
0.0f, 0.0f, -0.5f, 0.0f, //
|
0.0f, 0.0f, 0.5f, 1.0f //
|
||||||
0.0f, 0.0f, 0.5f, 1.0f //
|
) *
|
||||||
) *
|
proj;
|
||||||
proj;
|
|
||||||
else
|
|
||||||
// or use standard matrix but with 1..-1 Z range
|
|
||||||
// (reverse Z don't give any extra precision without clip_control, but it is used anyway for consistency)
|
|
||||||
return glm::mat4( //
|
|
||||||
1.0f, 0.0f, 0.0f, 0.0f, //
|
|
||||||
0.0f, 1.0f, 0.0f, 0.0f, //
|
|
||||||
0.0f, 0.0f, -1.0f, 0.0f, //
|
|
||||||
0.0f, 0.0f, 0.0f, 1.0f //
|
|
||||||
) *
|
|
||||||
proj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 opengl46_renderer::ortho_frustumtest_projection(float l, float r, float b, float t, float znear, float zfar)
|
glm::mat4 opengl46_renderer::ortho_frustumtest_projection(float l, float r, float b, float t, float znear, float zfar)
|
||||||
@@ -1826,22 +1788,13 @@ void opengl46_renderer::setup_shadow_bind_map()
|
|||||||
|
|
||||||
glm::mat4 coordmove;
|
glm::mat4 coordmove;
|
||||||
|
|
||||||
if (GLAD_GL_ARB_clip_control || GLAD_GL_EXT_clip_control)
|
// transform 1..-1 NDC xy coordinates to 1..0 (with clip_control z is already 1..0)
|
||||||
// transform 1..-1 NDC xy coordinates to 1..0
|
coordmove = glm::mat4( //
|
||||||
coordmove = glm::mat4( //
|
0.5, 0.0, 0.0, 0.0, //
|
||||||
0.5, 0.0, 0.0, 0.0, //
|
0.0, 0.5, 0.0, 0.0, //
|
||||||
0.0, 0.5, 0.0, 0.0, //
|
0.0, 0.0, 1.0, 0.0, //
|
||||||
0.0, 0.0, 1.0, 0.0, //
|
0.5, 0.5, 0.0, 1.0 //
|
||||||
0.5, 0.5, 0.0, 1.0 //
|
);
|
||||||
);
|
|
||||||
else
|
|
||||||
// without clip_control we also need to transform z
|
|
||||||
coordmove = glm::mat4( //
|
|
||||||
0.5, 0.0, 0.0, 0.0, //
|
|
||||||
0.0, 0.5, 0.0, 0.0, //
|
|
||||||
0.0, 0.0, 0.5, 0.0, //
|
|
||||||
0.5, 0.5, 0.5, 1.0 //
|
|
||||||
);
|
|
||||||
|
|
||||||
for( auto idx = 0; idx < m_shadowpass.size(); ++idx ) {
|
for( auto idx = 0; idx < m_shadowpass.size(); ++idx ) {
|
||||||
|
|
||||||
@@ -2310,38 +2263,24 @@ void opengl46_renderer::Bind_Material( material_handle const Material, TSubModel
|
|||||||
material.textures :
|
material.textures :
|
||||||
material.GetTextures(TSubModel::VariantId(sm))};
|
material.GetTextures(TSubModel::VariantId(sm))};
|
||||||
|
|
||||||
if (GLAD_GL_ARB_multi_bind)
|
GLuint lastdiff = 0;
|
||||||
{
|
size_t i;
|
||||||
GLuint lastdiff = 0;
|
for (i = 0; i < gl::MAX_TEXTURES; i++)
|
||||||
size_t i;
|
if (materialtextures[i] != null_handle)
|
||||||
for (i = 0; i < gl::MAX_TEXTURES; i++)
|
|
||||||
if (materialtextures[i] != null_handle)
|
|
||||||
{
|
|
||||||
opengl_texture &tex = m_textures.mark_as_used(materialtextures[i]);
|
|
||||||
tex.create();
|
|
||||||
if (opengl_texture::units[i] != tex.id)
|
|
||||||
{
|
|
||||||
opengl_texture::units[i] = tex.id;
|
|
||||||
lastdiff = i + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (lastdiff)
|
|
||||||
glBindTextures(0, lastdiff, &opengl_texture::units[0]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
size_t unit = 0;
|
|
||||||
for (auto &tex : materialtextures)
|
|
||||||
{
|
{
|
||||||
if (tex == null_handle)
|
opengl_texture &tex = m_textures.mark_as_used(materialtextures[i]);
|
||||||
break;
|
tex.create();
|
||||||
m_textures.bind(unit, tex);
|
if (opengl_texture::units[i] != tex.id)
|
||||||
unit++;
|
{
|
||||||
|
opengl_texture::units[i] = tex.id;
|
||||||
|
lastdiff = i + 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (lastdiff)
|
||||||
|
glBindTextures(0, lastdiff, &opengl_texture::units[0]);
|
||||||
|
|
||||||
material.shader->bind();
|
material.shader->bind();
|
||||||
}
|
}
|
||||||
@@ -5397,13 +5336,9 @@ glm::dvec3 opengl46_renderer::Update_Mouse_Position()
|
|||||||
|
|
||||||
if (pointdepth != std::numeric_limits<float>::max())
|
if (pointdepth != std::numeric_limits<float>::max())
|
||||||
{
|
{
|
||||||
m_mousehit = (GLAD_GL_ARB_clip_control || GLAD_GL_EXT_clip_control) ? pointdepth > 0.0f : pointdepth < 1.0f;
|
m_mousehit = pointdepth > 0.0f;
|
||||||
if (GLAD_GL_ARB_clip_control || GLAD_GL_EXT_clip_control) {
|
if (pointdepth > 0.0f)
|
||||||
if (pointdepth > 0.0f)
|
m_worldmousecoordinates = glm::unProjectZO(glm::vec3(bufferpos, pointdepth), glm::mat4(glm::mat3(m_colorpass.pass_camera.modelview())), m_colorpass.pass_camera.projection(),
|
||||||
m_worldmousecoordinates = glm::unProjectZO(glm::vec3(bufferpos, pointdepth), glm::mat4(glm::mat3(m_colorpass.pass_camera.modelview())), m_colorpass.pass_camera.projection(),
|
|
||||||
glm::vec4(0, 0, Global.gfx_framebuffer_width, Global.gfx_framebuffer_height));
|
|
||||||
} else if (pointdepth < 1.0f)
|
|
||||||
m_worldmousecoordinates = glm::unProjectNO(glm::vec3(bufferpos, pointdepth), glm::mat4(glm::mat3(m_colorpass.pass_camera.modelview())), m_colorpass.pass_camera.projection(),
|
|
||||||
glm::vec4(0, 0, Global.gfx_framebuffer_width, Global.gfx_framebuffer_height));
|
glm::vec4(0, 0, Global.gfx_framebuffer_width, Global.gfx_framebuffer_height));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5944,22 +5879,13 @@ void opengl46_renderer::Update_Lights(light_array &Lights)
|
|||||||
|
|
||||||
// set up helpers
|
// set up helpers
|
||||||
glm::mat4 coordmove;
|
glm::mat4 coordmove;
|
||||||
if (GLAD_GL_ARB_clip_control || GLAD_GL_EXT_clip_control)
|
// transform 1..-1 NDC xy coordinates to 1..0 (with clip_control z is already 1..0)
|
||||||
// transform 1..-1 NDC xy coordinates to 1..0
|
coordmove = glm::mat4( //
|
||||||
coordmove = glm::mat4( //
|
0.5, 0.0, 0.0, 0.0, //
|
||||||
0.5, 0.0, 0.0, 0.0, //
|
0.0, 0.5, 0.0, 0.0, //
|
||||||
0.0, 0.5, 0.0, 0.0, //
|
0.0, 0.0, 1.0, 0.0, //
|
||||||
0.0, 0.0, 1.0, 0.0, //
|
0.5, 0.5, 0.0, 1.0 //
|
||||||
0.5, 0.5, 0.0, 1.0 //
|
);
|
||||||
);
|
|
||||||
else
|
|
||||||
// without clip_control we also need to transform z
|
|
||||||
coordmove = glm::mat4( //
|
|
||||||
0.5, 0.0, 0.0, 0.0, //
|
|
||||||
0.0, 0.5, 0.0, 0.0, //
|
|
||||||
0.0, 0.0, 0.5, 0.0, //
|
|
||||||
0.5, 0.5, 0.5, 1.0 //
|
|
||||||
);
|
|
||||||
glm::mat4 mv = OpenGLMatrices.data( GL_MODELVIEW );
|
glm::mat4 mv = OpenGLMatrices.data( GL_MODELVIEW );
|
||||||
|
|
||||||
// fill vehicle headlights data
|
// fill vehicle headlights data
|
||||||
@@ -6120,9 +6046,9 @@ bool opengl46_renderer::Init_caps()
|
|||||||
|
|
||||||
crashreport_add_info("gl_family", "desktop");
|
crashreport_add_info("gl_family", "desktop");
|
||||||
|
|
||||||
if (!GLAD_GL_VERSION_3_3)
|
if (!GLAD_GL_VERSION_4_6)
|
||||||
{
|
{
|
||||||
ErrorLog("requires OpenGL >= 3.3!");
|
ErrorLog("requires OpenGL >= 4.6!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6132,18 +6058,6 @@ bool opengl46_renderer::Init_caps()
|
|||||||
if (!GLAD_GL_EXT_texture_compression_s3tc)
|
if (!GLAD_GL_EXT_texture_compression_s3tc)
|
||||||
ErrorLog("EXT_texture_compression_s3tc not supported!");
|
ErrorLog("EXT_texture_compression_s3tc not supported!");
|
||||||
|
|
||||||
if (GLAD_GL_ARB_texture_filter_anisotropic)
|
|
||||||
WriteLog("ARB_texture_filter_anisotropic supported!");
|
|
||||||
|
|
||||||
if (GLAD_GL_ARB_multi_bind)
|
|
||||||
WriteLog("ARB_multi_bind supported!");
|
|
||||||
|
|
||||||
if (GLAD_GL_ARB_direct_state_access)
|
|
||||||
WriteLog("ARB_direct_state_access supported!");
|
|
||||||
|
|
||||||
if (GLAD_GL_ARB_clip_control)
|
|
||||||
WriteLog("ARB_clip_control supported!");
|
|
||||||
|
|
||||||
glGetError();
|
glGetError();
|
||||||
glLineWidth(2.0f);
|
glLineWidth(2.0f);
|
||||||
if (!glGetError())
|
if (!glGetError())
|
||||||
@@ -6205,7 +6119,7 @@ bool opengl46_renderer::renderer_register = gfx_renderer_factory::get_instance()
|
|||||||
bool opengl46_renderer::opengl46_imgui_renderer::Init()
|
bool opengl46_renderer::opengl46_imgui_renderer::Init()
|
||||||
{
|
{
|
||||||
crashreport_add_info("imgui_ver", "gl3");
|
crashreport_add_info("imgui_ver", "gl3");
|
||||||
return ImGui_ImplOpenGL3_Init("#version 330 core");
|
return ImGui_ImplOpenGL3_Init("#version 460 core");
|
||||||
}
|
}
|
||||||
|
|
||||||
void opengl46_renderer::opengl46_imgui_renderer::Shutdown()
|
void opengl46_renderer::opengl46_imgui_renderer::Shutdown()
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ void bind_for_upload(opengl_texture const &Texture)
|
|||||||
|
|
||||||
void set_anisotropy(GLenum const Target)
|
void set_anisotropy(GLenum const Target)
|
||||||
{
|
{
|
||||||
if (Global.AnisotropicFiltering >= 0 && (GLAD_GL_EXT_texture_filter_anisotropic || GLAD_GL_ARB_texture_filter_anisotropic))
|
if (Global.AnisotropicFiltering >= 0)
|
||||||
::glTexParameterf(Target, GL_TEXTURE_MAX_ANISOTROPY_EXT, Global.AnisotropicFiltering);
|
::glTexParameterf(Target, GL_TEXTURE_MAX_ANISOTROPY_EXT, Global.AnisotropicFiltering);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,15 +41,4 @@ opengl_camera::visible( TDynamicObject const *Dynamic ) const {
|
|||||||
return ( m_frustum.sphere_inside( Dynamic->GetPosition(), static_cast<float>(Dynamic->radius() * 1.25) ) > 0.0f );
|
return ( m_frustum.sphere_inside( Dynamic->GetPosition(), static_cast<float>(Dynamic->radius() * 1.25) ) > 0.0f );
|
||||||
}
|
}
|
||||||
|
|
||||||
// debug helper, draws shape of frustum in world space
|
|
||||||
void
|
|
||||||
opengl_camera::draw( glm::vec3 const &Offset ) const {
|
|
||||||
|
|
||||||
::glBegin( GL_LINES );
|
|
||||||
for( auto const pointindex : frustumshapepoinstorder ) {
|
|
||||||
::glVertex3fv( glm::value_ptr( glm::vec3{ m_frustumpoints[ pointindex ] } - Offset ) );
|
|
||||||
}
|
|
||||||
::glEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -64,9 +64,6 @@ public:
|
|||||||
point = this->m_inversetransformation * point;
|
point = this->m_inversetransformation * point;
|
||||||
// ...and scale by transformed w
|
// ...and scale by transformed w
|
||||||
point = glm::vec4{ glm::vec3{ point } / point.w, 1.f }; } ); }
|
point = glm::vec4{ glm::vec3{ point } / point.w, 1.f }; } ); }
|
||||||
// debug helper, draws shape of frustum in world space
|
|
||||||
void
|
|
||||||
draw( glm::vec3 const &Offset ) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// members:
|
// members:
|
||||||
|
|||||||
@@ -12,6 +12,14 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include <stack>
|
#include <stack>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
// matrix modes of the fixed pipeline, which isn't part of the core profile; the stack below keeps them on the cpu side
|
||||||
|
#ifndef GL_MODELVIEW
|
||||||
|
#define GL_MODELVIEW 0x1700
|
||||||
|
#endif
|
||||||
|
#ifndef GL_PROJECTION
|
||||||
|
#define GL_PROJECTION 0x1701
|
||||||
|
#endif
|
||||||
|
|
||||||
// encapsulation of the fixed pipeline opengl matrix stack
|
// encapsulation of the fixed pipeline opengl matrix stack
|
||||||
class opengl_matrices {
|
class opengl_matrices {
|
||||||
|
|
||||||
@@ -82,8 +90,9 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// methods:
|
// methods:
|
||||||
|
// the core profile has no fixed pipeline matrices to upload to; the renderer passes the matrices to its shaders itself
|
||||||
void
|
void
|
||||||
upload() { ::glLoadMatrixf( glm::value_ptr( m_stack.back() ) ); }
|
upload() {}
|
||||||
|
|
||||||
// members:
|
// members:
|
||||||
std::vector<glm::mat4> m_stack;
|
std::vector<glm::mat4> m_stack;
|
||||||
@@ -110,8 +119,7 @@ public:
|
|||||||
case GL_MODELVIEW: { m_mode = stack_mode::gl_modelview; break; }
|
case GL_MODELVIEW: { m_mode = stack_mode::gl_modelview; break; }
|
||||||
case GL_PROJECTION: { m_mode = stack_mode::gl_projection; break; }
|
case GL_PROJECTION: { m_mode = stack_mode::gl_projection; break; }
|
||||||
case GL_TEXTURE: { m_mode = stack_mode::gl_texture; break; }
|
case GL_TEXTURE: { m_mode = stack_mode::gl_texture; break; }
|
||||||
default: { break; } }
|
default: { break; } } }
|
||||||
if( m_upload ) {::glMatrixMode( Mode ); } }
|
|
||||||
glm::mat4 const &
|
glm::mat4 const &
|
||||||
data( GLuint const Mode = -1 ) const {
|
data( GLuint const Mode = -1 ) const {
|
||||||
switch( Mode ) {
|
switch( Mode ) {
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ float calc_shadow()
|
|||||||
for (cascade = 0U; cascade < MAX_CASCADES; cascade++)
|
for (cascade = 0U; cascade < MAX_CASCADES; cascade++)
|
||||||
if (distance <= cascade_end[cascade])
|
if (distance <= cascade_end[cascade])
|
||||||
break;
|
break;
|
||||||
float dist_casc = distance / cascade_end[cascade];
|
|
||||||
// Normal offset: sample the shadow map from a point pushed along the surface normal
|
// Normal offset: sample the shadow map from a point pushed along the surface normal
|
||||||
// by a fraction of the cascade's texel footprint. A constant depth bias can't keep up
|
// by a fraction of the cascade's texel footprint. A constant depth bias can't keep up
|
||||||
// with large texels (far cascades, small shadow maps) on surfaces at a grazing angle
|
// with large texels (far cascades, small shadow maps) on surfaces at a grazing angle
|
||||||
@@ -65,18 +64,7 @@ float calc_shadow()
|
|||||||
|
|
||||||
|
|
||||||
float bias = 0.00005f * float(cascade + 1U);
|
float bias = 0.00005f * float(cascade + 1U);
|
||||||
vec2 texel = vec2(1.0) / vec2(textureSize(shadowmap, 0));
|
|
||||||
//float radius = 1.0; f_light_pos[cascade].w; //0.5 + 2.0 * max(abs(2.0 * coords.x - 1.0), abs(2.0 * coords.y - 1.0));
|
|
||||||
float radius = 1.0;
|
|
||||||
float minradius = 0.0;
|
|
||||||
if (cascade == 0U)
|
|
||||||
minradius = 1.0;
|
|
||||||
if (cascade < MAX_CASCADES - 1U)
|
|
||||||
radius = mix(minradius, f_light_pos[cascade+1U].w/f_light_pos[cascade].w, dist_casc);
|
|
||||||
else
|
|
||||||
radius = 0.5;
|
|
||||||
|
|
||||||
#if defined(GL_ARB_gpu_shader5) || defined(GL_EXT_gpu_shader5) || __VERSION__ >= 400
|
|
||||||
// Fast path: 4 textureGather() calls cover a 4x4 texel block. Raw gathered
|
// Fast path: 4 textureGather() calls cover a 4x4 texel block. Raw gathered
|
||||||
// comparisons must be weighted by the sub-texel position (bilinear weights),
|
// comparisons must be weighted by the sub-texel position (bilinear weights),
|
||||||
// otherwise the result is constant across each shadow map texel and shadow
|
// otherwise the result is constant across each shadow map texel and shadow
|
||||||
@@ -99,18 +87,6 @@ float calc_shadow()
|
|||||||
+ dot(g01, vec4((1.0 - f.x) * f.y, f.y, 1.0, 1.0 - f.x))
|
+ dot(g01, vec4((1.0 - f.x) * f.y, f.y, 1.0, 1.0 - f.x))
|
||||||
+ dot(g11, vec4(f.y, f.x * f.y, f.x, 1.0));
|
+ dot(g11, vec4(f.y, f.x * f.y, f.x, 1.0));
|
||||||
return shadow / 9.0;
|
return shadow / 9.0;
|
||||||
#else
|
|
||||||
// Fallback for drivers without textureGather on shadow samplers
|
|
||||||
// (notably GLES 3.0 and any 3.3 desktop driver that doesn't expose
|
|
||||||
// GL_ARB_texture_gather). Identical to the previous implementation.
|
|
||||||
float shadow = 0.0;
|
|
||||||
for (float y = -1.5; y <= 1.5; y += 1.0)
|
|
||||||
for (float x = -1.5; x <= 1.5; x += 1.0)
|
|
||||||
shadow += texture(shadowmap, vec4(coords.xy + vec2(x, y) * radius * texel, cascade, coords.z + bias) );
|
|
||||||
shadow /= 16.0;
|
|
||||||
|
|
||||||
return shadow;
|
|
||||||
#endif
|
|
||||||
#else
|
#else
|
||||||
return 0.0;
|
return 0.0;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user