mirror of
https://github.com/xtreme8000/CavEX.git
synced 2025-01-22 09:11:55 -05:00
Automatic texture atlas generation from terrain.png
cannot use terrain.png directly due to texture bleeding
This commit is contained in:
parent
c9719c5077
commit
ca295db3c7
67 changed files with 1204 additions and 302 deletions
|
@ -102,12 +102,14 @@ add_executable(cavex
|
|||
source/graphics/gui_util.c
|
||||
source/graphics/render_block.c
|
||||
source/graphics/render_item.c
|
||||
source/graphics/texture_atlas.c
|
||||
|
||||
source/platform/displaylist.c
|
||||
source/platform/gfx.c
|
||||
source/platform/input.c
|
||||
source/platform/thread.c
|
||||
source/platform/time.c
|
||||
source/platform/texture.c
|
||||
|
||||
source/chunk_mesher.c
|
||||
source/chunk.c
|
||||
|
|
2
Makefile
2
Makefile
|
@ -23,7 +23,7 @@ include $(DEVKITPPC)/wii_rules
|
|||
#---------------------------------------------------------------------------------
|
||||
TARGET := $(notdir $(CURDIR))
|
||||
BUILD := build
|
||||
SOURCES := source source/block source/graphics source/network source/game source/game/gui source/platform source/item source/cNBT
|
||||
SOURCES := source source/block source/graphics source/network source/game source/game/gui source/platform source/item source/cNBT source/lodepng
|
||||
DATA :=
|
||||
TEXTURES := textures
|
||||
INCLUDES :=
|
||||
|
|
|
@ -47,29 +47,33 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
if(this->block->metadata & 0x8) {
|
||||
switch(side) {
|
||||
case SIDE_TOP: return TEXTURE_INDEX(7, 8);
|
||||
case SIDE_TOP: return tex_atlas_lookup(TEXAT_BED_TOP_2);
|
||||
case SIDE_LEFT:
|
||||
case SIDE_RIGHT:
|
||||
return (this->block->metadata & 0x1) ? TEXTURE_INDEX(11, 8) :
|
||||
TEXTURE_INDEX(10, 8);
|
||||
return (this->block->metadata & 0x1) ?
|
||||
tex_atlas_lookup(TEXAT_BED_FRONT) :
|
||||
tex_atlas_lookup(TEXAT_BED_SIDE_2);
|
||||
case SIDE_FRONT:
|
||||
case SIDE_BACK:
|
||||
return (this->block->metadata & 0x1) ? TEXTURE_INDEX(10, 8) :
|
||||
TEXTURE_INDEX(11, 8);
|
||||
default: return TEXTURE_INDEX(4, 0);
|
||||
return (this->block->metadata & 0x1) ?
|
||||
tex_atlas_lookup(TEXAT_BED_SIDE_2) :
|
||||
tex_atlas_lookup(TEXAT_BED_FRONT);
|
||||
default: return tex_atlas_lookup(TEXAT_PLANKS);
|
||||
}
|
||||
} else {
|
||||
switch(side) {
|
||||
case SIDE_TOP: return TEXTURE_INDEX(6, 8);
|
||||
case SIDE_TOP: return tex_atlas_lookup(TEXAT_BED_TOP_1);
|
||||
case SIDE_LEFT:
|
||||
case SIDE_RIGHT:
|
||||
return (this->block->metadata & 0x1) ? TEXTURE_INDEX(8, 8) :
|
||||
TEXTURE_INDEX(9, 8);
|
||||
return (this->block->metadata & 0x1) ?
|
||||
tex_atlas_lookup(TEXAT_BED_BACK) :
|
||||
tex_atlas_lookup(TEXAT_BED_SIDE_1);
|
||||
case SIDE_FRONT:
|
||||
case SIDE_BACK:
|
||||
return (this->block->metadata & 0x1) ? TEXTURE_INDEX(9, 8) :
|
||||
TEXTURE_INDEX(8, 8);
|
||||
default: return TEXTURE_INDEX(4, 0);
|
||||
return (this->block->metadata & 0x1) ?
|
||||
tex_atlas_lookup(TEXAT_BED_SIDE_1) :
|
||||
tex_atlas_lookup(TEXAT_BED_BACK);
|
||||
default: return tex_atlas_lookup(TEXAT_PLANKS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(1, 1);
|
||||
return tex_atlas_lookup(TEXAT_BEDROCK);
|
||||
}
|
||||
|
||||
struct block block_bedrock = {
|
||||
|
|
|
@ -37,8 +37,8 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
switch(side) {
|
||||
case SIDE_TOP:
|
||||
case SIDE_BOTTOM: return TEXTURE_INDEX(4, 0);
|
||||
default: return TEXTURE_INDEX(3, 2);
|
||||
case SIDE_BOTTOM: return tex_atlas_lookup(TEXAT_PLANKS);
|
||||
default: return tex_atlas_lookup(TEXAT_BOOKSHELF);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(7, 0);
|
||||
return tex_atlas_lookup(TEXAT_BRICKS);
|
||||
}
|
||||
|
||||
struct block block_bricks = {
|
||||
|
|
|
@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(13, 1);
|
||||
return tex_atlas_lookup(TEXAT_MUSHROOM_BROWN);
|
||||
}
|
||||
|
||||
struct block block_brown_mushroom = {
|
||||
|
|
|
@ -45,9 +45,9 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
switch(side) {
|
||||
case SIDE_TOP: return TEXTURE_INDEX(5, 4);
|
||||
case SIDE_BOTTOM: return TEXTURE_INDEX(7, 4);
|
||||
default: return TEXTURE_INDEX(6, 4);
|
||||
case SIDE_TOP: return tex_atlas_lookup(TEXAT_CACTUS_TOP);
|
||||
case SIDE_BOTTOM: return tex_atlas_lookup(TEXAT_CACTUS_BOTTOM);
|
||||
default: return tex_atlas_lookup(TEXAT_CACTUS_SIDE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -46,12 +46,13 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
switch(side) {
|
||||
case SIDE_TOP: return TEXTURE_INDEX(9, 7);
|
||||
case SIDE_BOTTOM: return TEXTURE_INDEX(12, 7);
|
||||
case SIDE_TOP: return tex_atlas_lookup(TEXAT_CAKE_TOP);
|
||||
case SIDE_BOTTOM: return tex_atlas_lookup(TEXAT_CAKE_BOTTOM);
|
||||
case SIDE_LEFT:
|
||||
return (this->block->metadata > 0) ? TEXTURE_INDEX(11, 7) :
|
||||
TEXTURE_INDEX(10, 7);
|
||||
default: return TEXTURE_INDEX(10, 7);
|
||||
return (this->block->metadata > 0) ?
|
||||
tex_atlas_lookup(TEXAT_CAKE_SIDE_CUT) :
|
||||
tex_atlas_lookup(TEXAT_CAKE_SIDE);
|
||||
default: return tex_atlas_lookup(TEXAT_CAKE_SIDE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,19 +35,19 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex1(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(6, 1);
|
||||
return tex_atlas_lookup(TEXAT_CAST_BLOCK_IRON);
|
||||
}
|
||||
|
||||
static uint8_t getTextureIndex2(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(7, 1);
|
||||
return tex_atlas_lookup(TEXAT_CAST_BLOCK_GOLD);
|
||||
}
|
||||
|
||||
static uint8_t getTextureIndex3(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(8, 1);
|
||||
return tex_atlas_lookup(TEXAT_CAST_BLOCK_DIAMOND);
|
||||
}
|
||||
|
||||
static uint8_t getTextureIndex4(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(0, 9);
|
||||
return tex_atlas_lookup(TEXAT_CAST_BLOCK_LAPIS);
|
||||
}
|
||||
|
||||
struct block block_iron = {
|
||||
|
|
|
@ -45,59 +45,62 @@ static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
|||
if(right->type == this->block->type) {
|
||||
switch(side) {
|
||||
case SIDE_TOP:
|
||||
case SIDE_BOTTOM: return TEXTURE_INDEX(9, 1);
|
||||
case SIDE_BACK: return TEXTURE_INDEX(9, 2);
|
||||
case SIDE_FRONT: return TEXTURE_INDEX(10, 3);
|
||||
default: return TEXTURE_INDEX(10, 1);
|
||||
case SIDE_BOTTOM: return tex_atlas_lookup(TEXAT_CHEST_TOP);
|
||||
case SIDE_BACK: return tex_atlas_lookup(TEXAT_CHEST_FRONT_1);
|
||||
case SIDE_FRONT: return tex_atlas_lookup(TEXAT_CHEST_BACK_2);
|
||||
default: return tex_atlas_lookup(TEXAT_CHEST_SIDE);
|
||||
}
|
||||
}
|
||||
|
||||
if(left->type == this->block->type) {
|
||||
switch(side) {
|
||||
case SIDE_TOP:
|
||||
case SIDE_BOTTOM: return TEXTURE_INDEX(9, 1);
|
||||
case SIDE_BACK: return TEXTURE_INDEX(10, 2);
|
||||
case SIDE_FRONT: return TEXTURE_INDEX(9, 3);
|
||||
default: return TEXTURE_INDEX(10, 1);
|
||||
case SIDE_BOTTOM: return tex_atlas_lookup(TEXAT_CHEST_TOP);
|
||||
case SIDE_BACK: return tex_atlas_lookup(TEXAT_CHEST_FRONT_2);
|
||||
case SIDE_FRONT: return tex_atlas_lookup(TEXAT_CHEST_BACK_1);
|
||||
default: return tex_atlas_lookup(TEXAT_CHEST_SIDE);
|
||||
}
|
||||
}
|
||||
|
||||
if(back->type == this->block->type) {
|
||||
switch(side) {
|
||||
case SIDE_TOP:
|
||||
case SIDE_BOTTOM: return TEXTURE_INDEX(9, 1);
|
||||
case SIDE_RIGHT: return TEXTURE_INDEX(10, 2);
|
||||
case SIDE_LEFT: return TEXTURE_INDEX(9, 3);
|
||||
default: return TEXTURE_INDEX(10, 1);
|
||||
case SIDE_BOTTOM: return tex_atlas_lookup(TEXAT_CHEST_TOP);
|
||||
case SIDE_RIGHT: return tex_atlas_lookup(TEXAT_CHEST_FRONT_2);
|
||||
case SIDE_LEFT: return tex_atlas_lookup(TEXAT_CHEST_BACK_1);
|
||||
default: return tex_atlas_lookup(TEXAT_CHEST_SIDE);
|
||||
}
|
||||
}
|
||||
|
||||
if(front->type == this->block->type) {
|
||||
switch(side) {
|
||||
case SIDE_TOP:
|
||||
case SIDE_BOTTOM: return TEXTURE_INDEX(9, 1);
|
||||
case SIDE_RIGHT: return TEXTURE_INDEX(9, 2);
|
||||
case SIDE_LEFT: return TEXTURE_INDEX(10, 3);
|
||||
default: return TEXTURE_INDEX(10, 1);
|
||||
case SIDE_BOTTOM: return tex_atlas_lookup(TEXAT_CHEST_TOP);
|
||||
case SIDE_RIGHT: return tex_atlas_lookup(TEXAT_CHEST_FRONT_1);
|
||||
case SIDE_LEFT: return tex_atlas_lookup(TEXAT_CHEST_BACK_2);
|
||||
default: return tex_atlas_lookup(TEXAT_CHEST_SIDE);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t tex[SIDE_MAX] = {
|
||||
[SIDE_TOP] = TEXTURE_INDEX(9, 1), [SIDE_BOTTOM] = TEXTURE_INDEX(9, 1),
|
||||
[SIDE_BACK] = TEXTURE_INDEX(10, 1), [SIDE_FRONT] = TEXTURE_INDEX(10, 1),
|
||||
[SIDE_LEFT] = TEXTURE_INDEX(10, 1), [SIDE_RIGHT] = TEXTURE_INDEX(10, 1),
|
||||
[SIDE_TOP] = tex_atlas_lookup(TEXAT_CHEST_TOP),
|
||||
[SIDE_BOTTOM] = tex_atlas_lookup(TEXAT_CHEST_TOP),
|
||||
[SIDE_BACK] = tex_atlas_lookup(TEXAT_CHEST_SIDE),
|
||||
[SIDE_FRONT] = tex_atlas_lookup(TEXAT_CHEST_SIDE),
|
||||
[SIDE_LEFT] = tex_atlas_lookup(TEXAT_CHEST_SIDE),
|
||||
[SIDE_RIGHT] = tex_atlas_lookup(TEXAT_CHEST_SIDE),
|
||||
};
|
||||
|
||||
if(left->type && !right->type)
|
||||
tex[SIDE_RIGHT] = TEXTURE_INDEX(11, 1);
|
||||
tex[SIDE_RIGHT] = tex_atlas_lookup(TEXAT_CHEST_FRONT_SINGLE);
|
||||
else if(right->type && !left->type)
|
||||
tex[SIDE_LEFT] = TEXTURE_INDEX(11, 1);
|
||||
tex[SIDE_LEFT] = tex_atlas_lookup(TEXAT_CHEST_FRONT_SINGLE);
|
||||
else if(front->type && !back->type)
|
||||
tex[SIDE_BACK] = TEXTURE_INDEX(11, 1);
|
||||
tex[SIDE_BACK] = tex_atlas_lookup(TEXAT_CHEST_FRONT_SINGLE);
|
||||
else if(back->type && !front->type)
|
||||
tex[SIDE_FRONT] = TEXTURE_INDEX(11, 1);
|
||||
tex[SIDE_FRONT] = tex_atlas_lookup(TEXAT_CHEST_FRONT_SINGLE);
|
||||
else
|
||||
tex[SIDE_BACK] = TEXTURE_INDEX(11, 1);
|
||||
tex[SIDE_BACK] = tex_atlas_lookup(TEXAT_CHEST_FRONT_SINGLE);
|
||||
|
||||
return tex[side];
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(8, 4);
|
||||
return tex_atlas_lookup(TEXAT_CLAY);
|
||||
}
|
||||
|
||||
struct block block_clay = {
|
||||
|
|
|
@ -36,8 +36,8 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
switch(this->block->type) {
|
||||
default: return TEXTURE_INDEX(0, 1);
|
||||
case 48: return TEXTURE_INDEX(4, 2);
|
||||
default: return tex_atlas_lookup(TEXAT_COBBLESTONE);
|
||||
case 48: return tex_atlas_lookup(TEXAT_COBBLESTONE_MOSSY);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(11, 0);
|
||||
return tex_atlas_lookup(TEXAT_COBWEB);
|
||||
}
|
||||
|
||||
struct block block_cobweb = {
|
||||
|
|
|
@ -35,7 +35,17 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(this->block->metadata + 6, 5);
|
||||
switch(this->block->metadata) {
|
||||
case 0: return tex_atlas_lookup(TEXAT_CROPS_0);
|
||||
case 1: return tex_atlas_lookup(TEXAT_CROPS_1);
|
||||
case 2: return tex_atlas_lookup(TEXAT_CROPS_2);
|
||||
case 3: return tex_atlas_lookup(TEXAT_CROPS_3);
|
||||
case 4: return tex_atlas_lookup(TEXAT_CROPS_4);
|
||||
case 5: return tex_atlas_lookup(TEXAT_CROPS_5);
|
||||
case 6: return tex_atlas_lookup(TEXAT_CROPS_6);
|
||||
default:
|
||||
case 7: return tex_atlas_lookup(TEXAT_CROPS_7);
|
||||
}
|
||||
}
|
||||
|
||||
struct block block_crops = {
|
||||
|
|
|
@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(2, 0);
|
||||
return tex_atlas_lookup(TEXAT_DIRT);
|
||||
}
|
||||
|
||||
struct block block_dirt = {
|
||||
|
|
|
@ -38,25 +38,25 @@ static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
|||
switch(side) {
|
||||
case SIDE_FRONT:
|
||||
if(this->block->metadata == 2)
|
||||
return TEXTURE_INDEX(12, 4);
|
||||
return tex_atlas_lookup(TEXAT_DISPENSER_FRONT);
|
||||
else
|
||||
return TEXTURE_INDEX(13, 2);
|
||||
return tex_atlas_lookup(TEXAT_FURNACE_SIDE);
|
||||
case SIDE_BACK:
|
||||
if(this->block->metadata == 3)
|
||||
return TEXTURE_INDEX(12, 4);
|
||||
return tex_atlas_lookup(TEXAT_DISPENSER_FRONT);
|
||||
else
|
||||
return TEXTURE_INDEX(13, 2);
|
||||
return tex_atlas_lookup(TEXAT_FURNACE_SIDE);
|
||||
case SIDE_RIGHT:
|
||||
if(this->block->metadata == 5)
|
||||
return TEXTURE_INDEX(12, 4);
|
||||
return tex_atlas_lookup(TEXAT_DISPENSER_FRONT);
|
||||
else
|
||||
return TEXTURE_INDEX(13, 2);
|
||||
return tex_atlas_lookup(TEXAT_FURNACE_SIDE);
|
||||
case SIDE_LEFT:
|
||||
if(this->block->metadata == 4)
|
||||
return TEXTURE_INDEX(12, 4);
|
||||
return tex_atlas_lookup(TEXAT_DISPENSER_FRONT);
|
||||
else
|
||||
return TEXTURE_INDEX(13, 2);
|
||||
default: return TEXTURE_INDEX(13, 4);
|
||||
return tex_atlas_lookup(TEXAT_FURNACE_SIDE);
|
||||
default: return tex_atlas_lookup(TEXAT_FURNACE_TOP);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,11 +61,15 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex1(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(1, (this->block->metadata & 0x08) ? 5 : 6);
|
||||
return (this->block->metadata & 0x08) ?
|
||||
tex_atlas_lookup(TEXAT_DOOR_WOOD_TOP) :
|
||||
tex_atlas_lookup(TEXAT_DOOR_WOOD_BOTTOM);
|
||||
}
|
||||
|
||||
static uint8_t getTextureIndex2(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(2, (this->block->metadata & 0x08) ? 5 : 6);
|
||||
return (this->block->metadata & 0x08) ?
|
||||
tex_atlas_lookup(TEXAT_DOOR_IRON_TOP) :
|
||||
tex_atlas_lookup(TEXAT_DOOR_IRON_BOTTOM);
|
||||
}
|
||||
|
||||
struct block block_wooden_door = {
|
||||
|
|
|
@ -39,15 +39,16 @@ static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
|||
default:
|
||||
case 0:
|
||||
return (side == SIDE_TOP || side == SIDE_BOTTOM) ?
|
||||
TEXTURE_INDEX(6, 0) :
|
||||
TEXTURE_INDEX(5, 0);
|
||||
tex_atlas_lookup(TEXAT_SLAB_STONE_TOP) :
|
||||
tex_atlas_lookup(TEXAT_SLAB_STONE_SIDE);
|
||||
case 1:
|
||||
return (side == SIDE_TOP) ?
|
||||
TEXTURE_INDEX(0, 11) :
|
||||
((side == SIDE_BOTTOM) ? TEXTURE_INDEX(0, 13) :
|
||||
TEXTURE_INDEX(0, 12));
|
||||
case 2: return TEXTURE_INDEX(4, 0);
|
||||
case 3: return TEXTURE_INDEX(0, 1);
|
||||
tex_atlas_lookup(TEXAT_SANDSTONE_TOP) :
|
||||
((side == SIDE_BOTTOM) ?
|
||||
tex_atlas_lookup(TEXAT_SANDSTONE_BOTTOM) :
|
||||
tex_atlas_lookup(TEXAT_SANDSTONE_SIDE));
|
||||
case 2: return tex_atlas_lookup(TEXAT_PLANKS);
|
||||
case 3: return tex_atlas_lookup(TEXAT_COBBLESTONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,9 +41,10 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
switch(side) {
|
||||
case SIDE_TOP:
|
||||
return (this->block->metadata < 7) ? TEXTURE_INDEX(5, 5) :
|
||||
TEXTURE_INDEX(4, 5);
|
||||
default: return TEXTURE_INDEX(2, 0);
|
||||
return (this->block->metadata < 7) ?
|
||||
tex_atlas_lookup(TEXAT_FARMLAND_DRY) :
|
||||
tex_atlas_lookup(TEXAT_FARMLAND_WET);
|
||||
default: return tex_atlas_lookup(TEXAT_DIRT);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(4, 0);
|
||||
return tex_atlas_lookup(TEXAT_PLANKS);
|
||||
}
|
||||
|
||||
struct block block_fence = {
|
||||
|
|
|
@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(13, 0);
|
||||
return tex_atlas_lookup(TEXAT_DANDELION);
|
||||
}
|
||||
|
||||
struct block block_flower = {
|
||||
|
|
|
@ -34,29 +34,55 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
return face_occlusion_full();
|
||||
}
|
||||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
static uint8_t getTextureIndex1(struct block_info* this, enum side side) {
|
||||
switch(side) {
|
||||
case SIDE_FRONT:
|
||||
if(this->block->metadata == 2)
|
||||
return TEXTURE_INDEX(12, 2);
|
||||
return tex_atlas_lookup(TEXAT_FURNACE_FRONT);
|
||||
else
|
||||
return TEXTURE_INDEX(13, 2);
|
||||
return tex_atlas_lookup(TEXAT_FURNACE_SIDE);
|
||||
case SIDE_BACK:
|
||||
if(this->block->metadata == 3)
|
||||
return TEXTURE_INDEX(12, 2);
|
||||
return tex_atlas_lookup(TEXAT_FURNACE_FRONT);
|
||||
else
|
||||
return TEXTURE_INDEX(13, 2);
|
||||
return tex_atlas_lookup(TEXAT_FURNACE_SIDE);
|
||||
case SIDE_RIGHT:
|
||||
if(this->block->metadata == 5)
|
||||
return TEXTURE_INDEX(12, 2);
|
||||
return tex_atlas_lookup(TEXAT_FURNACE_FRONT);
|
||||
else
|
||||
return TEXTURE_INDEX(13, 2);
|
||||
return tex_atlas_lookup(TEXAT_FURNACE_SIDE);
|
||||
case SIDE_LEFT:
|
||||
if(this->block->metadata == 4)
|
||||
return TEXTURE_INDEX(12, 2);
|
||||
return tex_atlas_lookup(TEXAT_FURNACE_FRONT);
|
||||
else
|
||||
return TEXTURE_INDEX(13, 2);
|
||||
default: return TEXTURE_INDEX(13, 4);
|
||||
return tex_atlas_lookup(TEXAT_FURNACE_SIDE);
|
||||
default: return tex_atlas_lookup(TEXAT_FURNACE_TOP);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t getTextureIndex2(struct block_info* this, enum side side) {
|
||||
switch(side) {
|
||||
case SIDE_FRONT:
|
||||
if(this->block->metadata == 2)
|
||||
return tex_atlas_lookup(TEXAT_FURNACE_FRONT_LIT);
|
||||
else
|
||||
return tex_atlas_lookup(TEXAT_FURNACE_SIDE);
|
||||
case SIDE_BACK:
|
||||
if(this->block->metadata == 3)
|
||||
return tex_atlas_lookup(TEXAT_FURNACE_FRONT_LIT);
|
||||
else
|
||||
return tex_atlas_lookup(TEXAT_FURNACE_SIDE);
|
||||
case SIDE_RIGHT:
|
||||
if(this->block->metadata == 5)
|
||||
return tex_atlas_lookup(TEXAT_FURNACE_FRONT_LIT);
|
||||
else
|
||||
return tex_atlas_lookup(TEXAT_FURNACE_SIDE);
|
||||
case SIDE_LEFT:
|
||||
if(this->block->metadata == 4)
|
||||
return tex_atlas_lookup(TEXAT_FURNACE_FRONT_LIT);
|
||||
else
|
||||
return tex_atlas_lookup(TEXAT_FURNACE_SIDE);
|
||||
default: return tex_atlas_lookup(TEXAT_FURNACE_TOP);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,7 +91,7 @@ struct block block_furnaceoff = {
|
|||
.getSideMask = getSideMask,
|
||||
.getBoundingBox = getBoundingBox,
|
||||
.getMaterial = getMaterial,
|
||||
.getTextureIndex = getTextureIndex,
|
||||
.getTextureIndex = getTextureIndex1,
|
||||
.transparent = false,
|
||||
.renderBlock = render_block_full,
|
||||
.renderBlockAlways = NULL,
|
||||
|
@ -89,7 +115,7 @@ struct block block_furnaceon = {
|
|||
.getSideMask = getSideMask,
|
||||
.getBoundingBox = getBoundingBox,
|
||||
.getMaterial = getMaterial,
|
||||
.getTextureIndex = getTextureIndex,
|
||||
.getTextureIndex = getTextureIndex2,
|
||||
.transparent = false,
|
||||
.renderBlock = render_block_full,
|
||||
.renderBlockAlways = NULL,
|
||||
|
|
|
@ -36,7 +36,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(1, 3);
|
||||
return tex_atlas_lookup(TEXAT_GLASS);
|
||||
}
|
||||
|
||||
struct block block_glass = {
|
||||
|
|
|
@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(9, 6);
|
||||
return tex_atlas_lookup(TEXAT_GLOWSTONE);
|
||||
}
|
||||
|
||||
struct block block_glowstone = {
|
||||
|
|
|
@ -38,13 +38,13 @@ static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
|||
switch(side) {
|
||||
case SIDE_TOP:
|
||||
return (this->neighbours[SIDE_TOP].type == BLOCK_SNOW) ?
|
||||
TEXTURE_INDEX(2, 4) :
|
||||
TEXTURE_INDEX(5, 9);
|
||||
case SIDE_BOTTOM: return TEXTURE_INDEX(2, 0);
|
||||
tex_atlas_lookup(TEXAT_SNOW) :
|
||||
tex_atlas_lookup(TEXAT_GRASS_TOP);
|
||||
case SIDE_BOTTOM: return tex_atlas_lookup(TEXAT_DIRT);
|
||||
default:
|
||||
return (this->neighbours[SIDE_TOP].type == BLOCK_SNOW) ?
|
||||
TEXTURE_INDEX(4, 4) :
|
||||
TEXTURE_INDEX(5, 10);
|
||||
tex_atlas_lookup(TEXAT_GRASS_SIDE_SNOW) :
|
||||
tex_atlas_lookup(TEXAT_GRASS_SIDE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(3, 1);
|
||||
return tex_atlas_lookup(TEXAT_GRAVEL);
|
||||
}
|
||||
|
||||
struct block block_gravel = {
|
||||
|
|
|
@ -36,8 +36,8 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
switch(side) {
|
||||
case SIDE_TOP: return TEXTURE_INDEX(11, 4);
|
||||
default: return TEXTURE_INDEX(10, 4);
|
||||
case SIDE_TOP: return tex_atlas_lookup(TEXAT_JUKBEBOX_TOP);
|
||||
default: return tex_atlas_lookup(TEXAT_JUKBEBOX_SIDE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(3, 5);
|
||||
return tex_atlas_lookup(TEXAT_LADDER);
|
||||
}
|
||||
|
||||
struct block block_ladder = {
|
||||
|
|
|
@ -45,9 +45,9 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
switch(this->block->metadata & 0x3) {
|
||||
case 1: return TEXTURE_INDEX(4, 8);
|
||||
case 2: return TEXTURE_INDEX(4, 3);
|
||||
default: return TEXTURE_INDEX(5, 11);
|
||||
case 1: return tex_atlas_lookup(TEXAT_LEAVES_SPRUCE);
|
||||
case 2: return tex_atlas_lookup(TEXAT_LEAVES_BIRCH);
|
||||
default: return tex_atlas_lookup(TEXAT_LEAVES_OAK);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,29 +35,14 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
if(side == SIDE_TOP || side == SIDE_BOTTOM)
|
||||
return tex_atlas_lookup(TEXAT_LOG_OAK_TOP);
|
||||
|
||||
switch(this->block->metadata) {
|
||||
default:
|
||||
case 0:
|
||||
switch(side) {
|
||||
case SIDE_TOP:
|
||||
case SIDE_BOTTOM: return TEXTURE_INDEX(5, 1);
|
||||
default: return TEXTURE_INDEX(4, 1);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
switch(side) {
|
||||
case SIDE_TOP:
|
||||
case SIDE_BOTTOM: return TEXTURE_INDEX(5, 1);
|
||||
default: return TEXTURE_INDEX(4, 7);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
switch(side) {
|
||||
case SIDE_TOP:
|
||||
case SIDE_BOTTOM: return TEXTURE_INDEX(5, 1);
|
||||
default: return TEXTURE_INDEX(5, 7);
|
||||
}
|
||||
break;
|
||||
case 0: return tex_atlas_lookup(TEXAT_LOG_OAK_SIDE);
|
||||
case 1: return tex_atlas_lookup(TEXAT_LOG_SPRUCE_SIDE);
|
||||
case 2: return tex_atlas_lookup(TEXAT_LOG_BIRCH_SIDE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(7, 6);
|
||||
return tex_atlas_lookup(TEXAT_NETHERRACK);
|
||||
}
|
||||
|
||||
struct block block_netherrack = {
|
||||
|
|
|
@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(10, 4);
|
||||
return tex_atlas_lookup(TEXAT_JUKBEBOX_SIDE);
|
||||
}
|
||||
|
||||
struct block block_noteblock = {
|
||||
|
|
|
@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(5, 2);
|
||||
return tex_atlas_lookup(TEXAT_OBSIDIAN);
|
||||
}
|
||||
|
||||
struct block block_obsidian = {
|
||||
|
|
|
@ -37,18 +37,18 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
switch(this->block->type) {
|
||||
case 14: // gold
|
||||
return TEXTURE_INDEX(0, 2);
|
||||
return tex_atlas_lookup(TEXAT_ORE_GOLD);
|
||||
case 15: // iron
|
||||
return TEXTURE_INDEX(1, 2);
|
||||
return tex_atlas_lookup(TEXAT_ORE_IRON);
|
||||
case 16: // coal
|
||||
return TEXTURE_INDEX(2, 2);
|
||||
return tex_atlas_lookup(TEXAT_ORE_COAL);
|
||||
case 21: // lapis
|
||||
return TEXTURE_INDEX(0, 10);
|
||||
return tex_atlas_lookup(TEXAT_ORE_LAPIS);
|
||||
case 56: // diamond
|
||||
return TEXTURE_INDEX(2, 3);
|
||||
return tex_atlas_lookup(TEXAT_ORE_DIAMOND);
|
||||
case 73: // redstone
|
||||
case 74: return TEXTURE_INDEX(3, 3);
|
||||
default: return TEXTURE_INDEX(1, 0);
|
||||
case 74: return tex_atlas_lookup(TEXAT_ORE_REDSTONE);
|
||||
default: return tex_atlas_lookup(TEXAT_STONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(4, 0);
|
||||
return tex_atlas_lookup(TEXAT_PLANKS);
|
||||
}
|
||||
|
||||
struct block block_planks = {
|
||||
|
|
|
@ -44,11 +44,11 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex1(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(1, 0);
|
||||
return tex_atlas_lookup(TEXAT_STONE);
|
||||
}
|
||||
|
||||
static uint8_t getTextureIndex2(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(4, 0);
|
||||
return tex_atlas_lookup(TEXAT_PLANKS);
|
||||
}
|
||||
|
||||
struct block block_stone_pressure_plate = {
|
||||
|
|
|
@ -34,29 +34,55 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
return face_occlusion_full();
|
||||
}
|
||||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
static uint8_t getTextureIndex1(struct block_info* this, enum side side) {
|
||||
switch(side) {
|
||||
case SIDE_FRONT:
|
||||
if(this->block->metadata == 2)
|
||||
return TEXTURE_INDEX(7, 7);
|
||||
return tex_atlas_lookup(TEXAT_PUMPKIN_FRONT);
|
||||
else
|
||||
return TEXTURE_INDEX(6, 7);
|
||||
return tex_atlas_lookup(TEXAT_PUMPKIN_SIDE);
|
||||
case SIDE_BACK:
|
||||
if(this->block->metadata == 0)
|
||||
return TEXTURE_INDEX(7, 7);
|
||||
return tex_atlas_lookup(TEXAT_PUMPKIN_FRONT);
|
||||
else
|
||||
return TEXTURE_INDEX(6, 7);
|
||||
return tex_atlas_lookup(TEXAT_PUMPKIN_SIDE);
|
||||
case SIDE_RIGHT:
|
||||
if(this->block->metadata == 3)
|
||||
return TEXTURE_INDEX(7, 7);
|
||||
return tex_atlas_lookup(TEXAT_PUMPKIN_FRONT);
|
||||
else
|
||||
return TEXTURE_INDEX(6, 7);
|
||||
return tex_atlas_lookup(TEXAT_PUMPKIN_SIDE);
|
||||
case SIDE_LEFT:
|
||||
if(this->block->metadata == 1)
|
||||
return TEXTURE_INDEX(7, 7);
|
||||
return tex_atlas_lookup(TEXAT_PUMPKIN_FRONT);
|
||||
else
|
||||
return TEXTURE_INDEX(6, 7);
|
||||
default: return TEXTURE_INDEX(6, 6);
|
||||
return tex_atlas_lookup(TEXAT_PUMPKIN_SIDE);
|
||||
default: return tex_atlas_lookup(TEXAT_PUMPKIN_TOP);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t getTextureIndex2(struct block_info* this, enum side side) {
|
||||
switch(side) {
|
||||
case SIDE_FRONT:
|
||||
if(this->block->metadata == 2)
|
||||
return tex_atlas_lookup(TEXAT_PUMPKIN_FRONT_LIT);
|
||||
else
|
||||
return tex_atlas_lookup(TEXAT_PUMPKIN_SIDE);
|
||||
case SIDE_BACK:
|
||||
if(this->block->metadata == 0)
|
||||
return tex_atlas_lookup(TEXAT_PUMPKIN_FRONT_LIT);
|
||||
else
|
||||
return tex_atlas_lookup(TEXAT_PUMPKIN_SIDE);
|
||||
case SIDE_RIGHT:
|
||||
if(this->block->metadata == 3)
|
||||
return tex_atlas_lookup(TEXAT_PUMPKIN_FRONT_LIT);
|
||||
else
|
||||
return tex_atlas_lookup(TEXAT_PUMPKIN_SIDE);
|
||||
case SIDE_LEFT:
|
||||
if(this->block->metadata == 1)
|
||||
return tex_atlas_lookup(TEXAT_PUMPKIN_FRONT_LIT);
|
||||
else
|
||||
return tex_atlas_lookup(TEXAT_PUMPKIN_SIDE);
|
||||
default: return tex_atlas_lookup(TEXAT_PUMPKIN_TOP);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,7 +91,7 @@ struct block block_pumpkin = {
|
|||
.getSideMask = getSideMask,
|
||||
.getBoundingBox = getBoundingBox,
|
||||
.getMaterial = getMaterial,
|
||||
.getTextureIndex = getTextureIndex,
|
||||
.getTextureIndex = getTextureIndex1,
|
||||
.transparent = false,
|
||||
.renderBlock = render_block_full,
|
||||
.renderBlockAlways = NULL,
|
||||
|
@ -89,7 +115,7 @@ struct block block_pumpkin_lit = {
|
|||
.getSideMask = getSideMask,
|
||||
.getBoundingBox = getBoundingBox,
|
||||
.getMaterial = getMaterial,
|
||||
.getTextureIndex = getTextureIndex,
|
||||
.getTextureIndex = getTextureIndex2,
|
||||
.transparent = false,
|
||||
.renderBlock = render_block_full,
|
||||
.renderBlockAlways = NULL,
|
||||
|
|
|
@ -40,17 +40,18 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex1(struct block_info* this, enum side side) {
|
||||
return (this->block->metadata < 6) ? TEXTURE_INDEX(0, 8) :
|
||||
TEXTURE_INDEX(0, 7);
|
||||
return (this->block->metadata < 6) ? tex_atlas_lookup(TEXAT_RAIL) :
|
||||
tex_atlas_lookup(TEXAT_RAIL_CURVED);
|
||||
}
|
||||
|
||||
static uint8_t getTextureIndex2(struct block_info* this, enum side side) {
|
||||
return (this->block->metadata & 0x8) ? TEXTURE_INDEX(3, 11) :
|
||||
TEXTURE_INDEX(3, 10);
|
||||
return (this->block->metadata & 0x8) ?
|
||||
tex_atlas_lookup(TEXAT_RAIL_POWERED_ON) :
|
||||
tex_atlas_lookup(TEXAT_RAIL_POWERED_OFF);
|
||||
}
|
||||
|
||||
static uint8_t getTextureIndex3(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(3, 12);
|
||||
return tex_atlas_lookup(TEXAT_RAIL_DETECTOR);
|
||||
}
|
||||
|
||||
struct block block_rail = {
|
||||
|
|
|
@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(12, 1);
|
||||
return tex_atlas_lookup(TEXAT_MUSHROOM_RED);
|
||||
}
|
||||
|
||||
struct block block_red_mushroom = {
|
||||
|
|
|
@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(9, 4);
|
||||
return tex_atlas_lookup(TEXAT_REED);
|
||||
}
|
||||
|
||||
struct block block_reed = {
|
||||
|
|
|
@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(12, 0);
|
||||
return tex_atlas_lookup(TEXAT_ROSE);
|
||||
}
|
||||
|
||||
struct block block_rose = {
|
||||
|
|
|
@ -35,11 +35,11 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex1(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(2, 1);
|
||||
return tex_atlas_lookup(TEXAT_SAND);
|
||||
}
|
||||
|
||||
static uint8_t getTextureIndex2(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(8, 6);
|
||||
return tex_atlas_lookup(TEXAT_SOULSAND);
|
||||
}
|
||||
|
||||
struct block block_sand = {
|
||||
|
|
|
@ -36,9 +36,9 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
switch(side) {
|
||||
case SIDE_TOP: return TEXTURE_INDEX(0, 11);
|
||||
case SIDE_BOTTOM: return TEXTURE_INDEX(0, 13);
|
||||
default: return TEXTURE_INDEX(0, 12);
|
||||
case SIDE_TOP: return tex_atlas_lookup(TEXAT_SANDSTONE_TOP);
|
||||
case SIDE_BOTTOM: return tex_atlas_lookup(TEXAT_SANDSTONE_BOTTOM);
|
||||
default: return tex_atlas_lookup(TEXAT_SANDSTONE_SIDE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -36,9 +36,9 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
switch(this->block->metadata) {
|
||||
case 1: return TEXTURE_INDEX(7, 2);
|
||||
case 2: return TEXTURE_INDEX(8, 2);
|
||||
default: return TEXTURE_INDEX(6, 2);
|
||||
case 1: return tex_atlas_lookup(TEXAT_SAPLING_SPRUCE);
|
||||
case 2: return tex_atlas_lookup(TEXAT_SAPLING_BIRCH);
|
||||
default: return tex_atlas_lookup(TEXAT_SAPLING_OAK);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,15 +43,16 @@ static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
|||
default:
|
||||
case 0:
|
||||
return (side == SIDE_TOP || side == SIDE_BOTTOM) ?
|
||||
TEXTURE_INDEX(6, 0) :
|
||||
TEXTURE_INDEX(5, 0);
|
||||
tex_atlas_lookup(TEXAT_SLAB_STONE_TOP) :
|
||||
tex_atlas_lookup(TEXAT_SLAB_STONE_SIDE);
|
||||
case 1:
|
||||
return (side == SIDE_TOP) ?
|
||||
TEXTURE_INDEX(0, 11) :
|
||||
((side == SIDE_BOTTOM) ? TEXTURE_INDEX(0, 13) :
|
||||
TEXTURE_INDEX(0, 12));
|
||||
case 2: return TEXTURE_INDEX(4, 0);
|
||||
case 3: return TEXTURE_INDEX(0, 1);
|
||||
tex_atlas_lookup(TEXAT_SANDSTONE_TOP) :
|
||||
((side == SIDE_BOTTOM) ?
|
||||
tex_atlas_lookup(TEXAT_SANDSTONE_BOTTOM) :
|
||||
tex_atlas_lookup(TEXAT_SANDSTONE_SIDE));
|
||||
case 2: return tex_atlas_lookup(TEXAT_PLANKS);
|
||||
case 3: return tex_atlas_lookup(TEXAT_COBBLESTONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ getSideMask2(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(2, 4);
|
||||
return tex_atlas_lookup(TEXAT_SNOW);
|
||||
}
|
||||
|
||||
struct block block_snow = {
|
||||
|
|
|
@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(1, 4);
|
||||
return tex_atlas_lookup(TEXAT_SPAWNER);
|
||||
}
|
||||
|
||||
struct block block_spawner = {
|
||||
|
|
|
@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(0, 3);
|
||||
return tex_atlas_lookup(TEXAT_SPONGE);
|
||||
}
|
||||
|
||||
struct block block_sponge = {
|
||||
|
|
|
@ -98,11 +98,11 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex1(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(4, 0);
|
||||
return tex_atlas_lookup(TEXAT_PLANKS);
|
||||
}
|
||||
|
||||
static uint8_t getTextureIndex2(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(0, 1);
|
||||
return tex_atlas_lookup(TEXAT_COBBLESTONE);
|
||||
}
|
||||
|
||||
struct block block_wooden_stairs = {
|
||||
|
|
|
@ -35,7 +35,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(1, 0);
|
||||
return tex_atlas_lookup(TEXAT_STONE);
|
||||
}
|
||||
|
||||
struct block block_stone = {
|
||||
|
|
|
@ -36,14 +36,14 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
|
||||
static uint8_t getTextureIndex1(struct block_info* this, enum side side) {
|
||||
switch(this->block->metadata) {
|
||||
case 1: return TEXTURE_INDEX(5, 12); // tallgrass
|
||||
case 2: return TEXTURE_INDEX(5, 13); // fern
|
||||
default: return TEXTURE_INDEX(6, 3); // deadbush
|
||||
case 1: return tex_atlas_lookup(TEXAT_TALLGRASS); // tallgrass
|
||||
case 2: return tex_atlas_lookup(TEXAT_FERN); // fern
|
||||
default: return tex_atlas_lookup(TEXAT_DEADBUSH); // deadbush
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t getTextureIndex2(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(6, 3); // deadbush
|
||||
return tex_atlas_lookup(TEXAT_DEADBUSH); // deadbush
|
||||
}
|
||||
|
||||
struct block block_tallgrass = {
|
||||
|
|
|
@ -36,9 +36,9 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
switch(side) {
|
||||
case SIDE_TOP: return TEXTURE_INDEX(9, 0);
|
||||
case SIDE_BOTTOM: return TEXTURE_INDEX(10, 0);
|
||||
default: return TEXTURE_INDEX(8, 0);
|
||||
case SIDE_TOP: return tex_atlas_lookup(TEXAT_TNT_TOP);
|
||||
case SIDE_BOTTOM: return tex_atlas_lookup(TEXAT_TNT_BOTTOM);
|
||||
default: return tex_atlas_lookup(TEXAT_TNT_SIDE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,15 +44,15 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex1(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(0, 5);
|
||||
return tex_atlas_lookup(TEXAT_TORCH);
|
||||
}
|
||||
|
||||
static uint8_t getTextureIndex2(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(3, 7);
|
||||
return tex_atlas_lookup(TEXAT_REDSTONE_TORCH);
|
||||
}
|
||||
|
||||
static uint8_t getTextureIndex3(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(3, 6);
|
||||
return tex_atlas_lookup(TEXAT_REDSTONE_TORCH_LIT);
|
||||
}
|
||||
|
||||
struct block block_torch = {
|
||||
|
|
|
@ -69,7 +69,7 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
return TEXTURE_INDEX(8, 3);
|
||||
return tex_atlas_lookup(TEXAT_TRAPDOOR);
|
||||
}
|
||||
|
||||
struct block block_trapdoor = {
|
||||
|
|
|
@ -35,16 +35,24 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
}
|
||||
|
||||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
if(this->block->metadata >= 9)
|
||||
return TEXTURE_INDEX(1, 13 + 9 - this->block->metadata);
|
||||
|
||||
if(this->block->metadata == 8)
|
||||
return TEXTURE_INDEX(3, 13);
|
||||
|
||||
if(this->block->metadata >= 1)
|
||||
return TEXTURE_INDEX(2, 13 + 1 - this->block->metadata);
|
||||
|
||||
return TEXTURE_INDEX(0, 4);
|
||||
switch(this->block->metadata) {
|
||||
case 0: return tex_atlas_lookup(TEXAT_WOOL_0);
|
||||
case 1: return tex_atlas_lookup(TEXAT_WOOL_1);
|
||||
case 2: return tex_atlas_lookup(TEXAT_WOOL_2);
|
||||
case 3: return tex_atlas_lookup(TEXAT_WOOL_3);
|
||||
case 4: return tex_atlas_lookup(TEXAT_WOOL_4);
|
||||
case 5: return tex_atlas_lookup(TEXAT_WOOL_5);
|
||||
case 6: return tex_atlas_lookup(TEXAT_WOOL_6);
|
||||
case 7: return tex_atlas_lookup(TEXAT_WOOL_7);
|
||||
case 8: return tex_atlas_lookup(TEXAT_WOOL_8);
|
||||
case 9: return tex_atlas_lookup(TEXAT_WOOL_9);
|
||||
case 10: return tex_atlas_lookup(TEXAT_WOOL_10);
|
||||
case 11: return tex_atlas_lookup(TEXAT_WOOL_11);
|
||||
case 12: return tex_atlas_lookup(TEXAT_WOOL_12);
|
||||
case 13: return tex_atlas_lookup(TEXAT_WOOL_13);
|
||||
case 14: return tex_atlas_lookup(TEXAT_WOOL_14);
|
||||
case 15: return tex_atlas_lookup(TEXAT_WOOL_15);
|
||||
}
|
||||
}
|
||||
|
||||
struct block block_wool = {
|
||||
|
|
|
@ -37,12 +37,12 @@ getSideMask(struct block_info* this, enum side side, struct block_info* it) {
|
|||
static uint8_t getTextureIndex(struct block_info* this, enum side side) {
|
||||
switch(side) {
|
||||
case SIDE_FRONT:
|
||||
case SIDE_LEFT: return TEXTURE_INDEX(12, 3);
|
||||
case SIDE_LEFT: return tex_atlas_lookup(TEXAT_WORKBENCH_SIDE_2);
|
||||
case SIDE_RIGHT:
|
||||
case SIDE_BACK: return TEXTURE_INDEX(11, 3);
|
||||
case SIDE_TOP: return TEXTURE_INDEX(11, 2);
|
||||
case SIDE_BACK: return tex_atlas_lookup(TEXAT_WORKBENCH_SIDE_1);
|
||||
case SIDE_TOP: return tex_atlas_lookup(TEXAT_WORKBENCH_TOP);
|
||||
default:
|
||||
case SIDE_BOTTOM: return TEXTURE_INDEX(4, 0);
|
||||
case SIDE_BOTTOM: return tex_atlas_lookup(TEXAT_PLANKS);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,13 +23,10 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../graphics/texture_atlas.h"
|
||||
#include "../item/items.h"
|
||||
#include "../platform/displaylist.h"
|
||||
|
||||
#define TEXTURE_INDEX(x, y) (((y)*14) + (x))
|
||||
#define TEXTURE_X(idx) ((idx) % 14)
|
||||
#define TEXTURE_Y(idx) ((idx) / 14)
|
||||
|
||||
enum block_material {
|
||||
MATERIAL_WOOD,
|
||||
MATERIAL_STONE,
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
#include "../platform/gfx.h"
|
||||
#include "gui_util.h"
|
||||
#include "render_block.h"
|
||||
#include "texture_atlas.h"
|
||||
|
||||
int gutil_control_icon(int x, enum gutil_control_icon icon, char* str) {
|
||||
gfx_bind_texture(TEXTURE_GUI);
|
||||
|
@ -69,9 +71,14 @@ void gutil_bg() {
|
|||
int cx = (gfx_width() + scale - 1) / scale;
|
||||
int cy = (gfx_height() + scale - 1) / scale;
|
||||
|
||||
uint8_t tex = tex_atlas_lookup(TEXAT_DIRT);
|
||||
|
||||
uint8_t s = TEX_OFFSET(TEXTURE_X(tex));
|
||||
uint8_t t = TEX_OFFSET(TEXTURE_Y(tex));
|
||||
|
||||
for(int y = 0; y < cy; y++) {
|
||||
for(int x = 0; x < cx; x++) {
|
||||
gutil_texquad_col(x * scale, y * scale, 39, 3, 16, 16, scale, scale,
|
||||
gutil_texquad_col(x * scale, y * scale, s, t, 16, 16, scale, scale,
|
||||
0x40, 0x40, 0x40, 0xFF);
|
||||
}
|
||||
}
|
||||
|
|
323
source/graphics/texture_atlas.c
Normal file
323
source/graphics/texture_atlas.c
Normal file
|
@ -0,0 +1,323 @@
|
|||
/*
|
||||
Copyright (c) 2023 ByteBit/xtreme8000
|
||||
|
||||
This file is part of CavEX.
|
||||
|
||||
CavEX is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CavEX is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CavEX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "../platform/texture.h"
|
||||
#include "texture_atlas.h"
|
||||
|
||||
static uint8_t global_atlas[TEXAT_MAX];
|
||||
|
||||
static int clamp_n(int x, int n) {
|
||||
if(x < 0)
|
||||
return 0;
|
||||
if(x > n - 1)
|
||||
return n - 1;
|
||||
return x;
|
||||
}
|
||||
|
||||
void tex_atlas_reg(dict_atlas_src_t atlas, enum tex_atlas_entry name, uint8_t x,
|
||||
uint8_t y) {
|
||||
dict_atlas_src_push_back(atlas,
|
||||
(struct texture_entry) {
|
||||
.name = name,
|
||||
.x = x,
|
||||
.y = y,
|
||||
.bg.enable = false,
|
||||
.colorize.enable = false,
|
||||
});
|
||||
}
|
||||
|
||||
void tex_atlas_reg_col(dict_atlas_src_t atlas, enum tex_atlas_entry name,
|
||||
uint8_t x, uint8_t y, uint8_t r, uint8_t g, uint8_t b) {
|
||||
dict_atlas_src_push_back(atlas,
|
||||
(struct texture_entry) {
|
||||
.name = name,
|
||||
.x = x,
|
||||
.y = y,
|
||||
.bg.enable = false,
|
||||
.colorize.enable = true,
|
||||
.colorize.r = r,
|
||||
.colorize.g = g,
|
||||
.colorize.b = b,
|
||||
});
|
||||
}
|
||||
|
||||
void tex_atlas_reg_grass(dict_atlas_src_t atlas, enum tex_atlas_entry name,
|
||||
uint8_t x, uint8_t y, uint8_t r, uint8_t g, uint8_t b,
|
||||
uint8_t bg_x, uint8_t bg_y) {
|
||||
dict_atlas_src_push_back(atlas,
|
||||
(struct texture_entry) {
|
||||
.name = name,
|
||||
.x = x,
|
||||
.y = y,
|
||||
.bg.enable = true,
|
||||
.bg.x = bg_x,
|
||||
.bg.y = bg_y,
|
||||
.colorize.enable = true,
|
||||
.colorize.r = r,
|
||||
.colorize.g = g,
|
||||
.colorize.b = b,
|
||||
});
|
||||
}
|
||||
|
||||
void* tex_atlas_compute(dict_atlas_src_t atlas, uint8_t* atlas_dst,
|
||||
uint8_t* image, size_t width, size_t height) {
|
||||
assert(image && width >= 256 && width == height);
|
||||
|
||||
int tile_size = width / 16;
|
||||
int border_scale = width / 256;
|
||||
|
||||
uint8_t* output = malloc(width * height * 4);
|
||||
|
||||
if(!output)
|
||||
return NULL;
|
||||
|
||||
memset(output, 255, width * height * 4);
|
||||
|
||||
dict_atlas_src_it_t it;
|
||||
dict_atlas_src_it(it, atlas);
|
||||
|
||||
int current = 0;
|
||||
|
||||
while(!dict_atlas_src_end_p(it)) {
|
||||
struct texture_entry* e = dict_atlas_src_ref(it);
|
||||
|
||||
size_t current_x = (current % 14) * (tile_size + 2 * border_scale)
|
||||
+ 3 * border_scale;
|
||||
size_t current_y = (current / 14) * (tile_size + 2 * border_scale)
|
||||
+ 3 * border_scale;
|
||||
|
||||
for(int y = -border_scale; y < tile_size + border_scale; y++) {
|
||||
for(int x = -border_scale; x < tile_size + border_scale; x++) {
|
||||
uint8_t* src_col = image
|
||||
+ ((clamp_n(x, tile_size) + e->x * tile_size)
|
||||
+ (clamp_n(y, tile_size) + e->y * tile_size) * width)
|
||||
* 4;
|
||||
uint8_t* dst_col
|
||||
= output + ((current_x + x) + (current_y + y) * width) * 4;
|
||||
|
||||
if(e->colorize.enable) {
|
||||
dst_col[0] = src_col[0] * e->colorize.r / 255;
|
||||
dst_col[1] = src_col[1] * e->colorize.g / 255;
|
||||
dst_col[2] = src_col[2] * e->colorize.b / 255;
|
||||
dst_col[3] = src_col[3];
|
||||
} else {
|
||||
for(size_t k = 0; k < 4; k++)
|
||||
dst_col[k] = src_col[k];
|
||||
}
|
||||
|
||||
if(e->bg.enable && dst_col[3] < 128) {
|
||||
uint8_t* src_col2 = image
|
||||
+ ((clamp_n(x, tile_size) + e->bg.x * tile_size)
|
||||
+ (clamp_n(y, tile_size) + e->bg.y * tile_size)
|
||||
* width)
|
||||
* 4;
|
||||
for(size_t k = 0; k < 4; k++)
|
||||
dst_col[k] = src_col2[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
atlas_dst[e->name] = TEXTURE_INDEX(current % 14, current / 14);
|
||||
|
||||
current++;
|
||||
dict_atlas_src_next(it);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
uint8_t tex_atlas_lookup(enum tex_atlas_entry name) {
|
||||
return global_atlas[name];
|
||||
}
|
||||
|
||||
void* tex_atlas_block(const char* filename, size_t* width, size_t* height) {
|
||||
dict_atlas_src_t atlas;
|
||||
dict_atlas_src_init(atlas);
|
||||
|
||||
tex_atlas_reg(atlas, TEXAT_STONE, 1, 0);
|
||||
tex_atlas_reg(atlas, TEXAT_DIRT, 2, 0);
|
||||
tex_atlas_reg(atlas, TEXAT_PLANKS, 4, 0);
|
||||
tex_atlas_reg(atlas, TEXAT_SLAB_STONE_SIDE, 5, 0);
|
||||
tex_atlas_reg(atlas, TEXAT_SLAB_STONE_TOP, 6, 0);
|
||||
tex_atlas_reg(atlas, TEXAT_BRICKS, 7, 0);
|
||||
tex_atlas_reg(atlas, TEXAT_TNT_SIDE, 8, 0);
|
||||
tex_atlas_reg(atlas, TEXAT_TNT_TOP, 9, 0);
|
||||
tex_atlas_reg(atlas, TEXAT_TNT_BOTTOM, 10, 0);
|
||||
tex_atlas_reg(atlas, TEXAT_COBWEB, 11, 0);
|
||||
tex_atlas_reg(atlas, TEXAT_ROSE, 12, 0);
|
||||
tex_atlas_reg(atlas, TEXAT_DANDELION, 13, 0);
|
||||
tex_atlas_reg(atlas, TEXAT_SAPLING_OAK, 15, 0);
|
||||
|
||||
tex_atlas_reg(atlas, TEXAT_COBBLESTONE, 0, 1);
|
||||
tex_atlas_reg(atlas, TEXAT_BEDROCK, 1, 1);
|
||||
tex_atlas_reg(atlas, TEXAT_SAND, 2, 1);
|
||||
tex_atlas_reg(atlas, TEXAT_GRAVEL, 3, 1);
|
||||
tex_atlas_reg(atlas, TEXAT_LOG_OAK_SIDE, 4, 1);
|
||||
tex_atlas_reg(atlas, TEXAT_LOG_OAK_TOP, 5, 1);
|
||||
tex_atlas_reg(atlas, TEXAT_CAST_BLOCK_IRON, 6, 1);
|
||||
tex_atlas_reg(atlas, TEXAT_CAST_BLOCK_GOLD, 7, 1);
|
||||
tex_atlas_reg(atlas, TEXAT_CAST_BLOCK_DIAMOND, 8, 1);
|
||||
tex_atlas_reg(atlas, TEXAT_CHEST_TOP, 9, 1);
|
||||
tex_atlas_reg(atlas, TEXAT_CHEST_SIDE, 10, 1);
|
||||
tex_atlas_reg(atlas, TEXAT_CHEST_FRONT_SINGLE, 11, 1);
|
||||
tex_atlas_reg(atlas, TEXAT_MUSHROOM_RED, 12, 1);
|
||||
tex_atlas_reg(atlas, TEXAT_MUSHROOM_BROWN, 13, 1);
|
||||
|
||||
tex_atlas_reg(atlas, TEXAT_ORE_GOLD, 0, 2);
|
||||
tex_atlas_reg(atlas, TEXAT_ORE_IRON, 1, 2);
|
||||
tex_atlas_reg(atlas, TEXAT_ORE_COAL, 2, 2);
|
||||
tex_atlas_reg(atlas, TEXAT_BOOKSHELF, 3, 2);
|
||||
tex_atlas_reg(atlas, TEXAT_COBBLESTONE_MOSSY, 4, 2);
|
||||
tex_atlas_reg(atlas, TEXAT_OBSIDIAN, 5, 2);
|
||||
tex_atlas_reg(atlas, TEXAT_CHEST_FRONT_1, 9, 2);
|
||||
tex_atlas_reg(atlas, TEXAT_CHEST_FRONT_2, 10, 2);
|
||||
tex_atlas_reg(atlas, TEXAT_WORKBENCH_TOP, 11, 2);
|
||||
tex_atlas_reg(atlas, TEXAT_FURNACE_FRONT, 12, 2);
|
||||
tex_atlas_reg(atlas, TEXAT_FURNACE_SIDE, 13, 2);
|
||||
tex_atlas_reg(atlas, TEXAT_DISPENSER_FRONT, 14, 2);
|
||||
|
||||
tex_atlas_reg(atlas, TEXAT_SPONGE, 0, 3);
|
||||
tex_atlas_reg(atlas, TEXAT_GLASS, 1, 3);
|
||||
tex_atlas_reg(atlas, TEXAT_ORE_DIAMOND, 2, 3);
|
||||
tex_atlas_reg(atlas, TEXAT_ORE_REDSTONE, 3, 3);
|
||||
tex_atlas_reg_col(atlas, TEXAT_LEAVES_BIRCH, 4, 3, 128, 167, 85);
|
||||
tex_atlas_reg(atlas, TEXAT_DEADBUSH, 7, 3);
|
||||
tex_atlas_reg(atlas, TEXAT_CHEST_BACK_1, 9, 3);
|
||||
tex_atlas_reg(atlas, TEXAT_CHEST_BACK_2, 10, 3);
|
||||
tex_atlas_reg(atlas, TEXAT_WORKBENCH_SIDE_1, 11, 3);
|
||||
tex_atlas_reg(atlas, TEXAT_WORKBENCH_SIDE_2, 12, 3);
|
||||
tex_atlas_reg(atlas, TEXAT_FURNACE_FRONT_LIT, 13, 3);
|
||||
tex_atlas_reg(atlas, TEXAT_FURNACE_TOP, 14, 3);
|
||||
tex_atlas_reg(atlas, TEXAT_SAPLING_SPRUCE, 15, 3);
|
||||
|
||||
tex_atlas_reg(atlas, TEXAT_SPAWNER, 1, 4);
|
||||
tex_atlas_reg(atlas, TEXAT_SNOW, 2, 4);
|
||||
tex_atlas_reg(atlas, TEXAT_GRASS_SIDE_SNOW, 4, 4);
|
||||
tex_atlas_reg(atlas, TEXAT_CACTUS_TOP, 5, 4);
|
||||
tex_atlas_reg(atlas, TEXAT_CACTUS_SIDE, 6, 4);
|
||||
tex_atlas_reg(atlas, TEXAT_CACTUS_BOTTOM, 7, 4);
|
||||
tex_atlas_reg(atlas, TEXAT_CLAY, 8, 4);
|
||||
tex_atlas_reg(atlas, TEXAT_REED, 9, 4);
|
||||
tex_atlas_reg(atlas, TEXAT_JUKBEBOX_SIDE, 10, 4);
|
||||
tex_atlas_reg(atlas, TEXAT_JUKBEBOX_TOP, 11, 4);
|
||||
tex_atlas_reg(atlas, TEXAT_SAPLING_BIRCH, 15, 4);
|
||||
|
||||
tex_atlas_reg(atlas, TEXAT_TORCH, 0, 5);
|
||||
tex_atlas_reg(atlas, TEXAT_DOOR_WOOD_TOP, 1, 5);
|
||||
tex_atlas_reg(atlas, TEXAT_DOOR_IRON_TOP, 2, 5);
|
||||
tex_atlas_reg(atlas, TEXAT_LADDER, 3, 5);
|
||||
tex_atlas_reg(atlas, TEXAT_TRAPDOOR, 4, 5);
|
||||
tex_atlas_reg(atlas, TEXAT_FARMLAND_WET, 6, 5);
|
||||
tex_atlas_reg(atlas, TEXAT_FARMLAND_DRY, 7, 5);
|
||||
tex_atlas_reg(atlas, TEXAT_CROPS_0, 8, 5);
|
||||
tex_atlas_reg(atlas, TEXAT_CROPS_1, 9, 5);
|
||||
tex_atlas_reg(atlas, TEXAT_CROPS_2, 10, 5);
|
||||
tex_atlas_reg(atlas, TEXAT_CROPS_3, 11, 5);
|
||||
tex_atlas_reg(atlas, TEXAT_CROPS_4, 12, 5);
|
||||
tex_atlas_reg(atlas, TEXAT_CROPS_5, 13, 5);
|
||||
tex_atlas_reg(atlas, TEXAT_CROPS_6, 14, 5);
|
||||
tex_atlas_reg(atlas, TEXAT_CROPS_7, 15, 5);
|
||||
|
||||
// tex_atlas_reg(atlas, "lever", 0, 6);
|
||||
tex_atlas_reg(atlas, TEXAT_DOOR_WOOD_BOTTOM, 1, 6);
|
||||
tex_atlas_reg(atlas, TEXAT_DOOR_IRON_BOTTOM, 2, 6);
|
||||
tex_atlas_reg(atlas, TEXAT_REDSTONE_TORCH_LIT, 3, 6);
|
||||
tex_atlas_reg(atlas, TEXAT_PUMPKIN_TOP, 6, 6);
|
||||
tex_atlas_reg(atlas, TEXAT_NETHERRACK, 7, 6);
|
||||
tex_atlas_reg(atlas, TEXAT_SOULSAND, 8, 6);
|
||||
tex_atlas_reg(atlas, TEXAT_GLOWSTONE, 9, 6);
|
||||
/*tex_atlas_reg(atlas, "piston_front_sticky", 10, 6);
|
||||
tex_atlas_reg(atlas, "piston_front", 11, 6);
|
||||
tex_atlas_reg(atlas, "piston_side", 12, 6);
|
||||
tex_atlas_reg(atlas, "piston_back", 13, 6);
|
||||
tex_atlas_reg(atlas, "piston_inner", 14, 6);*/
|
||||
|
||||
tex_atlas_reg(atlas, TEXAT_RAIL_CURVED, 0, 7);
|
||||
tex_atlas_reg(atlas, TEXAT_REDSTONE_TORCH, 3, 7);
|
||||
tex_atlas_reg(atlas, TEXAT_LOG_SPRUCE_SIDE, 4, 7);
|
||||
tex_atlas_reg(atlas, TEXAT_LOG_BIRCH_SIDE, 5, 7);
|
||||
tex_atlas_reg(atlas, TEXAT_PUMPKIN_SIDE, 6, 7);
|
||||
tex_atlas_reg(atlas, TEXAT_PUMPKIN_FRONT, 7, 7);
|
||||
tex_atlas_reg(atlas, TEXAT_PUMPKIN_FRONT_LIT, 8, 7);
|
||||
tex_atlas_reg(atlas, TEXAT_CAKE_TOP, 9, 7);
|
||||
tex_atlas_reg(atlas, TEXAT_CAKE_SIDE, 10, 7);
|
||||
tex_atlas_reg(atlas, TEXAT_CAKE_SIDE_CUT, 11, 7);
|
||||
tex_atlas_reg(atlas, TEXAT_CAKE_BOTTOM, 12, 7);
|
||||
|
||||
tex_atlas_reg(atlas, TEXAT_RAIL, 0, 8);
|
||||
// tex_atlas_reg(atlas, "repeater_off", 3, 8);
|
||||
tex_atlas_reg_col(atlas, TEXAT_LEAVES_SPRUCE, 4, 8, 97, 153, 97);
|
||||
tex_atlas_reg(atlas, TEXAT_BED_TOP_1, 6, 8);
|
||||
tex_atlas_reg(atlas, TEXAT_BED_TOP_2, 7, 8);
|
||||
|
||||
tex_atlas_reg(atlas, TEXAT_CAST_BLOCK_LAPIS, 0, 9);
|
||||
// tex_atlas_reg(atlas, "repeater_on", 3, 9);
|
||||
tex_atlas_reg(atlas, TEXAT_BED_BACK, 5, 9);
|
||||
tex_atlas_reg(atlas, TEXAT_BED_SIDE_1, 6, 9);
|
||||
tex_atlas_reg(atlas, TEXAT_BED_SIDE_2, 7, 9);
|
||||
tex_atlas_reg(atlas, TEXAT_BED_FRONT, 8, 9);
|
||||
|
||||
tex_atlas_reg(atlas, TEXAT_ORE_LAPIS, 0, 10);
|
||||
tex_atlas_reg(atlas, TEXAT_RAIL_POWERED_OFF, 3, 10);
|
||||
/*tex_atlas_reg_col(atlas, "redstone_intersect", 4, 10, 252, 49, 0);
|
||||
tex_atlas_reg_col(atlas, "redstone_wire", 5, 10, 252, 49, 0);*/
|
||||
|
||||
tex_atlas_reg(atlas, TEXAT_SANDSTONE_TOP, 0, 11);
|
||||
tex_atlas_reg(atlas, TEXAT_RAIL_POWERED_ON, 3, 11);
|
||||
|
||||
tex_atlas_reg(atlas, TEXAT_SANDSTONE_SIDE, 0, 12);
|
||||
tex_atlas_reg(atlas, TEXAT_RAIL_DETECTOR, 3, 12);
|
||||
|
||||
tex_atlas_reg(atlas, TEXAT_SANDSTONE_BOTTOM, 0, 13);
|
||||
|
||||
tex_atlas_reg(atlas, TEXAT_WOOL_0, 0, 4);
|
||||
tex_atlas_reg(atlas, TEXAT_WOOL_1, 2, 13);
|
||||
tex_atlas_reg(atlas, TEXAT_WOOL_2, 2, 12);
|
||||
tex_atlas_reg(atlas, TEXAT_WOOL_3, 2, 11);
|
||||
tex_atlas_reg(atlas, TEXAT_WOOL_4, 2, 10);
|
||||
tex_atlas_reg(atlas, TEXAT_WOOL_5, 2, 9);
|
||||
tex_atlas_reg(atlas, TEXAT_WOOL_6, 2, 8);
|
||||
tex_atlas_reg(atlas, TEXAT_WOOL_7, 2, 7);
|
||||
tex_atlas_reg(atlas, TEXAT_WOOL_8, 1, 14);
|
||||
tex_atlas_reg(atlas, TEXAT_WOOL_9, 1, 13);
|
||||
tex_atlas_reg(atlas, TEXAT_WOOL_10, 1, 12);
|
||||
tex_atlas_reg(atlas, TEXAT_WOOL_11, 1, 11);
|
||||
tex_atlas_reg(atlas, TEXAT_WOOL_12, 1, 10);
|
||||
tex_atlas_reg(atlas, TEXAT_WOOL_13, 1, 9);
|
||||
tex_atlas_reg(atlas, TEXAT_WOOL_14, 1, 8);
|
||||
tex_atlas_reg(atlas, TEXAT_WOOL_15, 1, 7);
|
||||
|
||||
tex_atlas_reg_col(atlas, TEXAT_GRASS_TOP, 0, 0, 110, 198, 63);
|
||||
tex_atlas_reg_grass(atlas, TEXAT_GRASS_SIDE, 6, 2, 110, 198, 63, 3, 0);
|
||||
tex_atlas_reg_col(atlas, TEXAT_TALLGRASS, 7, 2, 110, 198, 63);
|
||||
tex_atlas_reg_col(atlas, TEXAT_LEAVES_OAK, 4, 3, 75, 182, 15);
|
||||
tex_atlas_reg_col(atlas, TEXAT_FERN, 8, 3, 110, 198, 63);
|
||||
|
||||
memset(global_atlas, 0, sizeof(global_atlas));
|
||||
|
||||
uint8_t* image = tex_read(filename, width, height);
|
||||
void* output
|
||||
= tex_atlas_compute(atlas, global_atlas, image, *width, *height);
|
||||
dict_atlas_src_clear(atlas);
|
||||
free(image);
|
||||
|
||||
return output;
|
||||
}
|
197
source/graphics/texture_atlas.h
Normal file
197
source/graphics/texture_atlas.h
Normal file
|
@ -0,0 +1,197 @@
|
|||
/*
|
||||
Copyright (c) 2023 ByteBit/xtreme8000
|
||||
|
||||
This file is part of CavEX.
|
||||
|
||||
CavEX is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CavEX is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CavEX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TEXTURE_ATLAS_H
|
||||
#define TEXTURE_ATLAS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <m-lib/m-array.h>
|
||||
|
||||
enum tex_atlas_entry {
|
||||
TEXAT_STONE,
|
||||
TEXAT_DIRT,
|
||||
TEXAT_PLANKS,
|
||||
TEXAT_SLAB_STONE_SIDE,
|
||||
TEXAT_SLAB_STONE_TOP,
|
||||
TEXAT_BRICKS,
|
||||
TEXAT_TNT_SIDE,
|
||||
TEXAT_TNT_TOP,
|
||||
TEXAT_TNT_BOTTOM,
|
||||
TEXAT_COBWEB,
|
||||
TEXAT_ROSE,
|
||||
TEXAT_DANDELION,
|
||||
TEXAT_SAPLING_OAK,
|
||||
TEXAT_COBBLESTONE,
|
||||
TEXAT_BEDROCK,
|
||||
TEXAT_SAND,
|
||||
TEXAT_GRAVEL,
|
||||
TEXAT_LOG_OAK_SIDE,
|
||||
TEXAT_LOG_OAK_TOP,
|
||||
TEXAT_CAST_BLOCK_IRON,
|
||||
TEXAT_CAST_BLOCK_GOLD,
|
||||
TEXAT_CAST_BLOCK_DIAMOND,
|
||||
TEXAT_CHEST_TOP,
|
||||
TEXAT_CHEST_SIDE,
|
||||
TEXAT_CHEST_FRONT_SINGLE,
|
||||
TEXAT_MUSHROOM_RED,
|
||||
TEXAT_MUSHROOM_BROWN,
|
||||
TEXAT_ORE_GOLD,
|
||||
TEXAT_ORE_IRON,
|
||||
TEXAT_ORE_COAL,
|
||||
TEXAT_BOOKSHELF,
|
||||
TEXAT_COBBLESTONE_MOSSY,
|
||||
TEXAT_OBSIDIAN,
|
||||
TEXAT_CHEST_FRONT_1,
|
||||
TEXAT_CHEST_FRONT_2,
|
||||
TEXAT_WORKBENCH_TOP,
|
||||
TEXAT_FURNACE_FRONT,
|
||||
TEXAT_FURNACE_SIDE,
|
||||
TEXAT_DISPENSER_FRONT,
|
||||
TEXAT_SPONGE,
|
||||
TEXAT_GLASS,
|
||||
TEXAT_ORE_DIAMOND,
|
||||
TEXAT_ORE_REDSTONE,
|
||||
TEXAT_LEAVES_BIRCH,
|
||||
TEXAT_DEADBUSH,
|
||||
TEXAT_CHEST_BACK_1,
|
||||
TEXAT_CHEST_BACK_2,
|
||||
TEXAT_WORKBENCH_SIDE_1,
|
||||
TEXAT_WORKBENCH_SIDE_2,
|
||||
TEXAT_FURNACE_FRONT_LIT,
|
||||
TEXAT_FURNACE_TOP,
|
||||
TEXAT_SAPLING_SPRUCE,
|
||||
TEXAT_SPAWNER,
|
||||
TEXAT_SNOW,
|
||||
TEXAT_GRASS_SIDE_SNOW,
|
||||
TEXAT_CACTUS_TOP,
|
||||
TEXAT_CACTUS_SIDE,
|
||||
TEXAT_CACTUS_BOTTOM,
|
||||
TEXAT_CLAY,
|
||||
TEXAT_REED,
|
||||
TEXAT_JUKBEBOX_SIDE,
|
||||
TEXAT_JUKBEBOX_TOP,
|
||||
TEXAT_SAPLING_BIRCH,
|
||||
TEXAT_TORCH,
|
||||
TEXAT_DOOR_WOOD_TOP,
|
||||
TEXAT_DOOR_IRON_TOP,
|
||||
TEXAT_LADDER,
|
||||
TEXAT_TRAPDOOR,
|
||||
TEXAT_FARMLAND_WET,
|
||||
TEXAT_FARMLAND_DRY,
|
||||
TEXAT_CROPS_0,
|
||||
TEXAT_CROPS_1,
|
||||
TEXAT_CROPS_2,
|
||||
TEXAT_CROPS_3,
|
||||
TEXAT_CROPS_4,
|
||||
TEXAT_CROPS_5,
|
||||
TEXAT_CROPS_6,
|
||||
TEXAT_CROPS_7,
|
||||
TEXAT_DOOR_WOOD_BOTTOM,
|
||||
TEXAT_DOOR_IRON_BOTTOM,
|
||||
TEXAT_REDSTONE_TORCH_LIT,
|
||||
TEXAT_PUMPKIN_TOP,
|
||||
TEXAT_NETHERRACK,
|
||||
TEXAT_SOULSAND,
|
||||
TEXAT_GLOWSTONE,
|
||||
TEXAT_RAIL_CURVED,
|
||||
TEXAT_REDSTONE_TORCH,
|
||||
TEXAT_LOG_SPRUCE_SIDE,
|
||||
TEXAT_LOG_BIRCH_SIDE,
|
||||
TEXAT_PUMPKIN_SIDE,
|
||||
TEXAT_PUMPKIN_FRONT,
|
||||
TEXAT_PUMPKIN_FRONT_LIT,
|
||||
TEXAT_CAKE_TOP,
|
||||
TEXAT_CAKE_SIDE,
|
||||
TEXAT_CAKE_SIDE_CUT,
|
||||
TEXAT_CAKE_BOTTOM,
|
||||
TEXAT_RAIL,
|
||||
TEXAT_LEAVES_SPRUCE,
|
||||
TEXAT_BED_TOP_1,
|
||||
TEXAT_BED_TOP_2,
|
||||
TEXAT_CAST_BLOCK_LAPIS,
|
||||
TEXAT_BED_BACK,
|
||||
TEXAT_BED_SIDE_1,
|
||||
TEXAT_BED_SIDE_2,
|
||||
TEXAT_BED_FRONT,
|
||||
TEXAT_ORE_LAPIS,
|
||||
TEXAT_RAIL_POWERED_OFF,
|
||||
TEXAT_SANDSTONE_TOP,
|
||||
TEXAT_RAIL_POWERED_ON,
|
||||
TEXAT_SANDSTONE_SIDE,
|
||||
TEXAT_RAIL_DETECTOR,
|
||||
TEXAT_SANDSTONE_BOTTOM,
|
||||
TEXAT_WOOL_0,
|
||||
TEXAT_WOOL_1,
|
||||
TEXAT_WOOL_2,
|
||||
TEXAT_WOOL_3,
|
||||
TEXAT_WOOL_4,
|
||||
TEXAT_WOOL_5,
|
||||
TEXAT_WOOL_6,
|
||||
TEXAT_WOOL_7,
|
||||
TEXAT_WOOL_8,
|
||||
TEXAT_WOOL_9,
|
||||
TEXAT_WOOL_10,
|
||||
TEXAT_WOOL_11,
|
||||
TEXAT_WOOL_12,
|
||||
TEXAT_WOOL_13,
|
||||
TEXAT_WOOL_14,
|
||||
TEXAT_WOOL_15,
|
||||
TEXAT_GRASS_TOP,
|
||||
TEXAT_GRASS_SIDE,
|
||||
TEXAT_TALLGRASS,
|
||||
TEXAT_LEAVES_OAK,
|
||||
TEXAT_FERN,
|
||||
|
||||
TEXAT_MAX,
|
||||
};
|
||||
|
||||
struct texture_entry {
|
||||
enum tex_atlas_entry name;
|
||||
uint8_t x : 4, y : 4;
|
||||
struct {
|
||||
bool enable;
|
||||
uint8_t r, g, b;
|
||||
} colorize;
|
||||
struct {
|
||||
bool enable;
|
||||
uint8_t x : 4, y : 4;
|
||||
} bg;
|
||||
};
|
||||
|
||||
ARRAY_DEF(dict_atlas_src, struct texture_entry, M_POD_OPLIST)
|
||||
|
||||
#define TEXTURE_INDEX(x, y) (((y)*14) + (x))
|
||||
#define TEXTURE_X(idx) ((idx) % 14)
|
||||
#define TEXTURE_Y(idx) ((idx) / 14)
|
||||
|
||||
void tex_atlas_reg(dict_atlas_src_t atlas, enum tex_atlas_entry name, uint8_t x,
|
||||
uint8_t y);
|
||||
void tex_atlas_reg_col(dict_atlas_src_t atlas, enum tex_atlas_entry name,
|
||||
uint8_t x, uint8_t y, uint8_t r, uint8_t g, uint8_t b);
|
||||
void tex_atlas_reg_grass(dict_atlas_src_t atlas, enum tex_atlas_entry name,
|
||||
uint8_t x, uint8_t y, uint8_t r, uint8_t g, uint8_t b,
|
||||
uint8_t bg_x, uint8_t bg_y);
|
||||
void* tex_atlas_compute(dict_atlas_src_t atlas, uint8_t* atlas_dst,
|
||||
uint8_t* image, size_t width, size_t height);
|
||||
|
||||
uint8_t tex_atlas_lookup(enum tex_atlas_entry name);
|
||||
void* tex_atlas_block(const char* filename, size_t* width, size_t* height);
|
||||
|
||||
#endif
|
|
@ -25,61 +25,45 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "../../game/game_state.h"
|
||||
#include "../../graphics/texture_atlas.h"
|
||||
#include "../../lodepng/lodepng.h"
|
||||
#include "../../util.h"
|
||||
#include "../gfx.h"
|
||||
#include "../input.h"
|
||||
#include "../texture.h"
|
||||
|
||||
static GLuint textures[8];
|
||||
|
||||
static GLuint load_tex(const char* filename, bool nearest) {
|
||||
unsigned width, height;
|
||||
unsigned char* img;
|
||||
if(lodepng_decode32_file(&img, &width, &height, filename))
|
||||
printf("error loading texture %s\n", filename);
|
||||
|
||||
GLuint tex;
|
||||
glGenTextures(1, &tex);
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
|
||||
GL_UNSIGNED_BYTE, img);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
||||
nearest ? GL_NEAREST : GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
||||
nearest ? GL_NEAREST : GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
free(img);
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
static void gfx_load_textures() {
|
||||
textures[0] = load_tex("terrain.png", true);
|
||||
textures[1] = load_tex("default.png", true);
|
||||
textures[2] = load_tex("anim.png", true);
|
||||
textures[3] = load_tex("gui.png", true);
|
||||
textures[4] = load_tex("gui_2.png", true);
|
||||
textures[5] = load_tex("items.png", true);
|
||||
glGenTextures(6, textures);
|
||||
|
||||
size_t w, h;
|
||||
void* output = tex_atlas_block("assets/terrain.png", &w, &h);
|
||||
if(output) {
|
||||
tex_gfx_load(output, w, h, TEX_FMT_RGBA16, textures[0], false);
|
||||
free(output);
|
||||
}
|
||||
|
||||
tex_gfx_load_file("assets/default.png", TEX_FMT_I8, textures[1], false);
|
||||
tex_gfx_load_file("assets/anim.png", TEX_FMT_RGBA32, textures[2], false);
|
||||
tex_gfx_load_file("assets/gui.png", TEX_FMT_IA4, textures[3], false);
|
||||
tex_gfx_load_file("assets/gui_2.png", TEX_FMT_RGBA16, textures[4], false);
|
||||
tex_gfx_load_file("assets/items.png", TEX_FMT_RGBA16, textures[5], false);
|
||||
}
|
||||
|
||||
static void testtest(GLuint shader) {
|
||||
GLint isCompiled = 0;
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled);
|
||||
if(isCompiled == GL_FALSE) {
|
||||
GLint maxLength = 0;
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength);
|
||||
static void shader_error(GLuint shader) {
|
||||
GLint is_compiled = 0;
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &is_compiled);
|
||||
|
||||
// The maxLength includes the NULL character
|
||||
char log[maxLength];
|
||||
glGetShaderInfoLog(shader, maxLength, &maxLength, log);
|
||||
if(!is_compiled) {
|
||||
GLint length = 0;
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
|
||||
|
||||
char log[length];
|
||||
glGetShaderInfoLog(shader, length, &length, log);
|
||||
printf("%s\n", log);
|
||||
|
||||
// Provide the infolog in whatever manor you deem best.
|
||||
// Exit with failure.
|
||||
glDeleteShader(shader); // Don't leak the shader.
|
||||
glDeleteShader(shader);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,12 +71,12 @@ static GLuint create_shader(const char* vertex, const char* fragment) {
|
|||
GLuint v = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(v, 1, (const GLchar* const*)&vertex, NULL);
|
||||
glCompileShader(v);
|
||||
testtest(v);
|
||||
shader_error(v);
|
||||
|
||||
GLuint f = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(f, 1, (const GLchar* const*)&fragment, NULL);
|
||||
glCompileShader(f);
|
||||
testtest(f);
|
||||
shader_error(f);
|
||||
|
||||
GLuint program = glCreateProgram();
|
||||
glAttachShader(program, v);
|
||||
|
@ -208,9 +192,9 @@ void gfx_setup() {
|
|||
printf("Renderer: %s\n", glGetString(GL_RENDERER));
|
||||
printf("Version: %s\n", glGetString(GL_VERSION));
|
||||
|
||||
void* vertex = file_read("vertex.shader");
|
||||
void* vertex = file_read("assets/vertex.shader");
|
||||
assert(vertex);
|
||||
void* fragment = file_read("fragment.shader");
|
||||
void* fragment = file_read("assets/fragment.shader");
|
||||
assert(fragment);
|
||||
|
||||
shader_prog = create_shader(vertex, fragment);
|
||||
|
|
36
source/platform/pc/texture.c
Normal file
36
source/platform/pc/texture.c
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
Copyright (c) 2023 ByteBit/xtreme8000
|
||||
|
||||
This file is part of CavEX.
|
||||
|
||||
CavEX is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CavEX is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CavEX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
void tex_gfx_load(void* img, size_t width, size_t height, enum tex_format type,
|
||||
int slot, bool linear) {
|
||||
assert(img && width > 0 && height > 0);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, slot);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
|
||||
GL_UNSIGNED_BYTE, img);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
||||
linear ? GL_LINEAR : GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
||||
linear ? GL_LINEAR : GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
61
source/platform/texture.c
Normal file
61
source/platform/texture.c
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
Copyright (c) 2023 ByteBit/xtreme8000
|
||||
|
||||
This file is part of CavEX.
|
||||
|
||||
CavEX is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CavEX is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CavEX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "../lodepng/lodepng.h"
|
||||
#include "texture.h"
|
||||
|
||||
uint8_t* tex_read(const char* filename, size_t* width, size_t* height) {
|
||||
assert(filename && width && height);
|
||||
|
||||
uint8_t* img;
|
||||
unsigned w, h;
|
||||
if(lodepng_decode32_file(&img, &w, &h, filename))
|
||||
return NULL;
|
||||
|
||||
*width = w;
|
||||
*height = h;
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
void tex_gfx_load_file(const char* filename, enum tex_format type, int slot,
|
||||
bool linear) {
|
||||
assert(filename);
|
||||
|
||||
size_t width, height;
|
||||
void* img = tex_read(filename, &width, &height);
|
||||
|
||||
if(!img)
|
||||
return;
|
||||
|
||||
tex_gfx_load(img, width, height, type, slot, linear);
|
||||
|
||||
free(img);
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_WII
|
||||
#include "wii/texture.c"
|
||||
#endif
|
||||
|
||||
#ifdef PLATFORM_PC
|
||||
#include "pc/texture.c"
|
||||
#endif
|
41
source/platform/texture.h
Normal file
41
source/platform/texture.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
Copyright (c) 2023 ByteBit/xtreme8000
|
||||
|
||||
This file is part of CavEX.
|
||||
|
||||
CavEX is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CavEX is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CavEX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TEXTURE_H
|
||||
#define TEXTURE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
enum tex_format {
|
||||
TEX_FMT_RGBA16,
|
||||
TEX_FMT_RGBA32,
|
||||
TEX_FMT_I8,
|
||||
TEX_FMT_IA4,
|
||||
};
|
||||
|
||||
uint8_t* tex_read(const char* filename, size_t* width, size_t* height);
|
||||
|
||||
void tex_gfx_load(void* img, size_t width, size_t height, enum tex_format type,
|
||||
int slot, bool linear);
|
||||
void tex_gfx_load_file(const char* filename, enum tex_format type, int slot,
|
||||
bool linear);
|
||||
|
||||
#endif
|
|
@ -24,11 +24,10 @@
|
|||
#include <ogc/tpl.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../../graphics/texture_atlas.h"
|
||||
#include "../../util.h"
|
||||
#include "../gfx.h"
|
||||
|
||||
#include "textures.h"
|
||||
#include "textures_tpl.h"
|
||||
#include "../texture.h"
|
||||
|
||||
#define FIFO_SIZE (256 * 1024)
|
||||
|
||||
|
@ -82,47 +81,44 @@ static void copy_buffers(u32 cnt) {
|
|||
}
|
||||
}
|
||||
|
||||
#define distance_2d(x1, y1, x2, y2) \
|
||||
(((x1) - (x2)) * ((x1) - (x2)) + ((y1) - (y2)) * ((y1) - (y2)))
|
||||
|
||||
static void texture_fog(uint8_t* img, size_t size) {
|
||||
for(size_t y = 0; y < size; y++) {
|
||||
for(size_t x = 0; x < size; x++) {
|
||||
float d = (sqrt(distance_2d(size / 2.0F, size / 2.0F, x + 0.5F,
|
||||
y + 0.5F))
|
||||
- (size / 2.0F - 9.0F))
|
||||
/ 8.0F;
|
||||
|
||||
uint8_t* pixel = img + (x + y * size) * 4;
|
||||
pixel[0] = pixel[1] = pixel[2]
|
||||
= roundf(glm_clamp(d * 255.0F, 0.0F, 255.0F));
|
||||
pixel[3] = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_load_textures() {
|
||||
GXTexObj terrain, font, anim, gui, gui2, items, fog;
|
||||
TPLFile spriteTPL;
|
||||
TPL_OpenTPLFromMemory(&spriteTPL, (void*)textures_tpl, textures_tpl_size);
|
||||
TPL_GetTexture(&spriteTPL, texture_terrain, &terrain);
|
||||
GX_InitTexObjFilterMode(&terrain, GX_NEAR, GX_NEAR);
|
||||
GX_InitTexObjMaxAniso(&terrain, GX_ANISO_1);
|
||||
GX_LoadTexObj(&terrain, GX_TEXMAP0);
|
||||
size_t w, h;
|
||||
void* output = tex_atlas_block("assets/terrain.png", &w, &h);
|
||||
if(output) {
|
||||
tex_gfx_load(output, w, h, TEX_FMT_RGBA16, GX_TEXMAP0, false);
|
||||
free(output);
|
||||
}
|
||||
|
||||
TPL_GetTexture(&spriteTPL, texture_font, &font);
|
||||
GX_InitTexObjFilterMode(&font, GX_NEAR, GX_NEAR);
|
||||
GX_InitTexObjMaxAniso(&font, GX_ANISO_1);
|
||||
GX_LoadTexObj(&font, GX_TEXMAP1);
|
||||
tex_gfx_load_file("assets/default.png", TEX_FMT_I8, GX_TEXMAP1, false);
|
||||
tex_gfx_load_file("assets/anim.png", TEX_FMT_RGBA32, GX_TEXMAP2, false);
|
||||
tex_gfx_load_file("assets/gui.png", TEX_FMT_IA4, GX_TEXMAP3, false);
|
||||
tex_gfx_load_file("assets/gui_2.png", TEX_FMT_RGBA16, GX_TEXMAP4, false);
|
||||
tex_gfx_load_file("assets/items.png", TEX_FMT_RGBA16, GX_TEXMAP5, false);
|
||||
|
||||
TPL_GetTexture(&spriteTPL, texture_anim, &anim);
|
||||
GX_InitTexObjFilterMode(&anim, GX_NEAR, GX_NEAR);
|
||||
GX_InitTexObjMaxAniso(&anim, GX_ANISO_1);
|
||||
GX_LoadTexObj(&anim, GX_TEXMAP2);
|
||||
|
||||
TPL_GetTexture(&spriteTPL, texture_gui, &gui);
|
||||
GX_InitTexObjFilterMode(&gui, GX_NEAR, GX_NEAR);
|
||||
GX_InitTexObjMaxAniso(&gui, GX_ANISO_1);
|
||||
GX_LoadTexObj(&gui, GX_TEXMAP3);
|
||||
|
||||
TPL_GetTexture(&spriteTPL, texture_gui2, &gui2);
|
||||
GX_InitTexObjFilterMode(&gui2, GX_NEAR, GX_NEAR);
|
||||
GX_InitTexObjMaxAniso(&gui2, GX_ANISO_1);
|
||||
GX_LoadTexObj(&gui2, GX_TEXMAP4);
|
||||
|
||||
TPL_GetTexture(&spriteTPL, texture_items, &items);
|
||||
GX_InitTexObjFilterMode(&items, GX_NEAR, GX_NEAR);
|
||||
GX_InitTexObjMaxAniso(&items, GX_ANISO_1);
|
||||
GX_LoadTexObj(&items, GX_TEXMAP5);
|
||||
|
||||
TPL_GetTexture(&spriteTPL, texture_fog, &fog);
|
||||
GX_InitTexObjFilterMode(&fog, GX_LINEAR, GX_LINEAR);
|
||||
GX_InitTexObjMaxAniso(&fog, GX_ANISO_1);
|
||||
GX_InitTexObjWrapMode(&fog, GX_CLAMP, GX_CLAMP);
|
||||
GX_LoadTexObj(&fog, GX_TEXMAP7);
|
||||
|
||||
TPL_CloseTPLFile(&spriteTPL);
|
||||
size_t fog_size = 128;
|
||||
uint8_t* fog = malloc(fog_size * fog_size * 4);
|
||||
texture_fog(fog, fog_size);
|
||||
tex_gfx_load(fog, fog_size, fog_size, TEX_FMT_I8, GX_TEXMAP6, true);
|
||||
free(fog);
|
||||
}
|
||||
|
||||
int gfx_width() {
|
||||
|
@ -389,7 +385,7 @@ void gfx_fog(bool enable) {
|
|||
|
||||
if(enable) {
|
||||
GX_SetTevOp(GX_TEVSTAGE1, GX_DECAL);
|
||||
GX_SetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD1, GX_TEXMAP7, GX_COLOR0A0);
|
||||
GX_SetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD1, GX_TEXMAP6, GX_COLOR0A0);
|
||||
GX_SetTevColorIn(GX_TEVSTAGE1, GX_CC_CPREV, GX_CC_C0, GX_CC_TEXA,
|
||||
GX_CC_ZERO);
|
||||
}
|
||||
|
|
187
source/platform/wii/texture.c
Normal file
187
source/platform/wii/texture.c
Normal file
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
Copyright (c) 2023 ByteBit/xtreme8000
|
||||
|
||||
This file is part of CavEX.
|
||||
|
||||
CavEX is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CavEX is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CavEX. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <gccore.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#define rgba16(r, g, b, a) \
|
||||
(((int)(a) << 12) | ((int)(r) << 8) | ((int)(g) << 4) | (int)(b))
|
||||
#define rgb16(r, g, b) (0x8000 | ((int)(r) << 10) | ((int)(g) << 5) | (int)(b))
|
||||
#define xy16(x, y) (((int)(x) << 8) | (int)(y))
|
||||
#define ia8(i, a) (((int)(a) << 4) | (int)(i))
|
||||
|
||||
static void* tex_conv_rgb32(uint8_t* image, size_t width, size_t height) {
|
||||
assert(image && (width % 4) == 0 && (height % 4) == 0);
|
||||
uint16_t* output = memalign(32, width * height * sizeof(uint16_t) * 2);
|
||||
|
||||
if(!output)
|
||||
return NULL;
|
||||
|
||||
size_t output_idx = 0;
|
||||
|
||||
for(size_t y = 0; y < height; y += 4) {
|
||||
for(size_t x = 0; x < width; x += 4) {
|
||||
for(size_t by = 0; by < 4; by++) {
|
||||
for(size_t bx = 0; bx < 4; bx++) {
|
||||
uint8_t* col = image + (x + bx + (y + by) * width) * 4;
|
||||
output[output_idx++] = xy16(col[3], col[0]);
|
||||
}
|
||||
}
|
||||
|
||||
for(size_t by = 0; by < 4; by++) {
|
||||
for(size_t bx = 0; bx < 4; bx++) {
|
||||
uint8_t* col = image + (x + bx + (y + by) * width) * 4;
|
||||
output[output_idx++] = xy16(col[1], col[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DCFlushRange(output, width * height * sizeof(uint16_t) * 2);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
static void* tex_conv_rgb16(uint8_t* image, size_t width, size_t height) {
|
||||
assert(image && (width % 4) == 0 && (height % 4) == 0);
|
||||
uint16_t* output = memalign(32, width * height * sizeof(uint16_t));
|
||||
|
||||
if(!output)
|
||||
return NULL;
|
||||
|
||||
size_t output_idx = 0;
|
||||
|
||||
for(size_t y = 0; y < height; y += 4) {
|
||||
for(size_t x = 0; x < width; x += 4) {
|
||||
for(size_t by = 0; by < 4; by++) {
|
||||
for(size_t bx = 0; bx < 4; bx++) {
|
||||
uint8_t* col = image + (x + bx + (y + by) * width) * 4;
|
||||
int alpha = col[3] >> 5;
|
||||
|
||||
if(alpha < 7) {
|
||||
output[output_idx++] = rgba16(col[0] >> 4, col[1] >> 4,
|
||||
col[2] >> 4, alpha);
|
||||
} else {
|
||||
output[output_idx++]
|
||||
= rgb16(col[0] >> 3, col[1] >> 3, col[2] >> 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DCFlushRange(output, width * height * sizeof(uint16_t));
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
static void* tex_conv_i8(uint8_t* image, size_t width, size_t height) {
|
||||
assert(image && (width % 8) == 0 && (height % 4) == 0);
|
||||
uint8_t* output = memalign(32, width * height * sizeof(uint8_t));
|
||||
|
||||
if(!output)
|
||||
return NULL;
|
||||
|
||||
size_t output_idx = 0;
|
||||
|
||||
for(size_t y = 0; y < height; y += 4) {
|
||||
for(size_t x = 0; x < width; x += 8) {
|
||||
for(size_t by = 0; by < 4; by++) {
|
||||
for(size_t bx = 0; bx < 8; bx++) {
|
||||
uint8_t* col = image + (x + bx + (y + by) * width) * 4;
|
||||
output[output_idx++]
|
||||
= ((int)col[0] + (int)col[1] + (int)col[2]) / 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DCFlushRange(output, width * height * sizeof(uint8_t));
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
static void* tex_conv_ia4(uint8_t* image, size_t width, size_t height) {
|
||||
assert(image && (width % 8) == 0 && (height % 4) == 0);
|
||||
uint8_t* output = memalign(32, width * height * sizeof(uint8_t));
|
||||
|
||||
if(!output)
|
||||
return NULL;
|
||||
|
||||
size_t output_idx = 0;
|
||||
|
||||
for(size_t y = 0; y < height; y += 4) {
|
||||
for(size_t x = 0; x < width; x += 8) {
|
||||
for(size_t by = 0; by < 4; by++) {
|
||||
for(size_t bx = 0; bx < 8; bx++) {
|
||||
uint8_t* col = image + (x + bx + (y + by) * width) * 4;
|
||||
output[output_idx++] = ia8(
|
||||
(((int)col[0] + (int)col[1] + (int)col[2]) / 3) >> 4,
|
||||
col[3] >> 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DCFlushRange(output, width * height * sizeof(uint8_t));
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
void tex_gfx_load(void* img, size_t width, size_t height, enum tex_format type,
|
||||
int slot, bool linear) {
|
||||
assert(img && width > 0 && height > 0);
|
||||
|
||||
void* output = NULL;
|
||||
uint8_t fmt;
|
||||
|
||||
switch(type) {
|
||||
case TEX_FMT_RGBA32:
|
||||
output = tex_conv_rgb32(img, width, height);
|
||||
fmt = GX_TF_RGBA8;
|
||||
break;
|
||||
case TEX_FMT_RGBA16:
|
||||
output = tex_conv_rgb16(img, width, height);
|
||||
fmt = GX_TF_RGB5A3;
|
||||
break;
|
||||
case TEX_FMT_I8:
|
||||
output = tex_conv_i8(img, width, height);
|
||||
fmt = GX_TF_I8;
|
||||
break;
|
||||
case TEX_FMT_IA4:
|
||||
output = tex_conv_ia4(img, width, height);
|
||||
fmt = GX_TF_IA4;
|
||||
break;
|
||||
default: return;
|
||||
}
|
||||
|
||||
if(output) {
|
||||
GXTexObj obj;
|
||||
GX_InitTexObj(&obj, output, width, height, fmt, GX_CLAMP, GX_CLAMP,
|
||||
GX_FALSE);
|
||||
GX_InitTexObjMaxAniso(&obj, GX_ANISO_1);
|
||||
GX_InitTexObjFilterMode(&obj, linear ? GX_LINEAR : GX_NEAR,
|
||||
linear ? GX_LINEAR : GX_NEAR);
|
||||
GX_LoadTexObj(&obj, slot);
|
||||
|
||||
// TODO: data needed by gpu, must not free
|
||||
// free(output);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue