22
33#include " billboardrenderer.h"
44#include " cakerenderer.h"
5+ #include " leavesrenderer.h"
6+ #include " torchrenderer.h"
57
68UniversalBlockRenderer globalBlockRenderer;
79
8- void BlockRenderer::renderNormalBlockSide (int local_x, int local_y, int local_z, const BLOCK_SIDE side, const TextureAtlasEntry tex, Chunk &c)
10+ void BlockRenderer::renderNormalBlockSide (int local_x, int local_y, int local_z, const BLOCK_SIDE side, const TextureAtlasEntry tex, Chunk &c, bool transparent )
911{
12+ const COLOR color = transparent ? TEXTURE_TRANSPARENT : 0 ;
1013 switch (side)
1114 {
1215 case BLOCK_FRONT:
13- c.addAlignedVertex (local_x, local_y, local_z, tex.left , tex.bottom , 0 );
14- c.addAlignedVertex (local_x, local_y + 1 , local_z, tex.left , tex.top , 0 );
15- c.addAlignedVertex (local_x + 1 , local_y + 1 , local_z, tex.right , tex.top , 0 );
16- c.addAlignedVertex (local_x + 1 , local_y, local_z, tex.right , tex.bottom , 0 );
16+ c.addAlignedVertex (local_x, local_y, local_z, tex.left , tex.bottom , color );
17+ c.addAlignedVertex (local_x, local_y + 1 , local_z, tex.left , tex.top , color );
18+ c.addAlignedVertex (local_x + 1 , local_y + 1 , local_z, tex.right , tex.top , color );
19+ c.addAlignedVertex (local_x + 1 , local_y, local_z, tex.right , tex.bottom , color );
1720 return ;
1821 case BLOCK_BACK:
19- c.addAlignedVertex (local_x + 1 , local_y, local_z + 1 , tex.left , tex.bottom , 0 );
20- c.addAlignedVertex (local_x + 1 , local_y + 1 , local_z + 1 , tex.left , tex.top , 0 );
21- c.addAlignedVertex (local_x, local_y + 1 , local_z + 1 , tex.right , tex.top , 0 );
22- c.addAlignedVertex (local_x, local_y, local_z + 1 , tex.right , tex.bottom , 0 );
22+ c.addAlignedVertex (local_x + 1 , local_y, local_z + 1 , tex.left , tex.bottom , color );
23+ c.addAlignedVertex (local_x + 1 , local_y + 1 , local_z + 1 , tex.left , tex.top , color );
24+ c.addAlignedVertex (local_x, local_y + 1 , local_z + 1 , tex.right , tex.top , color );
25+ c.addAlignedVertex (local_x, local_y, local_z + 1 , tex.right , tex.bottom , color );
2326 return ;
2427 case BLOCK_RIGHT:
25- c.addAlignedVertex (local_x + 1 , local_y, local_z, tex.right , tex.bottom , 0 );
26- c.addAlignedVertex (local_x + 1 , local_y + 1 , local_z, tex.right , tex.top , 0 );
27- c.addAlignedVertex (local_x + 1 , local_y + 1 , local_z + 1 , tex.left , tex.top , 0 );
28- c.addAlignedVertex (local_x + 1 , local_y, local_z + 1 , tex.left , tex.bottom , 0 );
28+ c.addAlignedVertex (local_x + 1 , local_y, local_z, tex.right , tex.bottom , color );
29+ c.addAlignedVertex (local_x + 1 , local_y + 1 , local_z, tex.right , tex.top , color );
30+ c.addAlignedVertex (local_x + 1 , local_y + 1 , local_z + 1 , tex.left , tex.top , color );
31+ c.addAlignedVertex (local_x + 1 , local_y, local_z + 1 , tex.left , tex.bottom , color );
2932 return ;
3033 case BLOCK_LEFT:
31- c.addAlignedVertex (local_x, local_y, local_z + 1 , tex.left , tex.bottom , 0 );
32- c.addAlignedVertex (local_x, local_y + 1 , local_z + 1 , tex.left , tex.top , 0 );
33- c.addAlignedVertex (local_x, local_y + 1 , local_z, tex.right , tex.top , 0 );
34- c.addAlignedVertex (local_x, local_y, local_z, tex.right , tex.bottom , 0 );
34+ c.addAlignedVertex (local_x, local_y, local_z + 1 , tex.left , tex.bottom , color );
35+ c.addAlignedVertex (local_x, local_y + 1 , local_z + 1 , tex.left , tex.top , color );
36+ c.addAlignedVertex (local_x, local_y + 1 , local_z, tex.right , tex.top , color );
37+ c.addAlignedVertex (local_x, local_y, local_z, tex.right , tex.bottom , color );
3538 return ;
3639 case BLOCK_TOP:
37- c.addAlignedVertex (local_x, local_y + 1 , local_z, tex.left , tex.bottom , 0 );
38- c.addAlignedVertex (local_x, local_y + 1 , local_z + 1 , tex.left , tex.top , 0 );
39- c.addAlignedVertex (local_x + 1 , local_y + 1 , local_z + 1 , tex.right , tex.top , 0 );
40- c.addAlignedVertex (local_x + 1 , local_y + 1 , local_z, tex.right , tex.bottom , 0 );
40+ c.addAlignedVertex (local_x, local_y + 1 , local_z, tex.left , tex.bottom , color );
41+ c.addAlignedVertex (local_x, local_y + 1 , local_z + 1 , tex.left , tex.top , color );
42+ c.addAlignedVertex (local_x + 1 , local_y + 1 , local_z + 1 , tex.right , tex.top , color );
43+ c.addAlignedVertex (local_x + 1 , local_y + 1 , local_z, tex.right , tex.bottom , color );
4144 return ;
4245 case BLOCK_BOTTOM:
43- c.addAlignedVertex (local_x + 1 , local_y, local_z, tex.left , tex.bottom , 0 );
44- c.addAlignedVertex (local_x + 1 , local_y, local_z + 1 , tex.left , tex.top , 0 );
45- c.addAlignedVertex (local_x, local_y, local_z + 1 , tex.right , tex.top , 0 );
46- c.addAlignedVertex (local_x, local_y, local_z, tex.right , tex.bottom , 0 );
46+ c.addAlignedVertex (local_x + 1 , local_y, local_z, tex.left , tex.bottom , color );
47+ c.addAlignedVertex (local_x + 1 , local_y, local_z + 1 , tex.left , tex.top , color );
48+ c.addAlignedVertex (local_x, local_y, local_z + 1 , tex.right , tex.top , color );
49+ c.addAlignedVertex (local_x, local_y, local_z, tex.right , tex.bottom , color );
4750 return ;
4851 default :
4952 return ; // WTF
@@ -52,24 +55,34 @@ void BlockRenderer::renderNormalBlockSide(int local_x, int local_y, int local_z,
5255
5356void BlockRenderer::renderBillboard (int local_x, int local_y, int local_z, const TextureAtlasEntry tex, Chunk &c)
5457{
55- // 0xFFFF: Black = transparent and no backface culling
56- c.addAlignedVertex (local_x, local_y, local_z, tex.left , tex.bottom , 0xFFFF );
57- c.addAlignedVertex (local_x, local_y + 1 , local_z, tex.left , tex.top , 0xFFFF );
58- c.addAlignedVertex (local_x + 1 , local_y + 1 , local_z + 1 , tex.right , tex.top , 0xFFFF );
59- c.addAlignedVertex (local_x + 1 , local_y, local_z + 1 , tex.right , tex.bottom , 0xFFFF );
58+ // | 0xFFF = no backface culling
59+ c.addAlignedVertex (local_x, local_y, local_z, tex.left , tex.bottom , TEXTURE_TRANSPARENT | 0xFFF );
60+ c.addAlignedVertex (local_x, local_y + 1 , local_z, tex.left , tex.top , TEXTURE_TRANSPARENT | 0xFFF );
61+ c.addAlignedVertex (local_x + 1 , local_y + 1 , local_z + 1 , tex.right , tex.top , TEXTURE_TRANSPARENT | 0xFFF );
62+ c.addAlignedVertex (local_x + 1 , local_y, local_z + 1 , tex.right , tex.bottom , TEXTURE_TRANSPARENT | 0xFFF );
6063
61- c.addAlignedVertex (local_x, local_y, local_z + 1 , tex.left , tex.bottom , 0xFFFF );
62- c.addAlignedVertex (local_x, local_y + 1 , local_z + 1 , tex.left , tex.top , 0xFFFF );
63- c.addAlignedVertex (local_x + 1 , local_y + 1 , local_z, tex.right , tex.top , 0xFFFF );
64- c.addAlignedVertex (local_x + 1 , local_y, local_z, tex.right , tex.bottom , 0xFFFF );
64+ c.addAlignedVertex (local_x, local_y, local_z + 1 , tex.left , tex.bottom , TEXTURE_TRANSPARENT | 0xFFF );
65+ c.addAlignedVertex (local_x, local_y + 1 , local_z + 1 , tex.left , tex.top , TEXTURE_TRANSPARENT | 0xFFF );
66+ c.addAlignedVertex (local_x + 1 , local_y + 1 , local_z, tex.right , tex.top , TEXTURE_TRANSPARENT | 0xFFF );
67+ c.addAlignedVertex (local_x + 1 , local_y, local_z, tex.right , tex.bottom , TEXTURE_TRANSPARENT | 0xFFF );
68+ }
69+
70+ void BlockRenderer::drawTextureAtlasEntry (TEXTURE &src, const TextureAtlasEntry &tex, bool transparent, TEXTURE &dest, const int dest_x, const int dest_y)
71+ {
72+ if (transparent)
73+ drawTransparentTexture (src, tex.left , tex.top , dest, dest_x, dest_y, tex.right - tex.left , tex.bottom - tex.top );
74+ else
75+ drawTexture (src, tex.left , tex.top , dest, dest_x, dest_y, tex.right - tex.left , tex.bottom - tex.top );
6576}
6677
6778UniversalBlockRenderer::UniversalBlockRenderer ()
6879{
6980 auto normal_renderer = std::make_shared<NormalBlockRenderer>();
81+ auto oriented_renderer = std::make_shared<OrientedBlockRenderer>();
7082 auto null_renderer = std::make_shared<NullBlockRenderer>();
83+
7184 BLOCK i = 1 ;
72- for (; i < BLOCK_NORMAL_MAX; i++ )
85+ for (; i <= BLOCK_NORMAL_LAST; ++i )
7386 map[i] = normal_renderer;
7487
7588 while (true )
@@ -83,20 +96,37 @@ UniversalBlockRenderer::UniversalBlockRenderer()
8396
8497 map[BLOCK_AIR] = null_renderer;
8598 map[BLOCK_CAKE] = std::make_shared<CakeRenderer>();
99+ map[BLOCK_TORCH] = std::make_shared<TorchRenderer>();
100+ map[BLOCK_LEAVES] = std::make_shared<LeavesRenderer>();
101+ map[BLOCK_FURNACE] = oriented_renderer;
102+ map[BLOCK_CRAFTING_TABLE] = oriented_renderer;
103+ map[BLOCK_PUMPKIN] = oriented_renderer;
104+ map[BLOCK_BOOKSHELF] = oriented_renderer;
86105
87106 auto flower_renderer = std::make_shared<BillboardRenderer>();
88- flower_renderer->setEntry (0 , 12 , 0 , " Red flower" );
89- flower_renderer->setEntry (1 , 13 , 0 , " Yellow flower" );
107+ flower_renderer->setEntry (0 , 12 , 0 , " Red flower" , BLOCK_SIZE, BLOCK_SIZE/ 2 , BLOCK_SIZE );
108+ flower_renderer->setEntry (1 , 13 , 0 , " Yellow flower" , BLOCK_SIZE, BLOCK_SIZE/ 2 , BLOCK_SIZE );
90109 map[BLOCK_FLOWER] = flower_renderer;
91110
92111 auto mushroom_renderer = std::make_shared<BillboardRenderer>();
93- mushroom_renderer->setEntry (0 , 12 , 1 , " Red mushroom" );
94- mushroom_renderer->setEntry (1 , 13 , 1 , " Grey mushroom" );
112+ mushroom_renderer->setEntry (0 , 12 , 1 , " Red mushroom" , BLOCK_SIZE/ 3 , BLOCK_SIZE/ 3 , BLOCK_SIZE/ 3 );
113+ mushroom_renderer->setEntry (1 , 13 , 1 , " Grey mushroom" , BLOCK_SIZE/ 3 , BLOCK_SIZE/ 3 , BLOCK_SIZE/ 3 );
95114 map[BLOCK_MUSHROOM] = mushroom_renderer;
96115
97116 auto spiderweb_renderer = std::make_shared<BillboardRenderer>();
98- spiderweb_renderer->setEntry (0 , 11 , 0 , " Spiderweb" );
117+ spiderweb_renderer->setEntry (0 , 11 , 0 , " Spiderweb" , BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE );
99118 map[BLOCK_SPIDERWEB] = spiderweb_renderer;
119+
120+ #ifdef DEBUG
121+ puts (" UniversalBlockRenderer created." );
122+ #endif
123+ }
124+
125+ UniversalBlockRenderer::~UniversalBlockRenderer ()
126+ {
127+ #ifdef DEBUG
128+ puts (" UniversalBlockRenderer destroyed." );
129+ #endif
100130}
101131
102132void UniversalBlockRenderer::renderSpecialBlock (const BLOCK_WDATA block, GLFix x, GLFix y, GLFix z, Chunk &c)
@@ -129,6 +159,11 @@ bool UniversalBlockRenderer::isOriented(const BLOCK_WDATA block)
129159 return map[getBLOCK (block)]->isOriented (block);
130160}
131161
162+ bool UniversalBlockRenderer::isFullyOriented (const BLOCK_WDATA block)
163+ {
164+ return map[getBLOCK (block)]->isFullyOriented (block);
165+ }
166+
132167bool UniversalBlockRenderer::isBlockShaped (const BLOCK_WDATA block)
133168{
134169 return map[getBLOCK (block)]->isBlockShaped (block);
@@ -139,7 +174,7 @@ AABB UniversalBlockRenderer::getAABB(const BLOCK_WDATA block, GLFix x, GLFix y,
139174 return map[getBLOCK (block)]->getAABB (block, x, y, z);
140175}
141176
142- void UniversalBlockRenderer::drawPreview (const BLOCK_WDATA block, TEXTURE &dest, int x, int y)
177+ void UniversalBlockRenderer::drawPreview (const BLOCK_WDATA block, TEXTURE &dest, const int x, const int y)
143178{
144179 return map[getBLOCK (block)]->drawPreview (block, dest, x, y);
145180}
@@ -171,11 +206,57 @@ const char *UniversalBlockRenderer::getName(const BLOCK_WDATA block)
171206
172207void NormalBlockRenderer::geometryNormalBlock (const BLOCK_WDATA block, int local_x, int local_y, int local_z, const BLOCK_SIDE side, Chunk &c)
173208{
174- return BlockRenderer::renderNormalBlockSide (local_x, local_y, local_z, side, block_textures[getBLOCK (block)][side].current , c);
209+ BlockRenderer::renderNormalBlockSide (local_x, local_y, local_z, side, block_textures[getBLOCK (block)][side].current , c);
175210}
176211
177- void NormalBlockRenderer::drawPreview (const BLOCK_WDATA block, TEXTURE &dest, int dest_x, int dest_y)
212+ void NormalBlockRenderer::drawPreview (const BLOCK_WDATA block, TEXTURE &dest, const int dest_x, const int dest_y)
178213{
179214 const TextureAtlasEntry tex = block_textures[getBLOCK (block)][BLOCK_FRONT].resized ;
180- return drawTexture (*terrain_resized, tex.left , tex.top , dest, dest_x, dest_y, tex.right - tex.left , tex.bottom - tex.top );
215+
216+ BlockRenderer::drawTextureAtlasEntry (*terrain_resized, tex, false , dest, dest_x, dest_y);
217+ }
218+
219+ void OrientedBlockRenderer::geometryNormalBlock (const BLOCK_WDATA block, int local_x, int local_y, int local_z, const BLOCK_SIDE side, Chunk &c)
220+ {
221+ BLOCK_SIDE map[BLOCK_SIDE_LAST + 1 ];
222+
223+ BLOCK type = getBLOCK (block);
224+ switch (static_cast <BLOCK_SIDE>(getBLOCKDATA (block)))
225+ {
226+ default :
227+ case BLOCK_FRONT:
228+ map[BLOCK_TOP] = BLOCK_TOP;
229+ map[BLOCK_BOTTOM] = BLOCK_BOTTOM;
230+ map[BLOCK_LEFT] = BLOCK_LEFT;
231+ map[BLOCK_RIGHT] = BLOCK_RIGHT;
232+ map[BLOCK_BACK] = BLOCK_BACK;
233+ map[BLOCK_FRONT] = BLOCK_FRONT;
234+ break ;
235+ case BLOCK_BACK:
236+ map[BLOCK_TOP] = BLOCK_TOP;
237+ map[BLOCK_BOTTOM] = BLOCK_BOTTOM;
238+ map[BLOCK_LEFT] = BLOCK_RIGHT;
239+ map[BLOCK_RIGHT] = BLOCK_LEFT;
240+ map[BLOCK_BACK] = BLOCK_FRONT;
241+ map[BLOCK_FRONT] = BLOCK_BACK;
242+ break ;
243+ case BLOCK_LEFT:
244+ map[BLOCK_TOP] = BLOCK_TOP;
245+ map[BLOCK_BOTTOM] = BLOCK_BOTTOM;
246+ map[BLOCK_LEFT] = BLOCK_FRONT;
247+ map[BLOCK_RIGHT] = BLOCK_BACK;
248+ map[BLOCK_BACK] = BLOCK_LEFT;
249+ map[BLOCK_FRONT] = BLOCK_RIGHT;
250+ break ;
251+ case BLOCK_RIGHT:
252+ map[BLOCK_TOP] = BLOCK_TOP;
253+ map[BLOCK_BOTTOM] = BLOCK_BOTTOM;
254+ map[BLOCK_LEFT] = BLOCK_BACK;
255+ map[BLOCK_RIGHT] = BLOCK_FRONT;
256+ map[BLOCK_BACK] = BLOCK_RIGHT;
257+ map[BLOCK_FRONT] = BLOCK_LEFT;
258+ break ;
259+ }
260+
261+ BlockRenderer::renderNormalBlockSide (local_x, local_y, local_z, side, block_textures[type][map[side]].current , c);
181262}
0 commit comments