correct normals for vheight floors

This commit is contained in:
Sean Barrett 2015-03-14 15:02:51 -07:00
parent c10b3fefae
commit 00810b7d11
3 changed files with 473 additions and 116 deletions

View File

@ -327,10 +327,10 @@ enum
STBVOX_GEOM_force, // all faces always visible, e.g. minecraft fancy leaves STBVOX_GEOM_force, // all faces always visible, e.g. minecraft fancy leaves
// these access vheight input // these access vheight input
STBVOX_GEOM_floor_vheight_02 = 12, // diagonal is SW-NE -- assuming index buffer 0,1,2,0,2,3 STBVOX_GEOM_floor_vheight_03 = 12, // diagonal is SW-NE
STBVOX_GEOM_floor_vheight_13, // diagonal is SE-NW -- assuming index buffer 0,1,2,0,2,3 STBVOX_GEOM_floor_vheight_12, // diagonal is SE-NW
STBVOX_GEOM_ceil_vheight_02, STBVOX_GEOM_ceil_vheight_03,
STBVOX_GEOM_ceil_vheight_13, STBVOX_GEOM_ceil_vheight_12,
STBVOX_GEOM_count, // number of geom cases STBVOX_GEOM_count, // number of geom cases
}; };
@ -551,51 +551,62 @@ struct stbvox_mesh_maker
// mode, and all the bits to choose the normal. // mode, and all the bits to choose the normal.
// Thus the bottom 3 bits have to be: // Thus the bottom 3 bits have to be:
// e, n, w, s, u, d, u, d // e, n, w, s, u, d, u, d
//
// These use compact names so tables are readable
enum enum
{ {
STBVOX_EFACE_east, STBVF_e,
STBVOX_EFACE_north, STBVF_n,
STBVOX_EFACE_west, STBVF_w,
STBVOX_EFACE_south, STBVF_s,
STBVOX_EFACE_up, STBVF_u,
STBVOX_EFACE_down, STBVF_d,
STBVOX_EFACE_east_up, STBVF_eu,
STBVOX_EFACE_east_down, STBVF_ed,
STBVOX_EFACE_east_up_wall, STBVF_eu_wall,
STBVOX_EFACE_north_up_wall, STBVF_nu_wall,
STBVOX_EFACE_west_up_wall, STBVF_wu_wall,
STBVOX_EFACE_south_up_wall, STBVF_su_wall,
STBVOX_EFACE_dummy_up_2, STBVF_ne_u,
STBVOX_EFACE_dummy_down_2, STBVF_ne_d,
STBVOX_EFACE_north_up, STBVF_nu,
STBVOX_EFACE_north_down, STBVF_nd,
STBVOX_EFACE_ne_up, STBVF_ed_wall,
STBVOX_EFACE_nw_up, STBVF_nd_wall,
STBVOX_EFACE_sw_up, STBVF_wd_wall,
STBVOX_EFACE_se_up, STBVF_sd_wall,
STBVOX_EFACE_dummy_up_3, STBVF_nw_u,
STBVOX_EFACE_dummy_down_3, STBVF_nw_d,
STBVOX_EFACE_west_up, STBVF_wu,
STBVOX_EFACE_west_down, STBVF_wd,
STBVOX_EFACE_ne_down, STBVF_ne_u_cross,
STBVOX_EFACE_nw_down, STBVF_nw_u_cross,
STBVOX_EFACE_sw_down, STBVF_sw_u_cross,
STBVOX_EFACE_se_down, STBVF_se_u_cross,
STBVOX_EFACE_dummy_up_4, STBVF_sw_u,
STBVOX_EFACE_dummy_down_4, STBVF_sw_d,
STBVOX_EFACE_south_up, STBVF_su,
STBVOX_EFACE_south_down, STBVF_sd,
// @TODO either we need more than 5 bits to encode the normal to fit these, or we can replace 'dummy' above with them but need to use full-size texgen table // @TODO we need more than 5 bits to encode the normal to fit the following
// so for now we just texture them with the wrong projection // so for now we use the right projection but the wrong normal
STBVOX_EFACE_east_down_wall = STBVOX_EFACE_east_down, STBVF_se_u = STBVF_su,
STBVOX_EFACE_north_down_wall = STBVOX_EFACE_north_down, STBVF_se_d = STBVF_sd,
STBVOX_EFACE_west_down_wall = STBVOX_EFACE_west_down,
STBVOX_EFACE_south_down_wall = STBVOX_EFACE_south_down, STBVF_count,
};
// get opposite-facing normal & texgen for opposite face, used to map up-facing vheight data to down-facing data
static unsigned char stbvox_reverse_face[STBVF_count] =
{
STBVF_w, STBVF_s, STBVF_e, STBVF_n, STBVF_d , STBVF_u , STBVF_wd, STBVF_wu,
0, 0, 0, 0, STBVF_sw_d, STBVF_sw_u, STBVF_sd, STBVF_su,
0, 0, 0, 0, STBVF_se_d, STBVF_se_u, STBVF_ed, STBVF_eu,
0, 0, 0, 0, STBVF_ne_d, STBVF_ne_d, STBVF_nd, STBVF_nu
}; };
static float stbvox_default_texgen[2][32][3] = static float stbvox_default_texgen[2][32][3] =
@ -638,26 +649,26 @@ static float stbvox_default_normals[32][3] =
{ 0, STBVOX_RSQRT2, STBVOX_RSQRT2 }, // north & up { 0, STBVOX_RSQRT2, STBVOX_RSQRT2 }, // north & up
{ -STBVOX_RSQRT2,0, STBVOX_RSQRT2 }, // west & up { -STBVOX_RSQRT2,0, STBVOX_RSQRT2 }, // west & up
{ 0,-STBVOX_RSQRT2, STBVOX_RSQRT2 }, // south & up { 0,-STBVOX_RSQRT2, STBVOX_RSQRT2 }, // south & up
{ 0,0,1 }, // up { STBVOX_RSQRT3, STBVOX_RSQRT3, STBVOX_RSQRT3 }, // ne & up
{ 0,0,-1 }, // down { STBVOX_RSQRT3, STBVOX_RSQRT3,-STBVOX_RSQRT3 }, // ne & down
{ 0, STBVOX_RSQRT2, STBVOX_RSQRT2 }, // north & up { 0, STBVOX_RSQRT2, STBVOX_RSQRT2 }, // north & up
{ 0, STBVOX_RSQRT2, -STBVOX_RSQRT2 }, // north & down { 0, STBVOX_RSQRT2, -STBVOX_RSQRT2 }, // north & down
{ STBVOX_RSQRT3, STBVOX_RSQRT3,STBVOX_RSQRT3 }, // NE & up { STBVOX_RSQRT2,0, -STBVOX_RSQRT2 }, // east & down
{ -STBVOX_RSQRT3, STBVOX_RSQRT3,STBVOX_RSQRT3 }, // NW & up { 0, STBVOX_RSQRT2, -STBVOX_RSQRT2 }, // north & down
{ -STBVOX_RSQRT3,-STBVOX_RSQRT3,STBVOX_RSQRT3 }, // SW & up { -STBVOX_RSQRT2,0, -STBVOX_RSQRT2 }, // west & down
{ STBVOX_RSQRT3,-STBVOX_RSQRT3,STBVOX_RSQRT3 }, // SE & up { 0,-STBVOX_RSQRT2, -STBVOX_RSQRT2 }, // south & down
{ 0,0,1 }, // up { -STBVOX_RSQRT3, STBVOX_RSQRT3, STBVOX_RSQRT3 }, // NW & up
{ 0,0,-1 }, // down { -STBVOX_RSQRT3, STBVOX_RSQRT3,-STBVOX_RSQRT3 }, // NW & down
{ -STBVOX_RSQRT2,0, STBVOX_RSQRT2 }, // west & up { -STBVOX_RSQRT2,0, STBVOX_RSQRT2 }, // west & up
{ -STBVOX_RSQRT2,0, -STBVOX_RSQRT2 }, // west & down { -STBVOX_RSQRT2,0, -STBVOX_RSQRT2 }, // west & down
{ STBVOX_RSQRT3, STBVOX_RSQRT3,-STBVOX_RSQRT3 }, // NE & down { STBVOX_RSQRT3, STBVOX_RSQRT3,STBVOX_RSQRT3 }, // NE & up crossed
{ -STBVOX_RSQRT3, STBVOX_RSQRT3,-STBVOX_RSQRT3 }, // NW & down { -STBVOX_RSQRT3, STBVOX_RSQRT3,STBVOX_RSQRT3 }, // NW & up crossed
{ -STBVOX_RSQRT3,-STBVOX_RSQRT3,-STBVOX_RSQRT3 }, // SW & down { -STBVOX_RSQRT3,-STBVOX_RSQRT3,STBVOX_RSQRT3 }, // SW & up crossed
{ STBVOX_RSQRT3,-STBVOX_RSQRT3,-STBVOX_RSQRT3 }, // SE & down { STBVOX_RSQRT3,-STBVOX_RSQRT3,STBVOX_RSQRT3 }, // SE & up crossed
{ 0,0,1 }, // up { -STBVOX_RSQRT3,-STBVOX_RSQRT3, STBVOX_RSQRT3 }, // SW & up
{ 0,0,-1 }, // down { -STBVOX_RSQRT3,-STBVOX_RSQRT3,-STBVOX_RSQRT3 }, // SW & up
{ 0,-STBVOX_RSQRT2, STBVOX_RSQRT2 }, // south & up { 0,-STBVOX_RSQRT2, STBVOX_RSQRT2 }, // south & up
{ 0,-STBVOX_RSQRT2, -STBVOX_RSQRT2 }, // south & down { 0,-STBVOX_RSQRT2, -STBVOX_RSQRT2 }, // south & down
}; };
@ -758,6 +769,9 @@ stbvox_tagged_string stbvox_vertex_program[] =
// per-buffer data // per-buffer data
"uniform vec3 transform[3];\n" "uniform vec3 transform[3];\n"
// per-frame data
"uniform vec4 camera_pos;\n" // 4th value is used for arbitrary hacking
// to simplify things, we avoid using more than 256 uniform vectors // to simplify things, we avoid using more than 256 uniform vectors
// in fragment shader to avoid possible 1024 component limit, so // in fragment shader to avoid possible 1024 component limit, so
// we access this table in the fragment shader. // we access this table in the fragment shader.
@ -802,6 +816,10 @@ stbvox_tagged_string stbvox_vertex_program[] =
" vnormal = normal_table[(facedata.w>>2) & 31u];\n" " vnormal = normal_table[(facedata.w>>2) & 31u];\n"
" objectspace_pos = offset * transform[0];\n" // object-to-world scale " objectspace_pos = offset * transform[0];\n" // object-to-world scale
" vec3 position = objectspace_pos + transform[1];\n" // object-to-world translate " vec3 position = objectspace_pos + transform[1];\n" // object-to-world translate
#if 0 // normal debugging
" if ((facedata.w & 28u) == 16u || (facedata.w & 28u) == 24u)\n"
" position += vnormal.xyz * camera_pos.w;\n"
#endif
}, },
{ STBVOX_TAG_NOT | STBVOX_TAG_gl_modelview, { STBVOX_TAG_NOT | STBVOX_TAG_gl_modelview,
@ -846,7 +864,7 @@ stbvox_tagged_string stbvox_fragment_program[] =
"uniform vec3 transform[3];\n" "uniform vec3 transform[3];\n"
// per-frame data // per-frame data
"uniform vec3 camera_pos;\n" "uniform vec4 camera_pos;\n" // 4th value is used for arbitrary hacking
// probably constant data // probably constant data
"uniform vec3 ambient[4];\n" "uniform vec3 ambient[4];\n"
@ -955,7 +973,7 @@ stbvox_tagged_string stbvox_fragment_program[] =
" amb_color *= amb_occ;\n" " amb_color *= amb_occ;\n"
" vec3 lit_color;\n" " vec3 lit_color;\n"
" vec3 lighting = compute_lighting(objectspace_pos + transform[1], normal) + amb_color * 0.25;\n" " vec3 lighting = compute_lighting(objectspace_pos + transform[1], normal) + amb_color;\n"
" if (!emissive)\n" " if (!emissive)\n"
" lit_color = lighting * albedo;\n" " lit_color = lighting * albedo;\n"
" else\n" " else\n"
@ -967,7 +985,7 @@ stbvox_tagged_string stbvox_fragment_program[] =
// smoothstep fog: // smoothstep fog:
#if 1 #if 1
" vec3 dist = objectspace_pos + (transform[1] - camera_pos);\n" " vec3 dist = objectspace_pos + (transform[1] - camera_pos.xyz);\n"
" float f = sqrt(dot(dist,dist))/1320.0;\n" " float f = sqrt(dot(dist,dist))/1320.0;\n"
" f = clamp(f, 0.0, 1.0);\n" " f = clamp(f, 0.0, 1.0);\n"
" f = 3.0*f*f - 2.0*f*f*f;\n" // smoothstep " f = 3.0*f*f - 2.0*f*f*f;\n" // smoothstep
@ -985,7 +1003,7 @@ stbvox_tagged_string stbvox_fragment_program[] =
"{\n" "{\n"
" vec3 light_dir = light_source[0] - pos;\n" " vec3 light_dir = light_source[0] - pos;\n"
" float lambert = dot(light_dir, norm) / dot(light_dir, light_dir);\n" " float lambert = dot(light_dir, norm) / dot(light_dir, light_dir);\n"
" return light_source[1] * clamp(lambert, 0.0, 1.0);\n" " return clamp(light_source[1] * clamp(lambert, 0.0, 1.0), 0.0, 1.0);\n"
"}\n" "}\n"
}, },
}; };
@ -1052,7 +1070,7 @@ stbvox_uniform_info stbvox_uniforms[] =
{ STBVOX_UNIFORM_TYPE_vec3 , 12, 64, "texgen" , stbvox_default_texgen[0][0] , STBVOX_TAG_textured }, { STBVOX_UNIFORM_TYPE_vec3 , 12, 64, "texgen" , stbvox_default_texgen[0][0] , STBVOX_TAG_textured },
{ STBVOX_UNIFORM_TYPE_vec3 , 12, 4, "ambient" , 0 , STBVOX_TAG_all }, { STBVOX_UNIFORM_TYPE_vec3 , 12, 4, "ambient" , 0 , STBVOX_TAG_all },
{ STBVOX_UNIFORM_TYPE_vec3 , 12, 1, "camera_pos" , stbvox_dummy_transform[0] , STBVOX_TAG_all }, { STBVOX_UNIFORM_TYPE_vec4 , 12, 1, "camera_pos" , stbvox_dummy_transform[0] , STBVOX_TAG_all },
}; };
stbvox_uniform_info *stbvox_get_uniform_info(stbvox_mesh_maker *mm, int uniform) stbvox_uniform_info *stbvox_get_uniform_info(stbvox_mesh_maker *mm, int uniform)
@ -1458,31 +1476,54 @@ void stbvox_make_mesh_for_face(stbvox_mesh_maker *mm, stbvox_rotate rot, int fac
} }
} }
static stbvox_face_up_normal_012[4][4][4];
static stbvox_face_up_normal_013[4][4][4];
static stbvox_face_up_normal_023[4][4][4];
static stbvox_face_up_normal_123[4][4][4];
// render non-planar quads by splitting into two triangles, rendering each as a degenerate quad // render non-planar quads by splitting into two triangles, rendering each as a degenerate quad
void stbvox_make_02_split_mesh_for_face(stbvox_mesh_maker *mm, stbvox_rotate rot, int face1, int face2, int v_off, stbvox_pos pos, stbvox_mesh_vertex vertbase, stbvox_mesh_vertex *face_coord, unsigned char mesh) void stbvox_make_12_split_mesh_for_face(stbvox_mesh_maker *mm, stbvox_rotate rot, int face, int v_off, stbvox_pos pos, stbvox_mesh_vertex vertbase, stbvox_mesh_vertex *face_coord, unsigned char mesh, unsigned char *ht)
{ {
stbvox_mesh_vertex v[4]; stbvox_mesh_vertex v[4];
v[0] = face_coord[0];
v[1] = face_coord[1]; unsigned char normal1 = stbvox_face_up_normal_012[ht[2]][ht[1]][ht[0]];
v[2] = face_coord[2]; unsigned char normal2 = stbvox_face_up_normal_123[ht[3]][ht[2]][ht[1]];
v[3] = face_coord[0];
stbvox_make_mesh_for_face(mm, rot, face1, v_off, pos, vertbase, v, mesh, face1); if (face == STBVOX_FACE_down) {
v[1] = face_coord[2]; normal1 = stbvox_reverse_face[normal1];
v[2] = face_coord[3]; normal2 = stbvox_reverse_face[normal2];
stbvox_make_mesh_for_face(mm, rot, face2, v_off, pos, vertbase, v, mesh, face2); }
// the floor side face_coord is stored in order NW,NE,SE,SW, but ht[] is stored SW,SE,NW,NE
v[0] = face_coord[2];
v[1] = face_coord[3];
v[2] = face_coord[0];
v[3] = face_coord[2];
stbvox_make_mesh_for_face(mm, rot, face, v_off, pos, vertbase, v, mesh, normal1);
v[1] = face_coord[0];
v[2] = face_coord[1];
stbvox_make_mesh_for_face(mm, rot, face, v_off, pos, vertbase, v, mesh, normal2);
} }
void stbvox_make_13_split_mesh_for_face(stbvox_mesh_maker *mm, stbvox_rotate rot, int face1, int face2, int v_off, stbvox_pos pos, stbvox_mesh_vertex vertbase, stbvox_mesh_vertex *face_coord, unsigned char mesh) void stbvox_make_03_split_mesh_for_face(stbvox_mesh_maker *mm, stbvox_rotate rot, int face, int v_off, stbvox_pos pos, stbvox_mesh_vertex vertbase, stbvox_mesh_vertex *face_coord, unsigned char mesh, unsigned char *ht)
{ {
stbvox_mesh_vertex v[4]; stbvox_mesh_vertex v[4];
unsigned char normal1 = stbvox_face_up_normal_013[ht[3]][ht[1]][ht[0]];
unsigned char normal2 = stbvox_face_up_normal_023[ht[3]][ht[2]][ht[0]];
if (face == STBVOX_FACE_down) {
normal1 = stbvox_reverse_face[normal1];
normal2 = stbvox_reverse_face[normal2];
}
v[0] = face_coord[1]; v[0] = face_coord[1];
v[1] = face_coord[2]; v[1] = face_coord[2];
v[2] = face_coord[3]; v[2] = face_coord[3];
v[3] = face_coord[1]; v[3] = face_coord[1];
stbvox_make_mesh_for_face(mm, rot, face1, v_off, pos, vertbase, v, mesh, face1); stbvox_make_mesh_for_face(mm, rot, face, v_off, pos, vertbase, v, mesh, normal1);
v[1] = face_coord[3]; v[1] = face_coord[3];
v[2] = face_coord[0]; v[2] = face_coord[0];
stbvox_make_mesh_for_face(mm, rot, face2, v_off, pos, vertbase, v, mesh, face2); stbvox_make_mesh_for_face(mm, rot, face, v_off, pos, vertbase, v, mesh, normal2); // this one is correct!
} }
// simple case for mesh generation: we have only solid and empty blocks // simple case for mesh generation: we have only solid and empty blocks
@ -1624,18 +1665,18 @@ static unsigned char stbvox_facetype[STBVOX_GEOM_count][6] =
// @TODO this could be done with math given the current arrangement of the enum, but let's not require it // @TODO this could be done with math given the current arrangement of the enum, but let's not require it
static unsigned char stbvox_floor_slope_for_rot[4] = static unsigned char stbvox_floor_slope_for_rot[4] =
{ {
STBVOX_EFACE_south_up, STBVF_su,
STBVOX_EFACE_west_up, // @TODO: why is this reversed from what it should be? this is a north-is-up face, so slope should be south&up STBVF_wu, // @TODO: why is this reversed from what it should be? this is a north-is-up face, so slope should be south&up
STBVOX_EFACE_north_up, STBVF_nu,
STBVOX_EFACE_east_up, STBVF_eu,
}; };
static unsigned char stbvox_ceil_slope_for_rot[4] = static unsigned char stbvox_ceil_slope_for_rot[4] =
{ {
STBVOX_EFACE_south_down, STBVF_sd,
STBVOX_EFACE_east_down, STBVF_ed,
STBVOX_EFACE_north_down, STBVF_nd,
STBVOX_EFACE_west_down, STBVF_wd,
}; };
// this table indicates whether, for each pair of types above, a face is visible. // this table indicates whether, for each pair of types above, a face is visible.
@ -1693,6 +1734,233 @@ static unsigned char stbvox_rotate_vertex[8][4] =
{ 7,6,4,5 }, // zyx=111 { 7,6,4,5 }, // zyx=111
}; };
#ifdef STBVOX_OPTIMIZED_VHEIGHT
// optimized vheight generates a single normal over the entire face, even if it's not planar
static stbvox_optimized_face_up_normal[4][4][4][4] =
{
{
{
{ STBVF_u , STBVF_ne_u, STBVF_ne_u, STBVF_ne_u, },
{ STBVF_nw_u, STBVF_nu , STBVF_nu , STBVF_ne_u, },
{ STBVF_nw_u, STBVF_nu , STBVF_nu , STBVF_nu , },
{ STBVF_nw_u, STBVF_nw_u, STBVF_nu , STBVF_nu , },
},{
{ STBVF_su , STBVF_eu , STBVF_eu , STBVF_ne_u, },
{ STBVF_u , STBVF_ne_u, STBVF_ne_u, STBVF_ne_u, },
{ STBVF_nw_u, STBVF_nu , STBVF_nu , STBVF_ne_u, },
{ STBVF_nw_u, STBVF_nu , STBVF_nu , STBVF_nu , },
},{
{ STBVF_eu , STBVF_eu , STBVF_eu , STBVF_eu , },
{ STBVF_su , STBVF_eu , STBVF_eu , STBVF_ne_u, },
{ STBVF_u , STBVF_ne_u, STBVF_ne_u, STBVF_ne_u, },
{ STBVF_nw_u, STBVF_nu , STBVF_nu , STBVF_ne_u, },
},{
{ STBVF_eu , STBVF_eu , STBVF_eu , STBVF_eu , },
{ STBVF_eu , STBVF_eu , STBVF_eu , STBVF_eu , },
{ STBVF_su , STBVF_eu , STBVF_eu , STBVF_ne_u, },
{ STBVF_u , STBVF_ne_u, STBVF_ne_u, STBVF_ne_u, },
},
},{
{
{ STBVF_sw_u, STBVF_u , STBVF_ne_u, STBVF_ne_u, },
{ STBVF_wu , STBVF_nw_u, STBVF_nu , STBVF_nu , },
{ STBVF_wu , STBVF_nw_u, STBVF_nu , STBVF_nu , },
{ STBVF_nw_u, STBVF_nw_u, STBVF_nw_u, STBVF_nu , },
},{
{ STBVF_su , STBVF_su , STBVF_eu , STBVF_eu , },
{ STBVF_sw_u, STBVF_u , STBVF_ne_u, STBVF_ne_u, },
{ STBVF_wu , STBVF_nw_u, STBVF_nu , STBVF_nu , },
{ STBVF_wu , STBVF_nw_u, STBVF_nu , STBVF_nu , },
},{
{ STBVF_su , STBVF_eu , STBVF_eu , STBVF_eu , },
{ STBVF_su , STBVF_su , STBVF_eu , STBVF_eu , },
{ STBVF_sw_u, STBVF_u , STBVF_ne_u, STBVF_ne_u, },
{ STBVF_wu , STBVF_nw_u, STBVF_nu , STBVF_nu , },
},{
{ STBVF_su , STBVF_eu , STBVF_eu , STBVF_eu , },
{ STBVF_su , STBVF_eu , STBVF_eu , STBVF_eu , },
{ STBVF_su , STBVF_su , STBVF_eu , STBVF_eu , },
{ STBVF_sw_u, STBVF_u , STBVF_ne_u, STBVF_ne_u, },
},
},{
{
{ STBVF_sw_u, STBVF_sw_u, STBVF_u , STBVF_ne_u, },
{ STBVF_wu , STBVF_wu , STBVF_nw_u, STBVF_nu , },
{ STBVF_wu , STBVF_wu , STBVF_nw_u, STBVF_nu , },
{ STBVF_wu , STBVF_nw_u, STBVF_nw_u, STBVF_nw_u, },
},{
{ STBVF_su , STBVF_su , STBVF_su , STBVF_eu , },
{ STBVF_sw_u, STBVF_sw_u, STBVF_u , STBVF_ne_u, },
{ STBVF_wu , STBVF_wu , STBVF_nw_u, STBVF_nu , },
{ STBVF_wu , STBVF_wu , STBVF_nw_u, STBVF_nu , },
},{
{ STBVF_su , STBVF_su , STBVF_eu , STBVF_eu , },
{ STBVF_su , STBVF_su , STBVF_su , STBVF_eu , },
{ STBVF_sw_u, STBVF_sw_u, STBVF_u , STBVF_ne_u, },
{ STBVF_wu , STBVF_wu , STBVF_nw_u, STBVF_nu , },
},{
{ STBVF_su , STBVF_su , STBVF_eu , STBVF_eu , },
{ STBVF_su , STBVF_su , STBVF_eu , STBVF_eu , },
{ STBVF_su , STBVF_su , STBVF_su , STBVF_eu , },
{ STBVF_sw_u, STBVF_sw_u, STBVF_u , STBVF_ne_u, },
},
},{
{
{ STBVF_sw_u, STBVF_sw_u, STBVF_sw_u, STBVF_u , },
{ STBVF_sw_u, STBVF_wu , STBVF_wu , STBVF_nw_u, },
{ STBVF_wu , STBVF_wu , STBVF_wu , STBVF_nw_u, },
{ STBVF_wu , STBVF_wu , STBVF_nw_u, STBVF_nw_u, },
},{
{ STBVF_sw_u, STBVF_su , STBVF_su , STBVF_su , },
{ STBVF_sw_u, STBVF_sw_u, STBVF_sw_u, STBVF_u , },
{ STBVF_sw_u, STBVF_wu , STBVF_wu , STBVF_nw_u, },
{ STBVF_wu , STBVF_wu , STBVF_wu , STBVF_nw_u, },
},{
{ STBVF_su , STBVF_su , STBVF_su , STBVF_eu , },
{ STBVF_sw_u, STBVF_su , STBVF_su , STBVF_su , },
{ STBVF_sw_u, STBVF_sw_u, STBVF_sw_u, STBVF_u , },
{ STBVF_sw_u, STBVF_wu , STBVF_wu , STBVF_nw_u, },
},{
{ STBVF_su , STBVF_su , STBVF_su , STBVF_eu , },
{ STBVF_su , STBVF_su , STBVF_su , STBVF_eu , },
{ STBVF_sw_u, STBVF_su , STBVF_su , STBVF_su , },
{ STBVF_sw_u, STBVF_sw_u, STBVF_sw_u, STBVF_u , },
},
},
};
#else
// which normal to use for a given vheight that's planar
// @TODO: this table was constructed by hand and may have bugs
// nw se sw
static stbvox_planar_face_up_normal[4][4][4] =
{
{ // sw,se,nw,ne
{ STBVF_u , 0 , 0 , 0 }, // 0,0,0,0; 1,0,0,-1; 2,0,0,-2; 3,0,0,-3;
{ STBVF_u , STBVF_u , 0 , 0 }, // 0,1,0,1; 1,1,0, 0; 2,1,0,-1; 3,1,0,-2;
{ STBVF_wu , STBVF_nw_u, STBVF_nu , 0 }, // 0,2,0,2; 1,2,0, 1; 2,2,0, 0; 3,2,0,-1;
{ STBVF_wu , STBVF_nw_u, STBVF_nw_u, STBVF_nu }, // 0,3,0,3; 1,3,0, 2; 2,3,0, 1; 3,3,0, 0;
},{
{ STBVF_u , STBVF_u , 0 , 0 }, // 0,0,1,1; 1,0,1, 0; 2,0,1,-1; 3,0,1,-2;
{ STBVF_sw_u, STBVF_u , STBVF_ne_u, 0 }, // 0,1,1,2; 1,1,1, 1; 2,1,1, 0; 3,1,1,-1;
{ STBVF_sw_u, STBVF_u , STBVF_u , STBVF_ne_u }, // 0,2,1,3; 1,2,1, 2; 2,2,1, 1; 3,2,1, 0;
{ 0 , STBVF_w , STBVF_nw_u, STBVF_nu }, // 0,3,1,4; 1,3,1, 3; 2,3,1, 2; 3,3,1, 1;
},{
{ STBVF_su , STBVF_se_u, STBVF_eu , 0 }, // 0,0,2,2; 1,0,2, 1; 2,0,2, 0; 3,0,2,-1;
{ STBVF_sw_u, STBVF_u , STBVF_u , STBVF_ne_u }, // 0,1,2,3; 1,1,2, 2; 2,1,2, 1; 3,1,2, 0;
{ 0 , STBVF_sw_u, STBVF_u , STBVF_ne_u }, // 0,2,2,4; 1,2,2, 3; 2,2,2, 2; 3,2,2, 1;
{ 0 , 0 , STBVF_u , STBVF_u }, // 0,3,2,5; 1,3,2, 4; 2,3,2, 3; 3,3,2, 2;
},{
{ STBVF_su , STBVF_se_u, STBVF_se_u, STBVF_eu }, // 0,0,3,3; 1,0,3, 2; 2,0,3, 1; 3,0,3, 0;
{ 0 , STBVF_su , STBVF_se_u, STBVF_eu }, // 0,1,3,4; 1,1,3, 3; 2,1,3, 2; 3,1,3, 1;
{ 0 , 0 , STBVF_u , STBVF_u }, // 0,2,3,5; 1,2,3, 4; 2,2,3, 3; 3,2,3, 2;
{ 0 , 0 , 0 , STBVF_u }, // 0,3,3,6; 1,3,3, 5; 2,3,3, 4; 3,3,3, 3;
}
};
// these tables were constructed automatically using a variant of the code
// below; however, they seem wrong, so who knows
static stbvox_face_up_normal_012[4][4][4] =
{
{
{ STBVF_u , STBVF_ne_u, STBVF_ne_u, STBVF_ne_u, },
{ STBVF_wu , STBVF_nu , STBVF_ne_u, STBVF_ne_u, },
{ STBVF_wu , STBVF_nw_u, STBVF_nu , STBVF_ne_u, },
{ STBVF_wu , STBVF_nw_u, STBVF_nw_u, STBVF_nu , },
},{
{ STBVF_su , STBVF_eu , STBVF_ne_u, STBVF_ne_u, },
{ STBVF_sw_u, STBVF_u , STBVF_ne_u, STBVF_ne_u, },
{ STBVF_sw_u, STBVF_wu , STBVF_nu , STBVF_ne_u, },
{ STBVF_sw_u, STBVF_wu , STBVF_nw_u, STBVF_nu , },
},{
{ STBVF_su , STBVF_eu , STBVF_eu , STBVF_ne_u, },
{ STBVF_sw_u, STBVF_su , STBVF_eu , STBVF_ne_u, },
{ STBVF_sw_u, STBVF_sw_u, STBVF_u , STBVF_ne_u, },
{ STBVF_sw_u, STBVF_sw_u, STBVF_wu , STBVF_nu , },
},{
{ STBVF_su , STBVF_su , STBVF_eu , STBVF_eu , },
{ STBVF_sw_u, STBVF_su , STBVF_eu , STBVF_eu , },
{ STBVF_sw_u, STBVF_sw_u, STBVF_su , STBVF_eu , },
{ STBVF_sw_u, STBVF_sw_u, STBVF_sw_u, STBVF_u , },
}
};
static stbvox_face_up_normal_013[4][4][4] =
{
{
{ STBVF_u , STBVF_eu , STBVF_eu , STBVF_eu , },
{ STBVF_nw_u, STBVF_nu , STBVF_ne_u, STBVF_ne_u, },
{ STBVF_nw_u, STBVF_nw_u, STBVF_nu , STBVF_ne_u, },
{ STBVF_nw_u, STBVF_nw_u, STBVF_nw_u, STBVF_nu , },
},{
{ STBVF_su , STBVF_eu , STBVF_eu , STBVF_eu , },
{ STBVF_wu , STBVF_u , STBVF_eu , STBVF_eu , },
{ STBVF_nw_u, STBVF_nw_u, STBVF_nu , STBVF_ne_u, },
{ STBVF_nw_u, STBVF_nw_u, STBVF_nw_u, STBVF_nu , },
},{
{ STBVF_su , STBVF_su , STBVF_su , STBVF_eu , },
{ STBVF_sw_u, STBVF_su , STBVF_eu , STBVF_eu , },
{ STBVF_wu , STBVF_wu , STBVF_u , STBVF_eu , },
{ STBVF_nw_u, STBVF_nw_u, STBVF_nw_u, STBVF_nu , },
},{
{ STBVF_su , STBVF_su , STBVF_su , STBVF_eu , },
{ STBVF_sw_u, STBVF_su , STBVF_su , STBVF_su , },
{ STBVF_sw_u, STBVF_sw_u, STBVF_su , STBVF_eu , },
{ STBVF_wu , STBVF_wu , STBVF_wu , STBVF_u , },
}
};
static stbvox_face_up_normal_023[4][4][4] =
{
{
{ STBVF_u , STBVF_nu , STBVF_nu , STBVF_nu , },
{ STBVF_eu , STBVF_eu , STBVF_ne_u, STBVF_ne_u, },
{ STBVF_su , STBVF_eu , STBVF_eu , STBVF_ne_u, },
{ STBVF_eu , STBVF_eu , STBVF_eu , STBVF_eu , },
},{
{ STBVF_wu , STBVF_nw_u, STBVF_nw_u, STBVF_nw_u, },
{ STBVF_su , STBVF_u , STBVF_nu , STBVF_nu , },
{ STBVF_su , STBVF_eu , STBVF_eu , STBVF_ne_u, },
{ STBVF_su , STBVF_su , STBVF_eu , STBVF_eu , },
},{
{ STBVF_wu , STBVF_nw_u, STBVF_nw_u, STBVF_nw_u, },
{ STBVF_sw_u, STBVF_wu , STBVF_nw_u, STBVF_nw_u, },
{ STBVF_su , STBVF_su , STBVF_u , STBVF_nu , },
{ STBVF_su , STBVF_su , STBVF_eu , STBVF_eu , },
},{
{ STBVF_wu , STBVF_nw_u, STBVF_nw_u, STBVF_nw_u, },
{ STBVF_sw_u, STBVF_wu , STBVF_nw_u, STBVF_nw_u, },
{ STBVF_sw_u, STBVF_sw_u, STBVF_wu , STBVF_nw_u, },
{ STBVF_su , STBVF_su , STBVF_su , STBVF_u , },
}
};
static stbvox_face_up_normal_123[4][4][4] =
{
{
{ STBVF_u , STBVF_nu , STBVF_nu , STBVF_nu , },
{ STBVF_eu , STBVF_ne_u, STBVF_ne_u, STBVF_ne_u, },
{ STBVF_eu , STBVF_ne_u, STBVF_ne_u, STBVF_ne_u, },
{ STBVF_eu , STBVF_ne_u, STBVF_ne_u, STBVF_ne_u, },
},{
{ STBVF_sw_u, STBVF_wu , STBVF_nw_u, STBVF_nw_u, },
{ STBVF_su , STBVF_u , STBVF_nu , STBVF_nu , },
{ STBVF_eu , STBVF_eu , STBVF_ne_u, STBVF_ne_u, },
{ STBVF_eu , STBVF_eu , STBVF_ne_u, STBVF_ne_u, },
},{
{ STBVF_sw_u, STBVF_sw_u, STBVF_wu , STBVF_nw_u, },
{ STBVF_sw_u, STBVF_sw_u, STBVF_wu , STBVF_nw_u, },
{ STBVF_su , STBVF_su , STBVF_u , STBVF_nu , },
{ STBVF_su , STBVF_eu , STBVF_eu , STBVF_ne_u, },
},{
{ STBVF_sw_u, STBVF_sw_u, STBVF_sw_u, STBVF_wu , },
{ STBVF_sw_u, STBVF_sw_u, STBVF_sw_u, STBVF_wu , },
{ STBVF_sw_u, STBVF_sw_u, STBVF_sw_u, STBVF_wu , },
{ STBVF_su , STBVF_su , STBVF_su , STBVF_u , },
}
};
#endif
void stbvox_make_mesh_for_block_with_geo(stbvox_mesh_maker *mm, stbvox_pos pos, int v_off) void stbvox_make_mesh_for_block_with_geo(stbvox_mesh_maker *mm, stbvox_pos pos, int v_off)
{ {
int ns_off = mm->y_stride_in_bytes; int ns_off = mm->y_stride_in_bytes;
@ -1911,7 +2179,7 @@ void stbvox_make_mesh_for_block_with_geo(stbvox_mesh_maker *mm, stbvox_pos pos,
if (visible_faces & (1 << STBVOX_FACE_west)) if (visible_faces & (1 << STBVOX_FACE_west))
stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_west , v_off, pos, basevert, vmesh[STBVOX_FACE_west ], mesh, STBVOX_FACE_west); stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_west , v_off, pos, basevert, vmesh[STBVOX_FACE_west ], mesh, STBVOX_FACE_west);
} }
if (geo >= STBVOX_GEOM_floor_vheight_02) { if (geo >= STBVOX_GEOM_floor_vheight_03) {
// this case can also be generated with regular block gen with special vmesh, // this case can also be generated with regular block gen with special vmesh,
// except: // except:
// if we want to generate middle diagonal for 'weird' blocks // if we want to generate middle diagonal for 'weird' blocks
@ -1951,7 +2219,7 @@ void stbvox_make_mesh_for_block_with_geo(stbvox_mesh_maker *mm, stbvox_pos pos,
// our visible_faces test was wrong // our visible_faces test was wrong
extreme = (ht[0] == 3 || ht[1] == 3 || ht[2] == 3 || ht[3] == 3); extreme = (ht[0] == 3 || ht[1] == 3 || ht[2] == 3 || ht[3] == 3);
if (geo >= STBVOX_GEOM_ceil_vheight_02) { if (geo >= STBVOX_GEOM_ceil_vheight_03) {
cube[0] = stbvox_vertex_p(0,0,ht[0],0,0); cube[0] = stbvox_vertex_p(0,0,ht[0],0,0);
cube[1] = stbvox_vertex_p(0,0,ht[1],0,0); cube[1] = stbvox_vertex_p(0,0,ht[1],0,0);
cube[2] = stbvox_vertex_p(0,0,ht[2],0,0); cube[2] = stbvox_vertex_p(0,0,ht[2],0,0);
@ -1992,30 +2260,44 @@ void stbvox_make_mesh_for_block_with_geo(stbvox_mesh_maker *mm, stbvox_pos pos,
// @TODO generate split faces // @TODO generate split faces
if (visible_faces & (1 << STBVOX_FACE_up)) { if (visible_faces & (1 << STBVOX_FACE_up)) {
#ifndef STBVOX_OPTIMIZED_VHEIGHT if (geo >= STBVOX_GEOM_ceil_vheight_03)
// check if it's planar // flat
if (geo < STBVOX_GEOM_ceil_vheight_02 && cube[5] + cube[6] != cube[4] + cube[7]) {
// not planar, split along diagonal and make degenerate
if (geo == STBVOX_GEOM_floor_vheight_02)
stbvox_make_02_split_mesh_for_face(mm, rotate, STBVOX_FACE_up, STBVOX_FACE_up, v_off, pos, basevert, vmesh[STBVOX_FACE_up], mesh);
else
stbvox_make_13_split_mesh_for_face(mm, rotate, STBVOX_FACE_up, STBVOX_FACE_up, v_off, pos, basevert, vmesh[STBVOX_FACE_up], mesh);
} else
#endif
stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_up , v_off, pos, basevert, vmesh[STBVOX_FACE_up], mesh, STBVOX_FACE_up); stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_up , v_off, pos, basevert, vmesh[STBVOX_FACE_up], mesh, STBVOX_FACE_up);
else {
#ifndef STBVOX_OPTIMIZED_VHEIGHT
// check if it's non-planar
if (cube[5] + cube[6] != cube[4] + cube[7]) {
// not planar, split along diagonal and make degenerate quads
if (geo == STBVOX_GEOM_floor_vheight_03)
stbvox_make_03_split_mesh_for_face(mm, rotate, STBVOX_FACE_up, v_off, pos, basevert, vmesh[STBVOX_FACE_up], mesh, ht);
else
stbvox_make_12_split_mesh_for_face(mm, rotate, STBVOX_FACE_up, v_off, pos, basevert, vmesh[STBVOX_FACE_up], mesh, ht);
} else
stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_up , v_off, pos, basevert, vmesh[STBVOX_FACE_up], mesh, stbvox_planar_face_up_normal[ht[2]][ht[1]][ht[0]]);
#else
stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_up , v_off, pos, basevert, vmesh[STBVOX_FACE_up], mesh, stbvox_optimized_face_up_normal[ht[3]][ht[2]][ht[1]][ht[0]]);
#endif
}
} }
if (visible_faces & (1 << STBVOX_FACE_down)) { if (visible_faces & (1 << STBVOX_FACE_down)) {
#ifndef STBVOX_OPTIMIZED_VHEIGHT if (geo < STBVOX_GEOM_ceil_vheight_03)
// check if it's planar // flat
if (geo >= STBVOX_GEOM_ceil_vheight_02 && cube[1] + cube[2] != cube[0] + cube[3]) {
// not planar, split along diagonal and make degenerate
if (geo == STBVOX_GEOM_ceil_vheight_02)
stbvox_make_02_split_mesh_for_face(mm, rotate, STBVOX_FACE_down, STBVOX_FACE_down, v_off, pos, basevert, vmesh[STBVOX_FACE_down], mesh);
else
stbvox_make_13_split_mesh_for_face(mm, rotate, STBVOX_FACE_down, STBVOX_FACE_down, v_off, pos, basevert, vmesh[STBVOX_FACE_down], mesh);
} else
#endif
stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_down, v_off, pos, basevert, vmesh[STBVOX_FACE_down], mesh, STBVOX_FACE_down); stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_down, v_off, pos, basevert, vmesh[STBVOX_FACE_down], mesh, STBVOX_FACE_down);
else {
#ifndef STBVOX_OPTIMIZED_VHEIGHT
// check if it's non-planar
if (cube[1] + cube[2] != cube[0] + cube[3]) {
// not planar, split along diagonal and make degenerate quads
if (geo == STBVOX_GEOM_ceil_vheight_03)
stbvox_make_03_split_mesh_for_face(mm, rotate, STBVOX_FACE_down, v_off, pos, basevert, vmesh[STBVOX_FACE_down], mesh, ht);
else
stbvox_make_12_split_mesh_for_face(mm, rotate, STBVOX_FACE_down, v_off, pos, basevert, vmesh[STBVOX_FACE_down], mesh, ht);
} else
stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_down, v_off, pos, basevert, vmesh[STBVOX_FACE_down], mesh, stbvox_reverse_face[stbvox_planar_face_up_normal[ht[2]][ht[1]][ht[0]]]);
#else
stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_down, v_off, pos, basevert, vmesh[STBVOX_FACE_down], mesh, stbvox_reverse_face[stbvox_optimized_face_up_normal[ht[3]][ht[2]][ht[1]][ht[0]]]);
#endif
}
} }
if (mm->input.rotate) { if (mm->input.rotate) {
@ -2067,10 +2349,10 @@ void stbvox_make_mesh_for_block_with_geo(stbvox_mesh_maker *mm, stbvox_pos pos,
} }
rot.facerot = 0; rot.facerot = 0;
stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_north, v_off, pos, basevert, stbvox_vmesh_crossed_pair[STBVOX_FACE_north], mesh, STBVOX_EFACE_ne_up); stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_north, v_off, pos, basevert, stbvox_vmesh_crossed_pair[STBVOX_FACE_north], mesh, STBVF_ne_u_cross);
stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_south, v_off, pos, basevert, stbvox_vmesh_crossed_pair[STBVOX_FACE_south], mesh, STBVOX_EFACE_sw_up); stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_south, v_off, pos, basevert, stbvox_vmesh_crossed_pair[STBVOX_FACE_south], mesh, STBVF_sw_u_cross);
stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_east , v_off, pos, basevert, stbvox_vmesh_crossed_pair[STBVOX_FACE_east ], mesh, STBVOX_EFACE_se_up); stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_east , v_off, pos, basevert, stbvox_vmesh_crossed_pair[STBVOX_FACE_east ], mesh, STBVF_se_u_cross);
stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_west , v_off, pos, basevert, stbvox_vmesh_crossed_pair[STBVOX_FACE_west ], mesh, STBVOX_EFACE_nw_up); stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_west , v_off, pos, basevert, stbvox_vmesh_crossed_pair[STBVOX_FACE_west ], mesh, STBVF_nw_u_cross);
} }
@ -2357,4 +2639,57 @@ void stbvox_config_set_z_precision(stbvox_mesh_maker *mm, int z_fractional_bits)
} }
/////////////////////////////////////////////////////////////////////////////
//
// offline computation
//
#if 0
// compute optimized vheight table
static char *normal_names[32] =
{
0,0,0,0,"u ",0, "eu ",0,
0,0,0,0,"ne_u",0, "nu ",0,
0,0,0,0,"nw_u",0, "wu ",0,
0,0,0,0,"sw_u",0, "su ",0,
};
static char *find_best_normal(float x, float y, float z)
{
int best_slot = 4;
float best_dot = 0;
int i;
for (i=0; i < 32; ++i) {
if (normal_names[i]) {
float dot = x * stbvox_default_normals[i].x + y * stbvox_default_normals[i].y + z * stbvox_default_normals[i].z;
if (dot > best_dot) {
best_dot = dot;
best_slot = i;
}
}
}
return normal_names[best_slot];
}
int main(int argc, char **argv)
{
int sw,se,nw,ne;
for (ne=0; ne < 4; ++ne) {
for (nw=0; nw < 4; ++nw) {
for (se=0; se < 4; ++se) {
printf(" { ");
for (sw=0; sw < 4; ++sw) {
float x = (float) (nw + sw - ne - se);
float y = (float) (sw + se - nw - ne);
float z = 2;
printf("STBVF_%s, ", find_best_normal(x,y,z));
}
printf("},\n");
}
}
}
return 0;
}
#endif
#endif // STB_VOXEL_RENDER_IMPLEMENTATION #endif // STB_VOXEL_RENDER_IMPLEMENTATION

