1 // Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
2 // This file is part of the "Irrlicht Engine".
3 // For conditions of distribution and use, see copyright notice in irrlicht.h
4 
5 #include "IrrCompileConfig.h"
6 #include "IBurningShader.h"
7 
8 #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
9 
10 // compile flag for this file
11 #undef USE_ZBUFFER
12 #undef IPOL_Z
13 #undef CMP_Z
14 #undef WRITE_Z
15 
16 #undef IPOL_W
17 #undef CMP_W
18 #undef WRITE_W
19 
20 #undef SUBTEXEL
21 #undef INVERSE_W
22 
23 #undef IPOL_C0
24 #undef IPOL_T0
25 #undef IPOL_T1
26 
27 // define render case
28 #define SUBTEXEL
29 #define INVERSE_W
30 
31 #define USE_ZBUFFER
32 #define IPOL_W
33 #define CMP_W
34 #define WRITE_W
35 
36 
37 //#define IPOL_C0
38 #define IPOL_T0
39 //#define IPOL_T1
40 
41 // apply global override
42 #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
43 	#undef INVERSE_W
44 #endif
45 
46 #ifndef SOFTWARE_DRIVER_2_SUBTEXEL
47 	#undef SUBTEXEL
48 #endif
49 
50 #if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
51 	#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
52 		#undef IPOL_W
53 	#endif
54 	#define IPOL_Z
55 
56 	#ifdef CMP_W
57 		#undef CMP_W
58 		#define CMP_Z
59 	#endif
60 
61 	#ifdef WRITE_W
62 		#undef WRITE_W
63 		#define WRITE_Z
64 	#endif
65 
66 #endif
67 
68 
69 namespace irr
70 {
71 
72 namespace video
73 {
74 
75 class CTRTextureWire2 : public IBurningShader
76 {
77 public:
78 
79 	//! constructor
80 	CTRTextureWire2(CBurningVideoDriver* driver);
81 
82 	//! draws an indexed triangle list
83 	virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
84 	virtual void drawLine ( const s4DVertex *a,const s4DVertex *b);
85 
86 
87 
88 private:
89 	void renderAlphaLine ( const s4DVertex *a,const s4DVertex *b ) const;
90 	void renderLine ( const s4DVertex *a,const s4DVertex *b ) const;
91 
92 };
93 
94 //! constructor
CTRTextureWire2(CBurningVideoDriver * driver)95 CTRTextureWire2::CTRTextureWire2(CBurningVideoDriver* driver)
96 : IBurningShader(driver)
97 {
98 	#ifdef _DEBUG
99 	setDebugName("CTRTextureWire2");
100 	#endif
101 }
102 
103 
104 // swap integer with xor
swap_xor(s32 & a,s32 & b)105 static inline void swap_xor ( s32 &a, s32 &b )
106 {
107 	a ^= b;
108 	b ^= a;
109 	a ^= b;
110 }
111 
112 
113 /*!
114 */
renderLine(const s4DVertex * a,const s4DVertex * b) const115 void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b ) const
116 {
117 
118 	int pitch0 = RenderTarget->getDimension().Width << VIDEO_SAMPLE_GRANULARITY;
119 	int pitch1 = RenderTarget->getDimension().Width << 2;
120 
121 	int aposx = (int) a->Pos.x;
122 	int aposy = (int) a->Pos.y;
123 	int bposx = (int) b->Pos.x;
124 	int bposy = (int) b->Pos.y;
125 
126 	int dx = bposx - aposx;
127 	int dy = bposy - aposy;
128 
129 	int c;
130 	int m;
131 	int d = 0;
132 	int run;
133 
134 	tVideoSample *dst;
135 #ifdef USE_ZBUFFER
136 	fp24 *z;
137 #endif
138 
139 	int xInc0 = 1 << VIDEO_SAMPLE_GRANULARITY;
140 	int yInc0 = pitch0;
141 
142 	int xInc1 = 4;
143 	int yInc1 = pitch1;
144 
145 	tVideoSample color;
146 
147 #ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
148 	tFixPoint r0, g0, b0;
149 	getSample_color ( r0, g0, b0, a->Color[0] );
150 	color = fix_to_color ( r0, g0, b0 );
151 #else
152 	color = (tVideoSample) 0xFFFFFFFF;
153 #endif
154 
155 	if ( dx < 0 )
156 	{
157 		xInc0 = - ( 1 << VIDEO_SAMPLE_GRANULARITY);
158 		xInc1 = -4;
159 		dx = -dx;
160 	}
161 
162 	if ( dy > dx )
163 	{
164 		swap_xor ( dx, dy );
165 		swap_xor ( xInc0, yInc0 );
166 		swap_xor ( xInc1, yInc1 );
167 	}
168 
169 	if ( 0 == dx )
170 		return;
171 
172 	dst = (tVideoSample*) ( (u8*) (tVideoSample*)RenderTarget->lock() + ( aposy * pitch0 ) + (aposx << VIDEO_SAMPLE_GRANULARITY ) );
173 #ifdef USE_ZBUFFER
174 	z = (fp24*) ( (u8*) (fp24*) DepthBuffer->lock() + ( aposy * pitch1 ) + (aposx << 2 ) );
175 #endif
176 
177 	c = dx << 1;
178 	m = dy << 1;
179 
180 #ifdef IPOL_Z
181 	f32 slopeZ = (b->Pos.z - a->Pos.z) / f32(dx);
182 	f32 dataZ = a->Pos.z;
183 #endif
184 
185 #ifdef IPOL_W
186 	fp24 slopeW = (b->Pos.w - a->Pos.w) / f32( dx );
187 	fp24 dataW = a->Pos.w;
188 #endif
189 
190 	run = dx;
191 	while ( run )
192 	{
193 #ifdef CMP_Z
194 		if ( *z >= dataZ )
195 #endif
196 #ifdef CMP_W
197 		if ( dataW >= *z )
198 #endif
199 		{
200 #ifdef WRITE_Z
201 			*z = dataZ;
202 #endif
203 #ifdef WRITE_W
204 			*z = dataW;
205 #endif
206 
207 		*dst = color;
208 
209 		}
210 
211 		dst = (tVideoSample*) ( (u8*) dst + xInc0 );	// x += xInc
212 #ifdef IPOL_Z
213 		z = (fp24*) ( (u8*) z + xInc1 );
214 #endif
215 #ifdef IPOL_W
216 		z = (fp24*) ( (u8*) z + xInc1 );
217 #endif
218 
219 		d += m;
220 		if ( d > dx )
221 		{
222 			dst = (tVideoSample*) ( (u8*) dst + yInc0 );	// y += yInc
223 #ifdef IPOL_Z
224 			z = (fp24*) ( (u8*) z + yInc1 );
225 #endif
226 #ifdef IPOL_W
227 			z = (fp24*) ( (u8*) z + yInc1 );
228 #endif
229 
230 			d -= c;
231 		}
232 		run -= 1;
233 #ifdef IPOL_Z
234 		dataZ += slopeZ;
235 #endif
236 #ifdef IPOL_W
237 		dataW += slopeW;
238 #endif
239 
240 	}
241 
242 }
243 
drawTriangle(const s4DVertex * a,const s4DVertex * b,const s4DVertex * c)244 void CTRTextureWire2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
245 {
246 	sScanLineData line;
247 
248 	// sort on height, y
249 	if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
250 	if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
251 	if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
252 
253 	renderLine ( a, b );
254 	renderLine ( b, c );
255 	renderLine ( a, c );
256 
257 }
258 
259 
drawLine(const s4DVertex * a,const s4DVertex * b)260 void CTRTextureWire2::drawLine ( const s4DVertex *a,const s4DVertex *b)
261 {
262 
263 	// query access to TexMaps
264 
265 	// sort on height, y
266 	if ( a->Pos.y > b->Pos.y ) swapVertexPointer(&a, &b);
267 
268 	renderLine ( a, b );
269 
270 }
271 
272 
273 } // end namespace video
274 } // end namespace irr
275 
276 #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
277 
278 namespace irr
279 {
280 namespace video
281 {
282 
283 
284 //! creates a flat triangle renderer
createTriangleRendererTextureGouraudWire2(CBurningVideoDriver * driver)285 IBurningShader* createTriangleRendererTextureGouraudWire2(CBurningVideoDriver* driver)
286 {
287 	#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
288 	return new CTRTextureWire2(driver);
289 	#else
290 	return 0;
291 	#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
292 }
293 
294 
295 } // end namespace video
296 } // end namespace irr
297 
298 
299