--- libgender/material.C 2004/11/04 04:49:04 1.36 +++ libgender/material.C 2005/02/07 07:37:00 1.56 @@ -8,10 +8,6 @@ #include "view.h" #include "util.h" -material::~material () -{ -} - GLuint texture::load_texture (SDL_Surface * surface, GLfloat * tex2oord) { @@ -69,40 +65,71 @@ return name; } +material::~material () +{ +} + void material::enable (view &ctx) { - pass::matmap_t &matmap = ctx.pass_data->matmap; + pass_data::matmap_t &matmap = ctx.pass->matmap; - pass::matmap_t::iterator i = matmap.find (this); - shader::program_object *p; + pass_data::matmap_t::iterator i = matmap.find (this); if (i == matmap.end ()) { - shader::program_object po; + string vsh_src, fsh_src; shader::shader_builder::start (); + + if (ctx.pass->l) + ctx.pass->l->vsh (); + vsh (ctx); - if (ctx.pass_data->l) - ctx.pass_data->l->vsh (); + // compute logarithmic depth - see the frustum matrix in view.C + { + using namespace shader::compile; + + temp_1f lz; + + // TODO: negative z is not calculated in an acceptable way, clipping does horrible things(?) + lz = z (vout.position); +#if 0 + lz = (log (max (lz, 0) + 1) / log (1e30)) - 1; +#else + lz = ifelse (lz <= 0, + 0, + log (lz + 1) / log (1e30) + ) - 1; +#endif + z (vout.position) = lz * w (vout.position); + } - po->vsh->compile (shader::shader_builder::stop ()); + vsh_src = shader::shader_builder::stop (); shader::shader_builder::start (); - shader::compile::fout.frag_color = shader::compile::float4 (1., 1., 0., 1.); - fsh (ctx); - po->fsh->compile (shader::shader_builder::stop ()); - po->link (); + if (ctx.pass->l) + { + ctx.pass->l->fsh (); + fsh (ctx); + } + else + // many drivers need both vertex and fragment shader, 'caboom!' otherwise + shader::compile::fout.frag_color = shader::compile::float4 (0., 0., 0., 0.); + + fsh_src = shader::shader_builder::stop (); - matmap.insert (pass::matmap_t::value_type (this, po)); + shader::program_object po = shader::get_program (vsh_src, fsh_src); + matmap.insert (pass_data::matmap_t::value_type (this, po)); - p = &po; + po->enable (); } else - p = &i->second; + i->second->enable (); - (*p)->enable (); + if (ctx.pass->l) + ctx.pass->l->enable (); } void material::disable (view &ctx) @@ -116,20 +143,42 @@ { } -static shader::varying_3f normal, lightvec; +static shader::varying_3f normal; static shader::varying_2f texcoord; +void test_material2::vsh (view &ctx) +{ + using namespace shader::compile; + std_vsh (); + + if (ctx.pass->l) + { + normal = normal_matrix * vin.normal; + } +} + +void test_material2::fsh (view &ctx) +{ + using namespace shader::compile; + + if (ctx.pass->l) + { + temp_1f fac; + fac = dot (normalize (normal), normalize (ctx.pass->l->sh_lightvec)); + xyz (fout.frag_color) = ctx.pass->l->sh_colour * fac;//normalize (ctx.pass->l->sh_lightvec); + } +} + void test_material::vsh (view &ctx) { using namespace shader::compile; std_vsh (); - if (ctx.pass_data->l) + if (ctx.pass->l) { texcoord = xy (vin.tex_coord[0]); normal = normal_matrix * vin.normal; - lightvec = xyz (ctx.pass_data->l->lightpos - model_view_matrix * vin.vertex); } } @@ -137,24 +186,27 @@ { using namespace shader::compile; - if (ctx.pass_data->l) + if (ctx.pass->l) { temp_3f lc; temp_1f fac; - lc = (*ctx.pass_data->l)(); - temp_3f rot1, rot2, rot3; - rot1 = yxz (texture_2d (normvar, texcoord) * 2.F - 1.F); + yxz (rot1) = (texture_2d (normvar, texcoord) * 2.F - 1.F); + + //rot1 = normal_matrix * rot1; + rot2 = float3 (x(rot1), z(rot1), -y(rot1)); rot3 = float3 (y(rot1), -x(rot1), z(rot1)); normal = mat3 (rot1, rot2, rot3) * normal; - fac = dot (normalize (normal), normalize (lightvec)); - fac = pow (max (fac, 0.0), 6); - xyz (fout.frag_color) = (texture_2d (texvar, texcoord) + 0.2F) * lc * fac; + fac = dot (normalize (normal), normalize (ctx.pass->l->sh_lightvec)); + fac = max (pow (max (fac, 0.0), 6), 0.3); + xyz (fout.frag_color) = (texture_2d (texvar, texcoord) + 0.2F) * fac + * ctx.pass->l->sh_colour; + //xyz (fout.frag_color) = lc * fac; } } @@ -173,4 +225,5 @@ } test_material *testmat; +test_material2 *testmat2;