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:
Sean Barrett 2015-03-12 19:03:49 -07:00
parent 3d4f545fd7
commit efcd76c9ab
5 changed files with 160 additions and 61 deletions

View File

@ -1,6 +1,5 @@
// @TODO
//
// - extend 2 bits below normal/texgen to support texture rotation
// - compute full set of texture normals
// - handle output buffer being full
// - gather vertex lighting from slopes correctly
@ -516,6 +515,13 @@ struct stbvox_mesh_maker
typedef unsigned int stbvox_uint32;
#endif
#ifdef _MSC_VER
#define STBVOX_NOTUSED(v) (void)(v)
#else
#define STBVOX_NOTUSED(v) (void)sizeof(v)
#endif
// 20-byte quad format:
//
// per vertex:
@ -536,10 +542,22 @@ struct stbvox_mesh_maker
// 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,0,-1 }, { 0,0,-1 }, { 0,0,-1 }, { 0,0,-1 }, { 0,-1,0 }, { 0,1,0 } },
{ { 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, 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] =
@ -684,7 +702,7 @@ stbvox_tagged_string stbvox_vertex_program[] =
" amb_occ = float( (attr_vertex >> 23u) & 63u ) / 63.0;\n" // a[23..28]
" 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
" vec3 position = objectspace_pos + transform[1];\n" // object-to-world translate
},
@ -745,8 +763,8 @@ stbvox_tagged_string stbvox_fragment_program[] =
#if 0
"uniform vec4 color_table[64];\n"
"uniform vec2 texscale[128];\n"
"uniform vec3 texgen[32];\n"
"uniform vec2 texscale[64];\n" // instead of 128, to avoid running out of uniforms
"uniform vec3 texgen[64];\n"
#else
"uniform samplerBuffer color_table;\n"
"uniform samplerBuffer texscale;\n"
@ -771,20 +789,20 @@ stbvox_tagged_string stbvox_fragment_program[] =
// unpack the values
" uint tex1_id = facedata.x;\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"
" bool texblend_mode = ((facedata.w & 128u) != 0u);\n"
#if 0
// load from uniforms / texture buffers
" vec3 texgen_s = texgen[texprojid];\n"
" vec3 texgen_t = texgen[texprojid+16u];\n"
" float tex1_scale = texscale[tex1_id & 127u].x;\n"
" float tex2_scale = texscale[tex2_id & 127u].y;\n"
" vec3 texgen_t = texgen[texprojid+32u];\n"
" float tex1_scale = texscale[tex1_id & 63u].x;\n"
" float tex2_scale = texscale[tex2_id & 63u].y;\n"
" vec4 color = color_table[color_id & 63u];\n"
#else
" 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 tex2_scale = texelFetch(texscale, int(tex2_id & 127u)).y;\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.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 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_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, 1, "camera_pos" , stbvox_dummy_transform[0] , STBVOX_TAG_all },
@ -960,8 +978,9 @@ typedef struct
{
unsigned char block;
unsigned char overlay;
unsigned char facerot:4;
unsigned char ecolor:4;
unsigned char tex2;
unsigned char ecolor;
} stbvox_rotate;
typedef struct
@ -983,7 +1002,7 @@ static unsigned char stbvox_rotate_face[6][4] =
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)
@ -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)))
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;
}
@ -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];
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 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;
#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);
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);
}
if (mm->input.rotate) {
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.tex2 = (val >> 4) & 3;
rot.ecolor = (val >> 6) & 3;
} else if (mm->input.selector) {
} else {
rot.block = rot.overlay = rot.tex2 = rot.ecolor = simple_rot;
}
rot.facerot = 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);
@ -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[5] = mm->input.geometry[v_off - 1];
#ifndef STBVOX_ROTATION_IN_LIGHTING
rot = (geo >> 4) & 3;
geo &= 15;
for (i=0; i < 6; ++i) {
nrot[i] = (ngeo[i] >> 4) & 3;
ngeo[i] &= 15;
}
#endif
STBVOX_NOTUSED(i);
} else {
int i;
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)
ngeo[i] = mm->input.block_geometry[nbt[i]];
if (mm->input.selector) {
#ifndef STBVOX_ROTATION_IN_LIGHTING
rot = (mm->input.selector[v_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;
@ -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[4] = (mm->input.selector[v_off + 1] >> 4) & 3;
nrot[5] = (mm->input.selector[v_off - 1] >> 4) & 3;
#endif
} else {
#ifndef STBVOX_ROTATION_IN_LIGHTING
rot = (geo>>4)&3;
geo &= 15;
for (i=0; i < 6; ++i) {
nrot[i] = (ngeo[i]>>4)&3;
ngeo[i] &= 15;
}
#endif
}
}
@ -1618,7 +1649,9 @@ void stbvox_make_mesh_for_block_with_geo(stbvox_mesh_maker *mm, stbvox_pos pos,
nrot[3] = (mm->input.lighting[v_off - ns_off]) & 3;
nrot[4] = (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) {
// transparency has a special rule: if the blocktype is the same,
@ -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
stbvox_mesh_vertex basevert;
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;
int i;
// 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;
}
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);
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);
}
if (mm->input.rotate) {
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.tex2 = (val >> 4) & 3;
rotate.ecolor = (val >> 6) & 3;
} else if (mm->input.selector) {
} else {
rotate.block = rotate.overlay = rotate.tex2 = rotate.ecolor = simple_rot;
}
rotate.facerot = 0;
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);
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 cube[8];
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 ht[4];
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)
ht[i] = raw[stbvox_rotate_vertex[i][rot]];
} else {
assert(mm->input.geometry);
assert(0);
}
// 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) {
// 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_rotate rot = { 0,0,0,0 };
unsigned char simple_rot;
unsigned char simple_rot=0;
stbvox_rotate rot = { 0,0,0,0,0 };
unsigned char mesh = mm->default_mesh;
if (mm->input.selector) {
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) {
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_south, v_off, pos, basevert, stbvox_vmesh_crossed_pair[STBVOX_FACE_south], mesh);

View File

@ -11,11 +11,13 @@ Not very. Many Minecraft blocks are not handled correctly:
* Only one wood type
* Colored glass becomes regular glass
* Glass panes become glass blocks
* Water is opaque
* Water level is incorrect
* No biome coloration
* Cactus is not shrunk, shows holes
* 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
* Incorrect textures for blocks that postdate terrain.png
* 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
using tex2 to overlay those effects, but you can't rotate
tex1 and tex2 independently, so you'd have to have a
separate texture for each orientation of rail, etc, and
you'd need special rendering for rail up/down sections.
tex1 and tex2 independently, so there may be cases where
the underlying texture needs a different rotation from the
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,
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.
Here is the approximate breakdown of an older version
of this executable and lib that did the building single-threaded,
and was a bit slower at building mesh data.
of this executable and lib that did the building single-threaded.
* 25% loading & parsing minecraft files (4/5ths of this is my zlib)
* 18% converting from minecraft blockids & lighting to stb blockids & lighting

View File

@ -66,7 +66,7 @@ static void print(char *text, ...)
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 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?
// if (!IsDebuggerPresent())
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();

View File

@ -121,7 +121,7 @@ unsigned char minecraft_info[256][7] =
{ C_empty }, // fire
{ C_trans, 65,65,65,65,65,65 },
{ 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
// 56
@ -237,7 +237,7 @@ unsigned char minecraft_info[256][7] =
// 144
{ C_empty }, // mob head
{ 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 plat eheavy
{ C_empty }, // comparator inactive
@ -315,11 +315,13 @@ void convert_fastchunk_inplace(fast_chunk *fc)
{
int i;
int num_blocks=0, step=0;
unsigned char rot[4096] = { 0 };
unsigned char rot[4096];
#ifndef IN_PLACE
unsigned char *storage;
#endif
memset(rot, 0, 4096);
for (i=0; i < 16; ++i)
num_blocks += fc->blockdata[i] != NULL;
@ -340,15 +342,12 @@ void convert_fastchunk_inplace(fast_chunk *fc)
sky = fc->skylight[i];
#ifdef IN_PLACE
assert(dd < sky && sky < lt && lt < bd);
out = bd;
outb = dd;
#else
out = storage + 16*16*16*2*step;
outb = out + 16*16*16;
++step;
#endif
// bd is written in place, but also reads from dd
for (o=0; o < 16*16*16/2; o += 1) {
unsigned char v1,v2;
unsigned char d = dd[o];
@ -359,7 +358,7 @@ void convert_fastchunk_inplace(fast_chunk *fc)
{
//unsigned char d = bd[o] & 15;
v1 = remap_data[remap[v1]][d&15];
rot[o] = rotate_data[d&3];
rot[o*2+0] = rotate_data[d&3];
} else
v1 = effective_blocktype[v1];
@ -367,7 +366,7 @@ void convert_fastchunk_inplace(fast_chunk *fc)
{
//unsigned char d = bd[o] >> 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
v2 = effective_blocktype[v2];
@ -375,18 +374,54 @@ void convert_fastchunk_inplace(fast_chunk *fc)
out[o*2+1] = v2;
}
// because this stores to data[], can't run at same time as above loop
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]);
// this reads from lt & sky
#ifndef IN_PLACE
outb = out + 16*16*16;
++step;
#endif
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+1]);
// MC used to write in this order and it makes it possible to compute in-place
if (dd < sky && sky < lt) {
// @TODO go this path always if !IN_PLACE
#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
@ -653,10 +688,11 @@ void build_stair_rotations(int blocktype, unsigned char *map)
int i,j,k;
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 = STBVOX_GEOM_solid;
for (i=0; i < 4; ++i) {
if (i == 0 && j == 0) {
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 {
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_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;
}
}
@ -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)
{
int i;
@ -750,6 +795,10 @@ void mesh_init(void)
remap[35] = 8;
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) {
if (remap[i])
effective_block_add[i] = 0;

View File

@ -123,6 +123,10 @@ SOURCE=.\glext_list.h
# End Source File
# Begin Source File
SOURCE=.\README.md
# End Source File
# Begin Source File
SOURCE=.\win32\SDL_windows_main.c
# End Source File
# Begin Source File