mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-05 07:34:27 +01:00
Remove legacy OpenGL 2.1 renderer
This commit is contained in:
@@ -68,7 +68,6 @@ if (APPLE)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
option(WITH_OPENGL_MODERN "Compile with OpenGL modern renderer" ON)
|
option(WITH_OPENGL_MODERN "Compile with OpenGL modern renderer" ON)
|
||||||
option(WITH_OPENGL_LEGACY "Compile with OpenGL legacy renderer" ON)
|
|
||||||
option(WITH_PYTHON "Python 3.14 embedded scripting" ON)
|
option(WITH_PYTHON "Python 3.14 embedded scripting" ON)
|
||||||
option(WITH_UART "Compile with libserialport" ON)
|
option(WITH_UART "Compile with libserialport" ON)
|
||||||
option(WITH_LUA "Compile with lua scripting support" ON)
|
option(WITH_LUA "Compile with lua scripting support" ON)
|
||||||
@@ -225,7 +224,6 @@ set(SOURCES
|
|||||||
"utilities/headtrack.cpp"
|
"utilities/headtrack.cpp"
|
||||||
"scripting/ladderlogic.cpp"
|
"scripting/ladderlogic.cpp"
|
||||||
"rendering/geometrybank.cpp"
|
"rendering/geometrybank.cpp"
|
||||||
"rendering/openglcolor.cpp"
|
|
||||||
"simulation/simulationsounds.cpp"
|
"simulation/simulationsounds.cpp"
|
||||||
"rendering/openglcamera.cpp"
|
"rendering/openglcamera.cpp"
|
||||||
|
|
||||||
@@ -284,9 +282,7 @@ set(SOURCES
|
|||||||
|
|
||||||
set(DEFINITIONS)
|
set(DEFINITIONS)
|
||||||
set(SOURCES ${SOURCES} "imgui/imgui_impl_opengl3.cpp")
|
set(SOURCES ${SOURCES} "imgui/imgui_impl_opengl3.cpp")
|
||||||
set(SOURCES ${SOURCES} "imgui/imgui_impl_opengl2.cpp")
|
|
||||||
set_source_files_properties("imgui/imgui_impl_opengl3.cpp" PROPERTIES SKIP_PRECOMPILE_HEADERS TRUE)
|
set_source_files_properties("imgui/imgui_impl_opengl3.cpp" PROPERTIES SKIP_PRECOMPILE_HEADERS TRUE)
|
||||||
set_source_files_properties("imgui/imgui_impl_opengl2.cpp" PROPERTIES SKIP_PRECOMPILE_HEADERS TRUE)
|
|
||||||
|
|
||||||
if (WITH_CRASHPAD)
|
if (WITH_CRASHPAD)
|
||||||
set(DEFINITIONS ${DEFINITIONS} "WITH_CRASHPAD")
|
set(DEFINITIONS ${DEFINITIONS} "WITH_CRASHPAD")
|
||||||
@@ -341,17 +337,6 @@ if (WITH_OPENGL_MODERN)
|
|||||||
set(DEFINITIONS ${DEFINITIONS} "WITH_OPENGL_MODERN")
|
set(DEFINITIONS ${DEFINITIONS} "WITH_OPENGL_MODERN")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (WITH_OPENGL_LEGACY)
|
|
||||||
set(SOURCES ${SOURCES}
|
|
||||||
"rendering/openglgeometrybank.cpp"
|
|
||||||
"rendering/opengllight.cpp"
|
|
||||||
"rendering/openglskydome.cpp"
|
|
||||||
"rendering/openglprecipitation.cpp"
|
|
||||||
"rendering/openglparticles.cpp"
|
|
||||||
"rendering/openglrenderer.cpp")
|
|
||||||
set(DEFINITIONS ${DEFINITIONS} "WITH_OPENGL_LEGACY")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_subdirectory("${DEPS_DIR}/glfw/" EXCLUDE_FROM_ALL)
|
add_subdirectory("${DEPS_DIR}/glfw/" EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
set(SOURCES ${SOURCES} "extras/piped_proc.cpp" "widgets/cameraview_extcam.cpp")
|
set(SOURCES ${SOURCES} "extras/piped_proc.cpp" "widgets/cameraview_extcam.cpp")
|
||||||
|
|||||||
@@ -1252,7 +1252,7 @@ int eu07_application::init_glfw()
|
|||||||
monitor = glfwGetPrimaryMonitor();
|
monitor = glfwGetPrimaryMonitor();
|
||||||
|
|
||||||
glfwWindowHint(GLFW_AUTO_ICONIFY, GLFW_FALSE);
|
glfwWindowHint(GLFW_AUTO_ICONIFY, GLFW_FALSE);
|
||||||
if ((Global.gfx_skippipeline || Global.LegacyRenderer) && Global.iMultisampling > 0)
|
if (Global.gfx_skippipeline && Global.iMultisampling > 0)
|
||||||
{
|
{
|
||||||
glfwWindowHint(GLFW_SAMPLES, 1 << Global.iMultisampling);
|
glfwWindowHint(GLFW_SAMPLES, 1 << Global.iMultisampling);
|
||||||
}
|
}
|
||||||
@@ -1265,39 +1265,23 @@ int eu07_application::init_glfw()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!Global.LegacyRenderer)
|
// activate core profile for opengl 3.3 renderer
|
||||||
|
if (!Global.gfx_usegles)
|
||||||
{
|
{
|
||||||
Global.bUseVBO = true;
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
// activate core profile for opengl 3.3 renderer
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
|
||||||
if (!Global.gfx_usegles)
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
{
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
|
||||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
|
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef GLFW_CONTEXT_CREATION_API
|
|
||||||
if (m_glfwversion >= 30200)
|
|
||||||
glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_EGL_CONTEXT_API);
|
|
||||||
#endif
|
|
||||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
|
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (Global.gfx_usegles)
|
#ifdef GLFW_CONTEXT_CREATION_API
|
||||||
{
|
if (m_glfwversion >= 30200)
|
||||||
ErrorLog("legacy renderer not supported in gles mode");
|
glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_EGL_CONTEXT_API);
|
||||||
return -1;
|
#endif
|
||||||
}
|
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
|
||||||
Global.gfx_shadergamma = false;
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_ANY_PROFILE);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
|
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Global.gfx_gldebug)
|
if (Global.gfx_gldebug)
|
||||||
@@ -1396,20 +1380,15 @@ int eu07_application::init_ui()
|
|||||||
int eu07_application::init_gfx()
|
int eu07_application::init_gfx()
|
||||||
{
|
{
|
||||||
|
|
||||||
if (Global.GfxRenderer == "default")
|
// NOTE: global_settings maps unsupported gfxrenderer values (e.g. the removed "legacy") to "default"
|
||||||
{
|
if (Global.GfxRenderer == "experimental")
|
||||||
// default render path
|
|
||||||
GfxRenderer = gfx_renderer_factory::get_instance()->create("modern");
|
|
||||||
}
|
|
||||||
else if (Global.GfxRenderer == "experimental")
|
|
||||||
{
|
{
|
||||||
GfxRenderer = gfx_renderer_factory::get_instance()->create(Global.GfxRenderer);
|
GfxRenderer = gfx_renderer_factory::get_instance()->create(Global.GfxRenderer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// legacy render path
|
// default render path
|
||||||
GfxRenderer = gfx_renderer_factory::get_instance()->create("legacy");
|
GfxRenderer = gfx_renderer_factory::get_instance()->create("modern");
|
||||||
Global.DisabledLogTypes |= static_cast<unsigned int>(logtype::material);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GfxRenderer)
|
if (!GfxRenderer)
|
||||||
|
|||||||
@@ -1446,26 +1446,8 @@ debug_panel::update_section_renderer( std::vector<text_line> &Output ) const {
|
|||||||
{
|
{
|
||||||
textline += "NVRHI on ";
|
textline += "NVRHI on ";
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if (Global.BasicRenderer)
|
|
||||||
{
|
|
||||||
textline += "Legacy Simple";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
textline += "Legacy";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Global.bUseVBO)
|
textline += ", VBO";
|
||||||
{
|
|
||||||
textline += ", VBO";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
textline += ", Display Lists";
|
|
||||||
}
|
|
||||||
|
|
||||||
textline += " ";
|
textline += " ";
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
#define EU07_SOUND_PROOFINGUSESRANGE
|
#define EU07_SOUND_PROOFINGUSESRANGE
|
||||||
|
|
||||||
class opengl_renderer;
|
|
||||||
class sound_source;
|
class sound_source;
|
||||||
|
|
||||||
using uint32_sequence = std::vector<std::uint32_t>;
|
using uint32_sequence = std::vector<std::uint32_t>;
|
||||||
@@ -101,8 +100,6 @@ private:
|
|||||||
|
|
||||||
class openal_renderer {
|
class openal_renderer {
|
||||||
|
|
||||||
friend opengl_renderer;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
openal_renderer() = default;
|
openal_renderer() = default;
|
||||||
~openal_renderer();
|
~openal_renderer();
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
|
|
||||||
class TSky {
|
class TSky {
|
||||||
|
|
||||||
friend opengl_renderer;
|
|
||||||
friend opengl33_renderer;
|
friend opengl33_renderer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
class cStars {
|
class cStars {
|
||||||
|
|
||||||
friend opengl_renderer;
|
|
||||||
friend opengl33_renderer;
|
friend opengl33_renderer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -1,349 +0,0 @@
|
|||||||
// dear imgui: Renderer Backend for OpenGL2 (legacy OpenGL, fixed pipeline)
|
|
||||||
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
|
||||||
|
|
||||||
// Implemented features:
|
|
||||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
|
||||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
|
||||||
// Missing features or Issues:
|
|
||||||
// [ ] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
|
||||||
|
|
||||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
|
||||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
|
||||||
// Learn about Dear ImGui:
|
|
||||||
// - FAQ https://dearimgui.com/faq
|
|
||||||
// - Getting Started https://dearimgui.com/getting-started
|
|
||||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
|
||||||
// - Introduction, links and more at the top of imgui.cpp
|
|
||||||
|
|
||||||
// **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)**
|
|
||||||
// **Prefer using the code in imgui_impl_opengl3.cpp**
|
|
||||||
// This code is mostly provided as a reference to learn how ImGui integration works, because it is shorter to read.
|
|
||||||
// If your code is using GL3+ context or any semi modern OpenGL calls, using this is likely to make everything more
|
|
||||||
// complicated, will require your code to reset every single OpenGL attributes to their initial state, and might
|
|
||||||
// confuse your GPU driver.
|
|
||||||
// The GL2 code is unable to reset attributes or even call e.g. "glUseProgram(0)" because they don't exist in that API.
|
|
||||||
|
|
||||||
// CHANGELOG
|
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
|
||||||
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
|
||||||
// 2024-10-07: OpenGL: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
|
||||||
// 2024-06-28: OpenGL: ImGui_ImplOpenGL2_NewFrame() recreates font texture if it has been destroyed by ImGui_ImplOpenGL2_DestroyFontsTexture(). (#7748)
|
|
||||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
|
||||||
// 2021-12-08: OpenGL: Fixed mishandling of the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86.
|
|
||||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
|
||||||
// 2021-05-19: OpenGL: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
|
||||||
// 2021-01-03: OpenGL: Backup, setup and restore GL_SHADE_MODEL state, disable GL_STENCIL_TEST and disable GL_NORMAL_ARRAY client state to increase compatibility with legacy OpenGL applications.
|
|
||||||
// 2020-01-23: OpenGL: Backup, setup and restore GL_TEXTURE_ENV to increase compatibility with legacy OpenGL applications.
|
|
||||||
// 2019-04-30: OpenGL: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
|
|
||||||
// 2019-02-11: OpenGL: Projecting clipping rectangles correctly using draw_data->FramebufferScale to allow multi-viewports for retina display.
|
|
||||||
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
|
|
||||||
// 2018-08-03: OpenGL: Disabling/restoring GL_LIGHTING and GL_COLOR_MATERIAL to increase compatibility with legacy OpenGL applications.
|
|
||||||
// 2018-06-08: Misc: Extracted imgui_impl_opengl2.cpp/.h away from the old combined GLFW/SDL+OpenGL2 examples.
|
|
||||||
// 2018-06-08: OpenGL: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle.
|
|
||||||
// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplOpenGL2_RenderDrawData() in the .h file so you can call it yourself.
|
|
||||||
// 2017-09-01: OpenGL: Save and restore current polygon mode.
|
|
||||||
// 2016-09-10: OpenGL: Uploading font texture as RGBA32 to increase compatibility with users shaders (not ideal).
|
|
||||||
// 2016-09-05: OpenGL: Fixed save and restore of current scissor rectangle.
|
|
||||||
|
|
||||||
#include "imgui.h"
|
|
||||||
#ifndef IMGUI_DISABLE
|
|
||||||
#include "imgui_impl_opengl2.h"
|
|
||||||
#include <stdint.h> // intptr_t
|
|
||||||
|
|
||||||
// Clang/GCC warnings with -Weverything
|
|
||||||
#if defined(__clang__)
|
|
||||||
#pragma clang diagnostic push
|
|
||||||
#pragma clang diagnostic ignored "-Wunused-macros" // warning: macro is not used
|
|
||||||
#pragma clang diagnostic ignored "-Wnonportable-system-include-path"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <glad/glad.h> // MaSzyna: GL functions come from glad, initialized by the simulator
|
|
||||||
|
|
||||||
// [Debugging]
|
|
||||||
//#define IMGUI_IMPL_OPENGL_DEBUG
|
|
||||||
#ifdef IMGUI_IMPL_OPENGL_DEBUG
|
|
||||||
#include <stdio.h>
|
|
||||||
#define GL_CALL(_CALL) do { _CALL; GLenum gl_err = glGetError(); if (gl_err != 0) fprintf(stderr, "GL error 0x%x returned from '%s'.\n", gl_err, #_CALL); } while (0) // Call with error check
|
|
||||||
#else
|
|
||||||
#define GL_CALL(_CALL) _CALL // Call without error check
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// OpenGL data
|
|
||||||
struct ImGui_ImplOpenGL2_Data
|
|
||||||
{
|
|
||||||
GLuint FontTexture;
|
|
||||||
|
|
||||||
ImGui_ImplOpenGL2_Data() { memset((void*)this, 0, sizeof(*this)); }
|
|
||||||
};
|
|
||||||
|
|
||||||
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
|
|
||||||
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
|
|
||||||
static ImGui_ImplOpenGL2_Data* ImGui_ImplOpenGL2_GetBackendData()
|
|
||||||
{
|
|
||||||
return ImGui::GetCurrentContext() ? (ImGui_ImplOpenGL2_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Forward Declarations
|
|
||||||
static void ImGui_ImplOpenGL2_InitMultiViewportSupport();
|
|
||||||
static void ImGui_ImplOpenGL2_ShutdownMultiViewportSupport();
|
|
||||||
|
|
||||||
// Functions
|
|
||||||
bool ImGui_ImplOpenGL2_Init()
|
|
||||||
{
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
IMGUI_CHECKVERSION();
|
|
||||||
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
|
||||||
|
|
||||||
// Setup backend capabilities flags
|
|
||||||
ImGui_ImplOpenGL2_Data* bd = IM_NEW(ImGui_ImplOpenGL2_Data)();
|
|
||||||
io.BackendRendererUserData = (void*)bd;
|
|
||||||
io.BackendRendererName = "imgui_impl_opengl2";
|
|
||||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
|
||||||
|
|
||||||
ImGui_ImplOpenGL2_InitMultiViewportSupport();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui_ImplOpenGL2_Shutdown()
|
|
||||||
{
|
|
||||||
ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData();
|
|
||||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
|
|
||||||
ImGui_ImplOpenGL2_ShutdownMultiViewportSupport();
|
|
||||||
ImGui_ImplOpenGL2_DestroyDeviceObjects();
|
|
||||||
io.BackendRendererName = nullptr;
|
|
||||||
io.BackendRendererUserData = nullptr;
|
|
||||||
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasViewports;
|
|
||||||
IM_DELETE(bd);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui_ImplOpenGL2_NewFrame()
|
|
||||||
{
|
|
||||||
ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData();
|
|
||||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplOpenGL2_Init()?");
|
|
||||||
|
|
||||||
if (!bd->FontTexture)
|
|
||||||
ImGui_ImplOpenGL2_CreateDeviceObjects();
|
|
||||||
if (!bd->FontTexture)
|
|
||||||
ImGui_ImplOpenGL2_CreateFontsTexture();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplOpenGL2_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height)
|
|
||||||
{
|
|
||||||
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers, polygon fill.
|
|
||||||
glEnable(GL_BLEND);
|
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
//glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // In order to composite our output buffer we need to preserve alpha
|
|
||||||
glDisable(GL_CULL_FACE);
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
|
||||||
glDisable(GL_STENCIL_TEST);
|
|
||||||
glDisable(GL_LIGHTING);
|
|
||||||
glDisable(GL_COLOR_MATERIAL);
|
|
||||||
glEnable(GL_SCISSOR_TEST);
|
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
||||||
glEnableClientState(GL_COLOR_ARRAY);
|
|
||||||
glDisableClientState(GL_NORMAL_ARRAY);
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
|
||||||
glShadeModel(GL_SMOOTH);
|
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
|
||||||
|
|
||||||
// If you are using this code with non-legacy OpenGL header/contexts (which you should not, prefer using imgui_impl_opengl3.cpp!!),
|
|
||||||
// you may need to backup/reset/restore other state, e.g. for current shader using the commented lines below.
|
|
||||||
// (DO NOT MODIFY THIS FILE! Add the code in your calling function)
|
|
||||||
// GLint last_program;
|
|
||||||
// glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
|
|
||||||
// glUseProgram(0);
|
|
||||||
// ImGui_ImplOpenGL2_RenderDrawData(...);
|
|
||||||
// glUseProgram(last_program)
|
|
||||||
// There are potentially many more states you could need to clear/setup that we can't access from default headers.
|
|
||||||
// e.g. glBindBuffer(GL_ARRAY_BUFFER, 0), glDisable(GL_TEXTURE_CUBE_MAP).
|
|
||||||
|
|
||||||
// Setup viewport, orthographic projection matrix
|
|
||||||
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
|
|
||||||
GL_CALL(glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height));
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
|
||||||
glPushMatrix();
|
|
||||||
glLoadIdentity();
|
|
||||||
glOrtho(draw_data->DisplayPos.x, draw_data->DisplayPos.x + draw_data->DisplaySize.x, draw_data->DisplayPos.y + draw_data->DisplaySize.y, draw_data->DisplayPos.y, -1.0f, +1.0f);
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
|
||||||
glPushMatrix();
|
|
||||||
glLoadIdentity();
|
|
||||||
}
|
|
||||||
|
|
||||||
// OpenGL2 Render function.
|
|
||||||
// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly.
|
|
||||||
// This is in order to be able to run within an OpenGL engine that doesn't do so.
|
|
||||||
void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
|
|
||||||
{
|
|
||||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
|
||||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
|
||||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
|
||||||
if (fb_width == 0 || fb_height == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Backup GL state
|
|
||||||
GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
|
||||||
GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
|
|
||||||
GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport);
|
|
||||||
GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box);
|
|
||||||
GLint last_shade_model; glGetIntegerv(GL_SHADE_MODEL, &last_shade_model);
|
|
||||||
GLint last_tex_env_mode; glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &last_tex_env_mode);
|
|
||||||
glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT);
|
|
||||||
|
|
||||||
// Setup desired GL state
|
|
||||||
ImGui_ImplOpenGL2_SetupRenderState(draw_data, fb_width, fb_height);
|
|
||||||
|
|
||||||
// Will project scissor/clipping rectangles into framebuffer space
|
|
||||||
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
|
|
||||||
ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
|
|
||||||
|
|
||||||
// Render command lists
|
|
||||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
|
||||||
{
|
|
||||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
|
||||||
const ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data;
|
|
||||||
const ImDrawIdx* idx_buffer = draw_list->IdxBuffer.Data;
|
|
||||||
glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, pos)));
|
|
||||||
glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, uv)));
|
|
||||||
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, col)));
|
|
||||||
|
|
||||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
|
||||||
{
|
|
||||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
|
||||||
if (pcmd->UserCallback)
|
|
||||||
{
|
|
||||||
// User callback, registered via ImDrawList::AddCallback()
|
|
||||||
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
|
||||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
|
||||||
ImGui_ImplOpenGL2_SetupRenderState(draw_data, fb_width, fb_height);
|
|
||||||
else
|
|
||||||
pcmd->UserCallback(draw_list, pcmd);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Project scissor/clipping rectangles into framebuffer space
|
|
||||||
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
|
|
||||||
ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
|
|
||||||
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Apply scissor/clipping rectangle (Y is inverted in OpenGL)
|
|
||||||
glScissor((int)clip_min.x, (int)((float)fb_height - clip_max.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y));
|
|
||||||
|
|
||||||
// Bind texture, Draw
|
|
||||||
glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID());
|
|
||||||
glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer + pcmd->IdxOffset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore modified GL state
|
|
||||||
glDisableClientState(GL_COLOR_ARRAY);
|
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture);
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
|
||||||
glPopMatrix();
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
|
||||||
glPopMatrix();
|
|
||||||
glPopAttrib();
|
|
||||||
glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]); glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]);
|
|
||||||
glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]);
|
|
||||||
glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]);
|
|
||||||
glShadeModel(last_shade_model);
|
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, last_tex_env_mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ImGui_ImplOpenGL2_CreateFontsTexture()
|
|
||||||
{
|
|
||||||
// Build texture atlas
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData();
|
|
||||||
unsigned char* pixels;
|
|
||||||
int width, height;
|
|
||||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bit (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory.
|
|
||||||
|
|
||||||
// Upload texture to graphics system
|
|
||||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
|
||||||
GLint last_texture;
|
|
||||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
|
||||||
glGenTextures(1, &bd->FontTexture);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, bd->FontTexture);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
|
||||||
|
|
||||||
// Store our identifier
|
|
||||||
io.Fonts->SetTexID((ImTextureID)(intptr_t)bd->FontTexture);
|
|
||||||
|
|
||||||
// Restore state
|
|
||||||
glBindTexture(GL_TEXTURE_2D, last_texture);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui_ImplOpenGL2_DestroyFontsTexture()
|
|
||||||
{
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData();
|
|
||||||
if (bd->FontTexture)
|
|
||||||
{
|
|
||||||
glDeleteTextures(1, &bd->FontTexture);
|
|
||||||
io.Fonts->SetTexID(0);
|
|
||||||
bd->FontTexture = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ImGui_ImplOpenGL2_CreateDeviceObjects()
|
|
||||||
{
|
|
||||||
return ImGui_ImplOpenGL2_CreateFontsTexture();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui_ImplOpenGL2_DestroyDeviceObjects()
|
|
||||||
{
|
|
||||||
ImGui_ImplOpenGL2_DestroyFontsTexture();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
|
||||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
|
||||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
static void ImGui_ImplOpenGL2_RenderWindow(ImGuiViewport* viewport, void*)
|
|
||||||
{
|
|
||||||
if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear))
|
|
||||||
{
|
|
||||||
ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
|
|
||||||
glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
}
|
|
||||||
ImGui_ImplOpenGL2_RenderDrawData(viewport->DrawData);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplOpenGL2_InitMultiViewportSupport()
|
|
||||||
{
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
||||||
platform_io.Renderer_RenderWindow = ImGui_ImplOpenGL2_RenderWindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplOpenGL2_ShutdownMultiViewportSupport()
|
|
||||||
{
|
|
||||||
ImGui::DestroyPlatformWindows();
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#if defined(__clang__)
|
|
||||||
#pragma clang diagnostic pop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
// dear imgui: Renderer Backend for OpenGL2 (legacy OpenGL, fixed pipeline)
|
|
||||||
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
|
||||||
|
|
||||||
// Implemented features:
|
|
||||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
|
||||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
|
||||||
// Missing features or Issues:
|
|
||||||
// [ ] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
|
||||||
|
|
||||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
|
||||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
|
||||||
// Learn about Dear ImGui:
|
|
||||||
// - FAQ https://dearimgui.com/faq
|
|
||||||
// - Getting Started https://dearimgui.com/getting-started
|
|
||||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
|
||||||
// - Introduction, links and more at the top of imgui.cpp
|
|
||||||
|
|
||||||
// **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)**
|
|
||||||
// **Prefer using the code in imgui_impl_opengl3.cpp**
|
|
||||||
// This code is mostly provided as a reference to learn how ImGui integration works, because it is shorter to read.
|
|
||||||
// If your code is using GL3+ context or any semi modern OpenGL calls, using this is likely to make everything more
|
|
||||||
// complicated, will require your code to reset every single OpenGL attributes to their initial state, and might
|
|
||||||
// confuse your GPU driver.
|
|
||||||
// The GL2 code is unable to reset attributes or even call e.g. "glUseProgram(0)" because they don't exist in that API.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "imgui.h" // IMGUI_IMPL_API
|
|
||||||
#ifndef IMGUI_DISABLE
|
|
||||||
|
|
||||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
|
||||||
IMGUI_IMPL_API bool ImGui_ImplOpenGL2_Init();
|
|
||||||
IMGUI_IMPL_API void ImGui_ImplOpenGL2_Shutdown();
|
|
||||||
IMGUI_IMPL_API void ImGui_ImplOpenGL2_NewFrame();
|
|
||||||
IMGUI_IMPL_API void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data);
|
|
||||||
|
|
||||||
// Called by Init/NewFrame/Shutdown
|
|
||||||
IMGUI_IMPL_API bool ImGui_ImplOpenGL2_CreateFontsTexture();
|
|
||||||
IMGUI_IMPL_API void ImGui_ImplOpenGL2_DestroyFontsTexture();
|
|
||||||
IMGUI_IMPL_API bool ImGui_ImplOpenGL2_CreateDeviceObjects();
|
|
||||||
IMGUI_IMPL_API void ImGui_ImplOpenGL2_DestroyDeviceObjects();
|
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
|
||||||
@@ -107,7 +107,6 @@ class TAnimContainer : public std::enable_shared_from_this<TAnimContainer>
|
|||||||
// opakowanie modelu, określające stan egzemplarza
|
// opakowanie modelu, określające stan egzemplarza
|
||||||
class TAnimModel : public scene::basic_node {
|
class TAnimModel : public scene::basic_node {
|
||||||
|
|
||||||
friend opengl_renderer;
|
|
||||||
friend opengl33_renderer;
|
friend opengl33_renderer;
|
||||||
friend itemproperties_panel;
|
friend itemproperties_panel;
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ class TSubModel
|
|||||||
{ // klasa submodelu - pojedyncza siatka, punkt świetlny albo grupa punktów
|
{ // klasa submodelu - pojedyncza siatka, punkt świetlny albo grupa punktów
|
||||||
//m7todo: zrobić normalną serializację
|
//m7todo: zrobić normalną serializację
|
||||||
|
|
||||||
friend opengl_renderer;
|
|
||||||
friend opengl33_renderer;
|
friend opengl33_renderer;
|
||||||
friend TModel3d; // temporary workaround. TODO: clean up class content/hierarchy
|
friend TModel3d; // temporary workaround. TODO: clean up class content/hierarchy
|
||||||
friend TDynamicObject; // temporary etc
|
friend TDynamicObject; // temporary etc
|
||||||
@@ -268,7 +267,6 @@ public:
|
|||||||
|
|
||||||
class TModel3d
|
class TModel3d
|
||||||
{
|
{
|
||||||
friend opengl_renderer;
|
|
||||||
friend opengl33_renderer;
|
friend opengl33_renderer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -1374,28 +1374,6 @@ opengl_texture::set_filtering() const
|
|||||||
// 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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( Global.LegacyRenderer ) {
|
|
||||||
|
|
||||||
bool sharpen{ false };
|
|
||||||
for( auto const &trait : traits ) {
|
|
||||||
|
|
||||||
switch( trait ) {
|
|
||||||
|
|
||||||
case '#': { sharpen = true; break; }
|
|
||||||
default: { break; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( true == sharpen ) {
|
|
||||||
// #: sharpen more
|
|
||||||
::glTexEnvf( GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, -2.0f );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// regular texture sharpening
|
|
||||||
::glTexEnvf( GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, -1.0f );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -306,9 +306,7 @@ int generate_nodebank_previews(int Argc, char *Argv[])
|
|||||||
|
|
||||||
// the full renderer, drawing offscreen
|
// the full renderer, drawing offscreen
|
||||||
Global.GfxRenderer = "default";
|
Global.GfxRenderer = "default";
|
||||||
Global.LegacyRenderer = false;
|
|
||||||
Global.NvRenderer = false;
|
Global.NvRenderer = false;
|
||||||
Global.BasicRenderer = false;
|
|
||||||
Global.gfx_usegles = false;
|
Global.gfx_usegles = false;
|
||||||
Global.gfx_skippipeline = false;
|
Global.gfx_skippipeline = false;
|
||||||
Global.gfx_postfx_motionblur_enabled = false;
|
Global.gfx_postfx_motionblur_enabled = false;
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
/*
|
|
||||||
This Source Code Form is subject to the
|
|
||||||
terms of the Mozilla Public License, v.
|
|
||||||
2.0. If a copy of the MPL was not
|
|
||||||
distributed with this file, You can
|
|
||||||
obtain one at
|
|
||||||
http://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
#include "rendering/openglcolor.h"
|
|
||||||
|
|
||||||
opengl_color OpenGLColor;
|
|
||||||
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
/*
|
|
||||||
This Source Code Form is subject to the
|
|
||||||
terms of the Mozilla Public License, v.
|
|
||||||
2.0. If a copy of the MPL was not
|
|
||||||
distributed with this file, You can
|
|
||||||
obtain one at
|
|
||||||
http://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "utilities/Globals.h"
|
|
||||||
|
|
||||||
// encapsulation of the fixed pipeline opengl color
|
|
||||||
class opengl_color {
|
|
||||||
|
|
||||||
public:
|
|
||||||
// constructors:
|
|
||||||
opengl_color() = default;
|
|
||||||
|
|
||||||
// methods:
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
color3( glm::vec3 const &Color ) {
|
|
||||||
return color4( glm::vec4{ Color, 1.f } ); }
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
color3( float const Red, float const Green, float const Blue ) {
|
|
||||||
return color3( glm::vec3 { Red, Green, Blue } ); }
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
color3( float const *Value ) {
|
|
||||||
return color3( glm::make_vec3( Value ) ); }
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
color4( glm::vec4 const &Color ) {
|
|
||||||
if( ( Color != m_color ) || ( false == Global.bUseVBO ) ) {
|
|
||||||
m_color = Color;
|
|
||||||
::glColor4fv( glm::value_ptr( m_color ) ); } }
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
color4( float const Red, float const Green, float const Blue, float const Alpha ) {
|
|
||||||
return color4( glm::vec4{ Red, Green, Blue, Alpha } ); }
|
|
||||||
inline
|
|
||||||
void
|
|
||||||
color4( float const *Value ) {
|
|
||||||
return color4( glm::make_vec4( Value ) );
|
|
||||||
}
|
|
||||||
inline
|
|
||||||
glm::vec4 const &
|
|
||||||
data() const {
|
|
||||||
return m_color; }
|
|
||||||
inline
|
|
||||||
float const *
|
|
||||||
data_array() const {
|
|
||||||
return glm::value_ptr( m_color ); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
// members:
|
|
||||||
glm::vec4 m_color { -1 };
|
|
||||||
};
|
|
||||||
|
|
||||||
extern opengl_color OpenGLColor;
|
|
||||||
|
|
||||||
// NOTE: standard opengl calls re-definitions
|
|
||||||
#undef glColor3f
|
|
||||||
#undef glColor3fv
|
|
||||||
#undef glColor4f
|
|
||||||
#undef glColor4fv
|
|
||||||
|
|
||||||
#define glColor3f OpenGLColor.color3
|
|
||||||
#define glColor3fv OpenGLColor.color3
|
|
||||||
#define glColor4f OpenGLColor.color4
|
|
||||||
#define glColor4fv OpenGLColor.color4
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
@@ -1,375 +0,0 @@
|
|||||||
/*
|
|
||||||
This Source Code Form is subject to the
|
|
||||||
terms of the Mozilla Public License, v.
|
|
||||||
2.0. If a copy of the MPL was not
|
|
||||||
distributed with this file, You can
|
|
||||||
obtain one at
|
|
||||||
http://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
#include "rendering/openglgeometrybank.h"
|
|
||||||
#include "rendering/openglcolor.h"
|
|
||||||
|
|
||||||
#include "utilities/Logs.h"
|
|
||||||
|
|
||||||
namespace gfx {
|
|
||||||
|
|
||||||
// opengl vbo-based variant of the geometry bank
|
|
||||||
|
|
||||||
GLuint opengl_vbogeometrybank::m_activevertexbuffer { 0 }; // buffer bound currently on the opengl end, if any
|
|
||||||
unsigned int opengl_vbogeometrybank::m_activestreams { gfx::stream::none }; // currently enabled data type pointers
|
|
||||||
std::vector<GLint> opengl_vbogeometrybank::m_activetexturearrays; // currently enabled texture coord arrays
|
|
||||||
|
|
||||||
// create() subclass details
|
|
||||||
void
|
|
||||||
opengl_vbogeometrybank::create_( gfx::geometry_handle const &Geometry ) {
|
|
||||||
// adding a chunk means we'll be (re)building the buffer, which will fill the chunk records, amongst other things.
|
|
||||||
// thus we don't need to initialize the values here
|
|
||||||
m_chunkrecords.emplace_back( chunk_record() );
|
|
||||||
// kiss the existing buffer goodbye, new overall data size means we'll be making a new one
|
|
||||||
delete_buffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
// replace() subclass details
|
|
||||||
void
|
|
||||||
opengl_vbogeometrybank::replace_( gfx::geometry_handle const &Geometry ) {
|
|
||||||
|
|
||||||
auto &chunkrecord = m_chunkrecords[ Geometry.chunk - 1 ];
|
|
||||||
chunkrecord.is_good = false;
|
|
||||||
// if the overall length of the chunk didn't change we can get away with reusing the old buffer...
|
|
||||||
if( geometry_bank::chunk( Geometry ).vertices.size() != chunkrecord.vertex_count ) {
|
|
||||||
// ...but otherwise we'll need to allocate a new one
|
|
||||||
// TBD: we could keep and reuse the old buffer also if the new chunk is smaller than the old one,
|
|
||||||
// but it'd require some extra tracking and work to keep all chunks up to date; also wasting vram; may be not worth it?
|
|
||||||
delete_buffer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw() subclass details
|
|
||||||
std::size_t
|
|
||||||
opengl_vbogeometrybank::draw_( gfx::geometry_handle const &Geometry, gfx::stream_units const &Units, unsigned int const Streams ) {
|
|
||||||
|
|
||||||
setup_buffer();
|
|
||||||
|
|
||||||
auto &chunkrecord { m_chunkrecords[ Geometry.chunk - 1 ] };
|
|
||||||
// sanity check; shouldn't be needed but, eh
|
|
||||||
if( chunkrecord.vertex_count == 0 ) { return 0; }
|
|
||||||
// setup...
|
|
||||||
if( m_activevertexbuffer != m_vertexbuffer ) {
|
|
||||||
bind_buffer();
|
|
||||||
}
|
|
||||||
auto const &chunk = gfx::geometry_bank::chunk( Geometry );
|
|
||||||
if( false == chunkrecord.is_good ) {
|
|
||||||
// we may potentially need to upload new buffer data before we can draw it
|
|
||||||
if( chunkrecord.index_count > 0 ) {
|
|
||||||
::glBufferSubData(
|
|
||||||
GL_ELEMENT_ARRAY_BUFFER,
|
|
||||||
chunkrecord.index_offset * sizeof( gfx::basic_index ),
|
|
||||||
chunkrecord.index_count * sizeof( gfx::basic_index ),
|
|
||||||
chunk.indices.data() );
|
|
||||||
}
|
|
||||||
::glBufferSubData(
|
|
||||||
GL_ARRAY_BUFFER,
|
|
||||||
chunkrecord.vertex_offset * sizeof( gfx::basic_vertex ),
|
|
||||||
chunkrecord.vertex_count * sizeof( gfx::basic_vertex ),
|
|
||||||
chunk.vertices.data() );
|
|
||||||
chunkrecord.is_good = true;
|
|
||||||
}
|
|
||||||
// ...render...
|
|
||||||
if( chunkrecord.index_count > 0 ) {
|
|
||||||
/*
|
|
||||||
::glDrawElementsBaseVertex(
|
|
||||||
chunk.type,
|
|
||||||
chunkrecord.index_count, GL_UNSIGNED_INT, reinterpret_cast<void const *>( chunkrecord.index_offset * sizeof( gfx::basic_index ) ),
|
|
||||||
chunkrecord.vertex_offset );
|
|
||||||
*/
|
|
||||||
if (glDrawRangeElementsBaseVertex) {
|
|
||||||
if( m_activestreams != Streams ) {
|
|
||||||
bind_streams( Units, Streams );
|
|
||||||
}
|
|
||||||
::glDrawRangeElementsBaseVertex(
|
|
||||||
chunk.type,
|
|
||||||
0, static_cast<GLuint>(chunkrecord.vertex_count),
|
|
||||||
static_cast<GLsizei>(chunkrecord.index_count), GL_UNSIGNED_INT, reinterpret_cast<void const *>( chunkrecord.index_offset * sizeof( gfx::basic_index ) ),
|
|
||||||
static_cast<GLint>(chunkrecord.vertex_offset) );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
bind_streams( Units, Streams, chunkrecord.vertex_offset );
|
|
||||||
::glDrawRangeElements(
|
|
||||||
chunk.type,
|
|
||||||
0, static_cast<GLuint>(chunkrecord.vertex_count),
|
|
||||||
static_cast<GLsizei>(chunkrecord.index_count), GL_UNSIGNED_INT, reinterpret_cast<void const *>( chunkrecord.index_offset * sizeof( gfx::basic_index ) ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if( m_activestreams != Streams ) {
|
|
||||||
bind_streams( Units, Streams );
|
|
||||||
}
|
|
||||||
::glDrawArrays( chunk.type, static_cast<GLint>(chunkrecord.vertex_offset), static_cast<GLsizei>(chunkrecord.vertex_count) );
|
|
||||||
}
|
|
||||||
// ...post-render cleanup
|
|
||||||
/*
|
|
||||||
::glDisableClientState( GL_VERTEX_ARRAY );
|
|
||||||
::glDisableClientState( GL_NORMAL_ARRAY );
|
|
||||||
::glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
|
||||||
::glBindBuffer( GL_ARRAY_BUFFER, 0 ); m_activebuffer = 0;
|
|
||||||
*/
|
|
||||||
auto const vertexcount { ( chunkrecord.index_count > 0 ? chunkrecord.index_count : chunkrecord.vertex_count ) };
|
|
||||||
switch( chunk.type ) {
|
|
||||||
case GL_TRIANGLES: { return vertexcount / 3; }
|
|
||||||
case GL_TRIANGLE_STRIP: { return vertexcount - 2; }
|
|
||||||
default: { return 0; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// release () subclass details
|
|
||||||
void
|
|
||||||
opengl_vbogeometrybank::release_() {
|
|
||||||
|
|
||||||
delete_buffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
opengl_vbogeometrybank::setup_buffer() {
|
|
||||||
|
|
||||||
if( m_vertexbuffer != 0 ) { return; }
|
|
||||||
// if there's no buffer, we'll have to make one
|
|
||||||
// NOTE: this isn't exactly optimal in terms of ensuring the gfx card doesn't stall waiting for the data
|
|
||||||
// may be better to initiate upload earlier (during update phase) and trust this effort won't go to waste
|
|
||||||
if( true == m_chunks.empty() ) { return; }
|
|
||||||
|
|
||||||
std::size_t vertexcount{ 0 };
|
|
||||||
std::size_t indexcount{ 0 };
|
|
||||||
auto chunkiterator = m_chunks.cbegin();
|
|
||||||
for( auto &chunkrecord : m_chunkrecords ) {
|
|
||||||
// fill records for all chunks, based on the chunk data
|
|
||||||
chunkrecord.is_good = false; // if we're re-creating buffer, chunks might've been uploaded in the old one
|
|
||||||
chunkrecord.vertex_offset = vertexcount;
|
|
||||||
chunkrecord.vertex_count = chunkiterator->vertices.size();
|
|
||||||
vertexcount += chunkrecord.vertex_count;
|
|
||||||
chunkrecord.index_offset = indexcount;
|
|
||||||
chunkrecord.index_count = chunkiterator->indices.size();
|
|
||||||
indexcount += chunkrecord.index_count;
|
|
||||||
++chunkiterator;
|
|
||||||
}
|
|
||||||
// the odds for all created chunks to get replaced with empty ones are quite low, but the possibility does exist
|
|
||||||
if( vertexcount == 0 ) { return; }
|
|
||||||
// try to set up the buffers we need
|
|
||||||
if( ( indexcount > 0 ) && ( m_indexbuffer == 0 ) ) {
|
|
||||||
::glGenBuffers( 1, &m_indexbuffer );
|
|
||||||
if( m_indexbuffer == 0 ) { return; } // if we didn't get a buffer we'll try again during the next draw call
|
|
||||||
}
|
|
||||||
if( m_vertexbuffer == 0 ) {
|
|
||||||
::glGenBuffers( 1, &m_vertexbuffer );
|
|
||||||
if( m_vertexbuffer == 0 ) { return; } // if we didn't get a buffer we'll try again during the next draw call
|
|
||||||
}
|
|
||||||
bind_buffer();
|
|
||||||
// NOTE: we're using static_draw since it's generally true for all we have implemented at the moment
|
|
||||||
// TODO: allow to specify usage hint at the object creation, and pass it here
|
|
||||||
if( indexcount > 0 ) {
|
|
||||||
::glBufferData(
|
|
||||||
GL_ELEMENT_ARRAY_BUFFER,
|
|
||||||
indexcount * sizeof( gfx::basic_index ),
|
|
||||||
nullptr,
|
|
||||||
GL_STATIC_DRAW );
|
|
||||||
if( ::glGetError() == GL_OUT_OF_MEMORY ) {
|
|
||||||
// TBD: throw a bad_alloc?
|
|
||||||
ErrorLog( "openGL error: out of memory; failed to create a geometry index buffer" );
|
|
||||||
delete_buffer();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
::glBufferData(
|
|
||||||
GL_ARRAY_BUFFER,
|
|
||||||
vertexcount * sizeof( gfx::basic_vertex ),
|
|
||||||
nullptr,
|
|
||||||
GL_STATIC_DRAW );
|
|
||||||
if( ::glGetError() == GL_OUT_OF_MEMORY ) {
|
|
||||||
// TBD: throw a bad_alloc?
|
|
||||||
ErrorLog( "openGL error: out of memory; failed to create a geometry buffer" );
|
|
||||||
delete_buffer();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
opengl_vbogeometrybank::bind_buffer() const {
|
|
||||||
|
|
||||||
::glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_indexbuffer );
|
|
||||||
::glBindBuffer( GL_ARRAY_BUFFER, m_vertexbuffer );
|
|
||||||
m_activevertexbuffer = m_vertexbuffer;
|
|
||||||
m_activestreams = gfx::stream::none;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
opengl_vbogeometrybank::delete_buffer() {
|
|
||||||
|
|
||||||
if( m_indexbuffer != 0 ) {
|
|
||||||
::glDeleteBuffers( 1, &m_indexbuffer );
|
|
||||||
m_indexbuffer = 0;
|
|
||||||
}
|
|
||||||
if( m_vertexbuffer != 0 ) {
|
|
||||||
|
|
||||||
::glDeleteBuffers( 1, &m_vertexbuffer );
|
|
||||||
if( m_activevertexbuffer == m_vertexbuffer ) {
|
|
||||||
m_activevertexbuffer = 0;
|
|
||||||
release_streams();
|
|
||||||
}
|
|
||||||
m_vertexbuffer = 0;
|
|
||||||
// NOTE: since we've deleted the buffer all chunks it held were rendered invalid as well
|
|
||||||
// instead of clearing their state here we're delaying it until new buffer is created to avoid looping through chunk records twice
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
opengl_vbogeometrybank::bind_streams( gfx::stream_units const &Units, unsigned int const Streams, size_t offset ) {
|
|
||||||
|
|
||||||
if( Streams & gfx::stream::position ) {
|
|
||||||
::glVertexPointer( 3, GL_FLOAT, sizeof( gfx::basic_vertex ), reinterpret_cast<void const *>( offsetof(gfx::basic_vertex, position) + sizeof( gfx::basic_vertex ) * offset ) );
|
|
||||||
::glEnableClientState( GL_VERTEX_ARRAY );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
::glDisableClientState( GL_VERTEX_ARRAY );
|
|
||||||
}
|
|
||||||
// NOTE: normal and color streams share the data, making them effectively mutually exclusive
|
|
||||||
if( Streams & gfx::stream::normal ) {
|
|
||||||
::glNormalPointer( GL_FLOAT, sizeof( gfx::basic_vertex ), reinterpret_cast<void const *>( offsetof(gfx::basic_vertex, normal) + sizeof( gfx::basic_vertex ) * offset ) );
|
|
||||||
::glEnableClientState( GL_NORMAL_ARRAY );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
::glDisableClientState( GL_NORMAL_ARRAY );
|
|
||||||
}
|
|
||||||
if( Streams & gfx::stream::color ) {
|
|
||||||
::glColorPointer( 3, GL_FLOAT, sizeof( gfx::basic_vertex ), reinterpret_cast<void const *>( offsetof(gfx::basic_vertex, normal) + sizeof( gfx::basic_vertex ) * offset ) );
|
|
||||||
::glEnableClientState( GL_COLOR_ARRAY );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
::glDisableClientState( GL_COLOR_ARRAY );
|
|
||||||
}
|
|
||||||
if( Streams & gfx::stream::texture ) {
|
|
||||||
for( auto unit : Units.texture ) {
|
|
||||||
::glClientActiveTexture( GL_TEXTURE0 + unit );
|
|
||||||
::glTexCoordPointer( 2, GL_FLOAT, sizeof( gfx::basic_vertex ), reinterpret_cast<void const *>( offsetof(gfx::basic_vertex, texture) + sizeof( gfx::basic_vertex ) * offset ) );
|
|
||||||
::glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
|
||||||
}
|
|
||||||
m_activetexturearrays = Units.texture;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for( auto unit : Units.texture ) {
|
|
||||||
::glClientActiveTexture( GL_TEXTURE0 + unit );
|
|
||||||
::glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
|
||||||
}
|
|
||||||
m_activetexturearrays.clear(); // NOTE: we're simplifying here, since we always toggle the same texture coord sets
|
|
||||||
}
|
|
||||||
|
|
||||||
m_activestreams = Streams;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
opengl_vbogeometrybank::release_streams() {
|
|
||||||
|
|
||||||
::glDisableClientState( GL_VERTEX_ARRAY );
|
|
||||||
::glDisableClientState( GL_NORMAL_ARRAY );
|
|
||||||
::glDisableClientState( GL_COLOR_ARRAY );
|
|
||||||
for( auto unit : m_activetexturearrays ) {
|
|
||||||
::glClientActiveTexture( GL_TEXTURE0 + unit );
|
|
||||||
::glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
|
||||||
}
|
|
||||||
|
|
||||||
m_activestreams = gfx::stream::none;
|
|
||||||
m_activetexturearrays.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
// opengl display list based variant of the geometry bank
|
|
||||||
|
|
||||||
// create() subclass details
|
|
||||||
void
|
|
||||||
opengl_dlgeometrybank::create_( gfx::geometry_handle const &Geometry ) {
|
|
||||||
|
|
||||||
m_chunkrecords.emplace_back( chunk_record() );
|
|
||||||
}
|
|
||||||
|
|
||||||
// replace() subclass details
|
|
||||||
void
|
|
||||||
opengl_dlgeometrybank::replace_( gfx::geometry_handle const &Geometry ) {
|
|
||||||
|
|
||||||
delete_list( Geometry );
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw() subclass details
|
|
||||||
std::size_t
|
|
||||||
opengl_dlgeometrybank::draw_( gfx::geometry_handle const &Geometry, gfx::stream_units const &Units, unsigned int const Streams ) {
|
|
||||||
|
|
||||||
auto &chunkrecord = m_chunkrecords[ Geometry.chunk - 1 ];
|
|
||||||
if( chunkrecord.streams != Streams ) {
|
|
||||||
delete_list( Geometry );
|
|
||||||
chunkrecord.primitive_count = 0;
|
|
||||||
}
|
|
||||||
if( chunkrecord.list == 0 ) {
|
|
||||||
// we don't have a list ready, so compile one
|
|
||||||
chunkrecord.streams = Streams;
|
|
||||||
chunkrecord.list = ::glGenLists( 1 );
|
|
||||||
auto const &chunk = gfx::geometry_bank::chunk( Geometry );
|
|
||||||
::glNewList( chunkrecord.list, GL_COMPILE );
|
|
||||||
|
|
||||||
::glBegin( chunk.type );
|
|
||||||
if( chunk.indices.size() > 0 ) {
|
|
||||||
// indexed geometry
|
|
||||||
for( auto const &index : chunk.indices ) {
|
|
||||||
auto const &vertex { chunk.vertices[ index ] };
|
|
||||||
if( Streams & gfx::stream::normal ) { ::glNormal3fv( glm::value_ptr( vertex.normal ) ); }
|
|
||||||
else if( Streams & gfx::stream::color ) { ::glColor3fv( glm::value_ptr( vertex.normal ) ); }
|
|
||||||
if( Streams & gfx::stream::texture ) { for( auto unit : Units.texture ) { ::glMultiTexCoord2fv( unit, glm::value_ptr( vertex.texture ) ); } }
|
|
||||||
if( Streams & gfx::stream::position ) { ::glVertex3fv( glm::value_ptr( vertex.position ) ); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// raw geometry
|
|
||||||
for( auto const &vertex : chunk.vertices ) {
|
|
||||||
if( Streams & gfx::stream::normal ) { ::glNormal3fv( glm::value_ptr( vertex.normal ) ); }
|
|
||||||
else if( Streams & gfx::stream::color ) { ::glColor3fv( glm::value_ptr( vertex.normal ) ); }
|
|
||||||
if( Streams & gfx::stream::texture ) { for( auto unit : Units.texture ) { ::glMultiTexCoord2fv( unit, glm::value_ptr( vertex.texture ) ); } }
|
|
||||||
if( Streams & gfx::stream::position ) { ::glVertex3fv( glm::value_ptr( vertex.position ) ); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
::glEnd();
|
|
||||||
::glEndList();
|
|
||||||
|
|
||||||
auto const vertexcount { ( chunk.indices.empty() ? chunk.vertices.size() : chunk.indices.size() ) };
|
|
||||||
switch( chunk.type ) {
|
|
||||||
case GL_TRIANGLES: { chunkrecord.primitive_count += vertexcount / 3; break; }
|
|
||||||
case GL_TRIANGLE_STRIP: { chunkrecord.primitive_count += vertexcount - 2; break; }
|
|
||||||
default: { break; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// with the list done we can just play it
|
|
||||||
::glCallList( chunkrecord.list );
|
|
||||||
return chunkrecord.primitive_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
// release () subclass details
|
|
||||||
void
|
|
||||||
opengl_dlgeometrybank::release_() {
|
|
||||||
|
|
||||||
for( auto &chunkrecord : m_chunkrecords ) {
|
|
||||||
if( chunkrecord.list != 0 ) {
|
|
||||||
::glDeleteLists( chunkrecord.list, 1 );
|
|
||||||
chunkrecord.list = 0;
|
|
||||||
}
|
|
||||||
chunkrecord.streams = gfx::stream::none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
opengl_dlgeometrybank::delete_list( gfx::geometry_handle const &Geometry ) {
|
|
||||||
// NOTE: given it's our own internal method we trust it to be called with valid parameters
|
|
||||||
auto &chunkrecord = m_chunkrecords[ Geometry.chunk - 1 ];
|
|
||||||
if( chunkrecord.list != 0 ) {
|
|
||||||
::glDeleteLists( chunkrecord.list, 1 );
|
|
||||||
chunkrecord.list = 0;
|
|
||||||
}
|
|
||||||
chunkrecord.streams = gfx::stream::none;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace gfx
|
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
/*
|
|
||||||
This Source Code Form is subject to the
|
|
||||||
terms of the Mozilla Public License, v.
|
|
||||||
2.0. If a copy of the MPL was not
|
|
||||||
distributed with this file, You can
|
|
||||||
obtain one at
|
|
||||||
http://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "rendering/geometrybank.h"
|
|
||||||
|
|
||||||
namespace gfx {
|
|
||||||
|
|
||||||
// opengl vbo-based variant of the geometry bank
|
|
||||||
|
|
||||||
class opengl_vbogeometrybank : public geometry_bank {
|
|
||||||
|
|
||||||
public:
|
|
||||||
// constructors:
|
|
||||||
opengl_vbogeometrybank() = default;
|
|
||||||
// destructor
|
|
||||||
~opengl_vbogeometrybank() {
|
|
||||||
delete_buffer(); }
|
|
||||||
// methods:
|
|
||||||
static
|
|
||||||
void
|
|
||||||
reset() {
|
|
||||||
m_activevertexbuffer = 0;
|
|
||||||
m_activestreams = gfx::stream::none; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
// types:
|
|
||||||
struct chunk_record {
|
|
||||||
std::size_t vertex_offset{ 0 }; // beginning of the chunk vertex data as offset from the beginning of the last established buffer
|
|
||||||
std::size_t vertex_count{ 0 }; // size of the chunk in the last established buffer
|
|
||||||
std::size_t index_offset{ 0 };
|
|
||||||
std::size_t index_count{ 0 };
|
|
||||||
bool is_good{ false }; // true if local content of the chunk matches the data on the opengl end
|
|
||||||
};
|
|
||||||
|
|
||||||
using chunkrecord_sequence = std::vector<chunk_record>;
|
|
||||||
|
|
||||||
// methods:
|
|
||||||
// create() subclass details
|
|
||||||
void
|
|
||||||
create_( gfx::geometry_handle const &Geometry ) override;
|
|
||||||
// replace() subclass details
|
|
||||||
void
|
|
||||||
replace_( gfx::geometry_handle const &Geometry ) override;
|
|
||||||
// draw() subclass details
|
|
||||||
auto
|
|
||||||
draw_( gfx::geometry_handle const &Geometry, gfx::stream_units const &Units, unsigned int const Streams ) -> std::size_t override;
|
|
||||||
// release() subclass details
|
|
||||||
void
|
|
||||||
release_() override;
|
|
||||||
void
|
|
||||||
setup_buffer();
|
|
||||||
void
|
|
||||||
bind_buffer() const;
|
|
||||||
void
|
|
||||||
delete_buffer();
|
|
||||||
static
|
|
||||||
void
|
|
||||||
bind_streams(gfx::stream_units const &Units, unsigned int const Streams , size_t offset = 0);
|
|
||||||
static
|
|
||||||
void
|
|
||||||
release_streams();
|
|
||||||
|
|
||||||
// members:
|
|
||||||
static GLuint m_activevertexbuffer; // buffer bound currently on the opengl end, if any
|
|
||||||
static unsigned int m_activestreams;
|
|
||||||
static std::vector<GLint> m_activetexturearrays;
|
|
||||||
GLuint m_vertexbuffer { 0 }; // id of the buffer holding vertex data on the opengl end
|
|
||||||
GLuint m_indexbuffer { 0 }; // id of the buffer holding index data on the opengl end
|
|
||||||
chunkrecord_sequence m_chunkrecords; // helper data for all stored geometry chunks, in matching order
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
// opengl display list based variant of the geometry bank
|
|
||||||
|
|
||||||
class opengl_dlgeometrybank : public geometry_bank {
|
|
||||||
|
|
||||||
public:
|
|
||||||
// constructors:
|
|
||||||
opengl_dlgeometrybank() = default;
|
|
||||||
// destructor:
|
|
||||||
~opengl_dlgeometrybank() {
|
|
||||||
for( auto const &chunkrecord : m_chunkrecords ) {
|
|
||||||
::glDeleteLists( chunkrecord.list, 1 ); } }
|
|
||||||
|
|
||||||
private:
|
|
||||||
// types:
|
|
||||||
struct chunk_record {
|
|
||||||
GLuint list { 0 }; // display list associated with the chunk
|
|
||||||
unsigned int streams { 0 }; // stream combination used to generate the display list
|
|
||||||
std::size_t primitive_count { 0 };
|
|
||||||
};
|
|
||||||
|
|
||||||
using chunkrecord_sequence = std::vector<chunk_record>;
|
|
||||||
|
|
||||||
// methods:
|
|
||||||
// create() subclass details
|
|
||||||
void
|
|
||||||
create_( gfx::geometry_handle const &Geometry ) override;
|
|
||||||
// replace() subclass details
|
|
||||||
void
|
|
||||||
replace_( gfx::geometry_handle const &Geometry ) override;
|
|
||||||
// draw() subclass details
|
|
||||||
auto
|
|
||||||
draw_( gfx::geometry_handle const &Geometry, gfx::stream_units const &Units, unsigned int const Streams ) -> std::size_t override;
|
|
||||||
// release () subclass details
|
|
||||||
void
|
|
||||||
release_() override;
|
|
||||||
void
|
|
||||||
delete_list( gfx::geometry_handle const &Geometry );
|
|
||||||
|
|
||||||
// members:
|
|
||||||
chunkrecord_sequence m_chunkrecords; // helper data for all stored geometry chunks, in matching order
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace gfx
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
This Source Code Form is subject to the
|
|
||||||
terms of the Mozilla Public License, v.
|
|
||||||
2.0. If a copy of the MPL was not
|
|
||||||
distributed with this file, You can
|
|
||||||
obtain one at
|
|
||||||
http://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
|
|
||||||
#include "rendering/opengllight.h"
|
|
||||||
|
|
||||||
void
|
|
||||||
opengl_light::apply_intensity( float const Factor ) {
|
|
||||||
|
|
||||||
if( Factor == 1.f ) {
|
|
||||||
|
|
||||||
::glLightfv( id, GL_AMBIENT, glm::value_ptr( ambient ) );
|
|
||||||
::glLightfv( id, GL_DIFFUSE, glm::value_ptr( diffuse ) );
|
|
||||||
::glLightfv( id, GL_SPECULAR, glm::value_ptr( specular ) );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
auto const factor{ std::clamp( Factor, 0.05f, 1.f ) };
|
|
||||||
// temporary light scaling mechanics (ultimately this work will be left to the shaders
|
|
||||||
glm::vec4 scaledambient( ambient.r * factor, ambient.g * factor, ambient.b * factor, ambient.a );
|
|
||||||
glm::vec4 scaleddiffuse( diffuse.r * factor, diffuse.g * factor, diffuse.b * factor, diffuse.a );
|
|
||||||
glm::vec4 scaledspecular( specular.r * factor, specular.g * factor, specular.b * factor, specular.a );
|
|
||||||
glLightfv( id, GL_AMBIENT, glm::value_ptr( scaledambient ) );
|
|
||||||
glLightfv( id, GL_DIFFUSE, glm::value_ptr( scaleddiffuse ) );
|
|
||||||
glLightfv( id, GL_SPECULAR, glm::value_ptr( scaledspecular ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
opengl_light::apply_angle() {
|
|
||||||
|
|
||||||
::glLightfv( id, GL_POSITION, glm::value_ptr( glm::vec4{ position, ( is_directional ? 0.f : 1.f ) } ) );
|
|
||||||
if( false == is_directional ) {
|
|
||||||
::glLightfv( id, GL_SPOT_DIRECTION, glm::value_ptr( direction ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
/*
|
|
||||||
This Source Code Form is subject to the
|
|
||||||
terms of the Mozilla Public License, v.
|
|
||||||
2.0. If a copy of the MPL was not
|
|
||||||
distributed with this file, You can
|
|
||||||
obtain one at
|
|
||||||
http://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "rendering/light.h"
|
|
||||||
|
|
||||||
struct opengl_light : public basic_light {
|
|
||||||
|
|
||||||
GLuint id { (GLuint)-1 };
|
|
||||||
|
|
||||||
void
|
|
||||||
apply_intensity( float const Factor = 1.0f );
|
|
||||||
void
|
|
||||||
apply_angle();
|
|
||||||
|
|
||||||
opengl_light &
|
|
||||||
operator=( basic_light const &Right ) {
|
|
||||||
basic_light::operator=( Right );
|
|
||||||
return *this; }
|
|
||||||
};
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
@@ -1,158 +0,0 @@
|
|||||||
/*
|
|
||||||
This Source Code Form is subject to the
|
|
||||||
terms of the Mozilla Public License, v.
|
|
||||||
2.0. If a copy of the MPL was not
|
|
||||||
distributed with this file, You can
|
|
||||||
obtain one at
|
|
||||||
http://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
#include "rendering/openglparticles.h"
|
|
||||||
|
|
||||||
#include "rendering/particles.h"
|
|
||||||
#include "rendering/openglcamera.h"
|
|
||||||
#include "simulation/simulation.h"
|
|
||||||
#include "utilities/Logs.h"
|
|
||||||
|
|
||||||
std::vector<std::pair<glm::vec3, glm::vec2>> const billboard_vertices {
|
|
||||||
|
|
||||||
{ { -0.5f, -0.5f, 0.f }, { 0.f, 0.f } },
|
|
||||||
{ { 0.5f, -0.5f, 0.f }, { 1.f, 0.f } },
|
|
||||||
{ { 0.5f, 0.5f, 0.f }, { 1.f, 1.f } },
|
|
||||||
{ { -0.5f, 0.5f, 0.f }, { 0.f, 1.f } }
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
|
||||||
opengl_particles::update( opengl_camera const &Camera ) {
|
|
||||||
|
|
||||||
m_particlevertices.clear();
|
|
||||||
|
|
||||||
if( false == Global.Smoke ) { return; }
|
|
||||||
|
|
||||||
// build a list of visible smoke sources
|
|
||||||
// NOTE: arranged by distance to camera, if we ever need sorting and/or total amount cap-based culling
|
|
||||||
std::multimap<float, smoke_source const &> sources;
|
|
||||||
|
|
||||||
for( auto const &source : simulation::Particles.sequence() ) {
|
|
||||||
if( false == Camera.visible( source.area() ) ) { continue; }
|
|
||||||
// NOTE: the distance is negative when the camera is inside the source's bounding area
|
|
||||||
sources.emplace(
|
|
||||||
static_cast<float>( glm::length( Camera.position() - source.area().center ) - source.area().radius ),
|
|
||||||
source );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( true == sources.empty() ) { return; }
|
|
||||||
|
|
||||||
// build billboard data for particles from visible sources
|
|
||||||
auto const camerarotation { glm::mat3( Camera.modelview() ) };
|
|
||||||
particle_vertex vertex;
|
|
||||||
for( auto const &[sourcekey, sourcedata] : sources ) {
|
|
||||||
|
|
||||||
auto const particlecolor {
|
|
||||||
glm::clamp(
|
|
||||||
sourcedata.color()
|
|
||||||
* ( glm::vec3 { Global.DayLight.ambient } + 0.35f * glm::vec3{ Global.DayLight.diffuse } )
|
|
||||||
* 255.f,
|
|
||||||
glm::vec3{ 0.f }, glm::vec3{ 255.f } ) };
|
|
||||||
auto const &particles { sourcedata.sequence() };
|
|
||||||
// TODO: put sanity cap on the overall amount of particles that can be drawn
|
|
||||||
auto const sizestep { 256.0 * billboard_vertices.size() };
|
|
||||||
m_particlevertices.reserve(
|
|
||||||
static_cast<std::size_t>( sizestep * std::ceil( static_cast<double>(m_particlevertices.size()) + ( static_cast<double>(particles.size() * billboard_vertices.size()) ) / sizestep ) ) );
|
|
||||||
for( auto const &particle : particles ) {
|
|
||||||
// TODO: particle color support
|
|
||||||
vertex.color[ 0 ] = static_cast<std::uint_fast8_t>( particlecolor.r );
|
|
||||||
vertex.color[ 1 ] = static_cast<std::uint_fast8_t>( particlecolor.g );
|
|
||||||
vertex.color[ 2 ] = static_cast<std::uint_fast8_t>( particlecolor.b );
|
|
||||||
vertex.color[ 3 ] = static_cast<std::uint_fast8_t>( std::clamp( particle.opacity * 255, 0.f, 255.f ) );
|
|
||||||
|
|
||||||
auto const offset { glm::vec3{ particle.position - Camera.position() } };
|
|
||||||
auto const rotation { glm::angleAxis( particle.rotation, glm::vec3{ 0.f, 0.f, 1.f } ) };
|
|
||||||
|
|
||||||
for( auto const &[billboardoffset, billboardtexture] : billboard_vertices ) {
|
|
||||||
vertex.position = offset + ( rotation * billboardoffset * particle.size ) * camerarotation;
|
|
||||||
vertex.texture = billboardtexture;
|
|
||||||
|
|
||||||
m_particlevertices.emplace_back( vertex );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ship the billboard data to the gpu:
|
|
||||||
// setup...
|
|
||||||
::glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT );
|
|
||||||
// ...make sure we have enough room...
|
|
||||||
if( m_buffercapacity < m_particlevertices.size() ) {
|
|
||||||
// allocate gpu side buffer big enough to hold the data
|
|
||||||
m_buffercapacity = 0;
|
|
||||||
if( m_buffer != (GLuint)-1 ) {
|
|
||||||
// get rid of the old buffer
|
|
||||||
::glDeleteBuffers( 1, &m_buffer );
|
|
||||||
m_buffer = (GLuint)-1;
|
|
||||||
}
|
|
||||||
::glGenBuffers( 1, &m_buffer );
|
|
||||||
if( ( m_buffer > 0 ) && ( m_buffer != (GLuint)-1 ) ) {
|
|
||||||
// if we didn't get a buffer we'll try again during the next draw call
|
|
||||||
// NOTE: we match capacity instead of current size to reduce number of re-allocations
|
|
||||||
auto const particlecount { m_particlevertices.capacity() };
|
|
||||||
::glBindBuffer( GL_ARRAY_BUFFER, m_buffer );
|
|
||||||
::glBufferData(
|
|
||||||
GL_ARRAY_BUFFER,
|
|
||||||
particlecount * sizeof( particle_vertex ),
|
|
||||||
nullptr,
|
|
||||||
GL_DYNAMIC_DRAW );
|
|
||||||
if( ::glGetError() == GL_OUT_OF_MEMORY ) {
|
|
||||||
// TBD: throw a bad_alloc?
|
|
||||||
ErrorLog( "openGL error: out of memory; failed to create a geometry buffer" );
|
|
||||||
::glDeleteBuffers( 1, &m_buffer );
|
|
||||||
m_buffer = (GLuint)-1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
m_buffercapacity = particlecount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ...send the data...
|
|
||||||
if( ( m_buffer > 0 ) && ( m_buffer != (GLuint)-1 ) ) {
|
|
||||||
// if the buffer exists at this point it's guaranteed to be big enough to hold our data
|
|
||||||
::glBindBuffer( GL_ARRAY_BUFFER, m_buffer );
|
|
||||||
::glBufferSubData(
|
|
||||||
GL_ARRAY_BUFFER,
|
|
||||||
0,
|
|
||||||
m_particlevertices.size() * sizeof( particle_vertex ),
|
|
||||||
m_particlevertices.data() );
|
|
||||||
}
|
|
||||||
// ...and cleanup
|
|
||||||
::glPopClientAttrib();
|
|
||||||
::glBindBuffer( GL_ARRAY_BUFFER, 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
std::size_t
|
|
||||||
opengl_particles::render( GLint const Textureunit ) {
|
|
||||||
|
|
||||||
if( false == Global.Smoke ) { return 0; }
|
|
||||||
if( m_buffercapacity == 0 ) { return 0; }
|
|
||||||
if( m_particlevertices.empty() ) { return 0; }
|
|
||||||
if( ( m_buffer == 0 ) || ( m_buffer == (GLuint)-1 ) ) { return 0; }
|
|
||||||
|
|
||||||
// setup...
|
|
||||||
::glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT );
|
|
||||||
::glBindBuffer( GL_ARRAY_BUFFER, m_buffer );
|
|
||||||
::glVertexPointer( 3, GL_FLOAT, sizeof( particle_vertex ), static_cast<char *>( nullptr ) );
|
|
||||||
::glEnableClientState( GL_VERTEX_ARRAY );
|
|
||||||
::glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( particle_vertex ), reinterpret_cast<void const *>( sizeof( float ) * 3 ) );
|
|
||||||
::glEnableClientState( GL_COLOR_ARRAY );
|
|
||||||
::glClientActiveTexture( GL_TEXTURE0 + Textureunit );
|
|
||||||
::glTexCoordPointer( 2, GL_FLOAT, sizeof( particle_vertex ), reinterpret_cast<void const *>( sizeof( float ) * 3 + sizeof( std::uint8_t ) * 4 ) );
|
|
||||||
::glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
|
||||||
// ...draw...
|
|
||||||
::glDrawArrays( GL_QUADS, 0, static_cast<GLsizei>(m_particlevertices.size()) );
|
|
||||||
// ...and cleanup
|
|
||||||
::glPopClientAttrib();
|
|
||||||
::glBindBuffer( GL_ARRAY_BUFFER, 0 );
|
|
||||||
|
|
||||||
return m_particlevertices.size() / 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
This Source Code Form is subject to the
|
|
||||||
terms of the Mozilla Public License, v.
|
|
||||||
2.0. If a copy of the MPL was not
|
|
||||||
distributed with this file, You can
|
|
||||||
obtain one at
|
|
||||||
http://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
class opengl_camera;
|
|
||||||
|
|
||||||
// particle data visualizer
|
|
||||||
class opengl_particles {
|
|
||||||
public:
|
|
||||||
// constructors
|
|
||||||
opengl_particles() = default;
|
|
||||||
// destructor
|
|
||||||
~opengl_particles() {
|
|
||||||
if( m_buffer != -1 ) {
|
|
||||||
::glDeleteBuffers( 1, &m_buffer ); } }
|
|
||||||
// methods
|
|
||||||
void
|
|
||||||
update( opengl_camera const &Camera );
|
|
||||||
std::size_t
|
|
||||||
render( GLint const Textureunit );
|
|
||||||
private:
|
|
||||||
// types
|
|
||||||
struct particle_vertex {
|
|
||||||
glm::vec3 position; // 3d space
|
|
||||||
std::uint8_t color[ 4 ]; // rgba, unsigned byte format
|
|
||||||
glm::vec2 texture; // uv space
|
|
||||||
float padding[ 2 ]; // experimental, some gfx hardware allegedly works better with 32-bit aligned data blocks
|
|
||||||
};
|
|
||||||
/*
|
|
||||||
using sourcedistance_pair = std::pair<smoke_source *, float>;
|
|
||||||
using source_sequence = std::vector<sourcedistance_pair>;
|
|
||||||
*/
|
|
||||||
using particlevertex_sequence = std::vector<particle_vertex>;
|
|
||||||
// methods
|
|
||||||
// members
|
|
||||||
/*
|
|
||||||
source_sequence m_sources; // list of particle sources visible in current render pass, with their respective distances to the camera
|
|
||||||
*/
|
|
||||||
particlevertex_sequence m_particlevertices; // geometry data of visible particles, generated on the cpu end
|
|
||||||
GLuint m_buffer{ (GLuint)-1 }; // id of the buffer holding geometry data on the opengl end
|
|
||||||
std::size_t m_buffercapacity{ 0 }; // total capacity of the last established buffer
|
|
||||||
};
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
@@ -1,173 +0,0 @@
|
|||||||
/*
|
|
||||||
This Source Code Form is subject to the
|
|
||||||
terms of the Mozilla Public License, v.
|
|
||||||
2.0. If a copy of the MPL was not
|
|
||||||
distributed with this file, You can
|
|
||||||
obtain one at
|
|
||||||
http://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
#include "rendering/openglprecipitation.h"
|
|
||||||
|
|
||||||
#include "utilities/Globals.h"
|
|
||||||
#include "rendering/renderer.h"
|
|
||||||
#include "simulation/simulationenvironment.h"
|
|
||||||
|
|
||||||
opengl_precipitation::~opengl_precipitation() {
|
|
||||||
|
|
||||||
if( m_vertexbuffer != -1 ) { ::glDeleteBuffers( 1, &m_vertexbuffer ); }
|
|
||||||
if( m_indexbuffer != -1 ) { ::glDeleteBuffers( 1, &m_indexbuffer ); }
|
|
||||||
if( m_uvbuffer != -1 ) { ::glDeleteBuffers( 1, &m_uvbuffer ); }
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
opengl_precipitation::create( int const Tesselation ) {
|
|
||||||
|
|
||||||
m_vertices.clear();
|
|
||||||
m_uvs.clear();
|
|
||||||
m_indices.clear();
|
|
||||||
|
|
||||||
auto const heightfactor { 10.f }; // height-to-radius factor
|
|
||||||
auto const verticaltexturestretchfactor { 1.5f }; // crude motion blur
|
|
||||||
|
|
||||||
// create geometry chunk
|
|
||||||
auto const latitudes { 3 }; // just a cylinder with end cones
|
|
||||||
auto const longitudes { Tesselation };
|
|
||||||
auto const longitudehalfstep { 0.5f * static_cast<float>( 2.0 * M_PI * 1.f / longitudes ) }; // for crude uv correction
|
|
||||||
|
|
||||||
std::uint16_t index = 0;
|
|
||||||
|
|
||||||
// auto const radius { 25.f }; // cylinder radius
|
|
||||||
std::vector radii { 25.f, 10.f, 5.f, 1.f };
|
|
||||||
for( auto radius : radii ) {
|
|
||||||
|
|
||||||
for( int i = 0; i <= latitudes; ++i ) {
|
|
||||||
|
|
||||||
auto const latitude{ static_cast<float>( M_PI * ( -0.5f + (float)( i ) / latitudes ) ) };
|
|
||||||
auto const z{ std::sin( latitude ) };
|
|
||||||
auto const zr{ std::cos( latitude ) };
|
|
||||||
|
|
||||||
for( int j = 0; j <= longitudes; ++j ) {
|
|
||||||
// NOTE: for the first and last row half of the points we create end up unused but, eh
|
|
||||||
auto const longitude{ static_cast<float>( 2.0 * M_PI * (float)( j ) / longitudes ) };
|
|
||||||
auto const x{ std::cos( longitude ) };
|
|
||||||
auto const y{ std::sin( longitude ) };
|
|
||||||
// NOTE: cartesian to opengl swap would be: -x, -z, -y
|
|
||||||
m_vertices.emplace_back( glm::vec3( -x * zr, -z * heightfactor, -y * zr ) * radius );
|
|
||||||
// uvs
|
|
||||||
// NOTE: first and last row receives modified u values to deal with limitation of mapping onto triangles
|
|
||||||
auto u = (
|
|
||||||
i == 0 ? longitude + longitudehalfstep :
|
|
||||||
i == latitudes ? longitude - longitudehalfstep :
|
|
||||||
longitude );
|
|
||||||
m_uvs.emplace_back(
|
|
||||||
u / ( 2.0 * M_PI ) * radius,
|
|
||||||
1.f - (float)( i ) / latitudes * radius * heightfactor * 0.5f / verticaltexturestretchfactor );
|
|
||||||
|
|
||||||
if( ( i == 0 ) || ( j == 0 ) ) {
|
|
||||||
// initial edge of the dome, don't start indices yet
|
|
||||||
++index;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// the end cones are built from one triangle of each quad, the middle rows use both
|
|
||||||
if( i < latitudes ) {
|
|
||||||
m_indices.emplace_back( index - 1 - ( longitudes + 1 ) );
|
|
||||||
m_indices.emplace_back( index - 1 );
|
|
||||||
m_indices.emplace_back( index );
|
|
||||||
}
|
|
||||||
if( i > 1 ) {
|
|
||||||
m_indices.emplace_back( index );
|
|
||||||
m_indices.emplace_back( index - ( longitudes + 1 ) );
|
|
||||||
m_indices.emplace_back( index - 1 - ( longitudes + 1 ) );
|
|
||||||
}
|
|
||||||
++index;
|
|
||||||
}
|
|
||||||
} // longitude
|
|
||||||
} // latitude
|
|
||||||
} // radius
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
opengl_precipitation::update() {
|
|
||||||
|
|
||||||
// NOTE: we should really be checking state of each buffer as theoretically allocation could go wrong mid-way, but, eh
|
|
||||||
if( m_vertexbuffer == (GLuint)-1 ) {
|
|
||||||
|
|
||||||
if( m_vertices.empty() ) {
|
|
||||||
// create visualization mesh
|
|
||||||
create( 18 );
|
|
||||||
}
|
|
||||||
// cache entry state
|
|
||||||
::glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT );
|
|
||||||
|
|
||||||
// build the buffers
|
|
||||||
::glGenBuffers( 1, &m_vertexbuffer );
|
|
||||||
::glBindBuffer( GL_ARRAY_BUFFER, m_vertexbuffer );
|
|
||||||
::glBufferData( GL_ARRAY_BUFFER, m_vertices.size() * sizeof( glm::vec3 ), m_vertices.data(), GL_STATIC_DRAW );
|
|
||||||
|
|
||||||
::glGenBuffers( 1, &m_uvbuffer );
|
|
||||||
::glBindBuffer( GL_ARRAY_BUFFER, m_uvbuffer );
|
|
||||||
::glBufferData( GL_ARRAY_BUFFER, m_uvs.size() * sizeof( glm::vec2 ), m_uvs.data(), GL_STATIC_DRAW );
|
|
||||||
|
|
||||||
::glGenBuffers( 1, &m_indexbuffer );
|
|
||||||
::glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_indexbuffer );
|
|
||||||
::glBufferData( GL_ELEMENT_ARRAY_BUFFER, m_indices.size() * sizeof( unsigned short ), m_indices.data(), GL_STATIC_DRAW );
|
|
||||||
// NOTE: vertex and index source data is superfluous past this point, but, eh
|
|
||||||
|
|
||||||
// cleanup
|
|
||||||
::glPopClientAttrib();
|
|
||||||
::glBindBuffer( GL_ARRAY_BUFFER, 0 );
|
|
||||||
::glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: include weather type check in the entry conditions
|
|
||||||
if( m_overcast == Global.Overcast ) { return; }
|
|
||||||
|
|
||||||
m_overcast = Global.Overcast;
|
|
||||||
|
|
||||||
std::string const densitysuffix { (
|
|
||||||
m_overcast < 1.35 ?
|
|
||||||
"_light" :
|
|
||||||
"_medium" ) };
|
|
||||||
if( Global.Weather == "rain:" ) {
|
|
||||||
m_texture = GfxRenderer->Fetch_Texture( "fx/rain" + densitysuffix );
|
|
||||||
}
|
|
||||||
else if( Global.Weather == "snow:" ) {
|
|
||||||
m_texture = GfxRenderer->Fetch_Texture( "fx/snow" + densitysuffix );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
opengl_precipitation::render( GLint const Textureunit ) {
|
|
||||||
|
|
||||||
if( m_texture == null_handle ) { return; }
|
|
||||||
|
|
||||||
GfxRenderer->Bind_Texture( m_texture );
|
|
||||||
|
|
||||||
// cache entry state
|
|
||||||
::glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT );
|
|
||||||
|
|
||||||
// positions
|
|
||||||
::glBindBuffer( GL_ARRAY_BUFFER, m_vertexbuffer );
|
|
||||||
::glVertexPointer( 3, GL_FLOAT, sizeof( glm::vec3 ), reinterpret_cast<void const*>( 0 ) );
|
|
||||||
::glEnableClientState( GL_VERTEX_ARRAY );
|
|
||||||
// uvs
|
|
||||||
::glBindBuffer( GL_ARRAY_BUFFER, m_uvbuffer );
|
|
||||||
::glClientActiveTexture( GL_TEXTURE0 + Textureunit );
|
|
||||||
::glTexCoordPointer( 2, GL_FLOAT, sizeof( glm::vec2 ), reinterpret_cast<void const*>( 0 ) );
|
|
||||||
::glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
|
||||||
// uv transformation matrix
|
|
||||||
::glMatrixMode( GL_TEXTURE );
|
|
||||||
::glLoadIdentity();
|
|
||||||
::glTranslatef( 0.f, simulation::Environment.precipitation().get_textureoffset(), 0.f );
|
|
||||||
// indices
|
|
||||||
::glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_indexbuffer );
|
|
||||||
::glDrawElements( GL_TRIANGLES, static_cast<GLsizei>( m_indices.size() ), GL_UNSIGNED_SHORT, reinterpret_cast<void const*>( 0 ) );
|
|
||||||
// cleanup
|
|
||||||
::glLoadIdentity();
|
|
||||||
::glMatrixMode( GL_MODELVIEW );
|
|
||||||
::glPopClientAttrib();
|
|
||||||
::glBindBuffer( GL_ARRAY_BUFFER, 0 );
|
|
||||||
::glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
This Source Code Form is subject to the
|
|
||||||
terms of the Mozilla Public License, v.
|
|
||||||
2.0. If a copy of the MPL was not
|
|
||||||
distributed with this file, You can
|
|
||||||
obtain one at
|
|
||||||
http://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "model/Texture.h"
|
|
||||||
|
|
||||||
class opengl_precipitation {
|
|
||||||
|
|
||||||
public:
|
|
||||||
// constructors
|
|
||||||
opengl_precipitation() = default;
|
|
||||||
// destructor
|
|
||||||
~opengl_precipitation();
|
|
||||||
// methods
|
|
||||||
void
|
|
||||||
update();
|
|
||||||
void
|
|
||||||
render( GLint const Textureunit );
|
|
||||||
|
|
||||||
private:
|
|
||||||
// methods
|
|
||||||
void create( int const Tesselation );
|
|
||||||
// members
|
|
||||||
std::vector<glm::vec3> m_vertices;
|
|
||||||
std::vector<glm::vec2> m_uvs;
|
|
||||||
std::vector<std::uint16_t> m_indices;
|
|
||||||
GLuint m_vertexbuffer { (GLuint)-1 };
|
|
||||||
GLuint m_uvbuffer { (GLuint)-1 };
|
|
||||||
GLuint m_indexbuffer { (GLuint)-1 };
|
|
||||||
texture_handle m_texture { null_handle };
|
|
||||||
float m_overcast { -1.f }; // cached overcast level, difference from current state triggers texture update
|
|
||||||
};
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,398 +0,0 @@
|
|||||||
/*
|
|
||||||
This Source Code Form is subject to the
|
|
||||||
terms of the Mozilla Public License, v.
|
|
||||||
2.0. If a copy of the MPL was not
|
|
||||||
distributed with this file, You can
|
|
||||||
obtain one at
|
|
||||||
http://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "rendering/renderer.h"
|
|
||||||
#include "rendering/opengllight.h"
|
|
||||||
#include "rendering/openglcamera.h"
|
|
||||||
#include "rendering/openglparticles.h"
|
|
||||||
#include "rendering/openglskydome.h"
|
|
||||||
#include "rendering/openglprecipitation.h"
|
|
||||||
#include "rendering/lightarray.h"
|
|
||||||
#include "scene/scene.h"
|
|
||||||
#include "simulation/simulationenvironment.h"
|
|
||||||
#include "world/MemCell.h"
|
|
||||||
|
|
||||||
#define EU07_USE_PICKING_FRAMEBUFFER
|
|
||||||
//#define EU07_USE_DEBUG_SHADOWMAP
|
|
||||||
//#define EU07_USE_DEBUG_CABSHADOWMAP
|
|
||||||
//#define EU07_USE_DEBUG_CAMERA
|
|
||||||
//#define EU07_USE_DEBUG_SOUNDEMITTERS
|
|
||||||
//#define EU07_DISABLECABREFLECTIONS
|
|
||||||
|
|
||||||
// bare-bones render controller, in lack of anything better yet
|
|
||||||
class opengl_renderer : public gfx_renderer {
|
|
||||||
|
|
||||||
public:
|
|
||||||
// types
|
|
||||||
// constructors
|
|
||||||
opengl_renderer() = default;
|
|
||||||
// destructor
|
|
||||||
~opengl_renderer() { }
|
|
||||||
// methods
|
|
||||||
bool
|
|
||||||
Init( GLFWwindow *Window ) override;
|
|
||||||
// main draw call. returns false on error
|
|
||||||
bool
|
|
||||||
Render() override;
|
|
||||||
void
|
|
||||||
SwapBuffers() override;
|
|
||||||
inline
|
|
||||||
float
|
|
||||||
Framerate() override { return m_framerate; }
|
|
||||||
|
|
||||||
bool AddViewport(const global_settings::extraviewport_config &conf) override { return false; }
|
|
||||||
bool Debug_Ui_State(std::optional<bool>) override { return false; }
|
|
||||||
void Shutdown() override {}
|
|
||||||
|
|
||||||
// geometry methods
|
|
||||||
// NOTE: hands-on geometry management is exposed as a temporary measure; ultimately all visualization data should be generated/handled automatically by the renderer itself
|
|
||||||
// creates a new geometry bank. returns: handle to the bank or NULL
|
|
||||||
gfx::geometrybank_handle
|
|
||||||
Create_Bank() override;
|
|
||||||
// creates a new indexed geometry chunk of specified type from supplied data, in specified bank. returns: handle to the chunk or NULL
|
|
||||||
gfx::geometry_handle Insert(gfx::index_array &Indices, gfx::vertex_array &Vertices, gfx::userdata_array &Userdata, gfx::geometrybank_handle const &Geometry, int const Type) override;
|
|
||||||
// creates a new geometry chunk of specified type from supplied data, in specified bank. returns: handle to the chunk or NULL
|
|
||||||
gfx::geometry_handle Insert(gfx::vertex_array &Vertices, gfx::userdata_array &Userdata, gfx::geometrybank_handle const &Geometry, int const Type) override;
|
|
||||||
// replaces data of specified chunk with the supplied vertex data, starting from specified offset
|
|
||||||
bool Replace(gfx::vertex_array &Vertices, gfx::userdata_array &Userdata, gfx::geometry_handle const &Geometry, int const Type, const std::size_t Offset = 0) override;
|
|
||||||
// adds supplied vertex data at the end of specified chunk
|
|
||||||
bool Append(gfx::vertex_array &Vertices, gfx::userdata_array &Userdata, gfx::geometry_handle const &Geometry, int const Type) override;
|
|
||||||
// provides direct access to index data of specfied chunk
|
|
||||||
gfx::index_array const &
|
|
||||||
Indices( gfx::geometry_handle const &Geometry ) const override;
|
|
||||||
// provides direct access to vertex data of specfied chunk
|
|
||||||
gfx::vertex_array const &
|
|
||||||
Vertices( gfx::geometry_handle const &Geometry ) const override;
|
|
||||||
// provides direct access to vertex data of specfied chunk
|
|
||||||
gfx::userdata_array const &
|
|
||||||
UserData( gfx::geometry_handle const &Geometry ) const override;
|
|
||||||
// material methods
|
|
||||||
material_handle
|
|
||||||
Fetch_Material( std::string const &Filename, bool const Loadnow = true ) override;
|
|
||||||
void
|
|
||||||
Bind_Material( material_handle const Material, TSubModel const *sm = nullptr, lighting_data const *lighting = nullptr ) override;
|
|
||||||
IMaterial const *
|
|
||||||
Material( material_handle const Material ) const override;
|
|
||||||
// shader methods
|
|
||||||
auto Fetch_Shader( std::string const &name ) -> std::shared_ptr<gl::program> override;
|
|
||||||
// texture methods
|
|
||||||
texture_handle
|
|
||||||
Fetch_Texture( std::string const &Filename, bool const Loadnow = true, GLint format_hint = GL_SRGB_ALPHA ) override;
|
|
||||||
void
|
|
||||||
Bind_Texture( texture_handle const Texture ) override;
|
|
||||||
void
|
|
||||||
Bind_Texture( std::size_t const Unit, texture_handle const Texture ) override;
|
|
||||||
ITexture &
|
|
||||||
Texture( texture_handle const Texture ) override;
|
|
||||||
ITexture const &
|
|
||||||
Texture( texture_handle const Texture ) const override;
|
|
||||||
// utility methods
|
|
||||||
void
|
|
||||||
Pick_Control_Callback( std::function<void( TSubModel const *, const glm::vec2 )> Callback ) override;
|
|
||||||
void
|
|
||||||
Pick_Node_Callback( std::function<void( scene::basic_node * )> Callback ) override;
|
|
||||||
TSubModel const *
|
|
||||||
Pick_Control() const override { return m_pickcontrolitem; }
|
|
||||||
scene::basic_node const *
|
|
||||||
Pick_Node() const override { return m_picksceneryitem; }
|
|
||||||
glm::dvec3
|
|
||||||
Mouse_Position() const override { return m_worldmousecoordinates; }
|
|
||||||
glm::mat4
|
|
||||||
Camera_View_Matrix() const override { return glm::mat4( glm::mat3( m_colorpass.camera.modelview() ) ); }
|
|
||||||
glm::mat4
|
|
||||||
Camera_Projection_Matrix() const override { return m_colorpass.camera.projection(); }
|
|
||||||
glm::dvec3
|
|
||||||
Camera_Position() const override { return m_colorpass.camera.position(); }
|
|
||||||
// maintenance methods
|
|
||||||
void
|
|
||||||
Update( double const Deltatime ) override;
|
|
||||||
void
|
|
||||||
Update_Pick_Control() override;
|
|
||||||
void
|
|
||||||
Update_Pick_Node() override;
|
|
||||||
glm::dvec3
|
|
||||||
Update_Mouse_Position() override;
|
|
||||||
// debug methods
|
|
||||||
std::string const &
|
|
||||||
info_times() const override;
|
|
||||||
std::string const &
|
|
||||||
info_stats() const override;
|
|
||||||
void MakeScreenshot() override;
|
|
||||||
|
|
||||||
opengl_material const & Material( TSubModel const * Submodel ) const;
|
|
||||||
|
|
||||||
// members
|
|
||||||
GLenum static const sunlight { GL_LIGHT0 };
|
|
||||||
|
|
||||||
static std::unique_ptr<gfx_renderer> create_func();
|
|
||||||
|
|
||||||
private:
|
|
||||||
// types
|
|
||||||
enum class rendermode {
|
|
||||||
none,
|
|
||||||
color,
|
|
||||||
shadows,
|
|
||||||
cabshadows,
|
|
||||||
reflections,
|
|
||||||
pickcontrols,
|
|
||||||
pickscenery
|
|
||||||
};
|
|
||||||
|
|
||||||
enum textureunit {
|
|
||||||
helper = 0,
|
|
||||||
shadows,
|
|
||||||
normals,
|
|
||||||
diffuse
|
|
||||||
};
|
|
||||||
|
|
||||||
struct debug_stats {
|
|
||||||
int dynamics { 0 };
|
|
||||||
int models { 0 };
|
|
||||||
int submodels { 0 };
|
|
||||||
int paths { 0 };
|
|
||||||
int traction { 0 };
|
|
||||||
int shapes { 0 };
|
|
||||||
int lines { 0 };
|
|
||||||
int particles { 0 };
|
|
||||||
int drawcalls { 0 };
|
|
||||||
};
|
|
||||||
|
|
||||||
using section_sequence = std::vector<scene::basic_section *>;
|
|
||||||
using distancecell_pair = std::pair<double, scene::basic_cell *>;
|
|
||||||
using cell_sequence = std::vector<distancecell_pair>;
|
|
||||||
|
|
||||||
struct renderpass_config {
|
|
||||||
|
|
||||||
opengl_camera camera;
|
|
||||||
rendermode draw_mode { rendermode::none };
|
|
||||||
float draw_range { 0.0f };
|
|
||||||
debug_stats draw_stats;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct units_state {
|
|
||||||
|
|
||||||
bool diffuse { false };
|
|
||||||
bool shadows { false };
|
|
||||||
bool reflections { false };
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::vector<opengl_light> opengllight_array;
|
|
||||||
|
|
||||||
// methods
|
|
||||||
void
|
|
||||||
Disable_Lights();
|
|
||||||
void
|
|
||||||
setup_pass( renderpass_config &Config, rendermode const Mode, float const Znear = 0.f, float const Zfar = 1.f, bool const Ignoredebug = false );
|
|
||||||
void
|
|
||||||
setup_matrices();
|
|
||||||
void
|
|
||||||
setup_drawing( bool const Alpha = false );
|
|
||||||
void
|
|
||||||
setup_units( bool const Diffuse, bool const Shadows, bool const Reflections );
|
|
||||||
void
|
|
||||||
setup_shadow_map( GLuint const Texture, glm::mat4 const &Transformation );
|
|
||||||
void
|
|
||||||
setup_shadow_color( glm::vec4 const &Shadowcolor );
|
|
||||||
void
|
|
||||||
setup_environment_light( TEnvironmentType const Environment = e_flat );
|
|
||||||
void
|
|
||||||
switch_units( bool const Diffuse, bool const Shadows, bool const Reflections );
|
|
||||||
// helper, texture manager method; activates specified texture unit
|
|
||||||
void
|
|
||||||
select_unit( GLint const Textureunit );
|
|
||||||
// runs jobs needed to generate graphics for specified render pass
|
|
||||||
void
|
|
||||||
Render_pass( rendermode const Mode );
|
|
||||||
// creates dynamic environment cubemap
|
|
||||||
bool
|
|
||||||
Render_reflections();
|
|
||||||
bool
|
|
||||||
Render( world_environment *Environment );
|
|
||||||
void
|
|
||||||
Render( scene::basic_region *Region );
|
|
||||||
void
|
|
||||||
Render( section_sequence::iterator First, section_sequence::iterator Last );
|
|
||||||
void
|
|
||||||
Render( cell_sequence::iterator First, cell_sequence::iterator Last );
|
|
||||||
void
|
|
||||||
Render( scene::shape_node const &Shape, bool const Ignorerange );
|
|
||||||
void
|
|
||||||
Render( TAnimModel *Instance );
|
|
||||||
bool
|
|
||||||
Render( TDynamicObject *Dynamic );
|
|
||||||
bool
|
|
||||||
Render( TModel3d *Model, material_data const *Material, float const Squaredistance, glm::dvec3 const &Position, glm::vec3 const &Angle );
|
|
||||||
bool
|
|
||||||
Render( TModel3d *Model, material_data const *Material, float const Squaredistance );
|
|
||||||
void
|
|
||||||
Render( TSubModel *Submodel );
|
|
||||||
void
|
|
||||||
Render( TTrack *Track );
|
|
||||||
void
|
|
||||||
Render( scene::basic_cell::path_sequence::const_iterator First, scene::basic_cell::path_sequence::const_iterator Last );
|
|
||||||
bool
|
|
||||||
Render_cab( TDynamicObject const *Dynamic, float const Lightlevel, bool const Alpha = false );
|
|
||||||
bool
|
|
||||||
Render_interior( bool const Alpha = false );
|
|
||||||
bool
|
|
||||||
Render_lowpoly( TDynamicObject *Dynamic, float const Squaredistance, bool const Setup, bool const Alpha = false );
|
|
||||||
bool
|
|
||||||
Render_coupler_adapter( TDynamicObject *Dynamic, float const Squaredistance, int const End, bool const Alpha = false );
|
|
||||||
void
|
|
||||||
Render( TMemCell *Memcell );
|
|
||||||
void
|
|
||||||
Render_particles();
|
|
||||||
void
|
|
||||||
Render_precipitation();
|
|
||||||
void
|
|
||||||
Render_Alpha( scene::basic_region *Region );
|
|
||||||
void
|
|
||||||
Render_Alpha( cell_sequence::reverse_iterator First, cell_sequence::reverse_iterator Last );
|
|
||||||
void
|
|
||||||
Render_Alpha( TAnimModel *Instance );
|
|
||||||
void
|
|
||||||
Render_Alpha( TTraction *Traction );
|
|
||||||
void
|
|
||||||
Render_Alpha( scene::lines_node const &Lines );
|
|
||||||
bool
|
|
||||||
Render_Alpha( TDynamicObject *Dynamic );
|
|
||||||
bool
|
|
||||||
Render_Alpha( TModel3d *Model, material_data const *Material, float const Squaredistance, glm::dvec3 const &Position, glm::vec3 const &Angle );
|
|
||||||
bool
|
|
||||||
Render_Alpha( TModel3d *Model, material_data const *Material, float const Squaredistance );
|
|
||||||
void
|
|
||||||
Render_Alpha( TSubModel *Submodel );
|
|
||||||
// characters of a text display
|
|
||||||
void
|
|
||||||
Render_Alpha_text( TSubModel *Submodel );
|
|
||||||
void
|
|
||||||
Update_Lights( light_array &Lights );
|
|
||||||
bool
|
|
||||||
Init_caps();
|
|
||||||
glm::vec3
|
|
||||||
pick_color( std::size_t const Index );
|
|
||||||
std::size_t
|
|
||||||
pick_index( glm::ivec3 const &Color );
|
|
||||||
|
|
||||||
// members
|
|
||||||
GLFWwindow *m_window { nullptr };
|
|
||||||
gfx::geometrybank_manager m_geometry;
|
|
||||||
material_manager m_materials;
|
|
||||||
texture_manager m_textures;
|
|
||||||
opengl_light m_sunlight;
|
|
||||||
opengllight_array m_lights;
|
|
||||||
opengl_skydome m_skydomerenderer;
|
|
||||||
opengl_precipitation m_precipitationrenderer;
|
|
||||||
opengl_particles m_particlerenderer; // particle visualization subsystem
|
|
||||||
/*
|
|
||||||
float m_sunandviewangle; // cached dot product of sunlight and camera vectors
|
|
||||||
*/
|
|
||||||
gfx::geometry_handle m_billboardgeometry { 0, 0 };
|
|
||||||
texture_handle m_glaretexture { -1 };
|
|
||||||
texture_handle m_suntexture { -1 };
|
|
||||||
texture_handle m_moontexture { -1 };
|
|
||||||
texture_handle m_reflectiontexture { -1 };
|
|
||||||
texture_handle m_smoketexture { -1 };
|
|
||||||
material_handle m_invalid_material;
|
|
||||||
// TODO: refactor framebuffer stuff into an object
|
|
||||||
bool m_framebuffersupport { false };
|
|
||||||
#ifdef EU07_USE_PICKING_FRAMEBUFFER
|
|
||||||
GLuint m_pickframebuffer { 0 };
|
|
||||||
GLuint m_picktexture { 0 };
|
|
||||||
GLuint m_pickdepthbuffer { 0 };
|
|
||||||
#endif
|
|
||||||
// main shadowmap resources
|
|
||||||
int m_shadowbuffersize { 2048 };
|
|
||||||
GLuint m_shadowframebuffer { 0 };
|
|
||||||
GLuint m_shadowtexture { 0 };
|
|
||||||
#ifdef EU07_USE_DEBUG_SHADOWMAP
|
|
||||||
GLuint m_shadowdebugtexture{ 0 };
|
|
||||||
#endif
|
|
||||||
#ifdef EU07_USE_DEBUG_CABSHADOWMAP
|
|
||||||
GLuint m_cabshadowdebugtexture{ 0 };
|
|
||||||
#endif
|
|
||||||
glm::mat4 m_shadowtexturematrix; // conversion from camera-centric world space to light-centric clip space
|
|
||||||
// cab shadowmap resources
|
|
||||||
GLuint m_cabshadowframebuffer { 0 };
|
|
||||||
GLuint m_cabshadowtexture { 0 };
|
|
||||||
glm::mat4 m_cabshadowtexturematrix; // conversion from cab-centric world space to light-centric clip space
|
|
||||||
// environment map resources
|
|
||||||
GLuint m_environmentframebuffer { 0 };
|
|
||||||
GLuint m_environmentcubetexture { 0 };
|
|
||||||
GLuint m_environmentdepthbuffer { 0 };
|
|
||||||
bool m_environmentcubetexturesupport { false }; // indicates whether we can use the dynamic environment cube map
|
|
||||||
int m_environmentcubetextureface { 0 }; // helper, currently processed cube map face
|
|
||||||
double m_environmentupdatetime { 0.0 }; // time of the most recent environment map update
|
|
||||||
glm::dvec3 m_environmentupdatelocation; // coordinates of most recent environment map update
|
|
||||||
|
|
||||||
int m_helpertextureunit { 0 };
|
|
||||||
int m_shadowtextureunit { 1 };
|
|
||||||
int m_normaltextureunit { 2 };
|
|
||||||
int m_diffusetextureunit{ 3 };
|
|
||||||
units_state m_unitstate;
|
|
||||||
|
|
||||||
unsigned int m_framestamp; // id of currently rendered gfx frame
|
|
||||||
float m_framerate;
|
|
||||||
double m_updateaccumulator { 0.0 };
|
|
||||||
// double m_pickupdateaccumulator { 0.0 };
|
|
||||||
std::string m_debugtimestext;
|
|
||||||
std::string m_pickdebuginfo;
|
|
||||||
std::string m_debugstatstext;
|
|
||||||
struct simulation_state {
|
|
||||||
std::string weather;
|
|
||||||
std::string season;
|
|
||||||
} m_simulationstate;
|
|
||||||
|
|
||||||
glm::vec4 m_baseambient { 0.0f, 0.0f, 0.0f, 1.0f };
|
|
||||||
glm::vec4 m_shadowcolor { colors::shadow };
|
|
||||||
float m_fogrange { 2000.f };
|
|
||||||
// TEnvironmentType m_environment { e_flat };
|
|
||||||
float m_specularopaquescalefactor { 1.f };
|
|
||||||
float m_speculartranslucentscalefactor { 1.f };
|
|
||||||
bool m_renderspecular{ false }; // controls whether to include specular component in the calculations
|
|
||||||
|
|
||||||
renderpass_config m_renderpass; // parameters for current render pass
|
|
||||||
section_sequence m_sectionqueue; // list of sections in current render pass
|
|
||||||
cell_sequence m_cellqueue;
|
|
||||||
renderpass_config m_colorpass; // parametrs of most recent color pass
|
|
||||||
renderpass_config m_shadowpass; // parametrs of most recent shadowmap pass
|
|
||||||
renderpass_config m_cabshadowpass; // parameters of most recent cab shadowmap pass
|
|
||||||
std::vector<TSubModel *> m_pickcontrolsitems;
|
|
||||||
TSubModel *m_pickcontrolitem { nullptr };
|
|
||||||
std::vector<scene::basic_node *> m_picksceneryitems;
|
|
||||||
scene::basic_node *m_picksceneryitem { nullptr };
|
|
||||||
glm::vec3 m_worldmousecoordinates { 0.f };
|
|
||||||
std::vector<std::function<void( TSubModel const *, const glm::vec2 )>> m_control_pick_requests;
|
|
||||||
std::vector<std::function<void( scene::basic_node * )>> m_node_pick_requests;
|
|
||||||
#ifdef EU07_USE_DEBUG_CAMERA
|
|
||||||
renderpass_config m_worldcamera; // debug item
|
|
||||||
#endif
|
|
||||||
bool m_isATI;
|
|
||||||
|
|
||||||
static bool renderer_register;
|
|
||||||
|
|
||||||
class opengl_imgui_renderer : public imgui_renderer
|
|
||||||
{
|
|
||||||
virtual bool Init() override;
|
|
||||||
virtual void Shutdown() override;
|
|
||||||
virtual void BeginFrame() override;
|
|
||||||
virtual void Render() override;
|
|
||||||
virtual std::uint64_t Create_Image(std::uint8_t const *Rgba, int const Width, int const Height) override;
|
|
||||||
virtual void Release_Image(std::uint64_t const Image) override;
|
|
||||||
} m_imgui_renderer;
|
|
||||||
|
|
||||||
virtual imgui_renderer *GetImguiRenderer() override
|
|
||||||
{
|
|
||||||
return &m_imgui_renderer;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
/*
|
|
||||||
This Source Code Form is subject to the
|
|
||||||
terms of the Mozilla Public License, v.
|
|
||||||
2.0. If a copy of the MPL was not
|
|
||||||
distributed with this file, You can
|
|
||||||
obtain one at
|
|
||||||
http://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "stdafx.h"
|
|
||||||
#include "rendering/openglskydome.h"
|
|
||||||
|
|
||||||
#include "simulation/simulationenvironment.h"
|
|
||||||
|
|
||||||
opengl_skydome::~opengl_skydome() {
|
|
||||||
|
|
||||||
if( m_vertexbuffer != -1 ) { ::glDeleteBuffers( 1, &m_vertexbuffer ); }
|
|
||||||
if( m_indexbuffer != -1 ) { ::glDeleteBuffers( 1, &m_indexbuffer ); }
|
|
||||||
if( m_coloursbuffer != -1 ) { ::glDeleteBuffers( 1, &m_coloursbuffer ); }
|
|
||||||
}
|
|
||||||
|
|
||||||
void opengl_skydome::update() {
|
|
||||||
|
|
||||||
auto &skydome { simulation::Environment.skydome() };
|
|
||||||
// cache entry state
|
|
||||||
::glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT );
|
|
||||||
// setup gpu data buffers:
|
|
||||||
// ...static data...
|
|
||||||
if( m_indexbuffer == (GLuint)-1 ) {
|
|
||||||
::glGenBuffers( 1, &m_indexbuffer );
|
|
||||||
if( ( m_indexbuffer > 0 ) && ( m_indexbuffer != (GLuint)-1 ) ) {
|
|
||||||
::glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_indexbuffer );
|
|
||||||
auto const &indices { skydome.indices() };
|
|
||||||
::glBufferData( GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof( unsigned short ), indices.data(), GL_STATIC_DRAW );
|
|
||||||
m_indexcount = indices.size();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( m_vertexbuffer == (GLuint)-1 ) {
|
|
||||||
::glGenBuffers( 1, &m_vertexbuffer );
|
|
||||||
if( ( m_vertexbuffer > 0 ) && ( m_vertexbuffer != (GLuint)-1 ) ) {
|
|
||||||
::glBindBuffer( GL_ARRAY_BUFFER, m_vertexbuffer );
|
|
||||||
auto const &vertices { skydome.vertices() };
|
|
||||||
::glBufferData( GL_ARRAY_BUFFER, vertices.size() * sizeof( glm::vec3 ), vertices.data(), GL_STATIC_DRAW );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ...and dynamic data
|
|
||||||
if( m_coloursbuffer == (GLuint)-1 ) {
|
|
||||||
::glGenBuffers( 1, &m_coloursbuffer );
|
|
||||||
if( ( m_coloursbuffer > 0 ) && ( m_coloursbuffer != (GLuint)-1 ) ) {
|
|
||||||
::glBindBuffer( GL_ARRAY_BUFFER, m_coloursbuffer );
|
|
||||||
auto const &colors { skydome.colors() };
|
|
||||||
::glBufferData( GL_ARRAY_BUFFER, colors.size() * sizeof( glm::vec3 ), colors.data(), GL_DYNAMIC_DRAW );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ship the current dynamic data to the gpu
|
|
||||||
// TODO: ship the data if it changed since the last update
|
|
||||||
if (true == skydome.is_dirty() && ( m_coloursbuffer > 0 ) && ( m_coloursbuffer != (GLuint)-1 )) {
|
|
||||||
::glBindBuffer( GL_ARRAY_BUFFER, m_coloursbuffer );
|
|
||||||
auto &colors{ skydome.colors() };
|
|
||||||
/*
|
|
||||||
float twilightfactor = std::clamp( -simulation::Environment.sun().getAngle(), 0.0f, 18.0f ) / 18.0f;
|
|
||||||
auto gamma = std::lerp( glm::vec3( 0.45f ), glm::vec3( 1.0f ), twilightfactor );
|
|
||||||
for( auto & color : colors ) {
|
|
||||||
color = glm::pow( color, gamma );
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
::glBufferSubData( GL_ARRAY_BUFFER, 0, colors.size() * sizeof( glm::vec3 ), colors.data() );
|
|
||||||
skydome.is_dirty() = false;
|
|
||||||
}
|
|
||||||
// cleanup
|
|
||||||
::glPopClientAttrib();
|
|
||||||
::glBindBuffer( GL_ARRAY_BUFFER, 0 );
|
|
||||||
::glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
// render skydome to screen
|
|
||||||
void opengl_skydome::render() {
|
|
||||||
|
|
||||||
if( ( m_indexbuffer == (GLuint)-1 )
|
|
||||||
|| ( m_vertexbuffer == (GLuint)-1 )
|
|
||||||
|| ( m_coloursbuffer == (GLuint)-1 ) ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// setup:
|
|
||||||
::glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT );
|
|
||||||
// ...positions...
|
|
||||||
::glBindBuffer( GL_ARRAY_BUFFER, m_vertexbuffer );
|
|
||||||
::glVertexPointer( 3, GL_FLOAT, sizeof( glm::vec3 ), reinterpret_cast<void const*>( 0 ) );
|
|
||||||
::glEnableClientState( GL_VERTEX_ARRAY );
|
|
||||||
// ...colours...
|
|
||||||
::glBindBuffer( GL_ARRAY_BUFFER, m_coloursbuffer );
|
|
||||||
::glColorPointer( 3, GL_FLOAT, sizeof( glm::vec3 ), reinterpret_cast<void const*>( 0 ) );
|
|
||||||
::glEnableClientState( GL_COLOR_ARRAY );
|
|
||||||
// ...indices
|
|
||||||
::glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_indexbuffer );
|
|
||||||
// draw
|
|
||||||
::glDisableClientState( GL_TEXTURE_COORD_ARRAY );
|
|
||||||
::glDrawElements( GL_TRIANGLES, static_cast<GLsizei>( m_indexcount ), GL_UNSIGNED_SHORT, reinterpret_cast<void const*>( 0 ) );
|
|
||||||
// cleanup
|
|
||||||
::glPopClientAttrib();
|
|
||||||
::glBindBuffer( GL_ARRAY_BUFFER, 0 );
|
|
||||||
::glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
This Source Code Form is subject to the
|
|
||||||
terms of the Mozilla Public License, v.
|
|
||||||
2.0. If a copy of the MPL was not
|
|
||||||
distributed with this file, You can
|
|
||||||
obtain one at
|
|
||||||
http://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
class opengl_skydome {
|
|
||||||
|
|
||||||
public:
|
|
||||||
// constructors
|
|
||||||
opengl_skydome() = default;
|
|
||||||
// destructor
|
|
||||||
~opengl_skydome();
|
|
||||||
// methods
|
|
||||||
// updates data stores on the opengl end. NOTE: unbinds buffers
|
|
||||||
void update();
|
|
||||||
// draws the skydome
|
|
||||||
void render();
|
|
||||||
|
|
||||||
private:
|
|
||||||
// members
|
|
||||||
GLuint m_indexbuffer{ (GLuint)-1 }; // id of the buffer holding index data on the opengl end
|
|
||||||
std::size_t m_indexcount { 0 };
|
|
||||||
GLuint m_vertexbuffer{ (GLuint)-1 }; // id of the buffer holding vertex data on the opengl end
|
|
||||||
GLuint m_coloursbuffer{ (GLuint)-1 }; // id of the buffer holding colour data on the opengl end
|
|
||||||
};
|
|
||||||
@@ -164,8 +164,6 @@ private:
|
|||||||
// holds all particle emitters defined in the scene and updates their state
|
// holds all particle emitters defined in the scene and updates their state
|
||||||
class particle_manager {
|
class particle_manager {
|
||||||
|
|
||||||
friend opengl_renderer;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// types
|
// types
|
||||||
using source_sequence = std::vector<smoke_source>;
|
using source_sequence = std::vector<smoke_source>;
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "input/command.h"
|
#include "input/command.h"
|
||||||
#include "utilities/utilities.h"
|
#include "utilities/utilities.h"
|
||||||
|
|
||||||
class opengl_renderer;
|
|
||||||
class opengl33_renderer;
|
class opengl33_renderer;
|
||||||
|
|
||||||
namespace scene {
|
namespace scene {
|
||||||
@@ -96,7 +95,6 @@ struct terrain_block {
|
|||||||
// TBD, TODO: replace with quadtree scheme?
|
// TBD, TODO: replace with quadtree scheme?
|
||||||
class basic_cell {
|
class basic_cell {
|
||||||
|
|
||||||
friend opengl_renderer;
|
|
||||||
friend opengl33_renderer;
|
friend opengl33_renderer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -294,7 +292,6 @@ public:
|
|||||||
// basic scene partitioning structure, holds terrain geometry and collection of cells
|
// basic scene partitioning structure, holds terrain geometry and collection of cells
|
||||||
class basic_section {
|
class basic_section {
|
||||||
|
|
||||||
friend opengl_renderer;
|
|
||||||
friend opengl33_renderer;
|
friend opengl33_renderer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -418,7 +415,6 @@ public:
|
|||||||
// top-level of scene spatial structure, holds collection of sections
|
// top-level of scene spatial structure, holds collection of sections
|
||||||
class basic_region {
|
class basic_region {
|
||||||
|
|
||||||
friend opengl_renderer;
|
|
||||||
friend opengl33_renderer;
|
friend opengl33_renderer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -17,13 +17,11 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "rendering/precipitation.h"
|
#include "rendering/precipitation.h"
|
||||||
#include "audio/sound.h"
|
#include "audio/sound.h"
|
||||||
|
|
||||||
class opengl_renderer;
|
|
||||||
class opengl33_renderer;
|
class opengl33_renderer;
|
||||||
|
|
||||||
// wrapper for environment elements -- sky, sun, stars, clouds etc
|
// wrapper for environment elements -- sky, sun, stars, clouds etc
|
||||||
class world_environment {
|
class world_environment {
|
||||||
|
|
||||||
friend opengl_renderer;
|
|
||||||
friend opengl33_renderer;
|
friend opengl33_renderer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
// Ra: zestaw klas do robienia wskaźników, aby uporządkować nagłówki
|
// Ra: zestaw klas do robienia wskaźników, aby uporządkować nagłówki
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
class opengl_renderer;
|
|
||||||
class opengl33_renderer;
|
class opengl33_renderer;
|
||||||
class TTrack; // odcinek trajektorii
|
class TTrack; // odcinek trajektorii
|
||||||
class basic_event;
|
class basic_event;
|
||||||
|
|||||||
@@ -283,7 +283,10 @@ bool global_settings::ConfigParseGraphics(cParser& Parser, const std::string& to
|
|||||||
|
|
||||||
if (token == "usevbo")
|
if (token == "usevbo")
|
||||||
{
|
{
|
||||||
ParseOne(Parser, bUseVBO);
|
// only the removed legacy renderer had a non-VBO path; read and ignore so old eu07.ini files still load
|
||||||
|
bool usevbo{true};
|
||||||
|
ParseOne(Parser, usevbo);
|
||||||
|
WriteLog("eu07.ini: \"usevbo\" is no longer supported and was ignored");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,8 +326,12 @@ bool global_settings::ConfigParseGraphics(cParser& Parser, const std::string& to
|
|||||||
GfxRenderer = "experimental";
|
GfxRenderer = "experimental";
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicRenderer = GfxRenderer == "simple";
|
if (GfxRenderer != "default" && GfxRenderer != "experimental")
|
||||||
LegacyRenderer = !NvRenderer && GfxRenderer != "default";
|
{
|
||||||
|
// the legacy OpenGL 2.1 renderer ("legacy", "simple" and other values) was removed
|
||||||
|
WriteLog("eu07.ini: gfxrenderer \"" + GfxRenderer + "\" is no longer supported, using \"default\"");
|
||||||
|
GfxRenderer = "default";
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1574,7 +1581,6 @@ global_settings::export_as_text( std::ostream &Output ) const {
|
|||||||
export_as_text( Output, "defaultext", szDefaultExt );
|
export_as_text( Output, "defaultext", szDefaultExt );
|
||||||
export_as_text( Output, "newaircouplers", bnewAirCouplers );
|
export_as_text( Output, "newaircouplers", bnewAirCouplers );
|
||||||
export_as_text( Output, "anisotropicfiltering", AnisotropicFiltering );
|
export_as_text( Output, "anisotropicfiltering", AnisotropicFiltering );
|
||||||
export_as_text( Output, "usevbo", bUseVBO );
|
|
||||||
export_as_text( Output, "feedbackmode", iFeedbackMode );
|
export_as_text( Output, "feedbackmode", iFeedbackMode );
|
||||||
export_as_text( Output, "feedbackport", iFeedbackPort );
|
export_as_text( Output, "feedbackport", iFeedbackPort );
|
||||||
export_as_text( Output, "multiplayer", iMultiplayer );
|
export_as_text( Output, "multiplayer", iMultiplayer );
|
||||||
|
|||||||
@@ -153,9 +153,7 @@ struct global_settings {
|
|||||||
int DynamicLightCount{ 7 };
|
int DynamicLightCount{ 7 };
|
||||||
bool ScaleSpecularValues{ true };
|
bool ScaleSpecularValues{ true };
|
||||||
std::string GfxRenderer{ "default" };
|
std::string GfxRenderer{ "default" };
|
||||||
bool LegacyRenderer{ false };
|
|
||||||
bool NvRenderer{ false };
|
bool NvRenderer{ false };
|
||||||
bool BasicRenderer{ false };
|
|
||||||
bool RenderShadows{ true };
|
bool RenderShadows{ true };
|
||||||
bool applicationQuitOrder{false};
|
bool applicationQuitOrder{false};
|
||||||
int RenderCabShadowsRange{ 0 };
|
int RenderCabShadowsRange{ 0 };
|
||||||
@@ -169,7 +167,6 @@ struct global_settings {
|
|||||||
float range_instances{ 750.f };
|
float range_instances{ 750.f };
|
||||||
float range_vehicles{ 250.f };
|
float range_vehicles{ 250.f };
|
||||||
} reflectiontune;
|
} reflectiontune;
|
||||||
bool bUseVBO{ true }; // czy jest VBO w karcie graficznej (czy użyć)
|
|
||||||
float AnisotropicFiltering{ 8.f }; // requested level of anisotropic filtering. TODO: move it to renderer object
|
float AnisotropicFiltering{ 8.f }; // requested level of anisotropic filtering. TODO: move it to renderer object
|
||||||
float FieldOfView{ 45.f }; // vertical field of view for the camera. TODO: move it to the renderer
|
float FieldOfView{ 45.f }; // vertical field of view for the camera. TODO: move it to the renderer
|
||||||
bool EditorOrtho{ false };
|
bool EditorOrtho{ false };
|
||||||
|
|||||||
@@ -188,7 +188,6 @@ struct material_data {
|
|||||||
|
|
||||||
class TDynamicObject { // klasa pojazdu
|
class TDynamicObject { // klasa pojazdu
|
||||||
|
|
||||||
friend opengl_renderer;
|
|
||||||
friend opengl33_renderer;
|
friend opengl33_renderer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -151,7 +151,6 @@ private:
|
|||||||
// trajektoria ruchu - opakowanie
|
// trajektoria ruchu - opakowanie
|
||||||
class TTrack : public scene::basic_node
|
class TTrack : public scene::basic_node
|
||||||
{
|
{
|
||||||
friend opengl_renderer;
|
|
||||||
friend opengl33_renderer;
|
friend opengl33_renderer;
|
||||||
// NOTE: temporary arrangement
|
// NOTE: temporary arrangement
|
||||||
friend itemproperties_panel;
|
friend itemproperties_panel;
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ class TTractionPowerSource;
|
|||||||
|
|
||||||
class TTraction : public scene::basic_node
|
class TTraction : public scene::basic_node
|
||||||
{
|
{
|
||||||
friend opengl_renderer;
|
|
||||||
friend opengl33_renderer;
|
friend opengl33_renderer;
|
||||||
|
|
||||||
public: // na razie
|
public: // na razie
|
||||||
|
|||||||
Reference in New Issue
Block a user