View File

@ -13,8 +13,11 @@
#include "sdl_thread.h" #include "sdl_thread.h"
#include <math.h> #include <math.h>
#define STB_VOXEL_RENDER_IMPLEMENTATION //#define VHEIGHT_TEST
//#define STBVOX_OPTIMIZED_VHEIGHT
#define STBVOX_ROTATION_IN_LIGHTING #define STBVOX_ROTATION_IN_LIGHTING
#define STB_VOXEL_RENDER_IMPLEMENTATION
#include "stb_voxel_render.h" #include "stb_voxel_render.h"
extern void ods(char *fmt, ...); extern void ods(char *fmt, ...);
@ -585,7 +588,9 @@ void build_chunk(int chunk_x, int chunk_y, fast_chunk *fc_table[4][4], raw_mesh
int a,b,z; int a,b,z;
stbvox_input_description *map; stbvox_input_description *map;
//unsigned char vheight[34][34][18]; #ifdef VHEIGHT_TEST
unsigned char vheight[34][34][18];
#endif
assert((chunk_x & 1) == 0); assert((chunk_x & 1) == 0);
assert((chunk_y & 1) == 0); assert((chunk_y & 1) == 0);
@ -632,7 +637,7 @@ void build_chunk(int chunk_x, int chunk_y, fast_chunk *fc_table[4][4], raw_mesh
map->blocktype = &rm->sv_blocktype[1][1][1-z]; // specify location of 0,0,0 so that accessing z0..z1 gets right data map->blocktype = &rm->sv_blocktype[1][1][1-z]; // specify location of 0,0,0 so that accessing z0..z1 gets right data
map->lighting = &rm->sv_lighting[1][1][1-z]; map->lighting = &rm->sv_lighting[1][1][1-z];
#if 0 #ifdef VHEIGHT_TEST
// hacky test of vheight // hacky test of vheight
for (a=0; a < 34; ++a) { for (a=0; a < 34; ++a) {
for (b=0; b < 34; ++b) { for (b=0; b < 34; ++b) {
@ -640,8 +645,12 @@ void build_chunk(int chunk_x, int chunk_y, fast_chunk *fc_table[4][4], raw_mesh
for (c=0; c < 17; ++c) { for (c=0; c < 17; ++c) {
if (rm->sv_blocktype[a][b][c] != 0 && rm->sv_blocktype[a][b][c+1] == 0) { if (rm->sv_blocktype[a][b][c] != 0 && rm->sv_blocktype[a][b][c+1] == 0) {
// topmost block // topmost block
rm->sv_blocktype[a][b][c] = 168;
vheight[a][b][c] = rand() & 255; vheight[a][b][c] = rand() & 255;
rm->sv_blocktype[a][b][c] = 168;
} else if (c > 0 && rm->sv_blocktype[a][b][c] != 0 && rm->sv_blocktype[a][b][c-1] == 0) {
// bottommost block
vheight[a][b][c] = ((rand() % 3) << 6) + ((rand() % 3) << 4) + ((rand() % 3) << 2) + (rand() % 3);
rm->sv_blocktype[a][b][c] = 169;
} }
} }
vheight[a][b][c] = STBVOX_MAKE_VHEIGHT(2,2,2,2); // flat top vheight[a][b][c] = STBVOX_MAKE_VHEIGHT(2,2,2,2); // flat top
@ -792,7 +801,7 @@ void mesh_init(void)
minecraft_color_for_blocktype[11][i] = 63; // emissive minecraft_color_for_blocktype[11][i] = 63; // emissive
} }
#if 0 // vheight test #ifdef VHEIGHT_TEST
effective_blocktype[168] = 168; effective_blocktype[168] = 168;
minecraft_tex1_for_blocktype[168][0] = 1; minecraft_tex1_for_blocktype[168][0] = 1;
minecraft_tex1_for_blocktype[168][1] = 1; minecraft_tex1_for_blocktype[168][1] = 1;
@ -800,7 +809,15 @@ void mesh_init(void)
minecraft_tex1_for_blocktype[168][3] = 1; minecraft_tex1_for_blocktype[168][3] = 1;
minecraft_tex1_for_blocktype[168][4] = 1; minecraft_tex1_for_blocktype[168][4] = 1;
minecraft_tex1_for_blocktype[168][5] = 1; minecraft_tex1_for_blocktype[168][5] = 1;
minecraft_geom_for_blocktype[168] = STBVOX_GEOM_floor_vheight_02; minecraft_geom_for_blocktype[168] = STBVOX_GEOM_floor_vheight_12;
effective_blocktype[169] = 169;
minecraft_tex1_for_blocktype[169][0] = 1;
minecraft_tex1_for_blocktype[169][1] = 1;
minecraft_tex1_for_blocktype[169][2] = 1;
minecraft_tex1_for_blocktype[169][3] = 1;
minecraft_tex1_for_blocktype[169][4] = 1;
minecraft_tex1_for_blocktype[169][5] = 1;
minecraft_geom_for_blocktype[169] = STBVOX_GEOM_ceil_vheight_03;
#endif #endif
remap[53] = 1; remap[53] = 1;

View File

@ -184,9 +184,12 @@ GLint uniform_loc[16];
float table3[128][3]; float table3[128][3];
GLint tablei[2]; GLint tablei[2];
float step=0;
void setup_uniforms(float pos[3]) void setup_uniforms(float pos[3])
{ {
int i,j; int i,j;
step += 1.0f/60.0f;
for (i=0; i < STBVOX_UNIFORM_count; ++i) { for (i=0; i < STBVOX_UNIFORM_count; ++i) {
stbvox_uniform_info *ui = stbvox_get_uniform_info(&g_mesh_maker, i); stbvox_uniform_info *ui = stbvox_get_uniform_info(&g_mesh_maker, i);
uniform_loc[i] = -1; uniform_loc[i] = -1;
@ -224,9 +227,11 @@ void setup_uniforms(float pos[3])
table3[0][0] = pos[0]; table3[0][0] = pos[0];
table3[0][1] = pos[1]; table3[0][1] = pos[1];
table3[0][2] = pos[2]; table3[0][2] = pos[2];
table3[0][3] = stb_max(0,(float)sin(step*2)*0.125f);
break; break;
case STBVOX_UNIFORM_ambient: { case STBVOX_UNIFORM_ambient: {
float bright = 0.75;
float amb[3][3]; float amb[3][3];
// ambient direction is sky-colored upwards // ambient direction is sky-colored upwards
@ -245,8 +250,8 @@ void setup_uniforms(float pos[3])
// amb[1] + (amb[2] - amb[1]) * dot/2 + (amb[2]-amb[1])/2 // amb[1] + (amb[2] - amb[1]) * dot/2 + (amb[2]-amb[1])/2
for (j=0; j < 3; ++j) { for (j=0; j < 3; ++j) {
table3[1][j] = (amb[2][j] - amb[1][j])/2; table3[1][j] = (amb[2][j] - amb[1][j])/2 * bright;
table3[2][j] = (amb[1][j] + amb[2][j])/2; table3[2][j] = (amb[1][j] + amb[2][j])/2 * bright;
} }
// fog color // fog color
@ -783,7 +788,7 @@ void render_caves(float campos[3])
{ {
float lighting[2][3] = { { campos[0],campos[1],campos[2] }, { 0.75,0.75,0.65f } }; float lighting[2][3] = { { campos[0],campos[1],campos[2] }, { 0.75,0.75,0.65f } };
float bright = 15; float bright = 8;
lighting[1][0] *= bright; lighting[1][0] *= bright;
lighting[1][1] *= bright; lighting[1][1] *= bright;
lighting[1][2] *= bright; lighting[1][2] *= bright;