Add stained glass and stained glass panels
Note that this commit changes the pseudo-ancil-data type from unsigned int to an unsigned short. Our pseudoancil code creates 5 bits of data to store adjacency information for glass. Glass also has 4 bits for color info. This means we need a total of 9 bits to render these (thus int --> short)
This commit is contained in:
@@ -207,7 +207,7 @@ unload_all_chunks(RenderState *state) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char
|
unsigned short
|
||||||
check_adjacent_blocks(RenderState *state, int x,int y,int z, unsigned short blockid) {
|
check_adjacent_blocks(RenderState *state, int x,int y,int z, unsigned short blockid) {
|
||||||
/*
|
/*
|
||||||
* Generates a pseudo ancillary data for blocks that depend of
|
* Generates a pseudo ancillary data for blocks that depend of
|
||||||
@@ -265,14 +265,14 @@ is_stairs(int block) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char
|
unsigned short
|
||||||
generate_pseudo_data(RenderState *state, unsigned char ancilData) {
|
generate_pseudo_data(RenderState *state, unsigned short ancilData) {
|
||||||
/*
|
/*
|
||||||
* Generates a fake ancillary data for blocks that are drawn
|
* Generates a fake ancillary data for blocks that are drawn
|
||||||
* depending on what are surrounded.
|
* depending on what are surrounded.
|
||||||
*/
|
*/
|
||||||
int x = state->x, y = state->y, z = state->z;
|
int x = state->x, y = state->y, z = state->z;
|
||||||
unsigned char data = 0;
|
unsigned short data = 0;
|
||||||
|
|
||||||
if (state->block == 2) { /* grass */
|
if (state->block == 2) { /* grass */
|
||||||
/* return 0x10 if grass is covered in snow */
|
/* return 0x10 if grass is covered in snow */
|
||||||
@@ -295,15 +295,18 @@ generate_pseudo_data(RenderState *state, unsigned char ancilData) {
|
|||||||
data = (check_adjacent_blocks(state, x, y, z, state->block) ^ 0x0f);
|
data = (check_adjacent_blocks(state, x, y, z, state->block) ^ 0x0f);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
} else if ((state->block == 20) || (state->block == 79)) { /* glass and ice */
|
} else if ((state->block == 20) || (state->block == 79) || (state->block == 95)) { /* glass and ice and stained glass*/
|
||||||
/* an aditional bit for top is added to the 4 bits of check_adjacent_blocks */
|
/* an aditional bit for top is added to the 4 bits of check_adjacent_blocks
|
||||||
if (get_data(state, BLOCKS, x, y+1, z) == 20) {
|
* Note that stained glass encodes 16 colors using 4 bits. this pushes us over the 8-bits of an unsigned char,
|
||||||
|
* forcing us to use an unsigned short to hold 16 bits of pseudo ancil data
|
||||||
|
* */
|
||||||
|
if ((get_data(state, BLOCKS, x, y+1, z) == 20) || (get_data(state, BLOCKS, x, y+1, z) == 95)) {
|
||||||
data = 0;
|
data = 0;
|
||||||
} else {
|
} else {
|
||||||
data = 16;
|
data = 16;
|
||||||
}
|
}
|
||||||
data = (check_adjacent_blocks(state, x, y, z, state->block) ^ 0x0f) | data;
|
data = (check_adjacent_blocks(state, x, y, z, state->block) ^ 0x0f) | data;
|
||||||
return data;
|
return (data << 4) | (ancilData & 0x0f);
|
||||||
} else if (state->block == 85) { /* fences */
|
} else if (state->block == 85) { /* fences */
|
||||||
/* check for fences AND fence gates */
|
/* check for fences AND fence gates */
|
||||||
return check_adjacent_blocks(state, x, y, z, state->block) | check_adjacent_blocks(state, x, y, z, 107);
|
return check_adjacent_blocks(state, x, y, z, state->block) | check_adjacent_blocks(state, x, y, z, 107);
|
||||||
@@ -379,12 +382,14 @@ generate_pseudo_data(RenderState *state, unsigned char ancilData) {
|
|||||||
}
|
}
|
||||||
return final_data;
|
return final_data;
|
||||||
|
|
||||||
} else if ((state->block == 101) || (state->block == 102)) {
|
} else if ((state->block == 101) || (state->block == 102) || (state->block == 160)) {
|
||||||
/* iron bars and glass panes:
|
/* iron bars and glass panes:
|
||||||
* they seem to stick to almost everything but air,
|
* they seem to stick to almost everything but air,
|
||||||
* not sure yet! Still a TODO! */
|
* not sure yet! Still a TODO! */
|
||||||
/* return check adjacent blocks with air, bit inverted */
|
/* return check adjacent blocks with air, bit inverted */
|
||||||
return check_adjacent_blocks(state, x, y, z, 0) ^ 0x0f;
|
// shift up 4 bits because the lower 4 bits encode color
|
||||||
|
data = (check_adjacent_blocks(state, x, y, z, 0) ^ 0x0f);
|
||||||
|
return (data << 4) | (ancilData & 0xf);
|
||||||
|
|
||||||
} else if ((state->block == 90) || (state->block == 113)) {
|
} else if ((state->block == 90) || (state->block == 113)) {
|
||||||
/* portal and nether brick fences */
|
/* portal and nether brick fences */
|
||||||
@@ -656,7 +661,7 @@ chunk_render(PyObject *self, PyObject *args) {
|
|||||||
state.imgy = yoff - state.x*6 + state.z*6 + 16*12 + 15*6;
|
state.imgy = yoff - state.x*6 + state.z*6 + 16*12 + 15*6;
|
||||||
|
|
||||||
for (state.y = 0; state.y < 16; state.y++) {
|
for (state.y = 0; state.y < 16; state.y++) {
|
||||||
unsigned char ancilData;
|
unsigned short ancilData;
|
||||||
|
|
||||||
state.imgy -= 12;
|
state.imgy -= 12;
|
||||||
|
|
||||||
@@ -701,6 +706,7 @@ chunk_render(PyObject *self, PyObject *args) {
|
|||||||
(state.block == 101) || (state.block == 102) ||
|
(state.block == 101) || (state.block == 102) ||
|
||||||
(state.block == 111) || (state.block == 113) ||
|
(state.block == 111) || (state.block == 113) ||
|
||||||
(state.block == 139) || (state.block == 175) ||
|
(state.block == 139) || (state.block == 175) ||
|
||||||
|
(state.block == 160) || (state.block == 95) ||
|
||||||
is_stairs(state.block)) {
|
is_stairs(state.block)) {
|
||||||
ancilData = generate_pseudo_data(&state, ancilData);
|
ancilData = generate_pseudo_data(&state, ancilData);
|
||||||
state.block_pdata = ancilData;
|
state.block_pdata = ancilData;
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
// increment this value if you've made a change to the c extesion
|
// increment this value if you've made a change to the c extesion
|
||||||
// and want to force users to rebuild
|
// and want to force users to rebuild
|
||||||
#define OVERVIEWER_EXTENSION_VERSION 43
|
#define OVERVIEWER_EXTENSION_VERSION 44
|
||||||
|
|
||||||
/* Python PIL, and numpy headers */
|
/* Python PIL, and numpy headers */
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
@@ -108,7 +108,7 @@ typedef struct {
|
|||||||
int x, y, z;
|
int x, y, z;
|
||||||
unsigned short block;
|
unsigned short block;
|
||||||
unsigned char block_data;
|
unsigned char block_data;
|
||||||
unsigned char block_pdata;
|
unsigned short block_pdata;
|
||||||
|
|
||||||
/* useful information about this, and neighboring, chunks */
|
/* useful information about this, and neighboring, chunks */
|
||||||
PyObject *blockdatas;
|
PyObject *blockdatas;
|
||||||
|
|||||||
@@ -914,15 +914,20 @@ def water(self, blockid, data):
|
|||||||
|
|
||||||
# other water, glass, and ice (no inner surfaces)
|
# other water, glass, and ice (no inner surfaces)
|
||||||
# uses pseudo-ancildata found in iterate.c
|
# uses pseudo-ancildata found in iterate.c
|
||||||
@material(blockid=[9, 20, 79], data=range(32), fluid=(9,), transparent=True, nospawn=True, solid=(79, 20))
|
@material(blockid=[9, 20, 79, 95], data=range(512), fluid=(9,), transparent=True, nospawn=True, solid=(79, 20, 95))
|
||||||
def no_inner_surfaces(self, blockid, data):
|
def no_inner_surfaces(self, blockid, data):
|
||||||
if blockid == 9:
|
if blockid == 9:
|
||||||
texture = self.load_water()
|
texture = self.load_water()
|
||||||
elif blockid == 20:
|
elif blockid == 20:
|
||||||
texture = self.load_image_texture("assets/minecraft/textures/blocks/glass.png")
|
texture = self.load_image_texture("assets/minecraft/textures/blocks/glass.png")
|
||||||
|
elif blockid == 95:
|
||||||
|
texture = self.load_image_texture("assets/minecraft/textures/blocks/glass_%s.png" % color_map[data & 0x0f])
|
||||||
else:
|
else:
|
||||||
texture = self.load_image_texture("assets/minecraft/textures/blocks/ice.png")
|
texture = self.load_image_texture("assets/minecraft/textures/blocks/ice.png")
|
||||||
|
|
||||||
|
# now that we've used the lower 4 bits to get color, shift down to get the 5 bits that encode face hiding
|
||||||
|
data = data >> 4
|
||||||
|
|
||||||
if (data & 0b10000) == 16:
|
if (data & 0b10000) == 16:
|
||||||
top = texture
|
top = texture
|
||||||
else:
|
else:
|
||||||
@@ -1774,7 +1779,8 @@ def stairs(self, blockid, data):
|
|||||||
return img
|
return img
|
||||||
|
|
||||||
# normal, locked (used in april's fool day), ender and trapped chest
|
# normal, locked (used in april's fool day), ender and trapped chest
|
||||||
@material(blockid=[54,95,130,146], data=range(30), transparent = True)
|
# NOTE: locked chest used to be id95 (which is now stained glass)
|
||||||
|
@material(blockid=[54,130,146], data=range(30), transparent = True)
|
||||||
def chests(self, blockid, data):
|
def chests(self, blockid, data):
|
||||||
# the first 3 bits are the orientation as stored in minecraft,
|
# the first 3 bits are the orientation as stored in minecraft,
|
||||||
# bits 0x8 and 0x10 indicate which half of the double chest is it.
|
# bits 0x8 and 0x10 indicate which half of the double chest is it.
|
||||||
@@ -1797,7 +1803,7 @@ def chests(self, blockid, data):
|
|||||||
elif orientation_data == 4: data = 3 | (data & 24)
|
elif orientation_data == 4: data = 3 | (data & 24)
|
||||||
elif orientation_data == 5: data = 2 | (data & 24)
|
elif orientation_data == 5: data = 2 | (data & 24)
|
||||||
|
|
||||||
if blockid in (95,130) and not data in [2,3,4,5]: return None
|
if blockid == 130 and not data in [2,3,4,5]: return None
|
||||||
# iterate.c will only return the ancil data (without pseudo
|
# iterate.c will only return the ancil data (without pseudo
|
||||||
# ancil data) for locked and ender chests, so only
|
# ancil data) for locked and ender chests, so only
|
||||||
# ancilData = 2,3,4,5 are used for this blockids
|
# ancilData = 2,3,4,5 are used for this blockids
|
||||||
@@ -3333,12 +3339,14 @@ def huge_mushroom(self, blockid, data):
|
|||||||
# iron bars and glass pane
|
# iron bars and glass pane
|
||||||
# TODO glass pane is not a sprite, it has a texture for the side,
|
# TODO glass pane is not a sprite, it has a texture for the side,
|
||||||
# at the moment is not used
|
# at the moment is not used
|
||||||
@material(blockid=[101,102], data=range(16), transparent=True, nospawn=True)
|
@material(blockid=[101,102, 160], data=range(256), transparent=True, nospawn=True)
|
||||||
def panes(self, blockid, data):
|
def panes(self, blockid, data):
|
||||||
# no rotation, uses pseudo data
|
# no rotation, uses pseudo data
|
||||||
if blockid == 101:
|
if blockid == 101:
|
||||||
# iron bars
|
# iron bars
|
||||||
t = self.load_image_texture("assets/minecraft/textures/blocks/iron_bars.png")
|
t = self.load_image_texture("assets/minecraft/textures/blocks/iron_bars.png")
|
||||||
|
elif blockid == 160:
|
||||||
|
t = self.load_image_texture("assets/minecraft/textures/blocks/glass_%s.png" % color_map[data & 0xf])
|
||||||
else:
|
else:
|
||||||
# glass panes
|
# glass panes
|
||||||
t = self.load_image_texture("assets/minecraft/textures/blocks/glass.png")
|
t = self.load_image_texture("assets/minecraft/textures/blocks/glass.png")
|
||||||
@@ -3362,6 +3370,9 @@ def panes(self, blockid, data):
|
|||||||
# First compose things in the back of the image,
|
# First compose things in the back of the image,
|
||||||
# then things in the front.
|
# then things in the front.
|
||||||
|
|
||||||
|
# the lower 4 bits encode color, the upper 4 encode adjencies
|
||||||
|
data = data >> 4
|
||||||
|
|
||||||
if (data & 0b0001) == 1 or data == 0:
|
if (data & 0b0001) == 1 or data == 0:
|
||||||
alpha_over(img,up_left, (6,3),up_left) # top left
|
alpha_over(img,up_left, (6,3),up_left) # top left
|
||||||
if (data & 0b1000) == 8 or data == 0:
|
if (data & 0b1000) == 8 or data == 0:
|
||||||
|
|||||||
Reference in New Issue
Block a user