From 6fb0af27566d88c05b33eb54623a77376b3123c1 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 11 May 2022 17:49:05 +0200 Subject: [PATCH] Make texture batching optional (for OpenGL 3.3 compat) --- README.md | 4 +++- assets/shaders/3d/terrain/fragment.glsl | 15 +++++++++++++-- build/debug.sh | 2 +- src/CMakeLists.txt | 2 +- src/client/client_config.c | 6 ++++++ src/client/client_config.h | 1 + src/client/client_entity.c | 2 +- src/client/client_inventory.c | 2 +- src/client/debug_menu.c | 2 +- src/client/font.c | 2 +- src/client/game.c | 2 +- src/client/gl_debug.h | 12 ------------ src/client/gui.c | 2 +- src/client/interact.c | 2 +- src/client/light.c | 2 +- src/client/mesh.c | 2 +- src/client/model.c | 4 ++-- src/client/{gl_debug.c => opengl.c} | 22 ++++++++++++++++------ src/client/opengl.h | 16 ++++++++++++++++ src/client/screenshot.c | 2 +- src/client/shader.c | 8 +++++--- src/client/sky.c | 2 +- src/client/terrain_gfx.c | 21 ++++++++++++--------- src/client/texture.c | 2 +- src/client/window.c | 2 +- 25 files changed, 89 insertions(+), 50 deletions(-) delete mode 100644 src/client/gl_debug.h rename src/client/{gl_debug.c => opengl.c} (74%) create mode 100644 src/client/opengl.h diff --git a/README.md b/README.md index 5a14615..4f35060 100644 --- a/README.md +++ b/README.md @@ -48,9 +48,11 @@ singleplayer.bat ## System Requirements Dragonblocks Alpha targets PCs only. Non x86-64 platforms may work, however there is no guarantee whatsoever. You need a POSIX system conforming to the ISO C and POSIX 2008 standards. However, so far only GNU/Linux systems, in particular Ubuntu and Debian, have been tested. -The minimum OpenGL version is 4.2.0. Dragonblocks has been tested on Intel Integrated and NVIDIA GPUs, however other graphics cards should work as well. +The minimum OpenGL version is 3.3 core. Dragonblocks has been tested on Intel Integrated and NVIDIA GPUs, however other graphics cards should work as well. A PC with at least 4 CPU cores is recommended, but not necessarily required. +Note: The game can work with OpenGL 3.3, but to use texture batching, you need at least OpenGL 4.0. If your machine doesn't that version, disable texture batching by adding the line "texture_batching off" to your client.conf file. + ## Current Features - Multiplayer, Animated player model, Nametags - Mountains, snow, temperature and humidity, dynamic grass color, oceans and beaches, vulcanos, boulders diff --git a/assets/shaders/3d/terrain/fragment.glsl b/assets/shaders/3d/terrain/fragment.glsl index 37bc567..340eb48 100755 --- a/assets/shaders/3d/terrain/fragment.glsl +++ b/assets/shaders/3d/terrain/fragment.glsl @@ -7,11 +7,22 @@ out vec4 outColor; uniform vec3 fogColor; uniform vec3 cameraPos; -uniform sampler2D textures[MAX_TEXTURE_UNITS]; + +#if TEXURE_BATCH_UNITS > 1 +uniform sampler2D textures[8]; +#else +uniform sampler2D texture0; +#endif void main() { - outColor = texture(textures[int(fragmentTextureIndex + 0.5)], fragmentTextureCoordinates) * vec4(fragmentColor, 1.0); +#if TEXURE_BATCH_UNITS > 1 + vec4 texel = texture(textures[int(fragmentTextureIndex + 0.5)], fragmentTextureCoordinates); +#else + vec4 texel = texture(texture0, fragmentTextureCoordinates); +#endif + + outColor = texel * vec4(fragmentColor, 1.0); outColor.rgb = mix(outColor.rgb, fogColor, clamp(length(fragmentPosition - cameraPos) / VIEW_DISTANCE, 0.0, 1.0)); if (outColor.a == 0.0) diff --git a/build/debug.sh b/build/debug.sh index 4323a99..8decc74 100755 --- a/build/debug.sh +++ b/build/debug.sh @@ -22,7 +22,7 @@ end " echo "$COMMON -break gl_error +break opengl_error run \"[::1]:4000\" < $DEBUG_DIR/name " > $DEBUG_DIR/client_script diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 48801d9..cc2ded0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -129,13 +129,13 @@ add_executable(dragonblocks_client client/font.c client/frustum.c client/game.c - client/gl_debug.c client/gui.c client/input.c client/interact.c client/light.c client/mesh.c client/model.c + client/opengl.c client/raycast.c client/screenshot.c client/shader.c diff --git a/src/client/client_config.c b/src/client/client_config.c index a1c34ab..a777cea 100644 --- a/src/client/client_config.c +++ b/src/client/client_config.c @@ -8,6 +8,7 @@ struct ClientConfig client_config = { .vsync = true, .meshgen_threads = 4, .swap_mouse_buttons = true, + .texture_batching = true, }; static ConfigEntry config_entries[] = { @@ -41,6 +42,11 @@ static ConfigEntry config_entries[] = { .key = "swap_mouse_buttons", .value = &client_config.meshgen_threads, }, + { + .type = CONFIG_BOOL, + .key = "texture_batching", + .value = &client_config.texture_batching, + }, }; __attribute__((constructor)) static void client_config_init() diff --git a/src/client/client_config.h b/src/client/client_config.h index 05fbbe7..0e4adf7 100644 --- a/src/client/client_config.h +++ b/src/client/client_config.h @@ -10,6 +10,7 @@ extern struct ClientConfig { bool vsync; unsigned int meshgen_threads; bool swap_mouse_buttons; + bool texture_batching; } client_config; #endif diff --git a/src/client/client_entity.c b/src/client/client_entity.c index 49f8d61..8b073a8 100644 --- a/src/client/client_entity.c +++ b/src/client/client_entity.c @@ -8,7 +8,7 @@ #include "client/client_entity.h" #include "client/client_player.h" #include "client/frustum.h" -#include "client/gl_debug.h" +#include "client/opengl.h" #include "client/light.h" #include "client/shader.h" #include "client/window.h" diff --git a/src/client/client_inventory.c b/src/client/client_inventory.c index c0f780b..d5178b9 100644 --- a/src/client/client_inventory.c +++ b/src/client/client_inventory.c @@ -4,7 +4,7 @@ #include "client/client_config.h" #include "client/client_inventory.h" #include "client/client_item.h" -#include "client/gl_debug.h" +#include "client/opengl.h" #include "client/frustum.h" #include "client/light.h" #include "client/shader.h" diff --git a/src/client/debug_menu.c b/src/client/debug_menu.c index ef1c457..f252565 100644 --- a/src/client/debug_menu.c +++ b/src/client/debug_menu.c @@ -11,7 +11,7 @@ #include "client/client_terrain.h" #include "client/debug_menu.h" #include "client/game.h" -#include "client/gl_debug.h" +#include "client/opengl.h" #include "client/gui.h" #include "client/interact.h" #include "client/window.h" diff --git a/src/client/font.c b/src/client/font.c index 56c6e07..e03c828 100644 --- a/src/client/font.c +++ b/src/client/font.c @@ -3,7 +3,7 @@ #include FT_FREETYPE_H #include "client/client.h" #include "client/font.h" -#include "client/gl_debug.h" +#include "client/opengl.h" #include "client/texture.h" #define NUM_CHARS 128 diff --git a/src/client/game.c b/src/client/game.c index 859d9cf..8366976 100644 --- a/src/client/game.c +++ b/src/client/game.c @@ -15,7 +15,7 @@ #include "client/font.h" #include "client/frustum.h" #include "client/game.h" -#include "client/gl_debug.h" +#include "client/opengl.h" #include "client/gui.h" #include "client/input.h" #include "client/interact.h" diff --git a/src/client/gl_debug.h b/src/client/gl_debug.h deleted file mode 100644 index f65f080..0000000 --- a/src/client/gl_debug.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _GL_DEBUG_H_ -#define _GL_DEBUG_H_ - -#ifdef ENABLE_GL_DEBUG -#define GL_DEBUG gl_debug(__FILE__, __LINE__); -#else -#define GL_DEBUG -#endif - -void gl_debug(const char *file, int line); - -#endif diff --git a/src/client/gui.c b/src/client/gui.c index 8e5e1f3..1d5f472 100644 --- a/src/client/gui.c +++ b/src/client/gui.c @@ -5,7 +5,7 @@ #include #include "client/client.h" #include "client/cube.h" -#include "client/gl_debug.h" +#include "client/opengl.h" #include "client/gui.h" #include "client/mesh.h" #include "client/shader.h" diff --git a/src/client/interact.c b/src/client/interact.c index 1e2fb6e..c8a74fc 100644 --- a/src/client/interact.c +++ b/src/client/interact.c @@ -8,7 +8,7 @@ #include "client/cube.h" #include "client/debug_menu.h" #include "client/frustum.h" -#include "client/gl_debug.h" +#include "client/opengl.h" #include "client/gui.h" #include "client/interact.h" #include "client/mesh.h" diff --git a/src/client/light.c b/src/client/light.c index a17c2d0..4d7cb46 100644 --- a/src/client/light.c +++ b/src/client/light.c @@ -1,6 +1,6 @@ #include #include "client/camera.h" -#include "client/gl_debug.h" +#include "client/opengl.h" #include "client/light.h" #include "common/day.h" diff --git a/src/client/mesh.c b/src/client/mesh.c index 75b0b10..59e495b 100644 --- a/src/client/mesh.c +++ b/src/client/mesh.c @@ -4,7 +4,7 @@ #include #include #include "client/cube.h" -#include "client/gl_debug.h" +#include "client/opengl.h" #include "client/mesh.h" typedef struct { diff --git a/src/client/model.c b/src/client/model.c index 93bc773..24a115f 100644 --- a/src/client/model.c +++ b/src/client/model.c @@ -6,7 +6,7 @@ #include "client/camera.h" #include "client/client_config.h" #include "client/frustum.h" -#include "client/gl_debug.h" +#include "client/opengl.h" #include "client/model.h" typedef struct { @@ -189,7 +189,7 @@ void model_init() list_ini(&scene_new); pthread_mutex_init(&lock_scene_new, NULL); - glGetIntegerv(GL_MAX_TEXTURE_UNITS, &units); GL_DEBUG + units = opengl_texture_batch_units(); } // ded diff --git a/src/client/gl_debug.c b/src/client/opengl.c similarity index 74% rename from src/client/gl_debug.c rename to src/client/opengl.c index 7aa163f..c0c128f 100644 --- a/src/client/gl_debug.c +++ b/src/client/opengl.c @@ -1,10 +1,9 @@ -#include -#include #include -#include "client/gl_debug.h" +#include "client/client_config.h" +#include "client/opengl.h" // put this into seperate function to make it easy to trace stack using external debugger -static void gl_error(GLenum err, const char *file, int line) +static void opengl_error(GLenum err, const char *file, int line) { switch (err) { case GL_INVALID_ENUM: fprintf(stderr, "[warning] OpenGL error: INVALID_ENUM %s:%d\n", file, line); break; @@ -17,10 +16,21 @@ static void gl_error(GLenum err, const char *file, int line) default: break; } } -void gl_debug(const char *file, int line) +void opengl_debug(const char *file, int line) { GLenum err = glGetError(); if (err != GL_NO_ERROR) - gl_error(err, file, line); + opengl_error(err, file, line); +} + +GLint opengl_texture_batch_units() +{ + if (!client_config.texture_batching) + return 1; + + GLint units; + glGetIntegerv(GL_MAX_TEXTURE_UNITS, &units); GL_DEBUG + + return units; } diff --git a/src/client/opengl.h b/src/client/opengl.h new file mode 100644 index 0000000..d08fadc --- /dev/null +++ b/src/client/opengl.h @@ -0,0 +1,16 @@ +#ifndef _OPENGL_H_ +#define _OPENGL_H_ + +#ifdef ENABLE_GL_DEBUG +#define GL_DEBUG opengl_debug(__FILE__, __LINE__); +#else +#define GL_DEBUG +#endif + +#include +#include + +void opengl_debug(const char *file, int line); +GLint opengl_texture_batch_units(); + +#endif diff --git a/src/client/screenshot.c b/src/client/screenshot.c index 1569d14..28d5acf 100644 --- a/src/client/screenshot.c +++ b/src/client/screenshot.c @@ -5,7 +5,7 @@ #include #include #include "client/game.h" -#include "client/gl_debug.h" +#include "client/opengl.h" #include "client/window.h" char *screenshot() diff --git a/src/client/shader.c b/src/client/shader.c index eeea589..a9c1346 100644 --- a/src/client/shader.c +++ b/src/client/shader.c @@ -2,7 +2,8 @@ #include #include #include -#include "client/gl_debug.h" +#include "client/client_config.h" +#include "client/opengl.h" #include "client/shader.h" static GLuint compile_shader(GLenum type, const char *path, const char *name, GLuint program, const char *def) @@ -48,8 +49,9 @@ static GLuint compile_shader(GLenum type, const char *path, const char *name, GL GLuint id = glCreateShader(type); GL_DEBUG - // Minimum OpenGL version is 4.2.0 (idk some shader feature from that version is required) - const char *version = "#version 420 core\n"; // 420 blaze it + const char *version = client_config.texture_batching + ? "#version 400 core\n" + : "#version 330 core\n"; const char *code_list[3] = { version, diff --git a/src/client/sky.c b/src/client/sky.c index d20b149..e9ac719 100644 --- a/src/client/sky.c +++ b/src/client/sky.c @@ -4,7 +4,7 @@ #include "client/camera.h" #include "client/client.h" #include "client/cube.h" -#include "client/gl_debug.h" +#include "client/opengl.h" #include "client/mesh.h" #include "client/shader.h" #include "client/sky.h" diff --git a/src/client/terrain_gfx.c b/src/client/terrain_gfx.c index d8ce09f..144c465 100644 --- a/src/client/terrain_gfx.c +++ b/src/client/terrain_gfx.c @@ -8,7 +8,7 @@ #include "client/client_terrain.h" #include "client/cube.h" #include "client/frustum.h" -#include "client/gl_debug.h" +#include "client/opengl.h" #include "client/light.h" #include "client/shader.h" #include "client/terrain_gfx.h" @@ -215,26 +215,29 @@ static Model *create_chunk_model(ChunkRenderData *data) void terrain_gfx_init() { - GLint texture_units; - glGetIntegerv(GL_MAX_TEXTURE_UNITS, &texture_units); GL_DEBUG + GLint texture_batch_units = opengl_texture_batch_units(); char *shader_def; asprintf(&shader_def, - "#define MAX_TEXTURE_UNITS %d\n" + "#define TEXURE_BATCH_UNITS %d\n" "#define VIEW_DISTANCE %lf\n", - texture_units, + texture_batch_units, client_config.view_distance ); + shader_prog = shader_program_create(ASSET_PATH "shaders/3d/terrain", shader_def); free(shader_def); loc_VP = glGetUniformLocation(shader_prog, "VP"); GL_DEBUG - GLint texture_indices[texture_units]; - for (GLint i = 0; i < texture_units; i++) - texture_indices[i] = i; + if (texture_batch_units > 1) { + GLint texture_indices[texture_batch_units]; + for (GLint i = 0; i < texture_batch_units; i++) + texture_indices[i] = i; - glProgramUniform1iv(shader_prog, glGetUniformLocation(shader_prog, "textures"), texture_units, texture_indices); GL_DEBUG + glProgramUniform1iv(shader_prog, glGetUniformLocation(shader_prog, "textures"), + texture_batch_units, texture_indices); GL_DEBUG + } model_shader.prog = shader_prog; model_shader.loc_transform = glGetUniformLocation(shader_prog, "model"); GL_DEBUG diff --git a/src/client/texture.c b/src/client/texture.c index fb489ca..a531d42 100644 --- a/src/client/texture.c +++ b/src/client/texture.c @@ -5,7 +5,7 @@ #include #include #include "client/client_config.h" -#include "client/gl_debug.h" +#include "client/opengl.h" #include "client/texture.h" static Tree textures; diff --git a/src/client/window.c b/src/client/window.c index 5f6cca8..01e61ca 100644 --- a/src/client/window.c +++ b/src/client/window.c @@ -5,7 +5,7 @@ #include "client/client_config.h" #include "client/debug_menu.h" #include "client/game.h" -#include "client/gl_debug.h" +#include "client/opengl.h" #include "client/gui.h" #include "client/input.h" #include "client/window.h"