various cleanup; vheight works (only one path tested)

This commit is contained in:
Sean Barrett 2015-02-22 17:42:46 -08:00
parent 1d18b23ea1
commit f9c24c20fc
5 changed files with 167 additions and 103 deletions

View File

@ -155,6 +155,14 @@
// stb_voxel_render 4..14 bytes : 2015/02??? // stb_voxel_render 4..14 bytes : 2015/02???
//
#ifndef STBVOX_MODE
#define STBVOX_MODE 0
#endif
// The following are candidate voxel modes. Only modes 0, 1, and 20 are // The following are candidate voxel modes. Only modes 0, 1, and 20 are
// currently implemented. Reducing the storage-per-quad further // currently implemented. Reducing the storage-per-quad further
// shouldn't improve performance, although obviously it allow you // shouldn't improve performance, although obviously it allow you
@ -252,7 +260,7 @@ enum
STBVOX_UNIFORM_ambient, STBVOX_UNIFORM_ambient,
STBVOX_UNIFORM_camera_pos, STBVOX_UNIFORM_camera_pos,
STBVOX_UNIFORM__count, STBVOX_UNIFORM_count,
}; };
enum enum
@ -928,7 +936,7 @@ stbvox_uniform_info *stbvox_get_uniform_info(stbvox_mesh_maker *mm, int uniform)
if (stbvox_default_palette[0][0] == 0) // NOTE: not threadsafe, so call once to init if (stbvox_default_palette[0][0] == 0) // NOTE: not threadsafe, so call once to init
stbvox_build_default_palette(); stbvox_build_default_palette();
if (uniform < 0 || uniform >= STBVOX_UNIFORM__count) if (uniform < 0 || uniform >= STBVOX_UNIFORM_count)
return NULL; return NULL;
if (stbvox_check_tag(mm, stbvox_uniforms[uniform].tags)) if (stbvox_check_tag(mm, stbvox_uniforms[uniform].tags))
@ -1322,12 +1330,39 @@ void stbvox_make_mesh_for_face(stbvox_mesh_maker *mm, stbvox_rotate rot, int fac
} }
} else { } else {
int i; *mv[0] = vertbase + face_coord[0] + p1[0];
for (i=0; i < 4; ++i) { *mv[1] = vertbase + face_coord[1] + p1[1];
*mv[i] = vertbase + face_coord[i] + p1[i]; *mv[2] = vertbase + face_coord[2] + p1[2];
*mv[3] = vertbase + face_coord[3] + p1[3];
} }
} }
} }
// 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)
{
stbvox_mesh_vertex v[4];
v[0] = face_coord[0];
v[1] = face_coord[1];
v[2] = face_coord[2];
v[3] = face_coord[0];
stbvox_make_mesh_for_face(mm, rot, face1, v_off, pos, vertbase, v, mesh);
v[1] = face_coord[2];
v[2] = face_coord[3];
stbvox_make_mesh_for_face(mm, rot, face2, v_off, pos, vertbase, v, mesh);
}
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)
{
stbvox_mesh_vertex v[4];
v[0] = face_coord[1];
v[1] = face_coord[2];
v[2] = face_coord[3];
v[3] = face_coord[1];
stbvox_make_mesh_for_face(mm, rot, face1, v_off, pos, vertbase, v, mesh);
v[1] = face_coord[3];
v[2] = face_coord[0];
stbvox_make_mesh_for_face(mm, rot, face2, v_off, pos, vertbase, v, mesh);
} }
// simple case for mesh generation: we have only solid and empty blocks // simple case for mesh generation: we have only solid and empty blocks
@ -1344,11 +1379,8 @@ void stbvox_make_mesh_for_block(stbvox_mesh_maker *mm, stbvox_pos pos, int v_off
unsigned char mesh = mm->default_mesh; unsigned char mesh = mm->default_mesh;
if (mm->input.selector) { if (mm->input.selector)
mesh = mm->input.selector[v_off]; mesh = mm->input.selector[v_off];
simple_rot = mesh >> 4;
mesh &= 15;
}
// check if we're going off the end // check if we're going off the end
if (mm->output_cur[mesh][0] + mm->output_size[mesh][0]*6 > mm->output_end[mesh][0]) { if (mm->output_cur[mesh][0] + mm->output_size[mesh][0]*6 > mm->output_end[mesh][0]) {
@ -1356,6 +1388,10 @@ void stbvox_make_mesh_for_block(stbvox_mesh_maker *mm, stbvox_pos pos, int v_off
return; return;
} }
#ifdef STBVOX_ROTATION_IN_LIGHTING
simple_rot = mm->input.lighting[v_off] & 3;
#endif
if (blockptr[ 1]==0) if (blockptr[ 1]==0)
stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_up , v_off, pos, basevert, vmesh+4*STBVOX_FACE_up, mesh); stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_up , v_off, pos, basevert, vmesh+4*STBVOX_FACE_up, mesh);
if (blockptr[-1]==0) if (blockptr[-1]==0)
@ -1404,14 +1440,14 @@ static unsigned char stbvox_hasface[STBVOX_MAX_GEOM][STBVOX_NUM_ROTATION] =
{ 0,0,0,0 }, // knockout { 0,0,0,0 }, // knockout
{ 63,63,63,63 }, // solid { 63,63,63,63 }, // solid
{ 63,63,63,63 }, // transp { 63,63,63,63 }, // transp
{ 63,63,63,63 }, // slabs { 63,63,63,63 }, // slab
{ 63,63,63,63 }, { 63,63,63,63 }, // slab
{ 1|2|4|48, 8|1|2|48, 4|8|1|48, 2|4|8|48, }, // floor slopes { 1|2|4|48, 8|1|2|48, 4|8|1|48, 2|4|8|48, }, // floor slopes
{ 1|2|4|48, 8|1|2|48, 4|8|1|48, 2|4|8|48, }, // ceil slopes { 1|2|4|48, 8|1|2|48, 4|8|1|48, 2|4|8|48, }, // ceil slopes
{ 47,47,47,47 }, // wall-projected diagonal with down face { 47,47,47,47 }, // wall-projected diagonal with down face
{ 31,31,31,31 }, // wall-projected diagonal with up face { 31,31,31,31 }, // wall-projected diagonal with up face
{ 63,63,63,63 }, // crossed-pair has special handling, but avoid early-out { 63,63,63,63 }, // crossed-pair has special handling, but avoid early-out
{ 63,63,63,63 }, // reserved { 63,63,63,63 }, // force
{ 63,63,63,63 }, { 63,63,63,63 },
{ 63,63,63,63 }, { 63,63,63,63 },
{ 63,63,63,63 }, { 63,63,63,63 },
@ -1430,17 +1466,13 @@ enum
STBVOX_FT_diag_013, STBVOX_FT_diag_013,
STBVOX_FT_diag_123, STBVOX_FT_diag_123,
STBVOX_FT_force , // can't be covered up, used for internal faces, also hides nothing STBVOX_FT_force , // can't be covered up, used for internal faces, also hides nothing
}; STBVOX_FT_partial , // only covered by solid, never covers anything else
// these are additional geometry types used internally STBVOX_FT_count
enum
{
STBVOX_GEOM_internal_force = STBVOX_GEOM_count,
STBVOX_GEOM_internal_count
}; };
// this determines which face type above is visible on each side of the geometry // this determines which face type above is visible on each side of the geometry
static unsigned char stbvox_facetype[STBVOX_GEOM_internal_count][6] = static unsigned char stbvox_facetype[STBVOX_GEOM_count][6] =
{ {
{ 0, }, // STBVOX_GEOM_empty { 0, }, // STBVOX_GEOM_empty
{ STBVOX_FT_solid, STBVOX_FT_solid, STBVOX_FT_solid, STBVOX_FT_solid, STBVOX_FT_solid, STBVOX_FT_solid }, // knockout { STBVOX_FT_solid, STBVOX_FT_solid, STBVOX_FT_solid, STBVOX_FT_solid, STBVOX_FT_solid, STBVOX_FT_solid }, // knockout
@ -1455,20 +1487,17 @@ static unsigned char stbvox_facetype[STBVOX_GEOM_internal_count][6] =
{ STBVOX_FT_diag_123, STBVOX_FT_solid, STBVOX_FT_diag_023, STBVOX_FT_force, STBVOX_FT_none, STBVOX_FT_solid }, { STBVOX_FT_diag_123, STBVOX_FT_solid, STBVOX_FT_diag_023, STBVOX_FT_force, STBVOX_FT_none, STBVOX_FT_solid },
{ STBVOX_FT_diag_012, STBVOX_FT_solid, STBVOX_FT_diag_013, STBVOX_FT_force, STBVOX_FT_solid, STBVOX_FT_none }, { STBVOX_FT_diag_012, STBVOX_FT_solid, STBVOX_FT_diag_013, STBVOX_FT_force, STBVOX_FT_solid, STBVOX_FT_none },
{ STBVOX_FT_force, STBVOX_FT_force, STBVOX_FT_force, STBVOX_FT_force, 0,0 }, // crossed pair { STBVOX_FT_force, STBVOX_FT_force, STBVOX_FT_force, STBVOX_FT_force, 0,0 }, // crossed pair
{ STBVOX_FT_force, STBVOX_FT_force, STBVOX_FT_force, STBVOX_FT_force, STBVOX_FT_force, STBVOX_FT_force }, { STBVOX_FT_force, STBVOX_FT_force, STBVOX_FT_force, STBVOX_FT_force, STBVOX_FT_force, STBVOX_FT_force }, // GEOM_force
//0, }, // GEOM_force, show as empty so that neighbors are always visible
{ 0,0,0,0,0, STBVOX_FT_solid }, // floor vheight { STBVOX_FT_partial,STBVOX_FT_partial,STBVOX_FT_partial,STBVOX_FT_partial, STBVOX_FT_force, STBVOX_FT_solid }, // floor vheight, all neighbors forced
{ 0,0,0,0,0, STBVOX_FT_solid }, // floor vheight { STBVOX_FT_partial,STBVOX_FT_partial,STBVOX_FT_partial,STBVOX_FT_partial, STBVOX_FT_force, STBVOX_FT_solid }, // floor vheight, all neighbors forced
{ 0,0,0,0, STBVOX_FT_solid,0 }, // ceil vheight { STBVOX_FT_partial,STBVOX_FT_partial,STBVOX_FT_partial,STBVOX_FT_partial, STBVOX_FT_solid, STBVOX_FT_force }, // ceil vheight, all neighbors forced
{ 0,0,0,0, STBVOX_FT_solid,0 }, // ceil vheight { STBVOX_FT_partial,STBVOX_FT_partial,STBVOX_FT_partial,STBVOX_FT_partial, STBVOX_FT_solid, STBVOX_FT_force }, // ceil vheight, all neighbors forced
//{ STBVOX_FT_solid, STBVOX_FT_solid, STBVOX_FT_solid, STBVOX_FT_solid, STBVOX_FT_solid, STBVOX_FT_solid }, // internal force
}; };
// 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.
// each value indicates whether a given type is visible for all neighbor types // each value indicates whether a given type is visible for all neighbor types
static unsigned short stbvox_face_visible[9] = static unsigned short stbvox_face_visible[STBVOX_FT_count] =
{ {
// we encode the table by listing which cases cause *obscuration*, and bitwise inverting that // we encode the table by listing which cases cause *obscuration*, and bitwise inverting that
// table is pre-shifted by 5 to save a shift when it's accessed // table is pre-shifted by 5 to save a shift when it's accessed
@ -1481,6 +1510,7 @@ static unsigned short stbvox_face_visible[9] =
(unsigned short) ((~((1<<STBVOX_FT_solid) | (1<<STBVOX_FT_diag_012)))<<5), // diag013 matches diag012 (unsigned short) ((~((1<<STBVOX_FT_solid) | (1<<STBVOX_FT_diag_012)))<<5), // diag013 matches diag012
(unsigned short) ((~((1<<STBVOX_FT_solid) | (1<<STBVOX_FT_diag_023)))<<5), // diag123 matches diag023 (unsigned short) ((~((1<<STBVOX_FT_solid) | (1<<STBVOX_FT_diag_023)))<<5), // diag123 matches diag023
(unsigned short) ((~0 )<<5), // force is always rendered regardless, always forces neighbor (unsigned short) ((~0 )<<5), // force is always rendered regardless, always forces neighbor
(unsigned short) ((~((1<<STBVOX_FT_solid) ))<<5), // partial is only completely obscured only by solid
}; };
// the vertex heights of the block types, in binary vertex order (zyx): // the vertex heights of the block types, in binary vertex order (zyx):
@ -1665,7 +1695,7 @@ void stbvox_make_mesh_for_block_with_geo(stbvox_mesh_maker *mm, stbvox_pos pos,
stbvox_mesh_vertex basevert; stbvox_mesh_vertex basevert;
stbvox_mesh_vertex vmesh[6][4]; stbvox_mesh_vertex vmesh[6][4];
stbvox_rotate rotate = { 0,0,0,0 }; stbvox_rotate rotate = { 0,0,0,0 };
unsigned char simple_rot = 0; unsigned char simple_rot = rot;
int i; int i;
// we only need to do this for the displayed faces, but it's easier // we only need to do this for the displayed faces, but it's easier
// to just do it up front; @OPTIMIZE check if it's faster to do it // to just do it up front; @OPTIMIZE check if it's faster to do it
@ -1721,8 +1751,10 @@ void stbvox_make_mesh_for_block_with_geo(stbvox_mesh_maker *mm, stbvox_pos pos,
stbvox_mesh_vertex cube[8]; stbvox_mesh_vertex cube[8];
stbvox_mesh_vertex basevert; stbvox_mesh_vertex basevert;
stbvox_rotate rotate = { 0,0,0,0 }; stbvox_rotate rotate = { 0,0,0,0 };
unsigned char simple_rot = 0; unsigned char simple_rot = rot;
unsigned char ht[4]; unsigned char ht[4];
int extreme;
// extract the heights // extract the heights
if (mm->input.vheight) { if (mm->input.vheight) {
unsigned char v = mm->input.vheight[v_off]; unsigned char v = mm->input.vheight[v_off];
@ -1732,15 +1764,34 @@ void stbvox_make_mesh_for_block_with_geo(stbvox_mesh_maker *mm, stbvox_pos pos,
ht[3] = (v >> 6) & 3; ht[3] = (v >> 6) & 3;
} else if (mm->input.block_vheight) { } else if (mm->input.block_vheight) {
unsigned char v = mm->input.block_vheight[bt]; unsigned char v = mm->input.block_vheight[bt];
// @TODO: these need to be rotated by 'rotate' unsigned char raw[4];
ht[0] = (v >> 0) & 3; int i;
ht[1] = (v >> 2) & 3;
ht[2] = (v >> 4) & 3; raw[0] = (v >> 0) & 3;
ht[3] = (v >> 6) & 3; raw[1] = (v >> 2) & 3;
raw[2] = (v >> 4) & 3;
raw[3] = (v >> 6) & 3;
for (i=0; i < 4; ++i)
ht[i] = raw[stbvox_rotate_vertex[i][rot]];
} else { } else {
assert(mm->input.geometry); assert(mm->input.geometry);
} }
// flag whether any sides go off the top of the block, which means
// our visible_faces test was wrong
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_02) {
cube[0] = stbvox_vertex_p(0,0,ht[0],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[3] = stbvox_vertex_p(0,0,ht[3],0,0);
cube[4] = stbvox_vertex_p(0,0,2,0,0);
cube[5] = stbvox_vertex_p(0,0,2,0,0);
cube[6] = stbvox_vertex_p(0,0,2,0,0);
cube[7] = stbvox_vertex_p(0,0,2,0,0);
} else {
cube[0] = stbvox_vertex_p(0,0,0,0,0); cube[0] = stbvox_vertex_p(0,0,0,0,0);
cube[1] = stbvox_vertex_p(0,0,0,0,0); cube[1] = stbvox_vertex_p(0,0,0,0,0);
cube[2] = stbvox_vertex_p(0,0,0,0,0); cube[2] = stbvox_vertex_p(0,0,0,0,0);
@ -1749,26 +1800,12 @@ void stbvox_make_mesh_for_block_with_geo(stbvox_mesh_maker *mm, stbvox_pos pos,
cube[5] = stbvox_vertex_p(0,0,ht[1],0,0); cube[5] = stbvox_vertex_p(0,0,ht[1],0,0);
cube[6] = stbvox_vertex_p(0,0,ht[2],0,0); cube[6] = stbvox_vertex_p(0,0,ht[2],0,0);
cube[7] = stbvox_vertex_p(0,0,ht[3],0,0); cube[7] = stbvox_vertex_p(0,0,ht[3],0,0);
} else {
cube[0] = stbvox_vertex_p(0,0,ht[0],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[3] = stbvox_vertex_p(0,0,ht[3],0,0);
cube[4] = stbvox_vertex_p(0,0,0,0,0);
cube[5] = stbvox_vertex_p(0,0,0,0,0);
cube[6] = stbvox_vertex_p(0,0,0,0,0);
cube[7] = stbvox_vertex_p(0,0,0,0,0);
} }
if (!mm->input.vheight && mm->input.block_vheight) { if (!mm->input.vheight && mm->input.block_vheight) {
int i;
// apply rotation
for (i=0; i < 6*4; ++i) {
int vert = stbvox_vertex_selector[0][i];
vert = stbvox_rotate_vertex[vert][rot];
vmesh[0][i] = stbvox_vmesh_pre_vheight[0][i]
+ cube[vert];
} }
} else {
// build vertex mesh
{
int i; int i;
for (i=0; i < 6*4; ++i) { for (i=0; i < 6*4; ++i) {
int vert = stbvox_vertex_selector[0][i]; int vert = stbvox_vertex_selector[0][i];
@ -1784,10 +1821,33 @@ void stbvox_make_mesh_for_block_with_geo(stbvox_mesh_maker *mm, stbvox_pos pos,
return; return;
} }
if (visible_faces & (1 << STBVOX_FACE_up)) // @TODO generate split faces
if (visible_faces & (1 << STBVOX_FACE_up)) {
#ifndef STBVOX_OPTIMIZED_VHEIGHT
// check if it's planar
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_make_mesh_for_face(mm, rotate, STBVOX_FACE_up , v_off, pos, basevert, vmesh[STBVOX_FACE_up], mesh);
if (visible_faces & (1 << STBVOX_FACE_down)) }
if (visible_faces & (1 << STBVOX_FACE_down)) {
#ifndef STBVOX_OPTIMIZED_VHEIGHT
// check if it's planar
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_make_mesh_for_face(mm, rotate, STBVOX_FACE_down, v_off, pos, basevert, vmesh[STBVOX_FACE_down], mesh);
}
if (mm->input.rotate) { if (mm->input.rotate) {
unsigned char val = mm->input.rotate[v_off]; unsigned char val = mm->input.rotate[v_off];
@ -1799,15 +1859,16 @@ void stbvox_make_mesh_for_block_with_geo(stbvox_mesh_maker *mm, stbvox_pos pos,
rotate.block = rotate.overlay = rotate.tex2 = rotate.ecolor = simple_rot; rotate.block = rotate.overlay = rotate.tex2 = rotate.ecolor = simple_rot;
} }
if (visible_faces & (1 << STBVOX_FACE_north)) if ((visible_faces & (1 << STBVOX_FACE_north)) || (extreme && (ht[2] == 3 || ht[3] == 3)))
stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_north, v_off, pos, basevert, vmesh[STBVOX_FACE_north], mesh); stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_north, v_off, pos, basevert, vmesh[STBVOX_FACE_north], mesh);
if (visible_faces & (1 << STBVOX_FACE_south)) if ((visible_faces & (1 << STBVOX_FACE_south)) || (extreme && (ht[0] == 3 || ht[1] == 3)))
stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_south, v_off, pos, basevert, vmesh[STBVOX_FACE_south], mesh); stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_south, v_off, pos, basevert, vmesh[STBVOX_FACE_south], mesh);
if (visible_faces & (1 << STBVOX_FACE_east)) if ((visible_faces & (1 << STBVOX_FACE_east)) || (extreme && (ht[1] == 3 || ht[3] == 3)))
stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_east , v_off, pos, basevert, vmesh[STBVOX_FACE_east ], mesh); stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_east , v_off, pos, basevert, vmesh[STBVOX_FACE_east ], mesh);
if (visible_faces & (1 << STBVOX_FACE_west)) if ((visible_faces & (1 << STBVOX_FACE_west)) || (extreme && (ht[0] == 3 || ht[2] == 3)))
stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_west , v_off, pos, basevert, vmesh[STBVOX_FACE_west ], mesh); stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_west , v_off, pos, basevert, vmesh[STBVOX_FACE_west ], mesh);
} }
if (geo == STBVOX_GEOM_crossed_pair) { if (geo == STBVOX_GEOM_crossed_pair) {
// this can be generated with a special vmesh // this can be generated with a special vmesh
stbvox_mesh_vertex basevert = stbvox_vertex_p(pos.x, pos.y, pos.z<<mm->precision_z , 0,0); stbvox_mesh_vertex basevert = stbvox_vertex_p(pos.x, pos.y, pos.z<<mm->precision_z , 0,0);

View File

@ -286,7 +286,6 @@ unsigned char minecraft_info[256][7] =
}; };
unsigned char minecraft_tex1_for_blocktype[256][6]; unsigned char minecraft_tex1_for_blocktype[256][6];
unsigned char minecraft_trans_for_blocktype[256];
unsigned char effective_blocktype[256]; unsigned char effective_blocktype[256];
unsigned char effective_block_add[256]; unsigned char effective_block_add[256];
unsigned char minecraft_color_for_blocktype[256][6]; unsigned char minecraft_color_for_blocktype[256][6];
@ -551,6 +550,8 @@ 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];
assert((chunk_x & 1) == 0); assert((chunk_x & 1) == 0);
assert((chunk_y & 1) == 0); assert((chunk_y & 1) == 0);
@ -596,6 +597,24 @@ 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
// hacky test of vheight
for (a=0; a < 34; ++a) {
for (b=0; b < 34; ++b) {
int c;
for (c=0; c < 17; ++c) {
if (rm->sv_blocktype[a][b][c] != 0 && rm->sv_blocktype[a][b][c+1] == 0) {
// topmost block
rm->sv_blocktype[a][b][c] = 168;
vheight[a][b][c] = rand() & 255;
}
}
vheight[a][b][c] = STBVOX_MAKE_VHEIGHT(2,2,2,2); // flat top
}
}
map->vheight = &vheight[1][1][1-z];
#endif
{ {
stbvox_set_input_range(&rm->mm, 0,0,z0, 32,32,z1); stbvox_set_input_range(&rm->mm, 0,0,z0, 32,32,z1);
stbvox_set_default_mesh(&rm->mm, 0); stbvox_set_default_mesh(&rm->mm, 0);
@ -680,7 +699,6 @@ void mesh_init(void)
for (i=0; i < 256; ++i) { for (i=0; i < 256; ++i) {
memcpy(minecraft_tex1_for_blocktype[i], minecraft_info[i]+1, 6); memcpy(minecraft_tex1_for_blocktype[i], minecraft_info[i]+1, 6);
minecraft_trans_for_blocktype[i] = (minecraft_info[i][0] != C_solid && minecraft_info[i][0] != C_water);
effective_blocktype[i] = (minecraft_info[i][0] == C_empty ? 0 : i); effective_blocktype[i] = (minecraft_info[i][0] == C_empty ? 0 : i);
minecraft_geom_for_blocktype[i] = geom_map[minecraft_info[i][0]]; minecraft_geom_for_blocktype[i] = geom_map[minecraft_info[i][0]];
} }
@ -708,6 +726,17 @@ void mesh_init(void)
minecraft_color_for_blocktype[11][i] = 63; // emissive minecraft_color_for_blocktype[11][i] = 63; // emissive
} }
#if 0 // vheight test
effective_blocktype[168] = 168;
minecraft_tex1_for_blocktype[168][0] = 1;
minecraft_tex1_for_blocktype[168][1] = 1;
minecraft_tex1_for_blocktype[168][2] = 1;
minecraft_tex1_for_blocktype[168][3] = 1;
minecraft_tex1_for_blocktype[168][4] = 1;
minecraft_tex1_for_blocktype[168][5] = 1;
minecraft_geom_for_blocktype[168] = STBVOX_GEOM_floor_vheight_02;
#endif
remap[53] = 1; remap[53] = 1;
remap[67] = 2; remap[67] = 2;
remap[108] = 3; remap[108] = 3;

