diff --git a/bind/v4k.lua b/bind/v4k.lua index 46afd96..d2dba94 100644 --- a/bind/v4k.lua +++ b/bind/v4k.lua @@ -1055,6 +1055,7 @@ typedef struct renderstate_t { float point_size; unsigned polygon_mode_face; unsigned polygon_mode_mode; + bool wireframe_enabled; bool scissor_test_enabled; } renderstate_t; renderstate_t renderstate(); @@ -1400,7 +1401,7 @@ typedef struct model_t { handle *textures; char **texture_names; material_t* materials; - unsigned uniforms[NUM_MODEL_UNIFORMS]; + int uniforms[NUM_MODEL_UNIFORMS]; texture_t sky_refl, sky_env; texture_t lightmap; float *lmdata; diff --git a/demos/99-pbr.c b/demos/99-pbr.c index 423e010..b4f8dc5 100644 --- a/demos/99-pbr.c +++ b/demos/99-pbr.c @@ -201,21 +201,32 @@ bool ModelLoad( Model *G, const char *_path ) { return true; } +static renderstate_t g_renderstate = {0}; + void ModelRender( Model *G, const mat44 _worldRootMatrix ) { unsigned _shader = G->shader; shader_bind( _shader ); shader_vec4("global_ambient", vec4(1,1,1,1)); // unused + do_once { + g_renderstate = renderstate(); + g_renderstate.cull_face_enabled = 1; + g_renderstate.blend_enabled = 1; + g_renderstate.blend_src = GL_SRC_ALPHA; + g_renderstate.blend_dst = GL_ONE_MINUS_SRC_ALPHA; + } + // loop thrice: first opaque, then transparent backface, then transparent frontface for(int j = 0; j < 3; ++j) { bool bTransparentPass = j > 0; if(bTransparentPass) { - glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - glCullFace( j == 1 ? GL_FRONT : GL_BACK ); // glDepthMask( GL_FALSE); + g_renderstate.cull_face_mode = j == 1 ? GL_FRONT : GL_BACK; + // glCullFace( j == 1 ? GL_FRONT : GL_BACK ); // glDepthMask( GL_FALSE); } + renderstate_apply(&g_renderstate); + mat44 mat_world; copy44(mat_world, _worldRootMatrix); // @fixme mMatrices[ node.mID ] * _worldRootMatrix shader_mat44( "mat_world", mat_world ); diff --git a/engine/joint/v4k.h b/engine/joint/v4k.h index ff430f5..d785917 100644 --- a/engine/joint/v4k.h +++ b/engine/joint/v4k.h @@ -17075,6 +17075,9 @@ typedef struct renderstate_t { unsigned polygon_mode_face; unsigned polygon_mode_mode; + // Wireframe mode + bool wireframe_enabled; + // Scissor test bool scissor_test_enabled; } renderstate_t; @@ -17660,7 +17663,7 @@ typedef struct model_t { handle *textures; char **texture_names; array(material_t) materials; - unsigned uniforms[NUM_MODEL_UNIFORMS]; + int uniforms[NUM_MODEL_UNIFORMS]; texture_t sky_refl, sky_env; @@ -376051,7 +376054,7 @@ void font_face_from_mem(const char *tag, const void *ttf_data, unsigned ttf_len, glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT); // upload constant uniforms - shader_bind(f->program); + glUseProgram(f->program); glUniform1i(glGetUniformLocation(f->program, "sampler_font"), 0); glUniform1i(glGetUniformLocation(f->program, "sampler_meta"), 1); glUniform1i(glGetUniformLocation(f->program, "sampler_colors"), 2); @@ -376113,7 +376116,7 @@ void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float fact glBindVertexArray(f->vao); // update uniforms - shader_bind(f->program); + glUseProgram(f->program); glUniform1f(glGetUniformLocation(f->program, "scale_factor"), factor); glUniform2fv(glGetUniformLocation(f->program, "string_offset"), 1, &offset.x); glUniform1f(glGetUniformLocation(f->program, "offset_firstline"), f->ascent*f->factor); @@ -376133,7 +376136,7 @@ void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float fact glDrawArraysInstanced(GL_TRIANGLES, 0, 6, glyph_idx); // Restore modified GL state - shader_bind(last_program); + glUseProgram(last_program); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, last_texture0); @@ -376736,7 +376739,7 @@ void gui_drawrect( texture_t texture, vec2 tex_start, vec2 tex_end, int rgba, ve renderstate_apply(&rect_rs); GLenum texture_type = texture.flags & TEXTURE_ARRAY ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D; - shader_bind( program ); + glUseProgram( program ); glBindVertexArray( vao ); @@ -376785,7 +376788,7 @@ void gui_drawrect( texture_t texture, vec2 tex_start, vec2 tex_end, int rgba, ve glDisableVertexAttribArray(1); glBindVertexArray( 0 ); glBindBuffer(GL_ARRAY_BUFFER, 0); - shader_bind( 0 ); + glUseProgram( 0 ); } // ---------------------------------------------------------------------------- @@ -383061,14 +383064,14 @@ void shader_apply_param(unsigned shader, unsigned param_no) { if( strchr("ibfv", type[0]) ) { GLint shader_bak; glGetIntegerv(GL_CURRENT_PROGRAM, &shader_bak); - shader_bind(shader); + glUseProgram(shader); /**/ if(type[0] == 'i') glUniform1i(glGetUniformLocation(shader, name), setv.x); else if(type[0] == 'b') glUniform1i(glGetUniformLocation(shader, name), !!setv.x); else if(type[0] == 'f') glUniform1f(glGetUniformLocation(shader, name), setv.x); else if(type[3] == '2') glUniform2fv(glGetUniformLocation(shader, name), 1, &setv.x); else if(type[3] == '3') glUniform3fv(glGetUniformLocation(shader, name), 1, &setv.x); else if(type[3] == '4') glUniform4fv(glGetUniformLocation(shader, name), 1, &setv.x); - shader_bind(shader_bak); + glUseProgram(shader_bak); } } } @@ -383302,57 +383305,35 @@ void ssbo_unbind(){ glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); } -typedef map(unsigned,int) uniform_binding; static __thread unsigned last_shader = -1; -static __thread quarks_db uniform_names; -static __thread map(handle, uniform_binding) uniforms; int shader_uniform(const char *name) { -#if 0 - do_once map_init(uniforms, less_int, hash_int); - if (!map_find(uniforms, last_shader)) { - uniform_binding names_map = 0; - map_init(names_map, less_int, hash_int); - map_insert(uniforms, last_shader, names_map); - } - - uniform_binding names = *map_find(uniforms, last_shader); - unsigned name_hash = quark_intern(&uniform_names, name); - if (!map_find(names, name_hash)) { - map_insert(names, name_hash, glGetUniformLocation(last_shader, name)); - } - - // int ret = glGetUniformLocation(last_shader, name); - // if( ret < 0 ) PRINTF("!cannot find uniform '%s' in shader program %d\n", name, (int)last_shader ); - return *map_find(names, name_hash); -#else return glGetUniformLocation(last_shader, name); -#endif } unsigned shader_get_active() { return last_shader; } -unsigned shader_bind(unsigned program) { if (program == last_shader) return last_shader; unsigned ret = last_shader; return glUseProgram(last_shader = program), ret; } -static inline void shader_int_(unsigned uniform, int i) { glUniform1i(uniform, i); } -static inline void shader_float_(unsigned uniform, float f) { glUniform1f(uniform, f); } -static inline void shader_vec2_(unsigned uniform, vec2 v) { glUniform2fv(uniform, 1, &v.x); } -static inline void shader_vec3_(unsigned uniform, vec3 v) { glUniform3fv(uniform, 1, &v.x); } -static inline void shader_vec3v_(unsigned uniform, int count, vec3 *v) { glUniform3fv(uniform, count, &v[0].x); } -static inline void shader_vec4_(unsigned uniform, vec4 v) { glUniform4fv(uniform, 1, &v.x); } -static inline void shader_mat44_(unsigned uniform, mat44 m) { glUniformMatrix4fv(uniform, 1, GL_FALSE/*GL_TRUE*/, m); } -static inline void shader_cubemap_(unsigned sampler, unsigned texture) { +unsigned shader_bind(unsigned program) { unsigned ret = last_shader; return glUseProgram(last_shader = program), ret; } +static inline void shader_int_(int uniform, int i) { glUniform1i(uniform, i); } +static inline void shader_float_(int uniform, float f) { glUniform1f(uniform, f); } +static inline void shader_vec2_(int uniform, vec2 v) { glUniform2fv(uniform, 1, &v.x); } +static inline void shader_vec3_(int uniform, vec3 v) { glUniform3fv(uniform, 1, &v.x); } +static inline void shader_vec3v_(int uniform, int count, vec3 *v) { glUniform3fv(uniform, count, &v[0].x); } +static inline void shader_vec4_(int uniform, vec4 v) { glUniform4fv(uniform, 1, &v.x); } +static inline void shader_mat44_(int uniform, mat44 m) { glUniformMatrix4fv(uniform, 1, GL_FALSE/*GL_TRUE*/, m); } +static inline void shader_cubemap_(int sampler, unsigned texture) { int id = texture_unit(); glUniform1i(sampler, id); glActiveTexture(GL_TEXTURE0 + id); glBindTexture(GL_TEXTURE_CUBE_MAP, texture); } -static inline void shader_bool_(unsigned uniform, bool x) { glUniform1i(uniform, x); } -static inline void shader_uint_(unsigned uniform, unsigned x ) { glUniform1ui(uniform, x); } -static inline void shader_texture_unit_(unsigned sampler, unsigned id, unsigned unit) { +static inline void shader_bool_(int uniform, bool x) { glUniform1i(uniform, x); } +static inline void shader_uint_(int uniform, unsigned x ) { glUniform1ui(uniform, x); } +static inline void shader_texture_unit_(int sampler, unsigned id, unsigned unit) { // @todo. if tex.h == 1 ? GL_TEXTURE_1D : GL_TEXTURE_2D glUniform1i(sampler, unit); glActiveTexture(GL_TEXTURE0 + unit); glBindTexture(GL_TEXTURE_2D, id); } -static inline void shader_texture_(unsigned sampler, texture_t t) { shader_texture_unit_(sampler, t.id, texture_unit()); } +static inline void shader_texture_(int sampler, texture_t t) { shader_texture_unit_(sampler, t.id, texture_unit()); } // public api void shader_int(const char *uniform, int i) { glUniform1i(shader_uniform(uniform), i); } @@ -384168,7 +384149,7 @@ void fullscreen_quad_rgb( texture_t texture ) { GLenum texture_type = texture.flags & TEXTURE_ARRAY ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D; renderstate_apply(&fullscreen_quad_rs); - shader_bind( program ); + glUseProgram( program ); float gamma = 1; glUniform1f( u_inv_gamma, gamma ); @@ -384183,7 +384164,7 @@ void fullscreen_quad_rgb( texture_t texture ) { glBindTexture( texture_type, 0 ); glBindVertexArray( 0 ); - shader_bind( 0 ); + glUseProgram( 0 ); // glDisable( GL_BLEND ); } @@ -384201,7 +384182,7 @@ void fullscreen_quad_rgb_flipped( texture_t texture ) { GLenum texture_type = texture.flags & TEXTURE_ARRAY ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D; renderstate_apply(&fullscreen_quad_rs); - shader_bind( program ); + glUseProgram( program ); float gamma = 1; glUniform1f( u_inv_gamma, gamma ); @@ -384216,7 +384197,7 @@ void fullscreen_quad_rgb_flipped( texture_t texture ) { glBindTexture( texture_type, 0 ); glBindVertexArray( 0 ); - shader_bind( 0 ); + glUseProgram( 0 ); // glDisable( GL_BLEND ); } @@ -384238,7 +384219,7 @@ void fullscreen_quad_ycbcr( texture_t textureYCbCr[3] ) { } renderstate_apply(&fullscreen_quad_rs); - shader_bind( program ); + glUseProgram( program ); // glUniform1f( u_gamma, gamma ); glBindVertexArray( vao ); @@ -384261,7 +384242,7 @@ void fullscreen_quad_ycbcr( texture_t textureYCbCr[3] ) { glBindTexture( GL_TEXTURE_2D, 0 ); glBindVertexArray( 0 ); - shader_bind( 0 ); + glUseProgram( 0 ); // glDisable( GL_BLEND ); } @@ -384283,7 +384264,7 @@ void fullscreen_quad_ycbcr_flipped( texture_t textureYCbCr[3] ) { } renderstate_apply(&fullscreen_quad_rs); - shader_bind( program ); + glUseProgram( program ); // glUniform1f( u_gamma, gamma ); glBindVertexArray( vao ); @@ -384306,7 +384287,7 @@ void fullscreen_quad_ycbcr_flipped( texture_t textureYCbCr[3] ) { glBindTexture( GL_TEXTURE_2D, 0 ); glBindVertexArray( 0 ); - shader_bind( 0 ); + glUseProgram( 0 ); // glDisable( GL_BLEND ); } @@ -384611,7 +384592,7 @@ void skybox_mie_calc_sh(skybox_t *sky, float sky_intensity) { for(int i = 0; i < 6; ++i) { glBindFramebuffer(GL_FRAMEBUFFER, sky->framebuffers[i]); glViewport(0, 0, WIDTH, HEIGHT); - shader_bind(sky->program); + glUseProgram(sky->program); mat44 proj; perspective44(proj, 90.0f, WIDTH / (float)HEIGHT, 0.1f, 500.f); mat44 view; lookat44(view, vec3(0,0,0), directions[i], vec3(0,-1,0)); @@ -385162,7 +385143,7 @@ int postfx_load_from_mem( postfx *fx, const char *name, const char *fs ) { p->program = shader(vs, fs2, "vtexcoord", "fragColor" , NULL); - shader_bind(p->program); // needed? + glUseProgram(p->program); // needed? for( int i = 0; i < countof(p->uniforms); ++i ) p->uniforms[i] = -1; @@ -385326,7 +385307,7 @@ bool postfx_end(postfx *fx) { passfx *pass = &fx->pass[i]; if( pass->enabled ) { if( !pass->program ) { --num_active_passes; continue; } - shader_bind(pass->program); + glUseProgram(pass->program); // bind texture to texture unit 0 // shader_texture_unit(fx->diffuse[frame], 0); @@ -385365,7 +385346,7 @@ bool postfx_end(postfx *fx) { if (bound) fbo_unbind(); } } - shader_bind(0); + glUseProgram(0); // restore clear color: needed in case transparent window is being used (alpha != 0) glClearColor(0,0,0,1); // @transparent @@ -385476,7 +385457,7 @@ static void brdf_load() { glDisable(GL_BLEND); handle old_shader = last_shader; - shader_bind( program ); + glUseProgram( program ); glViewport(0, 0, 512, 512); @@ -385490,7 +385471,7 @@ static void brdf_load() { glBindVertexArray( 0 ); - shader_bind( last_shader ); + glUseProgram( last_shader ); fbo_unbind(); fbo_destroy(lut_fbo); @@ -385612,7 +385593,7 @@ shadertoy_t* shadertoy_render(shadertoy_t *s, float delta) { struct tm *tm = localtime(&tmsec); s->t += delta * 1000; - shader_bind(s->program); + glUseProgram(s->program); glUniform1f(s->uniforms[iGlobalTime], s->t / 1000.f ); glUniform1f(s->uniforms[iGlobalFrame], s->frame++); glUniform1f(s->uniforms[iGlobalDelta], delta / 1000.f ); @@ -385782,6 +385763,8 @@ void model_set_texture(model_t m, texture_t t) { } } +//@fixme: some locations are invalid, find out why +#if 0 static void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view, mat44 model) { // @todo: cache uniform locs if(!m.iqm) return; @@ -385813,7 +385796,7 @@ void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view, shader_int_(loc, m.billboard); } if( (loc = m.uniforms[MODEL_UNIFORM_TEXLIT]) >= 0 ) { - shader_int_(loc, (m.lightmap.w != 0)); + shader_bool_(loc, (m.lightmap.w != 0)); } if ((loc = m.uniforms[MODEL_UNIFORM_MODEL]) >= 0) { shader_mat44_(loc, model); @@ -385833,7 +385816,7 @@ void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view, if( q->numanims ) if( (loc = m.uniforms[MODEL_UNIFORM_VS_BONE_MATRIX]) >= 0 ) glUniformMatrix3x4fv( loc, q->numjoints, GL_FALSE, q->outframe[0]); if ((loc = m.uniforms[MODEL_UNIFORM_U_MATCAPS]) >= 0) { - shader_int_(loc, m.flags & MODEL_MATCAPS ? GL_TRUE:GL_FALSE); + shader_bool_(loc, m.flags & MODEL_MATCAPS ? GL_TRUE:GL_FALSE); } if (m.shading == SHADING_PBR) { @@ -385858,6 +385841,132 @@ void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view, shader_bind(old_shader); } } +#else +static +void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view, mat44 model) { // @todo: cache uniform locs + if(!m.iqm) return; + iqm_t *q = m.iqm; + + shader_bind(shader); + int loc; + //if( (loc = glGetUniformLocation(shader, "M")) >= 0 ) glUniformMatrix4fv( loc, 1, GL_FALSE/*GL_TRUE*/, m); // RIM + if( (loc = glGetUniformLocation(shader, "MV")) >= 0 ) { + glUniformMatrix4fv( loc, 1, GL_FALSE, mv); + } + else + if( (loc = glGetUniformLocation(shader, "u_mv")) >= 0 ) { + glUniformMatrix4fv( loc, 1, GL_FALSE, mv); + } + if( (loc = glGetUniformLocation(shader, "MVP")) >= 0 ) { + mat44 mvp; multiply44x2(mvp, proj, mv); // multiply44x3(mvp, proj, view, model); + glUniformMatrix4fv( loc, 1, GL_FALSE, mvp); + } + else + if( (loc = glGetUniformLocation(shader, "u_mvp")) >= 0 ) { + mat44 mvp; multiply44x2(mvp, proj, mv); // multiply44x3(mvp, proj, view, model); + glUniformMatrix4fv( loc, 1, GL_FALSE, mvp); + } + if( (loc = glGetUniformLocation(shader, "VP")) >= 0 ) { + mat44 vp; multiply44x2(vp, proj, view); + glUniformMatrix4fv( loc, 1, GL_FALSE, vp); + } + else + if( (loc = glGetUniformLocation(shader, "u_vp")) >= 0 ) { + mat44 vp; multiply44x2(vp, proj, view); + glUniformMatrix4fv( loc, 1, GL_FALSE, vp); + } + if( (loc = glGetUniformLocation(shader, "u_cam_pos")) >= 0 ) { + vec3 pos = vec3(view[12], view[13], view[14]); + glUniform3fv( loc, 1, &pos.x ); + } + else + if( (loc = glGetUniformLocation(shader, "cam_pos")) >= 0 ) { + vec3 pos = vec3(view[12], view[13], view[14]); + glUniform3fv( loc, 1, &pos.x ); + } + if( (loc = glGetUniformLocation(shader, "u_cam_dir")) >= 0 ) { + vec3 dir = norm3(vec3(view[2], view[6], view[10])); + glUniform3fv( loc, 1, &dir.x ); + } + else + if( (loc = glGetUniformLocation(shader, "cam_dir")) >= 0 ) { + 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( (loc = glGetUniformLocation(shader, "texlit")) >= 0 ) { + glUniform1i( loc, (m.lightmap.w != 0) ); + } + else + if( (loc = glGetUniformLocation(shader, "u_texlit")) >= 0 ) { + glUniform1i( loc, (m.lightmap.w != 0) ); + } +#if 0 + // @todo: mat44 projview (useful?) +#endif + if ((loc = glGetUniformLocation(shader, "M")) >= 0) { + glUniformMatrix4fv(loc, 1, GL_FALSE, model); + } + else + if ((loc = glGetUniformLocation(shader, "model")) >= 0) { + glUniformMatrix4fv(loc, 1, GL_FALSE, model); + } + if ((loc = glGetUniformLocation(shader, "V")) >= 0) { + glUniformMatrix4fv(loc, 1, GL_FALSE, view); + } + else + if ((loc = glGetUniformLocation(shader, "view")) >= 0) { + glUniformMatrix4fv(loc, 1, GL_FALSE, view); + } + if ((loc = glGetUniformLocation(shader, "inv_view")) >= 0) { + mat44 inv_view; + invert44( inv_view, view); + glUniformMatrix4fv(loc, 1, GL_FALSE, inv_view); + } + if ((loc = glGetUniformLocation(shader, "P")) >= 0) { + glUniformMatrix4fv(loc, 1, GL_FALSE, proj); + } + else + if ((loc = glGetUniformLocation(shader, "proj")) >= 0) { + glUniformMatrix4fv(loc, 1, GL_FALSE, proj); + } + if( (loc = glGetUniformLocation(shader, "SKINNED")) >= 0 ) glUniform1i( loc, q->numanims ? GL_TRUE : GL_FALSE); + if( q->numanims ) + if( (loc = glGetUniformLocation(shader, "vsBoneMatrix")) >= 0 ) glUniformMatrix3x4fv( loc, q->numjoints, GL_FALSE, q->outframe[0]); + + if ((loc = glGetUniformLocation(shader, "u_matcaps")) >= 0) { + glUniform1i(loc, m.flags & MODEL_MATCAPS ? GL_TRUE:GL_FALSE); + } + + if (m.shading == SHADING_PBR) { + handle old_shader = last_shader; + shader_bind(shader); + shader_vec2( "resolution", vec2(window_width(),window_height())); + + bool has_tex_skysphere = m.sky_refl.id != texture_checker().id; + bool has_tex_skyenv = m.sky_env.id != texture_checker().id; + shader_bool( "has_tex_skysphere", has_tex_skysphere ); + shader_bool( "has_tex_skyenv", has_tex_skyenv ); + if( has_tex_skysphere ) { + float mipCount = floor( log2( max(m.sky_refl.w, m.sky_refl.h) ) ); + shader_texture("tex_skysphere", m.sky_refl); + shader_float( "skysphere_mip_count", mipCount ); + } + if( has_tex_skyenv ) { + shader_texture( "tex_skyenv", m.sky_env ); + } + shader_texture( "tex_brdf_lut", brdf_lut() ); + shader_uint( "frame_count", (unsigned)window_frame() ); + shader_bind(old_shader); + } +} +#endif static void model_set_state(model_t m) { if(!m.iqm) return; @@ -386671,6 +386780,7 @@ void model_draw_call(model_t m, int shader) { glUniform4f(loc, m.materials[i].layer[0].map.color.r, m.materials[i].layer[0].map.color.g, m.materials[i].layer[0].map.color.b, m.materials[i].layer[0].map.color.a); } } + } else { const material_t *material = &m.materials[i]; shader_colormap_model_internal( "map_diffuse.color", "map_diffuse.has_tex", "map_diffuse_tex", material->layer[MATERIAL_CHANNEL_DIFFUSE].map ); @@ -386717,59 +386827,104 @@ void model_render(model_t m, mat44 proj, mat44 view, mat44 model, int shader) { static inline void model_init_uniforms(model_t *m) { + for (int i=0; iuniforms[i] = -1; unsigned shader = m->program; - if (glGetUniformLocation(shader, "u_mv") >= 0) - m->uniforms[MODEL_UNIFORM_MV] = glGetUniformLocation(shader, "u_mv"); + int loc; + if ((loc = glGetUniformLocation(shader, "u_mv")) >= 0) + m->uniforms[MODEL_UNIFORM_MV] = loc; else - m->uniforms[MODEL_UNIFORM_MV] = glGetUniformLocation(shader, "MV"); - if (glGetUniformLocation(shader, "u_mvp") >= 0) - m->uniforms[MODEL_UNIFORM_MVP] = glGetUniformLocation(shader, "u_mvp"); + if ((loc = glGetUniformLocation(shader, "MV")) >= 0) + m->uniforms[MODEL_UNIFORM_MV] = loc; + + if ((loc = glGetUniformLocation(shader, "u_mvp")) >= 0) + m->uniforms[MODEL_UNIFORM_MVP] = loc; else - m->uniforms[MODEL_UNIFORM_MVP] = glGetUniformLocation(shader, "MVP"); - if (glGetUniformLocation(shader, "u_vp") >= 0) - m->uniforms[MODEL_UNIFORM_VP] = glGetUniformLocation(shader, "u_vp"); + if ((loc = glGetUniformLocation(shader, "MVP")) >= 0) + m->uniforms[MODEL_UNIFORM_MVP] = loc; + + if ((loc = glGetUniformLocation(shader, "u_vp")) >= 0) + m->uniforms[MODEL_UNIFORM_VP] = loc; else - m->uniforms[MODEL_UNIFORM_VP] = glGetUniformLocation(shader, "VP"); - if (glGetUniformLocation(shader, "u_cam_pos") >= 0) - m->uniforms[MODEL_UNIFORM_CAM_POS] = glGetUniformLocation(shader, "u_cam_pos"); + if ((loc = glGetUniformLocation(shader, "VP")) >= 0) + m->uniforms[MODEL_UNIFORM_VP] = loc; + + if ((loc = glGetUniformLocation(shader, "u_cam_pos")) >= 0) + m->uniforms[MODEL_UNIFORM_CAM_POS] = loc; else - m->uniforms[MODEL_UNIFORM_CAM_POS] = glGetUniformLocation(shader, "cam_pos"); - if (glGetUniformLocation(shader, "u_cam_dir") >= 0) - m->uniforms[MODEL_UNIFORM_CAM_DIR] = glGetUniformLocation(shader, "u_cam_dir"); + if ((loc = glGetUniformLocation(shader, "cam_pos")) >= 0) + m->uniforms[MODEL_UNIFORM_CAM_POS] = loc; + + if ((loc = glGetUniformLocation(shader, "u_cam_dir")) >= 0) + m->uniforms[MODEL_UNIFORM_CAM_DIR] = loc; else - m->uniforms[MODEL_UNIFORM_CAM_DIR] = glGetUniformLocation(shader, "cam_dir"); - if (glGetUniformLocation(shader, "u_billboard") >= 0) - m->uniforms[MODEL_UNIFORM_BILLBOARD] = glGetUniformLocation(shader, "u_billboard"); + if ((loc = glGetUniformLocation(shader, "cam_dir")) >= 0) + m->uniforms[MODEL_UNIFORM_CAM_DIR] = loc; + + if ((loc = glGetUniformLocation(shader, "u_billboard")) >= 0) + m->uniforms[MODEL_UNIFORM_BILLBOARD] = loc; else - m->uniforms[MODEL_UNIFORM_BILLBOARD] = glGetUniformLocation(shader, "billboard"); - if (glGetUniformLocation(shader, "u_texlit") >= 0) - m->uniforms[MODEL_UNIFORM_TEXLIT] = glGetUniformLocation(shader, "u_texlit"); + if ((loc = glGetUniformLocation(shader, "billboard")) >= 0) + m->uniforms[MODEL_UNIFORM_BILLBOARD] = loc; + + if ((loc = glGetUniformLocation(shader, "u_texlit")) >= 0) + m->uniforms[MODEL_UNIFORM_TEXLIT] = loc; else - m->uniforms[MODEL_UNIFORM_TEXLIT] = glGetUniformLocation(shader, "texlit"); - if (glGetUniformLocation(shader, "M") >= 0) - m->uniforms[MODEL_UNIFORM_MODEL] = glGetUniformLocation(shader, "M"); + if ((loc = glGetUniformLocation(shader, "texlit")) >= 0) + m->uniforms[MODEL_UNIFORM_TEXLIT] = loc; + + if ((loc = glGetUniformLocation(shader, "M")) >= 0) + m->uniforms[MODEL_UNIFORM_MODEL] = loc; else - m->uniforms[MODEL_UNIFORM_MODEL] = glGetUniformLocation(shader, "model"); - if (glGetUniformLocation(shader, "V") >= 0) - m->uniforms[MODEL_UNIFORM_VIEW] = glGetUniformLocation(shader, "V"); + if ((loc = glGetUniformLocation(shader, "model")) >= 0) + m->uniforms[MODEL_UNIFORM_MODEL] = loc; + + if ((loc = glGetUniformLocation(shader, "V")) >= 0) + m->uniforms[MODEL_UNIFORM_VIEW] = loc; else - m->uniforms[MODEL_UNIFORM_VIEW] = glGetUniformLocation(shader, "view"); - m->uniforms[MODEL_UNIFORM_INV_VIEW] = glGetUniformLocation(shader, "inv_view"); - if (glGetUniformLocation(shader, "P") >= 0) - m->uniforms[MODEL_UNIFORM_PROJ] = glGetUniformLocation(shader, "P"); + if ((loc = glGetUniformLocation(shader, "view")) >= 0) + m->uniforms[MODEL_UNIFORM_VIEW] = loc; + + if ((loc = glGetUniformLocation(shader, "inv_view")) >= 0) + m->uniforms[MODEL_UNIFORM_INV_VIEW] = loc; + + if ((loc = glGetUniformLocation(shader, "P")) >= 0) + m->uniforms[MODEL_UNIFORM_PROJ] = loc; else - m->uniforms[MODEL_UNIFORM_PROJ] = glGetUniformLocation(shader, "proj"); - m->uniforms[MODEL_UNIFORM_SKINNED] = glGetUniformLocation(shader, "SKINNED"); - m->uniforms[MODEL_UNIFORM_VS_BONE_MATRIX] = glGetUniformLocation(shader, "vsBoneMatrix"); - m->uniforms[MODEL_UNIFORM_U_MATCAPS] = glGetUniformLocation(shader, "u_matcaps"); - m->uniforms[MODEL_UNIFORM_HAS_TEX_SKYSPHERE] = glGetUniformLocation(shader, "has_tex_skysphere"); - m->uniforms[MODEL_UNIFORM_HAS_TEX_SKYENV] = glGetUniformLocation(shader, "has_tex_skyenv"); - m->uniforms[MODEL_UNIFORM_TEX_SKYSPHERE] = glGetUniformLocation(shader, "tex_skysphere"); - m->uniforms[MODEL_UNIFORM_SKYSPHERE_MIP_COUNT] = glGetUniformLocation(shader, "skysphere_mip_count"); - m->uniforms[MODEL_UNIFORM_TEX_SKYENV] = glGetUniformLocation(shader, "tex_skyenv"); - m->uniforms[MODEL_UNIFORM_TEX_BRDF_LUT] = glGetUniformLocation(shader, "tex_brdf_lut"); - m->uniforms[MODEL_UNIFORM_FRAME_COUNT] = glGetUniformLocation(shader, "frame_count"); - m->uniforms[MODEL_UNIFORM_RESOLUTION] = glGetUniformLocation(shader, "resolution"); + if ((loc = glGetUniformLocation(shader, "proj")) >= 0) + m->uniforms[MODEL_UNIFORM_PROJ] = loc; + + if ((loc = glGetUniformLocation(shader, "SKINNED")) >= 0) + m->uniforms[MODEL_UNIFORM_SKINNED] = loc; + + if ((loc = glGetUniformLocation(shader, "vsBoneMatrix")) >= 0) + m->uniforms[MODEL_UNIFORM_VS_BONE_MATRIX] = loc; + + if ((loc = glGetUniformLocation(shader, "u_matcaps")) >= 0) + m->uniforms[MODEL_UNIFORM_U_MATCAPS] = loc; + + if ((loc = glGetUniformLocation(shader, "has_tex_skysphere")) >= 0) + m->uniforms[MODEL_UNIFORM_HAS_TEX_SKYSPHERE] = loc; + + if ((loc = glGetUniformLocation(shader, "has_tex_skyenv")) >= 0) + m->uniforms[MODEL_UNIFORM_HAS_TEX_SKYENV] = loc; + + if ((loc = glGetUniformLocation(shader, "tex_skysphere")) >= 0) + m->uniforms[MODEL_UNIFORM_TEX_SKYSPHERE] = loc; + + if ((loc = glGetUniformLocation(shader, "skysphere_mip_count")) >= 0) + m->uniforms[MODEL_UNIFORM_SKYSPHERE_MIP_COUNT] = loc; + + if ((loc = glGetUniformLocation(shader, "tex_skyenv")) >= 0) + m->uniforms[MODEL_UNIFORM_TEX_SKYENV] = loc; + + if ((loc = glGetUniformLocation(shader, "tex_brdf_lut")) >= 0) + m->uniforms[MODEL_UNIFORM_TEX_BRDF_LUT] = loc; + + if ((loc = glGetUniformLocation(shader, "frame_count")) >= 0) + m->uniforms[MODEL_UNIFORM_FRAME_COUNT] = loc; + + if ((loc = glGetUniformLocation(shader, "resolution")) >= 0) + m->uniforms[MODEL_UNIFORM_RESOLUTION] = loc; } void model_shading(model_t *m, int shading) { @@ -386785,7 +386940,7 @@ void model_shading(model_t *m, int shading) { // rebind shader // @fixme: app crashes rn - // shader_bind(0); + // glUseProgram(0); // glDeleteProgram(m->program); const char *symbols[] = { "{{include-shadowmap}}", vfs_read("shaders/fs_0_0_shadowmap_lit.glsl") }; // #define RIM int shaderprog = shader(strlerp(1,symbols,vfs_read("shaders/vs_323444143_16_3322_model.glsl")), strlerp(1,symbols,vfs_read("shaders/fs_32_4_model.glsl")), //fs, @@ -388503,6 +388658,8 @@ void scene_render(int flags) { model->billboard = obj->billboard; + model->rs[RENDER_PASS_NORMAL].cull_face_enabled = flags&SCENE_CULLFACE ? 1 : 0; + model->rs[RENDER_PASS_NORMAL].polygon_mode_mode = flags&SCENE_WIREFRAME ? GL_LINE : GL_FILL; model_render(*model, cam->proj, cam->view, obj->transform, model->program); if( do_retexturing ) { diff --git a/engine/split/v4k_font.c b/engine/split/v4k_font.c index 15d271f..79b81c6 100644 --- a/engine/split/v4k_font.c +++ b/engine/split/v4k_font.c @@ -1886,7 +1886,7 @@ void font_face_from_mem(const char *tag, const void *ttf_data, unsigned ttf_len, glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT); // upload constant uniforms - shader_bind(f->program); + glUseProgram(f->program); glUniform1i(glGetUniformLocation(f->program, "sampler_font"), 0); glUniform1i(glGetUniformLocation(f->program, "sampler_meta"), 1); glUniform1i(glGetUniformLocation(f->program, "sampler_colors"), 2); @@ -1948,7 +1948,7 @@ void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float fact glBindVertexArray(f->vao); // update uniforms - shader_bind(f->program); + glUseProgram(f->program); glUniform1f(glGetUniformLocation(f->program, "scale_factor"), factor); glUniform2fv(glGetUniformLocation(f->program, "string_offset"), 1, &offset.x); glUniform1f(glGetUniformLocation(f->program, "offset_firstline"), f->ascent*f->factor); @@ -1968,7 +1968,7 @@ void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float fact glDrawArraysInstanced(GL_TRIANGLES, 0, 6, glyph_idx); // Restore modified GL state - shader_bind(last_program); + glUseProgram(last_program); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, last_texture0); diff --git a/engine/split/v4k_gui.c b/engine/split/v4k_gui.c index 2a2915d..8cc9ad1 100644 --- a/engine/split/v4k_gui.c +++ b/engine/split/v4k_gui.c @@ -39,7 +39,7 @@ void gui_drawrect( texture_t texture, vec2 tex_start, vec2 tex_end, int rgba, ve renderstate_apply(&rect_rs); GLenum texture_type = texture.flags & TEXTURE_ARRAY ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D; - shader_bind( program ); + glUseProgram( program ); glBindVertexArray( vao ); @@ -88,7 +88,7 @@ void gui_drawrect( texture_t texture, vec2 tex_start, vec2 tex_end, int rgba, ve glDisableVertexAttribArray(1); glBindVertexArray( 0 ); glBindBuffer(GL_ARRAY_BUFFER, 0); - shader_bind( 0 ); + glUseProgram( 0 ); } // ---------------------------------------------------------------------------- diff --git a/engine/split/v4k_render.c b/engine/split/v4k_render.c index d76835e..797506b 100644 --- a/engine/split/v4k_render.c +++ b/engine/split/v4k_render.c @@ -427,14 +427,14 @@ void shader_apply_param(unsigned shader, unsigned param_no) { if( strchr("ibfv", type[0]) ) { GLint shader_bak; glGetIntegerv(GL_CURRENT_PROGRAM, &shader_bak); - shader_bind(shader); + glUseProgram(shader); /**/ if(type[0] == 'i') glUniform1i(glGetUniformLocation(shader, name), setv.x); else if(type[0] == 'b') glUniform1i(glGetUniformLocation(shader, name), !!setv.x); else if(type[0] == 'f') glUniform1f(glGetUniformLocation(shader, name), setv.x); else if(type[3] == '2') glUniform2fv(glGetUniformLocation(shader, name), 1, &setv.x); else if(type[3] == '3') glUniform3fv(glGetUniformLocation(shader, name), 1, &setv.x); else if(type[3] == '4') glUniform4fv(glGetUniformLocation(shader, name), 1, &setv.x); - shader_bind(shader_bak); + glUseProgram(shader_bak); } } } @@ -668,57 +668,35 @@ void ssbo_unbind(){ glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); } -typedef map(unsigned,int) uniform_binding; static __thread unsigned last_shader = -1; -static __thread quarks_db uniform_names; -static __thread map(handle, uniform_binding) uniforms; int shader_uniform(const char *name) { -#if 0 - do_once map_init(uniforms, less_int, hash_int); - if (!map_find(uniforms, last_shader)) { - uniform_binding names_map = 0; - map_init(names_map, less_int, hash_int); - map_insert(uniforms, last_shader, names_map); - } - - uniform_binding names = *map_find(uniforms, last_shader); - unsigned name_hash = quark_intern(&uniform_names, name); - if (!map_find(names, name_hash)) { - map_insert(names, name_hash, glGetUniformLocation(last_shader, name)); - } - - // int ret = glGetUniformLocation(last_shader, name); - // if( ret < 0 ) PRINTF("!cannot find uniform '%s' in shader program %d\n", name, (int)last_shader ); - return *map_find(names, name_hash); -#else return glGetUniformLocation(last_shader, name); -#endif } unsigned shader_get_active() { return last_shader; } -unsigned shader_bind(unsigned program) { if (program == last_shader) return last_shader; unsigned ret = last_shader; return glUseProgram(last_shader = program), ret; } -static inline void shader_int_(unsigned uniform, int i) { glUniform1i(uniform, i); } -static inline void shader_float_(unsigned uniform, float f) { glUniform1f(uniform, f); } -static inline void shader_vec2_(unsigned uniform, vec2 v) { glUniform2fv(uniform, 1, &v.x); } -static inline void shader_vec3_(unsigned uniform, vec3 v) { glUniform3fv(uniform, 1, &v.x); } -static inline void shader_vec3v_(unsigned uniform, int count, vec3 *v) { glUniform3fv(uniform, count, &v[0].x); } -static inline void shader_vec4_(unsigned uniform, vec4 v) { glUniform4fv(uniform, 1, &v.x); } -static inline void shader_mat44_(unsigned uniform, mat44 m) { glUniformMatrix4fv(uniform, 1, GL_FALSE/*GL_TRUE*/, m); } -static inline void shader_cubemap_(unsigned sampler, unsigned texture) { +unsigned shader_bind(unsigned program) { unsigned ret = last_shader; return glUseProgram(last_shader = program), ret; } +static inline void shader_int_(int uniform, int i) { glUniform1i(uniform, i); } +static inline void shader_float_(int uniform, float f) { glUniform1f(uniform, f); } +static inline void shader_vec2_(int uniform, vec2 v) { glUniform2fv(uniform, 1, &v.x); } +static inline void shader_vec3_(int uniform, vec3 v) { glUniform3fv(uniform, 1, &v.x); } +static inline void shader_vec3v_(int uniform, int count, vec3 *v) { glUniform3fv(uniform, count, &v[0].x); } +static inline void shader_vec4_(int uniform, vec4 v) { glUniform4fv(uniform, 1, &v.x); } +static inline void shader_mat44_(int uniform, mat44 m) { glUniformMatrix4fv(uniform, 1, GL_FALSE/*GL_TRUE*/, m); } +static inline void shader_cubemap_(int sampler, unsigned texture) { int id = texture_unit(); glUniform1i(sampler, id); glActiveTexture(GL_TEXTURE0 + id); glBindTexture(GL_TEXTURE_CUBE_MAP, texture); } -static inline void shader_bool_(unsigned uniform, bool x) { glUniform1i(uniform, x); } -static inline void shader_uint_(unsigned uniform, unsigned x ) { glUniform1ui(uniform, x); } -static inline void shader_texture_unit_(unsigned sampler, unsigned id, unsigned unit) { +static inline void shader_bool_(int uniform, bool x) { glUniform1i(uniform, x); } +static inline void shader_uint_(int uniform, unsigned x ) { glUniform1ui(uniform, x); } +static inline void shader_texture_unit_(int sampler, unsigned id, unsigned unit) { // @todo. if tex.h == 1 ? GL_TEXTURE_1D : GL_TEXTURE_2D glUniform1i(sampler, unit); glActiveTexture(GL_TEXTURE0 + unit); glBindTexture(GL_TEXTURE_2D, id); } -static inline void shader_texture_(unsigned sampler, texture_t t) { shader_texture_unit_(sampler, t.id, texture_unit()); } +static inline void shader_texture_(int sampler, texture_t t) { shader_texture_unit_(sampler, t.id, texture_unit()); } // public api void shader_int(const char *uniform, int i) { glUniform1i(shader_uniform(uniform), i); } @@ -1534,7 +1512,7 @@ void fullscreen_quad_rgb( texture_t texture ) { GLenum texture_type = texture.flags & TEXTURE_ARRAY ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D; renderstate_apply(&fullscreen_quad_rs); - shader_bind( program ); + glUseProgram( program ); float gamma = 1; glUniform1f( u_inv_gamma, gamma ); @@ -1549,7 +1527,7 @@ void fullscreen_quad_rgb( texture_t texture ) { glBindTexture( texture_type, 0 ); glBindVertexArray( 0 ); - shader_bind( 0 ); + glUseProgram( 0 ); // glDisable( GL_BLEND ); } @@ -1567,7 +1545,7 @@ void fullscreen_quad_rgb_flipped( texture_t texture ) { GLenum texture_type = texture.flags & TEXTURE_ARRAY ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D; renderstate_apply(&fullscreen_quad_rs); - shader_bind( program ); + glUseProgram( program ); float gamma = 1; glUniform1f( u_inv_gamma, gamma ); @@ -1582,7 +1560,7 @@ void fullscreen_quad_rgb_flipped( texture_t texture ) { glBindTexture( texture_type, 0 ); glBindVertexArray( 0 ); - shader_bind( 0 ); + glUseProgram( 0 ); // glDisable( GL_BLEND ); } @@ -1604,7 +1582,7 @@ void fullscreen_quad_ycbcr( texture_t textureYCbCr[3] ) { } renderstate_apply(&fullscreen_quad_rs); - shader_bind( program ); + glUseProgram( program ); // glUniform1f( u_gamma, gamma ); glBindVertexArray( vao ); @@ -1627,7 +1605,7 @@ void fullscreen_quad_ycbcr( texture_t textureYCbCr[3] ) { glBindTexture( GL_TEXTURE_2D, 0 ); glBindVertexArray( 0 ); - shader_bind( 0 ); + glUseProgram( 0 ); // glDisable( GL_BLEND ); } @@ -1649,7 +1627,7 @@ void fullscreen_quad_ycbcr_flipped( texture_t textureYCbCr[3] ) { } renderstate_apply(&fullscreen_quad_rs); - shader_bind( program ); + glUseProgram( program ); // glUniform1f( u_gamma, gamma ); glBindVertexArray( vao ); @@ -1672,7 +1650,7 @@ void fullscreen_quad_ycbcr_flipped( texture_t textureYCbCr[3] ) { glBindTexture( GL_TEXTURE_2D, 0 ); glBindVertexArray( 0 ); - shader_bind( 0 ); + glUseProgram( 0 ); // glDisable( GL_BLEND ); } @@ -1977,7 +1955,7 @@ void skybox_mie_calc_sh(skybox_t *sky, float sky_intensity) { for(int i = 0; i < 6; ++i) { glBindFramebuffer(GL_FRAMEBUFFER, sky->framebuffers[i]); glViewport(0, 0, WIDTH, HEIGHT); - shader_bind(sky->program); + glUseProgram(sky->program); mat44 proj; perspective44(proj, 90.0f, WIDTH / (float)HEIGHT, 0.1f, 500.f); mat44 view; lookat44(view, vec3(0,0,0), directions[i], vec3(0,-1,0)); @@ -2528,7 +2506,7 @@ int postfx_load_from_mem( postfx *fx, const char *name, const char *fs ) { p->program = shader(vs, fs2, "vtexcoord", "fragColor" , NULL); - shader_bind(p->program); // needed? + glUseProgram(p->program); // needed? for( int i = 0; i < countof(p->uniforms); ++i ) p->uniforms[i] = -1; @@ -2692,7 +2670,7 @@ bool postfx_end(postfx *fx) { passfx *pass = &fx->pass[i]; if( pass->enabled ) { if( !pass->program ) { --num_active_passes; continue; } - shader_bind(pass->program); + glUseProgram(pass->program); // bind texture to texture unit 0 // shader_texture_unit(fx->diffuse[frame], 0); @@ -2731,7 +2709,7 @@ bool postfx_end(postfx *fx) { if (bound) fbo_unbind(); } } - shader_bind(0); + glUseProgram(0); // restore clear color: needed in case transparent window is being used (alpha != 0) glClearColor(0,0,0,1); // @transparent @@ -2842,7 +2820,7 @@ static void brdf_load() { glDisable(GL_BLEND); handle old_shader = last_shader; - shader_bind( program ); + glUseProgram( program ); glViewport(0, 0, 512, 512); @@ -2856,7 +2834,7 @@ static void brdf_load() { glBindVertexArray( 0 ); - shader_bind( last_shader ); + glUseProgram( last_shader ); fbo_unbind(); fbo_destroy(lut_fbo); @@ -2978,7 +2956,7 @@ shadertoy_t* shadertoy_render(shadertoy_t *s, float delta) { struct tm *tm = localtime(&tmsec); s->t += delta * 1000; - shader_bind(s->program); + glUseProgram(s->program); glUniform1f(s->uniforms[iGlobalTime], s->t / 1000.f ); glUniform1f(s->uniforms[iGlobalFrame], s->frame++); glUniform1f(s->uniforms[iGlobalDelta], delta / 1000.f ); @@ -3148,6 +3126,8 @@ void model_set_texture(model_t m, texture_t t) { } } +//@fixme: some locations are invalid, find out why +#if 0 static void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view, mat44 model) { // @todo: cache uniform locs if(!m.iqm) return; @@ -3179,7 +3159,7 @@ void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view, shader_int_(loc, m.billboard); } if( (loc = m.uniforms[MODEL_UNIFORM_TEXLIT]) >= 0 ) { - shader_int_(loc, (m.lightmap.w != 0)); + shader_bool_(loc, (m.lightmap.w != 0)); } if ((loc = m.uniforms[MODEL_UNIFORM_MODEL]) >= 0) { shader_mat44_(loc, model); @@ -3199,7 +3179,7 @@ void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view, if( q->numanims ) if( (loc = m.uniforms[MODEL_UNIFORM_VS_BONE_MATRIX]) >= 0 ) glUniformMatrix3x4fv( loc, q->numjoints, GL_FALSE, q->outframe[0]); if ((loc = m.uniforms[MODEL_UNIFORM_U_MATCAPS]) >= 0) { - shader_int_(loc, m.flags & MODEL_MATCAPS ? GL_TRUE:GL_FALSE); + shader_bool_(loc, m.flags & MODEL_MATCAPS ? GL_TRUE:GL_FALSE); } if (m.shading == SHADING_PBR) { @@ -3224,6 +3204,132 @@ void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view, shader_bind(old_shader); } } +#else +static +void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view, mat44 model) { // @todo: cache uniform locs + if(!m.iqm) return; + iqm_t *q = m.iqm; + + shader_bind(shader); + int loc; + //if( (loc = glGetUniformLocation(shader, "M")) >= 0 ) glUniformMatrix4fv( loc, 1, GL_FALSE/*GL_TRUE*/, m); // RIM + if( (loc = glGetUniformLocation(shader, "MV")) >= 0 ) { + glUniformMatrix4fv( loc, 1, GL_FALSE, mv); + } + else + if( (loc = glGetUniformLocation(shader, "u_mv")) >= 0 ) { + glUniformMatrix4fv( loc, 1, GL_FALSE, mv); + } + if( (loc = glGetUniformLocation(shader, "MVP")) >= 0 ) { + mat44 mvp; multiply44x2(mvp, proj, mv); // multiply44x3(mvp, proj, view, model); + glUniformMatrix4fv( loc, 1, GL_FALSE, mvp); + } + else + if( (loc = glGetUniformLocation(shader, "u_mvp")) >= 0 ) { + mat44 mvp; multiply44x2(mvp, proj, mv); // multiply44x3(mvp, proj, view, model); + glUniformMatrix4fv( loc, 1, GL_FALSE, mvp); + } + if( (loc = glGetUniformLocation(shader, "VP")) >= 0 ) { + mat44 vp; multiply44x2(vp, proj, view); + glUniformMatrix4fv( loc, 1, GL_FALSE, vp); + } + else + if( (loc = glGetUniformLocation(shader, "u_vp")) >= 0 ) { + mat44 vp; multiply44x2(vp, proj, view); + glUniformMatrix4fv( loc, 1, GL_FALSE, vp); + } + if( (loc = glGetUniformLocation(shader, "u_cam_pos")) >= 0 ) { + vec3 pos = vec3(view[12], view[13], view[14]); + glUniform3fv( loc, 1, &pos.x ); + } + else + if( (loc = glGetUniformLocation(shader, "cam_pos")) >= 0 ) { + vec3 pos = vec3(view[12], view[13], view[14]); + glUniform3fv( loc, 1, &pos.x ); + } + if( (loc = glGetUniformLocation(shader, "u_cam_dir")) >= 0 ) { + vec3 dir = norm3(vec3(view[2], view[6], view[10])); + glUniform3fv( loc, 1, &dir.x ); + } + else + if( (loc = glGetUniformLocation(shader, "cam_dir")) >= 0 ) { + 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( (loc = glGetUniformLocation(shader, "texlit")) >= 0 ) { + glUniform1i( loc, (m.lightmap.w != 0) ); + } + else + if( (loc = glGetUniformLocation(shader, "u_texlit")) >= 0 ) { + glUniform1i( loc, (m.lightmap.w != 0) ); + } +#if 0 + // @todo: mat44 projview (useful?) +#endif + if ((loc = glGetUniformLocation(shader, "M")) >= 0) { + glUniformMatrix4fv(loc, 1, GL_FALSE, model); + } + else + if ((loc = glGetUniformLocation(shader, "model")) >= 0) { + glUniformMatrix4fv(loc, 1, GL_FALSE, model); + } + if ((loc = glGetUniformLocation(shader, "V")) >= 0) { + glUniformMatrix4fv(loc, 1, GL_FALSE, view); + } + else + if ((loc = glGetUniformLocation(shader, "view")) >= 0) { + glUniformMatrix4fv(loc, 1, GL_FALSE, view); + } + if ((loc = glGetUniformLocation(shader, "inv_view")) >= 0) { + mat44 inv_view; + invert44( inv_view, view); + glUniformMatrix4fv(loc, 1, GL_FALSE, inv_view); + } + if ((loc = glGetUniformLocation(shader, "P")) >= 0) { + glUniformMatrix4fv(loc, 1, GL_FALSE, proj); + } + else + if ((loc = glGetUniformLocation(shader, "proj")) >= 0) { + glUniformMatrix4fv(loc, 1, GL_FALSE, proj); + } + if( (loc = glGetUniformLocation(shader, "SKINNED")) >= 0 ) glUniform1i( loc, q->numanims ? GL_TRUE : GL_FALSE); + if( q->numanims ) + if( (loc = glGetUniformLocation(shader, "vsBoneMatrix")) >= 0 ) glUniformMatrix3x4fv( loc, q->numjoints, GL_FALSE, q->outframe[0]); + + if ((loc = glGetUniformLocation(shader, "u_matcaps")) >= 0) { + glUniform1i(loc, m.flags & MODEL_MATCAPS ? GL_TRUE:GL_FALSE); + } + + if (m.shading == SHADING_PBR) { + handle old_shader = last_shader; + shader_bind(shader); + shader_vec2( "resolution", vec2(window_width(),window_height())); + + bool has_tex_skysphere = m.sky_refl.id != texture_checker().id; + bool has_tex_skyenv = m.sky_env.id != texture_checker().id; + shader_bool( "has_tex_skysphere", has_tex_skysphere ); + shader_bool( "has_tex_skyenv", has_tex_skyenv ); + if( has_tex_skysphere ) { + float mipCount = floor( log2( max(m.sky_refl.w, m.sky_refl.h) ) ); + shader_texture("tex_skysphere", m.sky_refl); + shader_float( "skysphere_mip_count", mipCount ); + } + if( has_tex_skyenv ) { + shader_texture( "tex_skyenv", m.sky_env ); + } + shader_texture( "tex_brdf_lut", brdf_lut() ); + shader_uint( "frame_count", (unsigned)window_frame() ); + shader_bind(old_shader); + } +} +#endif static void model_set_state(model_t m) { if(!m.iqm) return; @@ -4037,6 +4143,7 @@ void model_draw_call(model_t m, int shader) { glUniform4f(loc, m.materials[i].layer[0].map.color.r, m.materials[i].layer[0].map.color.g, m.materials[i].layer[0].map.color.b, m.materials[i].layer[0].map.color.a); } } + } else { const material_t *material = &m.materials[i]; shader_colormap_model_internal( "map_diffuse.color", "map_diffuse.has_tex", "map_diffuse_tex", material->layer[MATERIAL_CHANNEL_DIFFUSE].map ); @@ -4083,59 +4190,104 @@ void model_render(model_t m, mat44 proj, mat44 view, mat44 model, int shader) { static inline void model_init_uniforms(model_t *m) { + for (int i=0; iuniforms[i] = -1; unsigned shader = m->program; - if (glGetUniformLocation(shader, "u_mv") >= 0) - m->uniforms[MODEL_UNIFORM_MV] = glGetUniformLocation(shader, "u_mv"); + int loc; + if ((loc = glGetUniformLocation(shader, "u_mv")) >= 0) + m->uniforms[MODEL_UNIFORM_MV] = loc; else - m->uniforms[MODEL_UNIFORM_MV] = glGetUniformLocation(shader, "MV"); - if (glGetUniformLocation(shader, "u_mvp") >= 0) - m->uniforms[MODEL_UNIFORM_MVP] = glGetUniformLocation(shader, "u_mvp"); + if ((loc = glGetUniformLocation(shader, "MV")) >= 0) + m->uniforms[MODEL_UNIFORM_MV] = loc; + + if ((loc = glGetUniformLocation(shader, "u_mvp")) >= 0) + m->uniforms[MODEL_UNIFORM_MVP] = loc; else - m->uniforms[MODEL_UNIFORM_MVP] = glGetUniformLocation(shader, "MVP"); - if (glGetUniformLocation(shader, "u_vp") >= 0) - m->uniforms[MODEL_UNIFORM_VP] = glGetUniformLocation(shader, "u_vp"); + if ((loc = glGetUniformLocation(shader, "MVP")) >= 0) + m->uniforms[MODEL_UNIFORM_MVP] = loc; + + if ((loc = glGetUniformLocation(shader, "u_vp")) >= 0) + m->uniforms[MODEL_UNIFORM_VP] = loc; else - m->uniforms[MODEL_UNIFORM_VP] = glGetUniformLocation(shader, "VP"); - if (glGetUniformLocation(shader, "u_cam_pos") >= 0) - m->uniforms[MODEL_UNIFORM_CAM_POS] = glGetUniformLocation(shader, "u_cam_pos"); + if ((loc = glGetUniformLocation(shader, "VP")) >= 0) + m->uniforms[MODEL_UNIFORM_VP] = loc; + + if ((loc = glGetUniformLocation(shader, "u_cam_pos")) >= 0) + m->uniforms[MODEL_UNIFORM_CAM_POS] = loc; else - m->uniforms[MODEL_UNIFORM_CAM_POS] = glGetUniformLocation(shader, "cam_pos"); - if (glGetUniformLocation(shader, "u_cam_dir") >= 0) - m->uniforms[MODEL_UNIFORM_CAM_DIR] = glGetUniformLocation(shader, "u_cam_dir"); + if ((loc = glGetUniformLocation(shader, "cam_pos")) >= 0) + m->uniforms[MODEL_UNIFORM_CAM_POS] = loc; + + if ((loc = glGetUniformLocation(shader, "u_cam_dir")) >= 0) + m->uniforms[MODEL_UNIFORM_CAM_DIR] = loc; else - m->uniforms[MODEL_UNIFORM_CAM_DIR] = glGetUniformLocation(shader, "cam_dir"); - if (glGetUniformLocation(shader, "u_billboard") >= 0) - m->uniforms[MODEL_UNIFORM_BILLBOARD] = glGetUniformLocation(shader, "u_billboard"); + if ((loc = glGetUniformLocation(shader, "cam_dir")) >= 0) + m->uniforms[MODEL_UNIFORM_CAM_DIR] = loc; + + if ((loc = glGetUniformLocation(shader, "u_billboard")) >= 0) + m->uniforms[MODEL_UNIFORM_BILLBOARD] = loc; else - m->uniforms[MODEL_UNIFORM_BILLBOARD] = glGetUniformLocation(shader, "billboard"); - if (glGetUniformLocation(shader, "u_texlit") >= 0) - m->uniforms[MODEL_UNIFORM_TEXLIT] = glGetUniformLocation(shader, "u_texlit"); + if ((loc = glGetUniformLocation(shader, "billboard")) >= 0) + m->uniforms[MODEL_UNIFORM_BILLBOARD] = loc; + + if ((loc = glGetUniformLocation(shader, "u_texlit")) >= 0) + m->uniforms[MODEL_UNIFORM_TEXLIT] = loc; else - m->uniforms[MODEL_UNIFORM_TEXLIT] = glGetUniformLocation(shader, "texlit"); - if (glGetUniformLocation(shader, "M") >= 0) - m->uniforms[MODEL_UNIFORM_MODEL] = glGetUniformLocation(shader, "M"); + if ((loc = glGetUniformLocation(shader, "texlit")) >= 0) + m->uniforms[MODEL_UNIFORM_TEXLIT] = loc; + + if ((loc = glGetUniformLocation(shader, "M")) >= 0) + m->uniforms[MODEL_UNIFORM_MODEL] = loc; else - m->uniforms[MODEL_UNIFORM_MODEL] = glGetUniformLocation(shader, "model"); - if (glGetUniformLocation(shader, "V") >= 0) - m->uniforms[MODEL_UNIFORM_VIEW] = glGetUniformLocation(shader, "V"); + if ((loc = glGetUniformLocation(shader, "model")) >= 0) + m->uniforms[MODEL_UNIFORM_MODEL] = loc; + + if ((loc = glGetUniformLocation(shader, "V")) >= 0) + m->uniforms[MODEL_UNIFORM_VIEW] = loc; else - m->uniforms[MODEL_UNIFORM_VIEW] = glGetUniformLocation(shader, "view"); - m->uniforms[MODEL_UNIFORM_INV_VIEW] = glGetUniformLocation(shader, "inv_view"); - if (glGetUniformLocation(shader, "P") >= 0) - m->uniforms[MODEL_UNIFORM_PROJ] = glGetUniformLocation(shader, "P"); + if ((loc = glGetUniformLocation(shader, "view")) >= 0) + m->uniforms[MODEL_UNIFORM_VIEW] = loc; + + if ((loc = glGetUniformLocation(shader, "inv_view")) >= 0) + m->uniforms[MODEL_UNIFORM_INV_VIEW] = loc; + + if ((loc = glGetUniformLocation(shader, "P")) >= 0) + m->uniforms[MODEL_UNIFORM_PROJ] = loc; else - m->uniforms[MODEL_UNIFORM_PROJ] = glGetUniformLocation(shader, "proj"); - m->uniforms[MODEL_UNIFORM_SKINNED] = glGetUniformLocation(shader, "SKINNED"); - m->uniforms[MODEL_UNIFORM_VS_BONE_MATRIX] = glGetUniformLocation(shader, "vsBoneMatrix"); - m->uniforms[MODEL_UNIFORM_U_MATCAPS] = glGetUniformLocation(shader, "u_matcaps"); - m->uniforms[MODEL_UNIFORM_HAS_TEX_SKYSPHERE] = glGetUniformLocation(shader, "has_tex_skysphere"); - m->uniforms[MODEL_UNIFORM_HAS_TEX_SKYENV] = glGetUniformLocation(shader, "has_tex_skyenv"); - m->uniforms[MODEL_UNIFORM_TEX_SKYSPHERE] = glGetUniformLocation(shader, "tex_skysphere"); - m->uniforms[MODEL_UNIFORM_SKYSPHERE_MIP_COUNT] = glGetUniformLocation(shader, "skysphere_mip_count"); - m->uniforms[MODEL_UNIFORM_TEX_SKYENV] = glGetUniformLocation(shader, "tex_skyenv"); - m->uniforms[MODEL_UNIFORM_TEX_BRDF_LUT] = glGetUniformLocation(shader, "tex_brdf_lut"); - m->uniforms[MODEL_UNIFORM_FRAME_COUNT] = glGetUniformLocation(shader, "frame_count"); - m->uniforms[MODEL_UNIFORM_RESOLUTION] = glGetUniformLocation(shader, "resolution"); + if ((loc = glGetUniformLocation(shader, "proj")) >= 0) + m->uniforms[MODEL_UNIFORM_PROJ] = loc; + + if ((loc = glGetUniformLocation(shader, "SKINNED")) >= 0) + m->uniforms[MODEL_UNIFORM_SKINNED] = loc; + + if ((loc = glGetUniformLocation(shader, "vsBoneMatrix")) >= 0) + m->uniforms[MODEL_UNIFORM_VS_BONE_MATRIX] = loc; + + if ((loc = glGetUniformLocation(shader, "u_matcaps")) >= 0) + m->uniforms[MODEL_UNIFORM_U_MATCAPS] = loc; + + if ((loc = glGetUniformLocation(shader, "has_tex_skysphere")) >= 0) + m->uniforms[MODEL_UNIFORM_HAS_TEX_SKYSPHERE] = loc; + + if ((loc = glGetUniformLocation(shader, "has_tex_skyenv")) >= 0) + m->uniforms[MODEL_UNIFORM_HAS_TEX_SKYENV] = loc; + + if ((loc = glGetUniformLocation(shader, "tex_skysphere")) >= 0) + m->uniforms[MODEL_UNIFORM_TEX_SKYSPHERE] = loc; + + if ((loc = glGetUniformLocation(shader, "skysphere_mip_count")) >= 0) + m->uniforms[MODEL_UNIFORM_SKYSPHERE_MIP_COUNT] = loc; + + if ((loc = glGetUniformLocation(shader, "tex_skyenv")) >= 0) + m->uniforms[MODEL_UNIFORM_TEX_SKYENV] = loc; + + if ((loc = glGetUniformLocation(shader, "tex_brdf_lut")) >= 0) + m->uniforms[MODEL_UNIFORM_TEX_BRDF_LUT] = loc; + + if ((loc = glGetUniformLocation(shader, "frame_count")) >= 0) + m->uniforms[MODEL_UNIFORM_FRAME_COUNT] = loc; + + if ((loc = glGetUniformLocation(shader, "resolution")) >= 0) + m->uniforms[MODEL_UNIFORM_RESOLUTION] = loc; } void model_shading(model_t *m, int shading) { @@ -4151,7 +4303,7 @@ void model_shading(model_t *m, int shading) { // rebind shader // @fixme: app crashes rn - // shader_bind(0); + // glUseProgram(0); // glDeleteProgram(m->program); const char *symbols[] = { "{{include-shadowmap}}", vfs_read("shaders/fs_0_0_shadowmap_lit.glsl") }; // #define RIM int shaderprog = shader(strlerp(1,symbols,vfs_read("shaders/vs_323444143_16_3322_model.glsl")), strlerp(1,symbols,vfs_read("shaders/fs_32_4_model.glsl")), //fs, diff --git a/engine/split/v4k_render.h b/engine/split/v4k_render.h index aa644cf..a76ab82 100644 --- a/engine/split/v4k_render.h +++ b/engine/split/v4k_render.h @@ -53,6 +53,9 @@ typedef struct renderstate_t { unsigned polygon_mode_face; unsigned polygon_mode_mode; + // Wireframe mode + bool wireframe_enabled; + // Scissor test bool scissor_test_enabled; } renderstate_t; @@ -638,7 +641,7 @@ typedef struct model_t { handle *textures; char **texture_names; array(material_t) materials; - unsigned uniforms[NUM_MODEL_UNIFORMS]; + int uniforms[NUM_MODEL_UNIFORMS]; texture_t sky_refl, sky_env; diff --git a/engine/split/v4k_scene.c b/engine/split/v4k_scene.c index d623b64..341670b 100644 --- a/engine/split/v4k_scene.c +++ b/engine/split/v4k_scene.c @@ -558,6 +558,8 @@ void scene_render(int flags) { model->billboard = obj->billboard; + model->rs[RENDER_PASS_NORMAL].cull_face_enabled = flags&SCENE_CULLFACE ? 1 : 0; + model->rs[RENDER_PASS_NORMAL].polygon_mode_mode = flags&SCENE_WIREFRAME ? GL_LINE : GL_FILL; model_render(*model, cam->proj, cam->view, obj->transform, model->program); if( do_retexturing ) { diff --git a/engine/v4k.c b/engine/v4k.c index 28e3197..8f441e3 100644 --- a/engine/v4k.c +++ b/engine/v4k.c @@ -10591,7 +10591,7 @@ void font_face_from_mem(const char *tag, const void *ttf_data, unsigned ttf_len, glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT); // upload constant uniforms - shader_bind(f->program); + glUseProgram(f->program); glUniform1i(glGetUniformLocation(f->program, "sampler_font"), 0); glUniform1i(glGetUniformLocation(f->program, "sampler_meta"), 1); glUniform1i(glGetUniformLocation(f->program, "sampler_colors"), 2); @@ -10653,7 +10653,7 @@ void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float fact glBindVertexArray(f->vao); // update uniforms - shader_bind(f->program); + glUseProgram(f->program); glUniform1f(glGetUniformLocation(f->program, "scale_factor"), factor); glUniform2fv(glGetUniformLocation(f->program, "string_offset"), 1, &offset.x); glUniform1f(glGetUniformLocation(f->program, "offset_firstline"), f->ascent*f->factor); @@ -10673,7 +10673,7 @@ void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float fact glDrawArraysInstanced(GL_TRIANGLES, 0, 6, glyph_idx); // Restore modified GL state - shader_bind(last_program); + glUseProgram(last_program); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, last_texture0); @@ -11276,7 +11276,7 @@ void gui_drawrect( texture_t texture, vec2 tex_start, vec2 tex_end, int rgba, ve renderstate_apply(&rect_rs); GLenum texture_type = texture.flags & TEXTURE_ARRAY ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D; - shader_bind( program ); + glUseProgram( program ); glBindVertexArray( vao ); @@ -11325,7 +11325,7 @@ void gui_drawrect( texture_t texture, vec2 tex_start, vec2 tex_end, int rgba, ve glDisableVertexAttribArray(1); glBindVertexArray( 0 ); glBindBuffer(GL_ARRAY_BUFFER, 0); - shader_bind( 0 ); + glUseProgram( 0 ); } // ---------------------------------------------------------------------------- @@ -17601,14 +17601,14 @@ void shader_apply_param(unsigned shader, unsigned param_no) { if( strchr("ibfv", type[0]) ) { GLint shader_bak; glGetIntegerv(GL_CURRENT_PROGRAM, &shader_bak); - shader_bind(shader); + glUseProgram(shader); /**/ if(type[0] == 'i') glUniform1i(glGetUniformLocation(shader, name), setv.x); else if(type[0] == 'b') glUniform1i(glGetUniformLocation(shader, name), !!setv.x); else if(type[0] == 'f') glUniform1f(glGetUniformLocation(shader, name), setv.x); else if(type[3] == '2') glUniform2fv(glGetUniformLocation(shader, name), 1, &setv.x); else if(type[3] == '3') glUniform3fv(glGetUniformLocation(shader, name), 1, &setv.x); else if(type[3] == '4') glUniform4fv(glGetUniformLocation(shader, name), 1, &setv.x); - shader_bind(shader_bak); + glUseProgram(shader_bak); } } } @@ -17842,57 +17842,35 @@ void ssbo_unbind(){ glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); } -typedef map(unsigned,int) uniform_binding; static __thread unsigned last_shader = -1; -static __thread quarks_db uniform_names; -static __thread map(handle, uniform_binding) uniforms; int shader_uniform(const char *name) { -#if 0 - do_once map_init(uniforms, less_int, hash_int); - if (!map_find(uniforms, last_shader)) { - uniform_binding names_map = 0; - map_init(names_map, less_int, hash_int); - map_insert(uniforms, last_shader, names_map); - } - - uniform_binding names = *map_find(uniforms, last_shader); - unsigned name_hash = quark_intern(&uniform_names, name); - if (!map_find(names, name_hash)) { - map_insert(names, name_hash, glGetUniformLocation(last_shader, name)); - } - - // int ret = glGetUniformLocation(last_shader, name); - // if( ret < 0 ) PRINTF("!cannot find uniform '%s' in shader program %d\n", name, (int)last_shader ); - return *map_find(names, name_hash); -#else return glGetUniformLocation(last_shader, name); -#endif } unsigned shader_get_active() { return last_shader; } -unsigned shader_bind(unsigned program) { if (program == last_shader) return last_shader; unsigned ret = last_shader; return glUseProgram(last_shader = program), ret; } -static inline void shader_int_(unsigned uniform, int i) { glUniform1i(uniform, i); } -static inline void shader_float_(unsigned uniform, float f) { glUniform1f(uniform, f); } -static inline void shader_vec2_(unsigned uniform, vec2 v) { glUniform2fv(uniform, 1, &v.x); } -static inline void shader_vec3_(unsigned uniform, vec3 v) { glUniform3fv(uniform, 1, &v.x); } -static inline void shader_vec3v_(unsigned uniform, int count, vec3 *v) { glUniform3fv(uniform, count, &v[0].x); } -static inline void shader_vec4_(unsigned uniform, vec4 v) { glUniform4fv(uniform, 1, &v.x); } -static inline void shader_mat44_(unsigned uniform, mat44 m) { glUniformMatrix4fv(uniform, 1, GL_FALSE/*GL_TRUE*/, m); } -static inline void shader_cubemap_(unsigned sampler, unsigned texture) { +unsigned shader_bind(unsigned program) { unsigned ret = last_shader; return glUseProgram(last_shader = program), ret; } +static inline void shader_int_(int uniform, int i) { glUniform1i(uniform, i); } +static inline void shader_float_(int uniform, float f) { glUniform1f(uniform, f); } +static inline void shader_vec2_(int uniform, vec2 v) { glUniform2fv(uniform, 1, &v.x); } +static inline void shader_vec3_(int uniform, vec3 v) { glUniform3fv(uniform, 1, &v.x); } +static inline void shader_vec3v_(int uniform, int count, vec3 *v) { glUniform3fv(uniform, count, &v[0].x); } +static inline void shader_vec4_(int uniform, vec4 v) { glUniform4fv(uniform, 1, &v.x); } +static inline void shader_mat44_(int uniform, mat44 m) { glUniformMatrix4fv(uniform, 1, GL_FALSE/*GL_TRUE*/, m); } +static inline void shader_cubemap_(int sampler, unsigned texture) { int id = texture_unit(); glUniform1i(sampler, id); glActiveTexture(GL_TEXTURE0 + id); glBindTexture(GL_TEXTURE_CUBE_MAP, texture); } -static inline void shader_bool_(unsigned uniform, bool x) { glUniform1i(uniform, x); } -static inline void shader_uint_(unsigned uniform, unsigned x ) { glUniform1ui(uniform, x); } -static inline void shader_texture_unit_(unsigned sampler, unsigned id, unsigned unit) { +static inline void shader_bool_(int uniform, bool x) { glUniform1i(uniform, x); } +static inline void shader_uint_(int uniform, unsigned x ) { glUniform1ui(uniform, x); } +static inline void shader_texture_unit_(int sampler, unsigned id, unsigned unit) { // @todo. if tex.h == 1 ? GL_TEXTURE_1D : GL_TEXTURE_2D glUniform1i(sampler, unit); glActiveTexture(GL_TEXTURE0 + unit); glBindTexture(GL_TEXTURE_2D, id); } -static inline void shader_texture_(unsigned sampler, texture_t t) { shader_texture_unit_(sampler, t.id, texture_unit()); } +static inline void shader_texture_(int sampler, texture_t t) { shader_texture_unit_(sampler, t.id, texture_unit()); } // public api void shader_int(const char *uniform, int i) { glUniform1i(shader_uniform(uniform), i); } @@ -18708,7 +18686,7 @@ void fullscreen_quad_rgb( texture_t texture ) { GLenum texture_type = texture.flags & TEXTURE_ARRAY ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D; renderstate_apply(&fullscreen_quad_rs); - shader_bind( program ); + glUseProgram( program ); float gamma = 1; glUniform1f( u_inv_gamma, gamma ); @@ -18723,7 +18701,7 @@ void fullscreen_quad_rgb( texture_t texture ) { glBindTexture( texture_type, 0 ); glBindVertexArray( 0 ); - shader_bind( 0 ); + glUseProgram( 0 ); // glDisable( GL_BLEND ); } @@ -18741,7 +18719,7 @@ void fullscreen_quad_rgb_flipped( texture_t texture ) { GLenum texture_type = texture.flags & TEXTURE_ARRAY ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D; renderstate_apply(&fullscreen_quad_rs); - shader_bind( program ); + glUseProgram( program ); float gamma = 1; glUniform1f( u_inv_gamma, gamma ); @@ -18756,7 +18734,7 @@ void fullscreen_quad_rgb_flipped( texture_t texture ) { glBindTexture( texture_type, 0 ); glBindVertexArray( 0 ); - shader_bind( 0 ); + glUseProgram( 0 ); // glDisable( GL_BLEND ); } @@ -18778,7 +18756,7 @@ void fullscreen_quad_ycbcr( texture_t textureYCbCr[3] ) { } renderstate_apply(&fullscreen_quad_rs); - shader_bind( program ); + glUseProgram( program ); // glUniform1f( u_gamma, gamma ); glBindVertexArray( vao ); @@ -18801,7 +18779,7 @@ void fullscreen_quad_ycbcr( texture_t textureYCbCr[3] ) { glBindTexture( GL_TEXTURE_2D, 0 ); glBindVertexArray( 0 ); - shader_bind( 0 ); + glUseProgram( 0 ); // glDisable( GL_BLEND ); } @@ -18823,7 +18801,7 @@ void fullscreen_quad_ycbcr_flipped( texture_t textureYCbCr[3] ) { } renderstate_apply(&fullscreen_quad_rs); - shader_bind( program ); + glUseProgram( program ); // glUniform1f( u_gamma, gamma ); glBindVertexArray( vao ); @@ -18846,7 +18824,7 @@ void fullscreen_quad_ycbcr_flipped( texture_t textureYCbCr[3] ) { glBindTexture( GL_TEXTURE_2D, 0 ); glBindVertexArray( 0 ); - shader_bind( 0 ); + glUseProgram( 0 ); // glDisable( GL_BLEND ); } @@ -19151,7 +19129,7 @@ void skybox_mie_calc_sh(skybox_t *sky, float sky_intensity) { for(int i = 0; i < 6; ++i) { glBindFramebuffer(GL_FRAMEBUFFER, sky->framebuffers[i]); glViewport(0, 0, WIDTH, HEIGHT); - shader_bind(sky->program); + glUseProgram(sky->program); mat44 proj; perspective44(proj, 90.0f, WIDTH / (float)HEIGHT, 0.1f, 500.f); mat44 view; lookat44(view, vec3(0,0,0), directions[i], vec3(0,-1,0)); @@ -19702,7 +19680,7 @@ int postfx_load_from_mem( postfx *fx, const char *name, const char *fs ) { p->program = shader(vs, fs2, "vtexcoord", "fragColor" , NULL); - shader_bind(p->program); // needed? + glUseProgram(p->program); // needed? for( int i = 0; i < countof(p->uniforms); ++i ) p->uniforms[i] = -1; @@ -19866,7 +19844,7 @@ bool postfx_end(postfx *fx) { passfx *pass = &fx->pass[i]; if( pass->enabled ) { if( !pass->program ) { --num_active_passes; continue; } - shader_bind(pass->program); + glUseProgram(pass->program); // bind texture to texture unit 0 // shader_texture_unit(fx->diffuse[frame], 0); @@ -19905,7 +19883,7 @@ bool postfx_end(postfx *fx) { if (bound) fbo_unbind(); } } - shader_bind(0); + glUseProgram(0); // restore clear color: needed in case transparent window is being used (alpha != 0) glClearColor(0,0,0,1); // @transparent @@ -20016,7 +19994,7 @@ static void brdf_load() { glDisable(GL_BLEND); handle old_shader = last_shader; - shader_bind( program ); + glUseProgram( program ); glViewport(0, 0, 512, 512); @@ -20030,7 +20008,7 @@ static void brdf_load() { glBindVertexArray( 0 ); - shader_bind( last_shader ); + glUseProgram( last_shader ); fbo_unbind(); fbo_destroy(lut_fbo); @@ -20152,7 +20130,7 @@ shadertoy_t* shadertoy_render(shadertoy_t *s, float delta) { struct tm *tm = localtime(&tmsec); s->t += delta * 1000; - shader_bind(s->program); + glUseProgram(s->program); glUniform1f(s->uniforms[iGlobalTime], s->t / 1000.f ); glUniform1f(s->uniforms[iGlobalFrame], s->frame++); glUniform1f(s->uniforms[iGlobalDelta], delta / 1000.f ); @@ -20322,6 +20300,8 @@ void model_set_texture(model_t m, texture_t t) { } } +//@fixme: some locations are invalid, find out why +#if 0 static void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view, mat44 model) { // @todo: cache uniform locs if(!m.iqm) return; @@ -20353,7 +20333,7 @@ void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view, shader_int_(loc, m.billboard); } if( (loc = m.uniforms[MODEL_UNIFORM_TEXLIT]) >= 0 ) { - shader_int_(loc, (m.lightmap.w != 0)); + shader_bool_(loc, (m.lightmap.w != 0)); } if ((loc = m.uniforms[MODEL_UNIFORM_MODEL]) >= 0) { shader_mat44_(loc, model); @@ -20373,7 +20353,7 @@ void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view, if( q->numanims ) if( (loc = m.uniforms[MODEL_UNIFORM_VS_BONE_MATRIX]) >= 0 ) glUniformMatrix3x4fv( loc, q->numjoints, GL_FALSE, q->outframe[0]); if ((loc = m.uniforms[MODEL_UNIFORM_U_MATCAPS]) >= 0) { - shader_int_(loc, m.flags & MODEL_MATCAPS ? GL_TRUE:GL_FALSE); + shader_bool_(loc, m.flags & MODEL_MATCAPS ? GL_TRUE:GL_FALSE); } if (m.shading == SHADING_PBR) { @@ -20398,6 +20378,132 @@ void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view, shader_bind(old_shader); } } +#else +static +void model_set_uniforms(model_t m, int shader, mat44 mv, mat44 proj, mat44 view, mat44 model) { // @todo: cache uniform locs + if(!m.iqm) return; + iqm_t *q = m.iqm; + + shader_bind(shader); + int loc; + //if( (loc = glGetUniformLocation(shader, "M")) >= 0 ) glUniformMatrix4fv( loc, 1, GL_FALSE/*GL_TRUE*/, m); // RIM + if( (loc = glGetUniformLocation(shader, "MV")) >= 0 ) { + glUniformMatrix4fv( loc, 1, GL_FALSE, mv); + } + else + if( (loc = glGetUniformLocation(shader, "u_mv")) >= 0 ) { + glUniformMatrix4fv( loc, 1, GL_FALSE, mv); + } + if( (loc = glGetUniformLocation(shader, "MVP")) >= 0 ) { + mat44 mvp; multiply44x2(mvp, proj, mv); // multiply44x3(mvp, proj, view, model); + glUniformMatrix4fv( loc, 1, GL_FALSE, mvp); + } + else + if( (loc = glGetUniformLocation(shader, "u_mvp")) >= 0 ) { + mat44 mvp; multiply44x2(mvp, proj, mv); // multiply44x3(mvp, proj, view, model); + glUniformMatrix4fv( loc, 1, GL_FALSE, mvp); + } + if( (loc = glGetUniformLocation(shader, "VP")) >= 0 ) { + mat44 vp; multiply44x2(vp, proj, view); + glUniformMatrix4fv( loc, 1, GL_FALSE, vp); + } + else + if( (loc = glGetUniformLocation(shader, "u_vp")) >= 0 ) { + mat44 vp; multiply44x2(vp, proj, view); + glUniformMatrix4fv( loc, 1, GL_FALSE, vp); + } + if( (loc = glGetUniformLocation(shader, "u_cam_pos")) >= 0 ) { + vec3 pos = vec3(view[12], view[13], view[14]); + glUniform3fv( loc, 1, &pos.x ); + } + else + if( (loc = glGetUniformLocation(shader, "cam_pos")) >= 0 ) { + vec3 pos = vec3(view[12], view[13], view[14]); + glUniform3fv( loc, 1, &pos.x ); + } + if( (loc = glGetUniformLocation(shader, "u_cam_dir")) >= 0 ) { + vec3 dir = norm3(vec3(view[2], view[6], view[10])); + glUniform3fv( loc, 1, &dir.x ); + } + else + if( (loc = glGetUniformLocation(shader, "cam_dir")) >= 0 ) { + 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( (loc = glGetUniformLocation(shader, "texlit")) >= 0 ) { + glUniform1i( loc, (m.lightmap.w != 0) ); + } + else + if( (loc = glGetUniformLocation(shader, "u_texlit")) >= 0 ) { + glUniform1i( loc, (m.lightmap.w != 0) ); + } +#if 0 + // @todo: mat44 projview (useful?) +#endif + if ((loc = glGetUniformLocation(shader, "M")) >= 0) { + glUniformMatrix4fv(loc, 1, GL_FALSE, model); + } + else + if ((loc = glGetUniformLocation(shader, "model")) >= 0) { + glUniformMatrix4fv(loc, 1, GL_FALSE, model); + } + if ((loc = glGetUniformLocation(shader, "V")) >= 0) { + glUniformMatrix4fv(loc, 1, GL_FALSE, view); + } + else + if ((loc = glGetUniformLocation(shader, "view")) >= 0) { + glUniformMatrix4fv(loc, 1, GL_FALSE, view); + } + if ((loc = glGetUniformLocation(shader, "inv_view")) >= 0) { + mat44 inv_view; + invert44( inv_view, view); + glUniformMatrix4fv(loc, 1, GL_FALSE, inv_view); + } + if ((loc = glGetUniformLocation(shader, "P")) >= 0) { + glUniformMatrix4fv(loc, 1, GL_FALSE, proj); + } + else + if ((loc = glGetUniformLocation(shader, "proj")) >= 0) { + glUniformMatrix4fv(loc, 1, GL_FALSE, proj); + } + if( (loc = glGetUniformLocation(shader, "SKINNED")) >= 0 ) glUniform1i( loc, q->numanims ? GL_TRUE : GL_FALSE); + if( q->numanims ) + if( (loc = glGetUniformLocation(shader, "vsBoneMatrix")) >= 0 ) glUniformMatrix3x4fv( loc, q->numjoints, GL_FALSE, q->outframe[0]); + + if ((loc = glGetUniformLocation(shader, "u_matcaps")) >= 0) { + glUniform1i(loc, m.flags & MODEL_MATCAPS ? GL_TRUE:GL_FALSE); + } + + if (m.shading == SHADING_PBR) { + handle old_shader = last_shader; + shader_bind(shader); + shader_vec2( "resolution", vec2(window_width(),window_height())); + + bool has_tex_skysphere = m.sky_refl.id != texture_checker().id; + bool has_tex_skyenv = m.sky_env.id != texture_checker().id; + shader_bool( "has_tex_skysphere", has_tex_skysphere ); + shader_bool( "has_tex_skyenv", has_tex_skyenv ); + if( has_tex_skysphere ) { + float mipCount = floor( log2( max(m.sky_refl.w, m.sky_refl.h) ) ); + shader_texture("tex_skysphere", m.sky_refl); + shader_float( "skysphere_mip_count", mipCount ); + } + if( has_tex_skyenv ) { + shader_texture( "tex_skyenv", m.sky_env ); + } + shader_texture( "tex_brdf_lut", brdf_lut() ); + shader_uint( "frame_count", (unsigned)window_frame() ); + shader_bind(old_shader); + } +} +#endif static void model_set_state(model_t m) { if(!m.iqm) return; @@ -21211,6 +21317,7 @@ void model_draw_call(model_t m, int shader) { glUniform4f(loc, m.materials[i].layer[0].map.color.r, m.materials[i].layer[0].map.color.g, m.materials[i].layer[0].map.color.b, m.materials[i].layer[0].map.color.a); } } + } else { const material_t *material = &m.materials[i]; shader_colormap_model_internal( "map_diffuse.color", "map_diffuse.has_tex", "map_diffuse_tex", material->layer[MATERIAL_CHANNEL_DIFFUSE].map ); @@ -21257,59 +21364,104 @@ void model_render(model_t m, mat44 proj, mat44 view, mat44 model, int shader) { static inline void model_init_uniforms(model_t *m) { + for (int i=0; iuniforms[i] = -1; unsigned shader = m->program; - if (glGetUniformLocation(shader, "u_mv") >= 0) - m->uniforms[MODEL_UNIFORM_MV] = glGetUniformLocation(shader, "u_mv"); + int loc; + if ((loc = glGetUniformLocation(shader, "u_mv")) >= 0) + m->uniforms[MODEL_UNIFORM_MV] = loc; else - m->uniforms[MODEL_UNIFORM_MV] = glGetUniformLocation(shader, "MV"); - if (glGetUniformLocation(shader, "u_mvp") >= 0) - m->uniforms[MODEL_UNIFORM_MVP] = glGetUniformLocation(shader, "u_mvp"); + if ((loc = glGetUniformLocation(shader, "MV")) >= 0) + m->uniforms[MODEL_UNIFORM_MV] = loc; + + if ((loc = glGetUniformLocation(shader, "u_mvp")) >= 0) + m->uniforms[MODEL_UNIFORM_MVP] = loc; else - m->uniforms[MODEL_UNIFORM_MVP] = glGetUniformLocation(shader, "MVP"); - if (glGetUniformLocation(shader, "u_vp") >= 0) - m->uniforms[MODEL_UNIFORM_VP] = glGetUniformLocation(shader, "u_vp"); + if ((loc = glGetUniformLocation(shader, "MVP")) >= 0) + m->uniforms[MODEL_UNIFORM_MVP] = loc; + + if ((loc = glGetUniformLocation(shader, "u_vp")) >= 0) + m->uniforms[MODEL_UNIFORM_VP] = loc; else - m->uniforms[MODEL_UNIFORM_VP] = glGetUniformLocation(shader, "VP"); - if (glGetUniformLocation(shader, "u_cam_pos") >= 0) - m->uniforms[MODEL_UNIFORM_CAM_POS] = glGetUniformLocation(shader, "u_cam_pos"); + if ((loc = glGetUniformLocation(shader, "VP")) >= 0) + m->uniforms[MODEL_UNIFORM_VP] = loc; + + if ((loc = glGetUniformLocation(shader, "u_cam_pos")) >= 0) + m->uniforms[MODEL_UNIFORM_CAM_POS] = loc; else - m->uniforms[MODEL_UNIFORM_CAM_POS] = glGetUniformLocation(shader, "cam_pos"); - if (glGetUniformLocation(shader, "u_cam_dir") >= 0) - m->uniforms[MODEL_UNIFORM_CAM_DIR] = glGetUniformLocation(shader, "u_cam_dir"); + if ((loc = glGetUniformLocation(shader, "cam_pos")) >= 0) + m->uniforms[MODEL_UNIFORM_CAM_POS] = loc; + + if ((loc = glGetUniformLocation(shader, "u_cam_dir")) >= 0) + m->uniforms[MODEL_UNIFORM_CAM_DIR] = loc; else - m->uniforms[MODEL_UNIFORM_CAM_DIR] = glGetUniformLocation(shader, "cam_dir"); - if (glGetUniformLocation(shader, "u_billboard") >= 0) - m->uniforms[MODEL_UNIFORM_BILLBOARD] = glGetUniformLocation(shader, "u_billboard"); + if ((loc = glGetUniformLocation(shader, "cam_dir")) >= 0) + m->uniforms[MODEL_UNIFORM_CAM_DIR] = loc; + + if ((loc = glGetUniformLocation(shader, "u_billboard")) >= 0) + m->uniforms[MODEL_UNIFORM_BILLBOARD] = loc; else - m->uniforms[MODEL_UNIFORM_BILLBOARD] = glGetUniformLocation(shader, "billboard"); - if (glGetUniformLocation(shader, "u_texlit") >= 0) - m->uniforms[MODEL_UNIFORM_TEXLIT] = glGetUniformLocation(shader, "u_texlit"); + if ((loc = glGetUniformLocation(shader, "billboard")) >= 0) + m->uniforms[MODEL_UNIFORM_BILLBOARD] = loc; + + if ((loc = glGetUniformLocation(shader, "u_texlit")) >= 0) + m->uniforms[MODEL_UNIFORM_TEXLIT] = loc; else - m->uniforms[MODEL_UNIFORM_TEXLIT] = glGetUniformLocation(shader, "texlit"); - if (glGetUniformLocation(shader, "M") >= 0) - m->uniforms[MODEL_UNIFORM_MODEL] = glGetUniformLocation(shader, "M"); + if ((loc = glGetUniformLocation(shader, "texlit")) >= 0) + m->uniforms[MODEL_UNIFORM_TEXLIT] = loc; + + if ((loc = glGetUniformLocation(shader, "M")) >= 0) + m->uniforms[MODEL_UNIFORM_MODEL] = loc; else - m->uniforms[MODEL_UNIFORM_MODEL] = glGetUniformLocation(shader, "model"); - if (glGetUniformLocation(shader, "V") >= 0) - m->uniforms[MODEL_UNIFORM_VIEW] = glGetUniformLocation(shader, "V"); + if ((loc = glGetUniformLocation(shader, "model")) >= 0) + m->uniforms[MODEL_UNIFORM_MODEL] = loc; + + if ((loc = glGetUniformLocation(shader, "V")) >= 0) + m->uniforms[MODEL_UNIFORM_VIEW] = loc; else - m->uniforms[MODEL_UNIFORM_VIEW] = glGetUniformLocation(shader, "view"); - m->uniforms[MODEL_UNIFORM_INV_VIEW] = glGetUniformLocation(shader, "inv_view"); - if (glGetUniformLocation(shader, "P") >= 0) - m->uniforms[MODEL_UNIFORM_PROJ] = glGetUniformLocation(shader, "P"); + if ((loc = glGetUniformLocation(shader, "view")) >= 0) + m->uniforms[MODEL_UNIFORM_VIEW] = loc; + + if ((loc = glGetUniformLocation(shader, "inv_view")) >= 0) + m->uniforms[MODEL_UNIFORM_INV_VIEW] = loc; + + if ((loc = glGetUniformLocation(shader, "P")) >= 0) + m->uniforms[MODEL_UNIFORM_PROJ] = loc; else - m->uniforms[MODEL_UNIFORM_PROJ] = glGetUniformLocation(shader, "proj"); - m->uniforms[MODEL_UNIFORM_SKINNED] = glGetUniformLocation(shader, "SKINNED"); - m->uniforms[MODEL_UNIFORM_VS_BONE_MATRIX] = glGetUniformLocation(shader, "vsBoneMatrix"); - m->uniforms[MODEL_UNIFORM_U_MATCAPS] = glGetUniformLocation(shader, "u_matcaps"); - m->uniforms[MODEL_UNIFORM_HAS_TEX_SKYSPHERE] = glGetUniformLocation(shader, "has_tex_skysphere"); - m->uniforms[MODEL_UNIFORM_HAS_TEX_SKYENV] = glGetUniformLocation(shader, "has_tex_skyenv"); - m->uniforms[MODEL_UNIFORM_TEX_SKYSPHERE] = glGetUniformLocation(shader, "tex_skysphere"); - m->uniforms[MODEL_UNIFORM_SKYSPHERE_MIP_COUNT] = glGetUniformLocation(shader, "skysphere_mip_count"); - m->uniforms[MODEL_UNIFORM_TEX_SKYENV] = glGetUniformLocation(shader, "tex_skyenv"); - m->uniforms[MODEL_UNIFORM_TEX_BRDF_LUT] = glGetUniformLocation(shader, "tex_brdf_lut"); - m->uniforms[MODEL_UNIFORM_FRAME_COUNT] = glGetUniformLocation(shader, "frame_count"); - m->uniforms[MODEL_UNIFORM_RESOLUTION] = glGetUniformLocation(shader, "resolution"); + if ((loc = glGetUniformLocation(shader, "proj")) >= 0) + m->uniforms[MODEL_UNIFORM_PROJ] = loc; + + if ((loc = glGetUniformLocation(shader, "SKINNED")) >= 0) + m->uniforms[MODEL_UNIFORM_SKINNED] = loc; + + if ((loc = glGetUniformLocation(shader, "vsBoneMatrix")) >= 0) + m->uniforms[MODEL_UNIFORM_VS_BONE_MATRIX] = loc; + + if ((loc = glGetUniformLocation(shader, "u_matcaps")) >= 0) + m->uniforms[MODEL_UNIFORM_U_MATCAPS] = loc; + + if ((loc = glGetUniformLocation(shader, "has_tex_skysphere")) >= 0) + m->uniforms[MODEL_UNIFORM_HAS_TEX_SKYSPHERE] = loc; + + if ((loc = glGetUniformLocation(shader, "has_tex_skyenv")) >= 0) + m->uniforms[MODEL_UNIFORM_HAS_TEX_SKYENV] = loc; + + if ((loc = glGetUniformLocation(shader, "tex_skysphere")) >= 0) + m->uniforms[MODEL_UNIFORM_TEX_SKYSPHERE] = loc; + + if ((loc = glGetUniformLocation(shader, "skysphere_mip_count")) >= 0) + m->uniforms[MODEL_UNIFORM_SKYSPHERE_MIP_COUNT] = loc; + + if ((loc = glGetUniformLocation(shader, "tex_skyenv")) >= 0) + m->uniforms[MODEL_UNIFORM_TEX_SKYENV] = loc; + + if ((loc = glGetUniformLocation(shader, "tex_brdf_lut")) >= 0) + m->uniforms[MODEL_UNIFORM_TEX_BRDF_LUT] = loc; + + if ((loc = glGetUniformLocation(shader, "frame_count")) >= 0) + m->uniforms[MODEL_UNIFORM_FRAME_COUNT] = loc; + + if ((loc = glGetUniformLocation(shader, "resolution")) >= 0) + m->uniforms[MODEL_UNIFORM_RESOLUTION] = loc; } void model_shading(model_t *m, int shading) { @@ -21325,7 +21477,7 @@ void model_shading(model_t *m, int shading) { // rebind shader // @fixme: app crashes rn - // shader_bind(0); + // glUseProgram(0); // glDeleteProgram(m->program); const char *symbols[] = { "{{include-shadowmap}}", vfs_read("shaders/fs_0_0_shadowmap_lit.glsl") }; // #define RIM int shaderprog = shader(strlerp(1,symbols,vfs_read("shaders/vs_323444143_16_3322_model.glsl")), strlerp(1,symbols,vfs_read("shaders/fs_32_4_model.glsl")), //fs, @@ -23043,6 +23195,8 @@ void scene_render(int flags) { model->billboard = obj->billboard; + model->rs[RENDER_PASS_NORMAL].cull_face_enabled = flags&SCENE_CULLFACE ? 1 : 0; + model->rs[RENDER_PASS_NORMAL].polygon_mode_mode = flags&SCENE_WIREFRAME ? GL_LINE : GL_FILL; model_render(*model, cam->proj, cam->view, obj->transform, model->program); if( do_retexturing ) { diff --git a/engine/v4k.h b/engine/v4k.h index 82e7c26..b19af71 100644 --- a/engine/v4k.h +++ b/engine/v4k.h @@ -3142,6 +3142,9 @@ typedef struct renderstate_t { unsigned polygon_mode_face; unsigned polygon_mode_mode; + // Wireframe mode + bool wireframe_enabled; + // Scissor test bool scissor_test_enabled; } renderstate_t; @@ -3727,7 +3730,7 @@ typedef struct model_t { handle *textures; char **texture_names; array(material_t) materials; - unsigned uniforms[NUM_MODEL_UNIFORMS]; + int uniforms[NUM_MODEL_UNIFORMS]; texture_t sky_refl, sky_env;