mirror of
https://github.com/nothings/stb
synced 2024-12-15 20:32:33 +03:00
support texture rotation; better interaction of mouse centering & VC6 debugger; fix in-place conversion when mca blocks are written in different order
This commit is contained in:
parent
3d4f545fd7
commit
efcd76c9ab
@ -1,6 +1,5 @@
|
|||||||
// @TODO
|
// @TODO
|
||||||
//
|
//
|
||||||
// - extend 2 bits below normal/texgen to support texture rotation
|
|
||||||
// - compute full set of texture normals
|
// - compute full set of texture normals
|
||||||
// - handle output buffer being full
|
// - handle output buffer being full
|
||||||
// - gather vertex lighting from slopes correctly
|
// - gather vertex lighting from slopes correctly
|
||||||
@ -516,6 +515,13 @@ struct stbvox_mesh_maker
|
|||||||
typedef unsigned int stbvox_uint32;
|
typedef unsigned int stbvox_uint32;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define STBVOX_NOTUSED(v) (void)(v)
|
||||||
|
#else
|
||||||
|
#define STBVOX_NOTUSED(v) (void)sizeof(v)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// 20-byte quad format:
|
// 20-byte quad format:
|
||||||
//
|
//
|
||||||
// per vertex:
|
// per vertex:
|
||||||
@ -536,10 +542,22 @@ struct stbvox_mesh_maker
|
|||||||
|
|
||||||
// Default uniform values
|
// Default uniform values
|
||||||
|
|
||||||
static float stbvox_default_texgen[2][16][3] =
|
static float stbvox_default_texgen[2][32][3] =
|
||||||
{
|
{
|
||||||
{ { 0,1,0 }, { 1,0,0 }, { 0,-1,0 }, { -1,0,0 }, { 1,0,0 }, { -1,0,0 } },
|
{ { 0, 1,0 }, { 0, 0, 1 }, { 0,-1,0 }, { 0, 0,-1 },
|
||||||
{ { 0,0,-1 }, { 0,0,-1 }, { 0,0,-1 }, { 0,0,-1 }, { 0,-1,0 }, { 0,1,0 } },
|
{ 1, 0,0 }, { 0, 0, 1 }, { -1, 0,0 }, { 0, 0,-1 },
|
||||||
|
{ 0,-1,0 }, { 0, 0, 1 }, { 0, 1,0 }, { 0, 0,-1 },
|
||||||
|
{ -1, 0,0 }, { 0, 0, 1 }, { 1, 0,0 }, { 0, 0,-1 },
|
||||||
|
{ 1, 0,0 }, { 0, 1, 0 }, { -1, 0,0 }, { 0,-1, 0 },
|
||||||
|
{ -1, 0,0 }, { 0,-1, 0 }, { 1, 0,0 }, { 0, 1, 0 },
|
||||||
|
},
|
||||||
|
{ { 0, 0,-1 }, { 0, 1,0 }, { 0, 0, 1 }, { 0,-1,0 },
|
||||||
|
{ 0, 0,-1 }, { 1, 0,0 }, { 0, 0, 1 }, { -1, 0,0 },
|
||||||
|
{ 0, 0,-1 }, { 0,-1,0 }, { 0, 0, 1 }, { 0, 1,0 },
|
||||||
|
{ 0, 0,-1 }, { -1, 0,0 }, { 0, 0, 1 }, { 1, 0,0 },
|
||||||
|
{ 0,-1, 0 }, { 1, 0,0 }, { 0, 1, 0 }, { -1, 0,0 },
|
||||||
|
{ 0, 1, 0 }, { -1, 0,0 }, { 0,-1, 0 }, { 1, 0,0 },
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static float stbvox_default_normals[32][3] =
|
static float stbvox_default_normals[32][3] =
|
||||||
@ -684,7 +702,7 @@ stbvox_tagged_string stbvox_vertex_program[] =
|
|||||||
" amb_occ = float( (attr_vertex >> 23u) & 63u ) / 63.0;\n" // a[23..28]
|
" amb_occ = float( (attr_vertex >> 23u) & 63u ) / 63.0;\n" // a[23..28]
|
||||||
" texlerp = float( (attr_vertex >> 29u) ) / 7.0;\n" // a[29..31]
|
" texlerp = float( (attr_vertex >> 29u) ) / 7.0;\n" // a[29..31]
|
||||||
|
|
||||||
" vnormal = normal_table[facedata.w & 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
|
||||||
},
|
},
|
||||||
@ -745,8 +763,8 @@ stbvox_tagged_string stbvox_fragment_program[] =
|
|||||||
#if 0
|
#if 0
|
||||||
|
|
||||||
"uniform vec4 color_table[64];\n"
|
"uniform vec4 color_table[64];\n"
|
||||||
"uniform vec2 texscale[128];\n"
|
"uniform vec2 texscale[64];\n" // instead of 128, to avoid running out of uniforms
|
||||||
"uniform vec3 texgen[32];\n"
|
"uniform vec3 texgen[64];\n"
|
||||||
#else
|
#else
|
||||||
"uniform samplerBuffer color_table;\n"
|
"uniform samplerBuffer color_table;\n"
|
||||||
"uniform samplerBuffer texscale;\n"
|
"uniform samplerBuffer texscale;\n"
|
||||||
@ -771,20 +789,20 @@ stbvox_tagged_string stbvox_fragment_program[] =
|
|||||||
// unpack the values
|
// unpack the values
|
||||||
" uint tex1_id = facedata.x;\n"
|
" uint tex1_id = facedata.x;\n"
|
||||||
" uint tex2_id = facedata.y;\n"
|
" uint tex2_id = facedata.y;\n"
|
||||||
" uint texprojid = facedata.w & 15u;\n"
|
" uint texprojid = facedata.w & 31u;\n"
|
||||||
" uint color_id = facedata.z;\n"
|
" uint color_id = facedata.z;\n"
|
||||||
" bool texblend_mode = ((facedata.w & 128u) != 0u);\n"
|
" bool texblend_mode = ((facedata.w & 128u) != 0u);\n"
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// load from uniforms / texture buffers
|
// load from uniforms / texture buffers
|
||||||
" vec3 texgen_s = texgen[texprojid];\n"
|
" vec3 texgen_s = texgen[texprojid];\n"
|
||||||
" vec3 texgen_t = texgen[texprojid+16u];\n"
|
" vec3 texgen_t = texgen[texprojid+32u];\n"
|
||||||
" float tex1_scale = texscale[tex1_id & 127u].x;\n"
|
" float tex1_scale = texscale[tex1_id & 63u].x;\n"
|
||||||
" float tex2_scale = texscale[tex2_id & 127u].y;\n"
|
" float tex2_scale = texscale[tex2_id & 63u].y;\n"
|
||||||
" vec4 color = color_table[color_id & 63u];\n"
|
" vec4 color = color_table[color_id & 63u];\n"
|
||||||
#else
|
#else
|
||||||
" vec3 texgen_s = texelFetch(texgen, int(texprojid)).xyz;\n"
|
" vec3 texgen_s = texelFetch(texgen, int(texprojid)).xyz;\n"
|
||||||
" vec3 texgen_t = texelFetch(texgen, int(texprojid+16u)).xyz;\n"
|
" vec3 texgen_t = texelFetch(texgen, int(texprojid+32u)).xyz;\n"
|
||||||
" float tex1_scale = texelFetch(texscale, int(tex1_id & 127u)).x;\n"
|
" float tex1_scale = texelFetch(texscale, int(tex1_id & 127u)).x;\n"
|
||||||
" float tex2_scale = texelFetch(texscale, int(tex2_id & 127u)).y;\n"
|
" float tex2_scale = texelFetch(texscale, int(tex2_id & 127u)).y;\n"
|
||||||
" vec4 color = texelFetch(color_table, int(color_id & 63u));\n"
|
" vec4 color = texelFetch(color_table, int(color_id & 63u));\n"
|
||||||
@ -794,7 +812,7 @@ stbvox_tagged_string stbvox_fragment_program[] =
|
|||||||
" texcoord.s = dot(texturespace_pos, texgen_s);\n"
|
" texcoord.s = dot(texturespace_pos, texgen_s);\n"
|
||||||
" texcoord.t = dot(texturespace_pos, texgen_t);\n"
|
" texcoord.t = dot(texturespace_pos, texgen_t);\n"
|
||||||
|
|
||||||
// @TODO: use 2 bits of facedata.w to enable animation of facedata.x & y
|
// @TODO: use 2 bits of facedata.w to enable animation of facedata.x & y?
|
||||||
|
|
||||||
" vec4 tex1 = texture(tex_array[0], vec3(tex1_scale * texcoord, float(tex1_id)));\n"
|
" vec4 tex1 = texture(tex_array[0], vec3(tex1_scale * texcoord, float(tex1_id)));\n"
|
||||||
" vec4 tex2 = texture(tex_array[1], vec3(tex2_scale * texcoord, float(tex2_id)));\n"
|
" vec4 tex2 = texture(tex_array[1], vec3(tex2_scale * texcoord, float(tex2_id)));\n"
|
||||||
@ -925,7 +943,7 @@ stbvox_uniform_info stbvox_uniforms[] =
|
|||||||
{ STBVOX_UNIFORM_TYPE_vec4 , 16, 64, "color_table" , stbvox_default_palette[0] , STBVOX_TAG_textured },
|
{ STBVOX_UNIFORM_TYPE_vec4 , 16, 64, "color_table" , stbvox_default_palette[0] , STBVOX_TAG_textured },
|
||||||
|
|
||||||
{ STBVOX_UNIFORM_TYPE_vec3 , 12, 32, "normal_table" , stbvox_default_normals[0] , STBVOX_TAG_all },
|
{ STBVOX_UNIFORM_TYPE_vec3 , 12, 32, "normal_table" , stbvox_default_normals[0] , STBVOX_TAG_all },
|
||||||
{ STBVOX_UNIFORM_TYPE_vec3 , 12, 32, "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_vec3 , 12, 1, "camera_pos" , stbvox_dummy_transform[0] , STBVOX_TAG_all },
|
||||||
@ -960,8 +978,9 @@ typedef struct
|
|||||||
{
|
{
|
||||||
unsigned char block;
|
unsigned char block;
|
||||||
unsigned char overlay;
|
unsigned char overlay;
|
||||||
|
unsigned char facerot:4;
|
||||||
|
unsigned char ecolor:4;
|
||||||
unsigned char tex2;
|
unsigned char tex2;
|
||||||
unsigned char ecolor;
|
|
||||||
} stbvox_rotate;
|
} stbvox_rotate;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@ -983,7 +1002,7 @@ static unsigned char stbvox_rotate_face[6][4] =
|
|||||||
|
|
||||||
static unsigned char face_info_for_side[6] =
|
static unsigned char face_info_for_side[6] =
|
||||||
{
|
{
|
||||||
0,1,2,3,4,5
|
0*4,1*4,2*4,3*4,4*4,5*4
|
||||||
};
|
};
|
||||||
|
|
||||||
stbvox_mesh_face stbvox_compute_mesh_face_value(stbvox_mesh_maker *mm, stbvox_rotate rot, int face, int v_off)
|
stbvox_mesh_face stbvox_compute_mesh_face_value(stbvox_mesh_maker *mm, stbvox_rotate rot, int face, int v_off)
|
||||||
@ -1058,7 +1077,7 @@ stbvox_mesh_face stbvox_compute_mesh_face_value(stbvox_mesh_maker *mm, stbvox_ro
|
|||||||
if (mm->input.color3 && (mm->input.color3_facemask[v_off] & (1 << color_face)))
|
if (mm->input.color3 && (mm->input.color3_facemask[v_off] & (1 << color_face)))
|
||||||
face_data.color = mm->input.color3[v_off];
|
face_data.color = mm->input.color3[v_off];
|
||||||
}
|
}
|
||||||
face_data.face_info = face_info_for_side[face];
|
face_data.face_info = face_info_for_side[face] + rot.facerot;
|
||||||
return face_data;
|
return face_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1374,7 +1393,7 @@ void stbvox_make_mesh_for_block(stbvox_mesh_maker *mm, stbvox_pos pos, int v_off
|
|||||||
unsigned char *blockptr = &mm->input.blocktype[v_off];
|
unsigned char *blockptr = &mm->input.blocktype[v_off];
|
||||||
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);
|
||||||
|
|
||||||
stbvox_rotate rot = { 0,0,0,0 };
|
stbvox_rotate rot = { 0,0,0,0,0 };
|
||||||
unsigned char simple_rot = 0;
|
unsigned char simple_rot = 0;
|
||||||
|
|
||||||
unsigned char mesh = mm->default_mesh;
|
unsigned char mesh = mm->default_mesh;
|
||||||
@ -1392,10 +1411,14 @@ void stbvox_make_mesh_for_block(stbvox_mesh_maker *mm, stbvox_pos pos, int v_off
|
|||||||
simple_rot = mm->input.lighting[v_off] & 3;
|
simple_rot = mm->input.lighting[v_off] & 3;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (blockptr[ 1]==0)
|
if (blockptr[ 1]==0) {
|
||||||
|
rot.facerot = simple_rot;
|
||||||
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) {
|
||||||
|
rot.facerot = (-simple_rot) & 3;
|
||||||
stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_down, v_off, pos, basevert, vmesh+4*STBVOX_FACE_down, mesh);
|
stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_down, v_off, pos, basevert, vmesh+4*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];
|
||||||
@ -1403,9 +1426,10 @@ void stbvox_make_mesh_for_block(stbvox_mesh_maker *mm, stbvox_pos pos, int v_off
|
|||||||
rot.overlay = (val >> 2) & 3;
|
rot.overlay = (val >> 2) & 3;
|
||||||
rot.tex2 = (val >> 4) & 3;
|
rot.tex2 = (val >> 4) & 3;
|
||||||
rot.ecolor = (val >> 6) & 3;
|
rot.ecolor = (val >> 6) & 3;
|
||||||
} else if (mm->input.selector) {
|
} else {
|
||||||
rot.block = rot.overlay = rot.tex2 = rot.ecolor = simple_rot;
|
rot.block = rot.overlay = rot.tex2 = rot.ecolor = simple_rot;
|
||||||
}
|
}
|
||||||
|
rot.facerot = 0;
|
||||||
|
|
||||||
if (blockptr[ ns_off]==0)
|
if (blockptr[ ns_off]==0)
|
||||||
stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_north, v_off, pos, basevert, vmesh+4*STBVOX_FACE_north, mesh);
|
stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_north, v_off, pos, basevert, vmesh+4*STBVOX_FACE_north, mesh);
|
||||||
@ -1580,12 +1604,15 @@ void stbvox_make_mesh_for_block_with_geo(stbvox_mesh_maker *mm, stbvox_pos pos,
|
|||||||
ngeo[4] = mm->input.geometry[v_off + 1];
|
ngeo[4] = mm->input.geometry[v_off + 1];
|
||||||
ngeo[5] = mm->input.geometry[v_off - 1];
|
ngeo[5] = mm->input.geometry[v_off - 1];
|
||||||
|
|
||||||
|
#ifndef STBVOX_ROTATION_IN_LIGHTING
|
||||||
rot = (geo >> 4) & 3;
|
rot = (geo >> 4) & 3;
|
||||||
geo &= 15;
|
geo &= 15;
|
||||||
for (i=0; i < 6; ++i) {
|
for (i=0; i < 6; ++i) {
|
||||||
nrot[i] = (ngeo[i] >> 4) & 3;
|
nrot[i] = (ngeo[i] >> 4) & 3;
|
||||||
ngeo[i] &= 15;
|
ngeo[i] &= 15;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
STBVOX_NOTUSED(i);
|
||||||
} else {
|
} else {
|
||||||
int i;
|
int i;
|
||||||
assert(mm->input.block_geometry);
|
assert(mm->input.block_geometry);
|
||||||
@ -1593,6 +1620,7 @@ void stbvox_make_mesh_for_block_with_geo(stbvox_mesh_maker *mm, stbvox_pos pos,
|
|||||||
for (i=0; i < 6; ++i)
|
for (i=0; i < 6; ++i)
|
||||||
ngeo[i] = mm->input.block_geometry[nbt[i]];
|
ngeo[i] = mm->input.block_geometry[nbt[i]];
|
||||||
if (mm->input.selector) {
|
if (mm->input.selector) {
|
||||||
|
#ifndef STBVOX_ROTATION_IN_LIGHTING
|
||||||
rot = (mm->input.selector[v_off ] >> 4) & 3;
|
rot = (mm->input.selector[v_off ] >> 4) & 3;
|
||||||
nrot[0] = (mm->input.selector[v_off + ew_off] >> 4) & 3;
|
nrot[0] = (mm->input.selector[v_off + ew_off] >> 4) & 3;
|
||||||
nrot[1] = (mm->input.selector[v_off + ns_off] >> 4) & 3;
|
nrot[1] = (mm->input.selector[v_off + ns_off] >> 4) & 3;
|
||||||
@ -1600,13 +1628,16 @@ void stbvox_make_mesh_for_block_with_geo(stbvox_mesh_maker *mm, stbvox_pos pos,
|
|||||||
nrot[3] = (mm->input.selector[v_off - ns_off] >> 4) & 3;
|
nrot[3] = (mm->input.selector[v_off - ns_off] >> 4) & 3;
|
||||||
nrot[4] = (mm->input.selector[v_off + 1] >> 4) & 3;
|
nrot[4] = (mm->input.selector[v_off + 1] >> 4) & 3;
|
||||||
nrot[5] = (mm->input.selector[v_off - 1] >> 4) & 3;
|
nrot[5] = (mm->input.selector[v_off - 1] >> 4) & 3;
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
|
#ifndef STBVOX_ROTATION_IN_LIGHTING
|
||||||
rot = (geo>>4)&3;
|
rot = (geo>>4)&3;
|
||||||
geo &= 15;
|
geo &= 15;
|
||||||
for (i=0; i < 6; ++i) {
|
for (i=0; i < 6; ++i) {
|
||||||
nrot[i] = (ngeo[i]>>4)&3;
|
nrot[i] = (ngeo[i]>>4)&3;
|
||||||
ngeo[i] &= 15;
|
ngeo[i] &= 15;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1620,6 +1651,8 @@ void stbvox_make_mesh_for_block_with_geo(stbvox_mesh_maker *mm, stbvox_pos pos,
|
|||||||
nrot[5] = (mm->input.lighting[v_off - 1]) & 3;
|
nrot[5] = (mm->input.lighting[v_off - 1]) & 3;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//rot = 2;
|
||||||
|
|
||||||
if (geo == STBVOX_GEOM_transp) {
|
if (geo == STBVOX_GEOM_transp) {
|
||||||
// transparency has a special rule: if the blocktype is the same,
|
// transparency has a special rule: if the blocktype is the same,
|
||||||
// and the faces are compatible, then can hide them; otherwise,
|
// and the faces are compatible, then can hide them; otherwise,
|
||||||
@ -1694,7 +1727,7 @@ void stbvox_make_mesh_for_block_with_geo(stbvox_mesh_maker *mm, stbvox_pos pos,
|
|||||||
// this is the simple case, we can just use regular block gen with special vmesh calculated with vheight
|
// this is the simple case, we can just use regular block gen with special vmesh calculated with vheight
|
||||||
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,0 };
|
||||||
unsigned char simple_rot = rot;
|
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
|
||||||
@ -1718,10 +1751,14 @@ void stbvox_make_mesh_for_block_with_geo(stbvox_mesh_maker *mm, stbvox_pos pos,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (visible_faces & (1 << STBVOX_FACE_up))
|
if (visible_faces & (1 << STBVOX_FACE_up)) {
|
||||||
|
rotate.facerot = simple_rot;
|
||||||
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)) {
|
||||||
|
rotate.facerot = (-rotate.facerot) & 3;
|
||||||
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];
|
||||||
@ -1729,10 +1766,12 @@ void stbvox_make_mesh_for_block_with_geo(stbvox_mesh_maker *mm, stbvox_pos pos,
|
|||||||
rotate.overlay = (val >> 2) & 3;
|
rotate.overlay = (val >> 2) & 3;
|
||||||
rotate.tex2 = (val >> 4) & 3;
|
rotate.tex2 = (val >> 4) & 3;
|
||||||
rotate.ecolor = (val >> 6) & 3;
|
rotate.ecolor = (val >> 6) & 3;
|
||||||
} else if (mm->input.selector) {
|
} else {
|
||||||
rotate.block = rotate.overlay = rotate.tex2 = rotate.ecolor = simple_rot;
|
rotate.block = rotate.overlay = rotate.tex2 = rotate.ecolor = simple_rot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rotate.facerot = 0;
|
||||||
|
|
||||||
if (visible_faces & (1 << STBVOX_FACE_north))
|
if (visible_faces & (1 << STBVOX_FACE_north))
|
||||||
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))
|
||||||
@ -1750,7 +1789,7 @@ void stbvox_make_mesh_for_block_with_geo(stbvox_mesh_maker *mm, stbvox_pos pos,
|
|||||||
stbvox_mesh_vertex vmesh[6][4];
|
stbvox_mesh_vertex vmesh[6][4];
|
||||||
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,0 };
|
||||||
unsigned char simple_rot = rot;
|
unsigned char simple_rot = rot;
|
||||||
unsigned char ht[4];
|
unsigned char ht[4];
|
||||||
int extreme;
|
int extreme;
|
||||||
@ -1775,7 +1814,7 @@ void stbvox_make_mesh_for_block_with_geo(stbvox_mesh_maker *mm, stbvox_pos pos,
|
|||||||
for (i=0; i < 4; ++i)
|
for (i=0; i < 4; ++i)
|
||||||
ht[i] = raw[stbvox_rotate_vertex[i][rot]];
|
ht[i] = raw[stbvox_rotate_vertex[i][rot]];
|
||||||
} else {
|
} else {
|
||||||
assert(mm->input.geometry);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// flag whether any sides go off the top of the block, which means
|
// flag whether any sides go off the top of the block, which means
|
||||||
@ -1872,9 +1911,8 @@ void stbvox_make_mesh_for_block_with_geo(stbvox_mesh_maker *mm, stbvox_pos pos,
|
|||||||
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);
|
||||||
stbvox_rotate rot = { 0,0,0,0 };
|
unsigned char simple_rot=0;
|
||||||
unsigned char simple_rot;
|
stbvox_rotate rot = { 0,0,0,0,0 };
|
||||||
|
|
||||||
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];
|
||||||
@ -1897,6 +1935,7 @@ void stbvox_make_mesh_for_block_with_geo(stbvox_mesh_maker *mm, stbvox_pos pos,
|
|||||||
} else if (mm->input.selector) {
|
} else if (mm->input.selector) {
|
||||||
rot.block = rot.overlay = rot.tex2 = rot.ecolor = simple_rot;
|
rot.block = rot.overlay = rot.tex2 = rot.ecolor = simple_rot;
|
||||||
}
|
}
|
||||||
|
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_make_mesh_for_face(mm, rot, STBVOX_FACE_north, v_off, pos, basevert, stbvox_vmesh_crossed_pair[STBVOX_FACE_north], mesh);
|
||||||
stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_south, v_off, pos, basevert, stbvox_vmesh_crossed_pair[STBVOX_FACE_south], mesh);
|
stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_south, v_off, pos, basevert, stbvox_vmesh_crossed_pair[STBVOX_FACE_south], mesh);
|
||||||
|
@ -11,11 +11,13 @@ Not very. Many Minecraft blocks are not handled correctly:
|
|||||||
* Only one wood type
|
* Only one wood type
|
||||||
* Colored glass becomes regular glass
|
* Colored glass becomes regular glass
|
||||||
* Glass panes become glass blocks
|
* Glass panes become glass blocks
|
||||||
|
* Water is opaque
|
||||||
* Water level is incorrect
|
* Water level is incorrect
|
||||||
* No biome coloration
|
* No biome coloration
|
||||||
* Cactus is not shrunk, shows holes
|
* Cactus is not shrunk, shows holes
|
||||||
* Chests are not shrunk
|
* Chests are not shrunk
|
||||||
* Chests, pumpkins, etc. are not rotated properly
|
* Double-chests draw as two chests
|
||||||
|
* Pumpkins etc. are not rotated properly
|
||||||
* Torches are drawn hackily, do not attach to walls
|
* Torches are drawn hackily, do not attach to walls
|
||||||
* Incorrect textures for blocks that postdate terrain.png
|
* Incorrect textures for blocks that postdate terrain.png
|
||||||
* Transparent textures have black fringes due to non-premultiplied-alpha
|
* Transparent textures have black fringes due to non-premultiplied-alpha
|
||||||
@ -47,9 +49,11 @@ things that way wouldn't be so bad.
|
|||||||
|
|
||||||
Rails, ladders, and redstone lines could be implemented by
|
Rails, ladders, and redstone lines could be implemented by
|
||||||
using tex2 to overlay those effects, but you can't rotate
|
using tex2 to overlay those effects, but you can't rotate
|
||||||
tex1 and tex2 independently, so you'd have to have a
|
tex1 and tex2 independently, so there may be cases where
|
||||||
separate texture for each orientation of rail, etc, and
|
the underlying texture needs a different rotation from the
|
||||||
you'd need special rendering for rail up/down sections.
|
overlaid texture, which would require separate rendering.
|
||||||
|
Handling redstone's brightness being different from underlying
|
||||||
|
block's brightness would require separate rendering.
|
||||||
|
|
||||||
You can use the face-color effect to do biome coloration,
|
You can use the face-color effect to do biome coloration,
|
||||||
but the change won't be smooth the way it is in Minecraft.
|
but the change won't be smooth the way it is in Minecraft.
|
||||||
@ -60,8 +64,7 @@ but the change won't be smooth the way it is in Minecraft.
|
|||||||
Partly because converting from minecraft data is expensive.
|
Partly because converting from minecraft data is expensive.
|
||||||
|
|
||||||
Here is the approximate breakdown of an older version
|
Here is the approximate breakdown of an older version
|
||||||
of this executable and lib that did the building single-threaded,
|
of this executable and lib that did the building single-threaded.
|
||||||
and was a bit slower at building mesh data.
|
|
||||||
|
|
||||||
* 25% loading & parsing minecraft files (4/5ths of this is my zlib)
|
* 25% loading & parsing minecraft files (4/5ths of this is my zlib)
|
||||||
* 18% converting from minecraft blockids & lighting to stb blockids & lighting
|
* 18% converting from minecraft blockids & lighting to stb blockids & lighting
|
||||||
|
@ -66,7 +66,7 @@ static void print(char *text, ...)
|
|||||||
pos_y += 10;
|
pos_y += 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
float camang[3], camloc[3] = { 0,0,75 };
|
float camang[3], camloc[3] = { 60,22,77 };
|
||||||
float player_zoom = 1.0;
|
float player_zoom = 1.0;
|
||||||
float rotate_view = 0.0;
|
float rotate_view = 0.0;
|
||||||
|
|
||||||
@ -551,8 +551,12 @@ int SDL_main(int argc, char **argv)
|
|||||||
|
|
||||||
SDL_GL_MakeCurrent(window, context); // is this true by default?
|
SDL_GL_MakeCurrent(window, context); // is this true by default?
|
||||||
|
|
||||||
// if (!IsDebuggerPresent())
|
|
||||||
SDL_SetRelativeMouseMode(SDL_TRUE);
|
SDL_SetRelativeMouseMode(SDL_TRUE);
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER < 1300
|
||||||
|
// work around broken behavior in VC6 debugging
|
||||||
|
if (IsDebuggerPresent())
|
||||||
|
SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, "1");
|
||||||
|
#endif
|
||||||
|
|
||||||
stbgl_initExtensions();
|
stbgl_initExtensions();
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ unsigned char minecraft_info[256][7] =
|
|||||||
{ C_empty }, // fire
|
{ C_empty }, // fire
|
||||||
{ C_trans, 65,65,65,65,65,65 },
|
{ C_trans, 65,65,65,65,65,65 },
|
||||||
{ C_stair, 4,4,4,4,4,4 },
|
{ C_stair, 4,4,4,4,4,4 },
|
||||||
{ C_solid, 27,26,26,26,25,25 },
|
{ C_solid, 26,26,26,27,25,25 },
|
||||||
{ C_empty }, // redstone
|
{ C_empty }, // redstone
|
||||||
|
|
||||||
// 56
|
// 56
|
||||||
@ -237,7 +237,7 @@ unsigned char minecraft_info[256][7] =
|
|||||||
// 144
|
// 144
|
||||||
{ C_empty }, // mob head
|
{ C_empty }, // mob head
|
||||||
{ C_empty }, // anvil
|
{ C_empty }, // anvil
|
||||||
{ C_solid, 27,26,26,26,25,25 }, // trapped chest
|
{ C_solid, 26,26,26,27,25,25 }, // trapped chest
|
||||||
{ C_empty }, // weighted pressure plate light
|
{ C_empty }, // weighted pressure plate light
|
||||||
{ C_empty }, // weighted pressure plat eheavy
|
{ C_empty }, // weighted pressure plat eheavy
|
||||||
{ C_empty }, // comparator inactive
|
{ C_empty }, // comparator inactive
|
||||||
@ -315,11 +315,13 @@ void convert_fastchunk_inplace(fast_chunk *fc)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int num_blocks=0, step=0;
|
int num_blocks=0, step=0;
|
||||||
unsigned char rot[4096] = { 0 };
|
unsigned char rot[4096];
|
||||||
#ifndef IN_PLACE
|
#ifndef IN_PLACE
|
||||||
unsigned char *storage;
|
unsigned char *storage;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
memset(rot, 0, 4096);
|
||||||
|
|
||||||
for (i=0; i < 16; ++i)
|
for (i=0; i < 16; ++i)
|
||||||
num_blocks += fc->blockdata[i] != NULL;
|
num_blocks += fc->blockdata[i] != NULL;
|
||||||
|
|
||||||
@ -340,15 +342,12 @@ void convert_fastchunk_inplace(fast_chunk *fc)
|
|||||||
sky = fc->skylight[i];
|
sky = fc->skylight[i];
|
||||||
|
|
||||||
#ifdef IN_PLACE
|
#ifdef IN_PLACE
|
||||||
assert(dd < sky && sky < lt && lt < bd);
|
|
||||||
out = bd;
|
out = bd;
|
||||||
outb = dd;
|
|
||||||
#else
|
#else
|
||||||
out = storage + 16*16*16*2*step;
|
out = storage + 16*16*16*2*step;
|
||||||
outb = out + 16*16*16;
|
|
||||||
++step;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// bd is written in place, but also reads from dd
|
||||||
for (o=0; o < 16*16*16/2; o += 1) {
|
for (o=0; o < 16*16*16/2; o += 1) {
|
||||||
unsigned char v1,v2;
|
unsigned char v1,v2;
|
||||||
unsigned char d = dd[o];
|
unsigned char d = dd[o];
|
||||||
@ -359,7 +358,7 @@ void convert_fastchunk_inplace(fast_chunk *fc)
|
|||||||
{
|
{
|
||||||
//unsigned char d = bd[o] & 15;
|
//unsigned char d = bd[o] & 15;
|
||||||
v1 = remap_data[remap[v1]][d&15];
|
v1 = remap_data[remap[v1]][d&15];
|
||||||
rot[o] = rotate_data[d&3];
|
rot[o*2+0] = rotate_data[d&3];
|
||||||
} else
|
} else
|
||||||
v1 = effective_blocktype[v1];
|
v1 = effective_blocktype[v1];
|
||||||
|
|
||||||
@ -367,7 +366,7 @@ void convert_fastchunk_inplace(fast_chunk *fc)
|
|||||||
{
|
{
|
||||||
//unsigned char d = bd[o] >> 4;
|
//unsigned char d = bd[o] >> 4;
|
||||||
v2 = remap_data[remap[v2]][d>>4];
|
v2 = remap_data[remap[v2]][d>>4];
|
||||||
rot[o+1] = rotate_data[(d>>4)&3];
|
rot[o*2+1] = rotate_data[(d>>4)&3];
|
||||||
} else
|
} else
|
||||||
v2 = effective_blocktype[v2];
|
v2 = effective_blocktype[v2];
|
||||||
|
|
||||||
@ -375,18 +374,54 @@ void convert_fastchunk_inplace(fast_chunk *fc)
|
|||||||
out[o*2+1] = v2;
|
out[o*2+1] = v2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// because this stores to data[], can't run at same time as above loop
|
// this reads from lt & sky
|
||||||
for (o=0; o < 16*16*16/2; ++o) {
|
#ifndef IN_PLACE
|
||||||
int bright;
|
outb = out + 16*16*16;
|
||||||
bright = (lt[o]&15)*12 + 15 + (sky[o]&15)*16;
|
++step;
|
||||||
if (bright > 255) bright = 255;
|
#endif
|
||||||
if (bright < 32) bright = 32;
|
|
||||||
outb[o*2+0] = STBVOX_MAKE_LIGHTING((unsigned char) bright, rot[o]);
|
|
||||||
|
|
||||||
bright = (lt[o]>>4)*12 + 15 + (sky[o]>>4)*16;
|
// MC used to write in this order and it makes it possible to compute in-place
|
||||||
if (bright > 255) bright = 255;
|
if (dd < sky && sky < lt) {
|
||||||
if (bright < 32) bright = 32;
|
// @TODO go this path always if !IN_PLACE
|
||||||
outb[o*2+1] = STBVOX_MAKE_LIGHTING((unsigned char) bright, rot[o+1]);
|
#ifdef IN_PLACE
|
||||||
|
outb = dd;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (o=0; o < 16*16*16/2; ++o) {
|
||||||
|
int bright;
|
||||||
|
bright = (lt[o]&15)*12 + 15 + (sky[o]&15)*16;
|
||||||
|
if (bright > 255) bright = 255;
|
||||||
|
if (bright < 32) bright = 32;
|
||||||
|
outb[o*2+0] = STBVOX_MAKE_LIGHTING((unsigned char) bright, (rot[o*2+0]&3));
|
||||||
|
|
||||||
|
bright = (lt[o]>>4)*12 + 15 + (sky[o]>>4)*16;
|
||||||
|
if (bright > 255) bright = 255;
|
||||||
|
if (bright < 32) bright = 32;
|
||||||
|
outb[o*2+1] = STBVOX_MAKE_LIGHTING((unsigned char) bright, (rot[o*2+1]&3));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// @TODO: if blocktype is in between others, this breaks; need to find which side has two pointers, and use that
|
||||||
|
// overwrite rot[] array, then copy out
|
||||||
|
#ifdef IN_PLACE
|
||||||
|
outb = (dd < sky) ? dd : sky;
|
||||||
|
if (lt < outb) lt = outb;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (o=0; o < 16*16*16/2; ++o) {
|
||||||
|
int bright;
|
||||||
|
bright = (lt[o]&15)*12 + 15 + (sky[o]&15)*16;
|
||||||
|
if (bright > 255) bright = 255;
|
||||||
|
if (bright < 32) bright = 32;
|
||||||
|
rot[o*2+0] = STBVOX_MAKE_LIGHTING((unsigned char) bright, (rot[o*2+0]&3));
|
||||||
|
|
||||||
|
bright = (lt[o]>>4)*12 + 15 + (sky[o]>>4)*16;
|
||||||
|
if (bright > 255) bright = 255;
|
||||||
|
if (bright < 32) bright = 32;
|
||||||
|
rot[o*2+1] = STBVOX_MAKE_LIGHTING((unsigned char) bright, (rot[o*2+1]&3));
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(outb, rot, 4096);
|
||||||
|
fc->data[i] = outb;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef IN_PLACE
|
#ifndef IN_PLACE
|
||||||
@ -653,10 +688,11 @@ void build_stair_rotations(int blocktype, unsigned char *map)
|
|||||||
int i,j,k;
|
int i,j,k;
|
||||||
for (j=0; j < 2; ++j) {
|
for (j=0; j < 2; ++j) {
|
||||||
int geom = j ? STBVOX_GEOM_ceil_slope_north_is_bottom : STBVOX_GEOM_floor_slope_north_is_top;
|
int geom = j ? STBVOX_GEOM_ceil_slope_north_is_bottom : STBVOX_GEOM_floor_slope_north_is_top;
|
||||||
|
//int geom = STBVOX_GEOM_solid;
|
||||||
for (i=0; i < 4; ++i) {
|
for (i=0; i < 4; ++i) {
|
||||||
if (i == 0 && j == 0) {
|
if (i == 0 && j == 0) {
|
||||||
map[j*4+i+8] = map[j*4+i] = blocktype;
|
map[j*4+i+8] = map[j*4+i] = blocktype;
|
||||||
minecraft_geom_for_blocktype[blocktype] = (unsigned char) STBVOX_MAKE_GEOMETRY(geom, mc_rot[i], 0);
|
minecraft_geom_for_blocktype[blocktype] = (unsigned char) STBVOX_MAKE_GEOMETRY(geom, 0, 0);
|
||||||
} else {
|
} else {
|
||||||
map[j*4+i+8] = map[j*4+i] = next_blocktype;
|
map[j*4+i+8] = map[j*4+i] = next_blocktype;
|
||||||
|
|
||||||
@ -664,7 +700,7 @@ void build_stair_rotations(int blocktype, unsigned char *map)
|
|||||||
minecraft_color_for_blocktype[next_blocktype][k] = minecraft_color_for_blocktype[blocktype][k];
|
minecraft_color_for_blocktype[next_blocktype][k] = minecraft_color_for_blocktype[blocktype][k];
|
||||||
minecraft_tex1_for_blocktype [next_blocktype][k] = minecraft_tex1_for_blocktype [blocktype][k];
|
minecraft_tex1_for_blocktype [next_blocktype][k] = minecraft_tex1_for_blocktype [blocktype][k];
|
||||||
}
|
}
|
||||||
minecraft_geom_for_blocktype[next_blocktype] = (unsigned char) STBVOX_MAKE_GEOMETRY(geom, mc_rot[i], 0);
|
minecraft_geom_for_blocktype[next_blocktype] = (unsigned char) STBVOX_MAKE_GEOMETRY(geom, 0, 0);
|
||||||
--next_blocktype;
|
--next_blocktype;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -690,6 +726,15 @@ void build_wool_variations(int bt, unsigned char *map)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void remap_in_place(int bt, int rm)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
remap[bt] = rm;
|
||||||
|
for (i=0; i < 16; ++i)
|
||||||
|
remap_data[rm][i] = bt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void mesh_init(void)
|
void mesh_init(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -750,6 +795,10 @@ void mesh_init(void)
|
|||||||
remap[35] = 8;
|
remap[35] = 8;
|
||||||
build_wool_variations(35, remap_data[remap[35]]);
|
build_wool_variations(35, remap_data[remap[35]]);
|
||||||
|
|
||||||
|
// set the remap flags for these so they write the rotation values
|
||||||
|
remap_in_place(54, 9);
|
||||||
|
remap_in_place(146, 10);
|
||||||
|
|
||||||
for (i=0; i < 256; ++i) {
|
for (i=0; i < 256; ++i) {
|
||||||
if (remap[i])
|
if (remap[i])
|
||||||
effective_block_add[i] = 0;
|
effective_block_add[i] = 0;
|
||||||
|
@ -123,6 +123,10 @@ SOURCE=.\glext_list.h
|
|||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\README.md
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\win32\SDL_windows_main.c
|
SOURCE=.\win32\SDL_windows_main.c
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
Loading…
Reference in New Issue
Block a user