View File

@ -10,8 +10,6 @@
#include "stb_image.h" #include "stb_image.h"
#include "stb.h" #include "stb.h"
// @TODO: need to unload LRU compressed chunks
#define NUM_CHUNKS_PER_REGION 32 // only on one axis #define NUM_CHUNKS_PER_REGION 32 // only on one axis
#define NUM_CHUNKS_PER_REGION_LOG2 5 #define NUM_CHUNKS_PER_REGION_LOG2 5
@ -523,6 +521,7 @@ static decoded_buffer decoded_buffers[MAX_DECODED_CHUNK_Z][MAX_DECODED_CHUNK_X];
void lock_chunk_get_mutex(void); void lock_chunk_get_mutex(void);
void unlock_chunk_get_mutex(void); void unlock_chunk_get_mutex(void);
#ifdef FAST_CHUNK
fast_chunk *get_decoded_fastchunk_uncached(int chunk_x, int chunk_z) fast_chunk *get_decoded_fastchunk_uncached(int chunk_x, int chunk_z)
{ {
unsigned char *decoded; unsigned char *decoded;
@ -592,7 +591,9 @@ fast_chunk *get_decoded_fastchunk(int chunk_x, int chunk_z)
decoded_buffer *db = get_decoded_buffer(chunk_x, chunk_z); decoded_buffer *db = get_decoded_buffer(chunk_x, chunk_z);
return db->fc; return db->fc;
} }
#endif
#ifndef FAST_CHUNK
chunk *get_decoded_chunk_raw(int chunk_x, int chunk_z) chunk *get_decoded_chunk_raw(int chunk_x, int chunk_z)
{ {
unsigned char *decoded; unsigned char *decoded;
@ -628,17 +629,4 @@ chunk *get_decoded_chunk(int chunk_x, int chunk_z)
decoded_chunks[chunk_z&(MAX_DECODED_CHUNK_Z-1)][chunk_x&(MAX_DECODED_CHUNK_X-1)] = c; decoded_chunks[chunk_z&(MAX_DECODED_CHUNK_Z-1)][chunk_x&(MAX_DECODED_CHUNK_X-1)] = c;
return c; return c;
} }
#if 0
chunk *map[257][257];
int main(int argc, char **argv)
{
int i,j;
for (j= -32; j <= 32; ++j)
for (i= -32; i <= 32; ++i)
map[j+128][i+128] = get_decoded_chunk(i,j);
return 0;
}
#endif #endif

