From 62390a3e4bdc19f7cdba84591e85345f92d7db78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Madar=C3=A1sz?= Date: Mon, 6 Nov 2023 09:30:19 +0100 Subject: [PATCH] billboarding fixed --- demos/99-billboard.c | 114 +----------------- .../shaders/vs_323444143_16_332_model.glsl | 50 +++++--- engine/joint/v4k.h | 8 ++ engine/split/v4k_render.c | 8 ++ engine/v4k.c | 8 ++ .../art/lite/data/languages/language_glsl.lua | 67 ++++++++++ tools/editor/v4k_editor.h | 2 +- 7 files changed, 133 insertions(+), 124 deletions(-) create mode 100644 tools/editor/art/lite/data/languages/language_glsl.lua diff --git a/demos/99-billboard.c b/demos/99-billboard.c index b4e0c3f..26b5214 100644 --- a/demos/99-billboard.c +++ b/demos/99-billboard.c @@ -1,118 +1,24 @@ #include "v4k.h" - +/* float* billboard(mat44 modelview, bool billboard_x, bool billboard_y, bool billboard_z) { if( billboard_x ) { modelview[0*4+0] = 1; modelview[0*4+1] = 0; modelview[0*4+2] = 0; } if( billboard_y ) { modelview[1*4+0] = 0; modelview[1*4+1] = 1; modelview[1*4+2] = 0; } if( billboard_z ) { modelview[2*4+0] = 0; modelview[2*4+1] = 0; modelview[2*4+2] = 1; } return modelview; } +*/ const char *billboard_name(bool billboard_x, bool billboard_y, bool billboard_z) { // Spherical billboarding makes the object to always face the camera no matter the position of the camera on an imaginary sphere. // Cylindrical billboarding makes the object to face the camera only when the camera looks at the right or at the left. return billboard_x && billboard_y && billboard_z ? "(spherical billboard)" : billboard_x && billboard_z ? "(cylindrical billboard)" : ""; } - -const char *shader_projected_vs = -"#version 150\n" -"in vec3 att_position;\n" -"in vec2 att_uv;\n" -"out vec2 uv;\n" -"uniform mat4 u_projection;\n" -"uniform mat4 u_modelview;\n" -//"uniform mat4 u_billboard;\n" -"uniform float u_aspect;\n" - -"void main() {\n" -" gl_Position = u_projection * u_modelview * vec4(att_position, 1.0f);\n" -" uv = vec2(att_uv.x, 1.0 - att_uv.y);\n" -"return;" -" // billboarding keeping scale (see: https://stackoverflow.com/questions/15937842/glsl-billboard-shader-keep-the-scaling)\n" -" vec2 scale = vec2( length(u_modelview[0]) / u_aspect, length(u_modelview[1]) );\n" -" vec4 billboard = u_modelview * vec4(vec3(0.0), 1.0);\n" -" gl_Position = u_projection * billboard + vec4(scale * att_position.xy, 0.0, 0.0);\n" -"" -"}\n"; - -const char *shader_textured_fs = -"#version 150\n" -"in vec2 uv;\n" -"out vec4 out_color;\n" -"uniform sampler2D u_texture;\n" -"void main() {\n" -" out_color = texture(u_texture, uv);\n" -"}\n"; - int main() { // create the window window_create( 0.5f, 0 ); window_color( RGB3(40,40,50) ); - // enable some gl stuff. needed? - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - - // compile shaders - GLuint program = // shader(shader_projected_vs, shader_textured_fs); - shader(shader_projected_vs, shader_textured_fs, "att_position,att_uv", "out_color", NULL ); - - // a test cube: 3POS + 2UV - GLfloat vertices[] = { - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, - 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, - - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, - - -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, - -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, - - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, - 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, - 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, - - -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, - 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, - 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, - -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, - -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, - - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, - 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, - -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, - -0.5f, 0.5f, -0.5f, 0.0f, 1.0f - }; - typedef struct MyVertex { - vec3 pos; - vec2 texcoord; - } MyVertex; - - GLuint indices[] = { - 0,2,1,3,5,4,6,7,8,9,10,11,12,13,14,15,16,17,18,20,19,21,23,22,24,25,26,27,28,29,30,32,31,33,35,34 - }; - - mesh_t cube = mesh(); - mesh_update(&cube, "p3 t2", 0,36,vertices, 36,indices, 0); - - mat44 cube_transform; id44(cube_transform); + model_t cube = model("Alien.fbx", 0); // create (fps) camera camera_t cam = camera(); @@ -122,10 +28,6 @@ int main() { if (input(KEY_ESC)) break; - // setup projection - mat44 proj; - perspective44(proj, 45, window_aspect(), 0.1f, 100.0f); - // fps camera bool active = ui_hover() || ui_active() || gizmo_active() ? false : input(MOUSE_L) || input(MOUSE_M) || input(MOUSE_R); window_cursor( !active ); @@ -141,15 +43,9 @@ int main() { static int billboard_x = 0; if( input_down(KEY_1) ) billboard_x ^= 1; static int billboard_y = 0; if( input_down(KEY_2) ) billboard_y ^= 1; static int billboard_z = 0; if( input_down(KEY_3) ) billboard_z ^= 1; + cube.billboard = (billboard_x << 2)|(billboard_y << 1)|(billboard_z << 0); - // draw cube - mat44 modelview; multiply44x2(modelview, cam.view, cube_transform); - shader_bind(program); - shader_mat44("u_projection", proj); - shader_mat44("u_modelview", billboard(modelview, billboard_x,billboard_y,billboard_z) ); - shader_texture("u_texture", texture_checker()); - - mesh_render(&cube); + model_render(cube, cam.proj, cam.view, cube.pivot, 0); window_title(va("billboard_x: %s, billboard_y: %s, billboard_z: %s %s", billboard_x ? "on":"off", billboard_y ? "on":"off", billboard_z ? "on":"off", billboard_name(billboard_x,billboard_y,billboard_z))); } diff --git a/engine/art/shaders/vs_323444143_16_332_model.glsl b/engine/art/shaders/vs_323444143_16_332_model.glsl index 4ce7864..2d243ac 100644 --- a/engine/art/shaders/vs_323444143_16_332_model.glsl +++ b/engine/art/shaders/vs_323444143_16_332_model.glsl @@ -5,7 +5,8 @@ uniform mat3x4 vsBoneMatrix[MAX_BONES]; uniform bool SKINNED = false; uniform mat4 M; // RIM uniform mat4 VP; - +uniform mat4 P; +uniform int u_billboard; #if 0 // Fetch blend channels from all attached blend deformers. @@ -109,16 +110,37 @@ void main() { v_normal = vec4(att_normal, 0.0) * m; //@todo: tangents } - - // vec3 tangent = att_tangent.xyz; - // vec3 bitangent = cross(att_normal, att_tangent.xyz) * att_tangent.w; - - v_normal_ws = normalize(vec3(model * vec4(v_normal, 0.))); // normal to world/model space - v_normal = normalize(v_normal); - v_position_ws = (att_instanced_matrix * vec4( objPos, 1.0 )).xyz; - v_position = att_position; - v_texcoord = att_texcoord; - v_color = att_color; - gl_Position = VP * att_instanced_matrix * vec4( objPos, 1.0 ); - do_shadow(); - } \ No newline at end of file + + // vec3 tangent = att_tangent.xyz; + // vec3 bitangent = cross(att_normal, att_tangent.xyz) * att_tangent.w; + mat4 modelView = view * att_instanced_matrix; + if(u_billboard > 0) { + float sx = length(vec3(modelView[0][0], modelView[1][0], modelView[2][0])); + float sy = length(vec3(modelView[0][1], modelView[1][1], modelView[2][1])); + float sz = length(vec3(modelView[0][2], modelView[1][2], modelView[2][2])); + + if((u_billboard & 4) != 0) { + modelView[0][0] = sx; + modelView[0][1] = 0.0; + modelView[0][2] = 0.0; + } + if((u_billboard & 2) != 0) { + modelView[1][0] = 0.0; + modelView[1][1] = sy; + modelView[1][2] = 0.0; + } + if((u_billboard & 1) != 0) { + modelView[2][0] = 0.0; + modelView[2][1] = 0.0; + modelView[2][2] = sz; + } + } + v_normal_ws = normalize(vec3(model * vec4(v_normal, 0.))); // normal to world/model space + v_normal = normalize(v_normal); + v_position_ws = (att_instanced_matrix * vec4( objPos, 1.0 )).xyz; + v_position = att_position; + v_texcoord = att_texcoord; + v_color = att_color; + gl_Position = P * modelView * vec4( objPos, 1.0 ); + do_shadow(); +} \ No newline at end of file diff --git a/engine/joint/v4k.h b/engine/joint/v4k.h index fea7b09..07fcd8d 100644 --- a/engine/joint/v4k.h +++ b/engine/joint/v4k.h @@ -354025,6 +354025,13 @@ void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view, vec3 dir = norm3(vec3(view[2], view[6], view[10])); glUniform3fv( loc, 1, &dir.x ); } + if( (loc = glGetUniformLocation(shader, "billboard")) >= 0 ) { + glUniform1i( loc, m.billboard ); + } + else + if( (loc = glGetUniformLocation(shader, "u_billboard")) >= 0 ) { + glUniform1i( loc, m.billboard ); + } #if 0 // @todo: mat44 projview (useful?) #endif @@ -354469,6 +354476,7 @@ model_t model_from_mem(const void *mem, int len, int flags) { "att_position,att_texcoord,att_normal,att_tangent,att_instanced_matrix,,,,att_indexes,att_weights,att_vertexindex,att_color,att_bitangent","fragColor", va("SHADING_PHONG,%s", (flags&MODEL_RIMLIGHT)?"RIM":"")); // } + // ASSERT(shaderprog > 0); iqm_t *q = CALLOC(1, sizeof(iqm_t)); m.program = shaderprog; diff --git a/engine/split/v4k_render.c b/engine/split/v4k_render.c index d4331fa..d049ac7 100644 --- a/engine/split/v4k_render.c +++ b/engine/split/v4k_render.c @@ -3947,6 +3947,13 @@ void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view, vec3 dir = norm3(vec3(view[2], view[6], view[10])); glUniform3fv( loc, 1, &dir.x ); } + if( (loc = glGetUniformLocation(shader, "billboard")) >= 0 ) { + glUniform1i( loc, m.billboard ); + } + else + if( (loc = glGetUniformLocation(shader, "u_billboard")) >= 0 ) { + glUniform1i( loc, m.billboard ); + } #if 0 // @todo: mat44 projview (useful?) #endif @@ -4391,6 +4398,7 @@ model_t model_from_mem(const void *mem, int len, int flags) { "att_position,att_texcoord,att_normal,att_tangent,att_instanced_matrix,,,,att_indexes,att_weights,att_vertexindex,att_color,att_bitangent","fragColor", va("SHADING_PHONG,%s", (flags&MODEL_RIMLIGHT)?"RIM":"")); // } + // ASSERT(shaderprog > 0); iqm_t *q = CALLOC(1, sizeof(iqm_t)); m.program = shaderprog; diff --git a/engine/v4k.c b/engine/v4k.c index 871fc96..cf1dedc 100644 --- a/engine/v4k.c +++ b/engine/v4k.c @@ -20111,6 +20111,13 @@ void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view, vec3 dir = norm3(vec3(view[2], view[6], view[10])); glUniform3fv( loc, 1, &dir.x ); } + if( (loc = glGetUniformLocation(shader, "billboard")) >= 0 ) { + glUniform1i( loc, m.billboard ); + } + else + if( (loc = glGetUniformLocation(shader, "u_billboard")) >= 0 ) { + glUniform1i( loc, m.billboard ); + } #if 0 // @todo: mat44 projview (useful?) #endif @@ -20555,6 +20562,7 @@ model_t model_from_mem(const void *mem, int len, int flags) { "att_position,att_texcoord,att_normal,att_tangent,att_instanced_matrix,,,,att_indexes,att_weights,att_vertexindex,att_color,att_bitangent","fragColor", va("SHADING_PHONG,%s", (flags&MODEL_RIMLIGHT)?"RIM":"")); // } + // ASSERT(shaderprog > 0); iqm_t *q = CALLOC(1, sizeof(iqm_t)); m.program = shaderprog; diff --git a/tools/editor/art/lite/data/languages/language_glsl.lua b/tools/editor/art/lite/data/languages/language_glsl.lua new file mode 100644 index 0000000..55d9891 --- /dev/null +++ b/tools/editor/art/lite/data/languages/language_glsl.lua @@ -0,0 +1,67 @@ +local syntax = require "core.syntax" + +syntax.add { + files = { "%.fx$", "%.glsl$", "%.fs$", "%.vs$", "%.gs$" }, + comment = "//", + patterns = { + { pattern = "//.-\n", type = "comment" }, + { pattern = { "/%*", "%*/" }, type = "comment" }, + { pattern = { "#", "[^\\]\n" }, type = "comment" }, + { pattern = { '"', '"', '\\' }, type = "string" }, + { pattern = { "'", "'", '\\' }, type = "string" }, + { pattern = "-?0x%x+", type = "number" }, + { pattern = "-?%d+[%d%.eE]*f?", type = "number" }, + { pattern = "-?%.?%d+f?", type = "number" }, + { pattern = "[%+%-=/%*%^%%<>!~|&]", type = "operator" }, + { pattern = "[%a_][%w_]*%f[(]", type = "function" }, + { pattern = "[%a_][%w_]*", type = "symbol" }, + }, + symbols = { + ["if"] = "keyword", + ["then"] = "keyword", + ["else"] = "keyword", + ["elseif"] = "keyword", + ["do"] = "keyword", + ["while"] = "keyword", + ["for"] = "keyword", + ["break"] = "keyword", + ["continue"] = "keyword", + ["return"] = "keyword", + ["goto"] = "keyword", + ["struct"] = "keyword", + ["union"] = "keyword", + ["typedef"] = "keyword", + ["enum"] = "keyword", + ["extern"] = "keyword", + ["static"] = "keyword", + ["volatile"] = "keyword", + ["const"] = "keyword", + ["inline"] = "keyword", + ["switch"] = "keyword", + ["case"] = "keyword", + ["default"] = "keyword", + ["auto"] = "keyword", + ["const"] = "keyword", + ["void"] = "keyword", + ["uniform"] = "keyword", + ["in"] = "keyword", + ["out"] = "keyword", + ["inout"] = "keyword", + ["int"] = "keyword2", + ["short"] = "keyword2", + ["long"] = "keyword2", + ["float"] = "keyword2", + ["double"] = "keyword2", + ["char"] = "keyword2", + ["unsigned"] = "keyword2", + ["bool"] = "keyword2", + ["vec2"] = "keyword2", + ["vec3"] = "keyword2", + ["vec4"] = "keyword2", + ["sampler2D"]= "keyword2", + ["true"] = "literal", + ["false"] = "literal", + ["NULL"] = "literal", + }, +} + diff --git a/tools/editor/v4k_editor.h b/tools/editor/v4k_editor.h index f4e1b6e..5211ce2 100644 --- a/tools/editor/v4k_editor.h +++ b/tools/editor/v4k_editor.h @@ -576,7 +576,7 @@ void editor_frame( void (*game)(unsigned, float, double) ) { game(editor.frame, editor.dt, editor.t); // timing - editor.dt = clampf(window_delta(), 0, 1/60.f) * !window_has_pause() * editor.slomo; + editor.dt = window_delta() /*clampf(window_delta(), 0, 1/60.f)*/ * !window_has_pause() * editor.slomo; editor.t += editor.dt; editor.frame += !window_has_pause(); editor.frame += !editor.frame;