PageRenderTime 1397ms CodeModel.GetById 232ms app.highlight 951ms RepoModel.GetById 200ms app.codeStats 1ms

/opengles/src/ContextLines.cpp

http://ftk.googlecode.com/
C++ | 440 lines | 284 code | 109 blank | 47 comment | 40 complexity | 416a1bc44250a5058265daa014cb4ecb MD5 | raw file
  1// ==========================================================================
  2//
  3// ContextLines.cpp	Rendering Context Class for 3D Rendering Library
  4//
  5//					Rendering Operations for Lines
  6//
  7// --------------------------------------------------------------------------
  8//
  9// 08-12-2003	Hans-Martin Will	initial version
 10//
 11// --------------------------------------------------------------------------
 12//
 13// Copyright (c) 2004, Hans-Martin Will. All rights reserved.
 14// 
 15// Redistribution and use in source and binary forms, with or without 
 16// modification, are permitted provided that the following conditions are 
 17// met:
 18// 
 19//	 *  Redistributions of source code must retain the above copyright
 20// 		notice, this list of conditions and the following disclaimer. 
 21//   *	Redistributions in binary form must reproduce the above copyright
 22// 		notice, this list of conditions and the following disclaimer in the 
 23// 		documentation and/or other materials provided with the distribution. 
 24// 
 25// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 26// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 27// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
 28// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
 29// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 
 30// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
 31// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 32// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 33// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 34// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
 35// THE POSSIBILITY OF SUCH DAMAGE.
 36//
 37// ==========================================================================
 38
 39
 40#include "stdafx.h"
 41#include "Context.h"
 42#include "fixed.h"
 43#include "Rasterizer.h"
 44
 45using namespace EGL;
 46
 47
 48void Context :: LineWidthx(GLfixed width) { 
 49
 50	if (width <= 0) {
 51		RecordError(GL_INVALID_VALUE);
 52	} else {
 53		GetRasterizerState()->SetLineWidth(width);
 54	}
 55}
 56
 57
 58// --------------------------------------------------------------------------
 59// Lines
 60// --------------------------------------------------------------------------
 61
 62
 63void Context :: RenderLines(GLint first, GLsizei count) {
 64
 65	m_Rasterizer->PrepareLine();
 66
 67	while (count >= 2) {
 68		count -= 2;
 69
 70		RasterPos pos0, pos1;
 71		SelectArrayElement(first++);
 72		CurrentValuesToRasterPos(&pos0);
 73		SelectArrayElement(first++);
 74		CurrentValuesToRasterPos(&pos1);
 75
 76		RenderLine(pos0, pos1);
 77	}
 78}
 79
 80
 81void Context :: RenderLines(GLsizei count, const GLubyte * indices) {
 82
 83	m_Rasterizer->PrepareLine();
 84
 85	while (count >= 2) {
 86		count -= 2;
 87
 88		RasterPos pos0, pos1;
 89		SelectArrayElement(*indices++);
 90		CurrentValuesToRasterPos(&pos0);
 91		SelectArrayElement(*indices++);
 92		CurrentValuesToRasterPos(&pos1);
 93
 94		RenderLine(pos0, pos1);
 95	}
 96}
 97
 98
 99void Context :: RenderLines(GLsizei count, const GLushort * indices) {
100
101	m_Rasterizer->PrepareLine();
102
103	while (count >= 2) {
104		count -= 2;
105
106		RasterPos pos0, pos1;
107		SelectArrayElement(*indices++);
108		CurrentValuesToRasterPos(&pos0);
109		SelectArrayElement(*indices++);
110		CurrentValuesToRasterPos(&pos1);
111
112		RenderLine(pos0, pos1);
113	}
114}
115
116
117// --------------------------------------------------------------------------
118// Line Strips
119// --------------------------------------------------------------------------
120
121
122void Context :: RenderLineStrip(GLint first, GLsizei count) {
123
124	if (count >= 2) {
125		m_Rasterizer->PrepareLine();
126
127		RasterPos pos0, pos1;
128		SelectArrayElement(first++);
129		CurrentValuesToRasterPos(&pos0);
130		--count;
131
132		while (count >= 2) {
133			count -= 2;
134
135			SelectArrayElement(first++);
136			CurrentValuesToRasterPos(&pos1);
137			RenderLine(pos0, pos1);
138
139			SelectArrayElement(first++);
140			CurrentValuesToRasterPos(&pos0);
141			RenderLine(pos1, pos0);
142		}
143
144		if (count >= 1) {
145			SelectArrayElement(first++);
146			CurrentValuesToRasterPos(&pos1);
147			RenderLine(pos0, pos1);
148		}
149	}
150}
151
152
153void Context :: RenderLineStrip(GLsizei count, const GLubyte * indices) {
154
155	if (count >= 2) {
156		m_Rasterizer->PrepareLine();
157
158		RasterPos pos0, pos1;
159		SelectArrayElement(*indices++);
160		CurrentValuesToRasterPos(&pos0);
161		--count;
162
163		while (count >= 2) {
164			count -= 2;
165
166			SelectArrayElement(*indices++);
167			CurrentValuesToRasterPos(&pos1);
168			RenderLine(pos0, pos1);
169
170			SelectArrayElement(*indices++);
171			CurrentValuesToRasterPos(&pos0);
172			RenderLine(pos1, pos0);
173		}
174
175		if (count >= 1) {
176			SelectArrayElement(*indices++);
177			CurrentValuesToRasterPos(&pos1);
178			RenderLine(pos0, pos1);
179		}
180	}
181}
182
183
184void Context :: RenderLineStrip(GLsizei count, const GLushort * indices) {
185
186	if (count >= 2) {
187		m_Rasterizer->PrepareLine();
188
189		RasterPos pos0, pos1;
190		SelectArrayElement(*indices++);
191		CurrentValuesToRasterPos(&pos0);
192		--count;
193
194		while (count >= 2) {
195			count -= 2;
196
197			SelectArrayElement(*indices++);
198			CurrentValuesToRasterPos(&pos1);
199			RenderLine(pos0, pos1);
200
201			SelectArrayElement(*indices++);
202			CurrentValuesToRasterPos(&pos0);
203			RenderLine(pos1, pos0);
204		}
205
206		if (count >= 1) {
207			SelectArrayElement(*indices++);
208			CurrentValuesToRasterPos(&pos1);
209			RenderLine(pos0, pos1);
210		}
211	}
212}
213
214
215// --------------------------------------------------------------------------
216// Line Loops
217// --------------------------------------------------------------------------
218
219
220void Context :: RenderLineLoop(GLint first, GLsizei count) {
221
222	if (count >= 2) {
223		m_Rasterizer->PrepareLine();
224
225		RasterPos pos0, pos1, start;
226		SelectArrayElement(first++);
227		CurrentValuesToRasterPos(&start);
228		SelectArrayElement(first++);
229		CurrentValuesToRasterPos(&pos0);
230		RenderLine(start, pos0);
231
232		count -= 2;
233
234		while (count >= 2) {
235			count -= 2;
236
237			SelectArrayElement(first++);
238			CurrentValuesToRasterPos(&pos1);
239			RenderLine(pos0, pos1);
240
241			SelectArrayElement(first++);
242			CurrentValuesToRasterPos(&pos0);
243			RenderLine(pos1, pos0);
244		}
245
246		if (count >= 1) {
247			SelectArrayElement(first++);
248			CurrentValuesToRasterPos(&pos1);
249			RenderLine(pos0, pos1);
250			RenderLine(pos1, start);
251		} else {
252			RenderLine(pos0, start);
253		}
254	}
255}
256
257
258void Context :: RenderLineLoop(GLsizei count, const GLubyte * indices) {
259
260	if (count >= 2) {
261		m_Rasterizer->PrepareLine();
262
263		RasterPos pos0, pos1, start;
264		SelectArrayElement(*indices++);
265		CurrentValuesToRasterPos(&start);
266		SelectArrayElement(*indices++);
267		CurrentValuesToRasterPos(&pos0);
268		RenderLine(start, pos0);
269
270		count -= 2;
271
272		while (count >= 2) {
273			count -= 2;
274
275			SelectArrayElement(*indices++);
276			CurrentValuesToRasterPos(&pos1);
277			RenderLine(pos0, pos1);
278
279			SelectArrayElement(*indices++);
280			CurrentValuesToRasterPos(&pos0);
281			RenderLine(pos1, pos0);
282		}
283
284		if (count >= 1) {
285			SelectArrayElement(*indices++);
286			CurrentValuesToRasterPos(&pos1);
287			RenderLine(pos0, pos1);
288			RenderLine(pos1, start);
289		} else {
290			RenderLine(pos0, start);
291		}
292	}
293}
294
295
296void Context :: RenderLineLoop(GLsizei count, const GLushort * indices) {
297
298	if (count >= 2) {
299		m_Rasterizer->PrepareLine();
300
301		RasterPos pos0, pos1, start;
302		SelectArrayElement(*indices++);
303		CurrentValuesToRasterPos(&start);
304		SelectArrayElement(*indices++);
305		CurrentValuesToRasterPos(&pos0);
306		RenderLine(start, pos0);
307
308		count -= 2;
309
310		while (count >= 2) {
311			count -= 2;
312
313			SelectArrayElement(*indices++);
314			CurrentValuesToRasterPos(&pos1);
315			RenderLine(pos0, pos1);
316
317			SelectArrayElement(*indices++);
318			CurrentValuesToRasterPos(&pos0);
319			RenderLine(pos1, pos0);
320		}
321
322		if (count >= 1) {
323			SelectArrayElement(*indices++);
324			CurrentValuesToRasterPos(&pos1);
325			RenderLine(pos0, pos1);
326			RenderLine(pos1, start);
327		} else {
328			RenderLine(pos0, start);
329		}
330	}
331}
332
333
334namespace {
335
336	inline EGL_Fixed Interpolate(EGL_Fixed x0, EGL_Fixed x1, EGL_Fixed num, EGL_Fixed denom) {
337		return x1 + (EGL_Fixed)((((I64)(x0-x1))*num)/denom);
338	}
339
340	inline void Interpolate(RasterPos& result, const RasterPos& dst, const RasterPos& src, EGL_Fixed num, EGL_Fixed denom) {
341		result.m_ClipCoords.setX(Interpolate(dst.m_ClipCoords.x(), src.m_ClipCoords.x(), num, denom));
342		result.m_ClipCoords.setY(Interpolate(dst.m_ClipCoords.y(), src.m_ClipCoords.y(), num, denom));
343		result.m_ClipCoords.setZ(Interpolate(dst.m_ClipCoords.z(), src.m_ClipCoords.z(), num, denom));
344		result.m_ClipCoords.setW(Interpolate(dst.m_ClipCoords.w(), src.m_ClipCoords.w(), num, denom));
345		result.m_Color.r = Interpolate(dst.m_Color.r, src.m_Color.r, num, denom);
346		result.m_Color.g = Interpolate(dst.m_Color.g, src.m_Color.g, num, denom);
347		result.m_Color.b = Interpolate(dst.m_Color.b, src.m_Color.b, num, denom);
348		result.m_Color.a = Interpolate(dst.m_Color.a, src.m_Color.a, num, denom);
349
350		for (size_t index = 0; index < EGL_NUM_TEXTURE_UNITS; ++index) {
351			result.m_TextureCoords[index].tu = Interpolate(dst.m_TextureCoords[index].tu, src.m_TextureCoords[index].tu, num, denom);
352			result.m_TextureCoords[index].tv = Interpolate(dst.m_TextureCoords[index].tv, src.m_TextureCoords[index].tv, num, denom);
353		}
354
355		result.m_FogDensity = Interpolate(dst.m_FogDensity, src.m_FogDensity, num, denom);
356	}
357
358	inline bool ClipX(RasterPos*& from, RasterPos*& to, RasterPos *&tempVertices) {
359#		define COORDINATE x()
360#		include "LineClipper.inc"
361#		undef COORDINATE
362	}
363
364	inline bool ClipY(RasterPos*& from, RasterPos*& to, RasterPos *&tempVertices) {
365#		define COORDINATE y()
366#		include "LineClipper.inc"
367#		undef COORDINATE
368	}
369
370	inline bool ClipZ(RasterPos*& from, RasterPos*& to, RasterPos *&tempVertices) {
371#		define COORDINATE z()
372#		include "LineClipper.inc"
373#		undef COORDINATE
374	}
375
376	inline bool ClipUser(const Vec4D& plane, RasterPos*& from, RasterPos*& to, RasterPos *&tempVertices) {
377
378		EGL_Fixed f = from->m_EyeCoords * plane;
379		EGL_Fixed t = to->m_EyeCoords * plane;
380
381		if (f < 0) {
382			if (t < 0) {
383				return false;
384			}
385
386			Interpolate(*tempVertices, *from, *to, t, t - f);
387			from = tempVertices++;
388
389			return true;
390
391		} else if (t < 0) {
392
393			Interpolate(*tempVertices, *to, *from, f, f - t);
394			to = tempVertices++;
395
396			return true;
397
398		} else {
399			// no clipping
400			return true;
401		}
402	}
403}
404
405
406void Context :: RenderLine(RasterPos& from, RasterPos& to) {
407
408	RasterPos * tempVertices = m_Temporary;
409	RasterPos * pFrom = &from;
410	RasterPos * pTo = &to;
411
412	if (m_ClipPlaneEnabled) {
413		for (size_t index = 0, mask = 1; index < NUM_CLIP_PLANES; ++index, mask <<= 1) {
414			if (m_ClipPlaneEnabled & mask) {
415				if (!ClipUser(m_ClipPlanes[index], pFrom, pTo, tempVertices)) {
416					return;
417				}
418			}
419		}
420	}
421
422	if (ClipX(pFrom, pTo, tempVertices) &&
423		ClipY(pFrom, pTo, tempVertices) &&
424		ClipZ(pFrom, pTo, tempVertices)) {
425
426		ClipCoordsToWindowCoords(*pFrom);
427		ClipCoordsToWindowCoords(*pTo);
428
429		if (m_RasterizerState.GetShadeModel() == RasterizerState::ShadeModelSmooth) {
430			pFrom->m_Color = pFrom->m_FrontColor;
431		} else {
432			pFrom->m_Color = pTo->m_FrontColor;
433		}
434
435		pTo->m_Color = pTo->m_FrontColor;
436		m_Rasterizer->RasterLine(*pFrom, *pTo);
437	}
438}
439
440