View File

@ -1,5 +1,6 @@
// This file takes renders vertex buffers and manages // This file renders vertex buffers, converts raw meshes
// threads that invoke mesh building (found in cave_mesher.c) // to GL meshes, and manages threads that do the raw-mesh
// building (found in cave_mesher.c)
#include "stb_voxel_render.h" #include "stb_voxel_render.h"
@ -14,11 +15,14 @@
#include "sdl.h" #include "sdl.h"
#include "sdl_thread.h" #include "sdl_thread.h"
#include <math.h> #include <math.h>
#include <assert.h>
// currently no dynamic way to set mesh cache size or view distance
//#define SHORTVIEW //#define SHORTVIEW
// renderer maintains GL meshes, draws them
stbvox_mesh_maker g_mesh_maker; stbvox_mesh_maker g_mesh_maker;
GLuint main_prog; GLuint main_prog;
@ -182,7 +186,7 @@ GLint tablei[2];
void setup_uniforms(float pos[3]) void setup_uniforms(float pos[3])
{ {
int i,j; int i,j;
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;
@ -663,6 +667,7 @@ static void matd_mul(double out[4][4], double src1[4][4], double src2[4][4])
} }
} }
// https://fgiesen.wordpress.com/2012/08/31/frustum-planes-from-the-projection-matrix/
static void compute_frustum(void) static void compute_frustum(void)
{ {
int i; int i;
@ -684,6 +689,7 @@ static int test_plane(plane *p, float x0, float y0, float z0, float x1, float y1
{ {
// return false if the box is entirely behind the plane // return false if the box is entirely behind the plane
float d=0; float d=0;
assert(x0 <= x1 && y0 <= y1 && z0 <= z1);
if (p->x > 0) d += x1*p->x; else d += x0*p->x; if (p->x > 0) d += x1*p->x; else d += x0*p->x;
if (p->y > 0) d += y1*p->y; else d += y0*p->y; if (p->y > 0) d += y1*p->y; else d += y0*p->y;
if (p->z > 0) d += z1*p->z; else d += z0*p->z; if (p->z > 0) d += z1*p->z; else d += z0*p->z;

View File

@ -6,27 +6,7 @@ GLEXT(TexSubImage3D,TEXSUBIMAGE3D)
GLEXT(GenerateMipmap,GENERATEMIPMAP) GLEXT(GenerateMipmap,GENERATEMIPMAP)
GLARB(DebugMessageCallback,DEBUGMESSAGECALLBACK) GLARB(DebugMessageCallback,DEBUGMESSAGECALLBACK)
//GLARB(DeleteObject,DELETEOBJECT)
//GLARB(CreateProgramObject,CREATEPROGRAMOBJECT)
//GLARB(UseProgramObject,USEPROGRAMOBJECT)
//GLARB(CreateShaderObject,CREATESHADEROBJECT)
//GLARB(ShaderSource,SHADERSOURCE)
//GLARB(CompileShader,COMPILESHADER)
//GLARB(GetInfoLog,GETINFOLOG)
//GLARB(AttachObject,ATTACHOBJECT)
//GLARB(LinkProgram,LINKPROGRAM)
//GLARB(GetObjectParameteriv,GETOBJECTPARAMETERIV)
//GLARB(GetUniformLocation,GETUNIFORMLOCATION)
////GLARB(Uniform1i,UNIFORM1I)
//GLARB(Uniform1f,UNIFORM1F)
//GLARB(Uniform4f,UNIFORM4F)
//GLARB(Uniform2fv,UNIFORM2FV)
//GLARB(Uniform3fv,UNIFORM3FV)
//GLARB(Uniform4fv,UNIFORM4FV)
//GLARB(VertexAttribPointer,VERTEXATTRIBPOINTER)
GLCORE(VertexAttribIPointer,VERTEXATTRIBIPOINTER) GLCORE(VertexAttribIPointer,VERTEXATTRIBIPOINTER)
//GLARB(EnableVertexAttribArray,ENABLEVERTEXATTRIBARRAY)
//GLARB(DisableVertexAttribArray,DISABLEVERTEXATTRIBARRAY)
GLEXT(BindFramebuffer,BINDFRAMEBUFFER) GLEXT(BindFramebuffer,BINDFRAMEBUFFER)
GLEXT(DeleteFramebuffers,DELETEFRAMEBUFFERS) GLEXT(DeleteFramebuffers,DELETEFRAMEBUFFERS)