PageRenderTime 1047ms CodeModel.GetById 678ms app.highlight 115ms RepoModel.GetById 142ms app.codeStats 0ms

/opengles/src/linux-ftk/Surface.cpp

http://ftk.googlecode.com/
C++ | 368 lines | 262 code | 60 blank | 46 comment | 44 complexity | 3dd5a09a56666a1f9c9cb70231215c4b MD5 | raw file
  1// ==========================================================================
  2//
  3// Surface.cpp		Drawing Surface Class for 3D Rendering Library
  4//
  5// --------------------------------------------------------------------------
  6//
  7// 08-14-2003		Hans-Martin Will	initial version
  8// 08-18-2010		Li XianJing		Adapt to ftk
  9//
 10// --------------------------------------------------------------------------
 11//
 12// Copyright (c) 2004, Hans-Martin Will. All rights reserved.
 13//
 14// Redistribution and use in source and binary forms, with or without
 15// modification, are permitted provided that the following conditions are
 16// met:
 17//
 18//	 *	Redistributions of source code must retain the above copyright
 19//		notice, this list of conditions and the following disclaimer.
 20//	 *	Redistributions in binary form must reproduce the above copyright
 21//		notice, this list of conditions and the following disclaimer in the
 22//		documentation and/or other materials provided with the distribution.
 23//
 24// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 25// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 26// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 27// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 28// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
 29// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 30// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 31// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 32// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 33// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 34// THE POSSIBILITY OF SUCH DAMAGE.
 35//
 36// ==========================================================================
 37
 38
 39#include "stdafx.h"
 40#include "Surface.h"
 41#include "Color.h"
 42#include <string.h>
 43
 44using namespace EGL;
 45
 46Surface :: Surface(const Config & config, NativeDisplayType display, NativeWindowType win)
 47	:	m_Config(config),
 48	  m_Rect (0, 0, config.GetConfigAttrib(EGL_WIDTH), 
 49			  config.GetConfigAttrib(EGL_HEIGHT)),
 50	  m_Display(NULL)
 51{
 52	FtkColor bg = {0};
 53	U32 width = GetWidth();
 54	U32 height = GetHeight();
 55
 56	m_Config.SetConfigAttrib(EGL_WIDTH, width);
 57	m_Config.SetConfigAttrib(EGL_HEIGHT, height);
 58
 59	m_AlphaBuffer	= new U8[width * height];
 60	m_DepthBuffer	= new U16[width * height];
 61	m_StencilBuffer = new U32[width * height];
 62	m_ColorBuffer	= new U16[width * height];
 63	
 64	bg.a = 0xff;
 65	m_Window = win;
 66	if(win != NULL)
 67	{
 68		m_Bitmap = ftk_bitmap_create(width, height, bg);
 69	}
 70
 71	if (display != NULL) 
 72	{
 73		m_Display = display;
 74	}
 75	else
 76	{
 77		m_Display = ftk_default_display();
 78	}
 79
 80	return;
 81}
 82
 83Surface :: ~Surface() 
 84{
 85	if (m_Bitmap)
 86	{
 87		ftk_bitmap_unref(m_Bitmap);
 88		m_Bitmap = NULL;
 89	}
 90
 91	if (m_Display != NULL) 
 92	{
 93		m_Display = NULL;
 94	}
 95	
 96	if(m_ColorBuffer != NULL)
 97	{
 98		delete m_ColorBuffer;
 99		m_ColorBuffer = NULL;
100	}
101
102	if (m_AlphaBuffer != 0) 
103	{
104		delete [] m_AlphaBuffer;
105		m_AlphaBuffer = 0;
106	}
107	
108	if (m_DepthBuffer != 0) 
109	{
110		delete[] m_DepthBuffer;
111		m_DepthBuffer = 0;
112	}
113
114	if (m_StencilBuffer != 0) 
115	{
116		delete[] m_StencilBuffer;
117		m_StencilBuffer = 0;
118	}
119
120	return;
121}
122
123void Surface :: Dispose() 
124{
125	if (GetCurrentContext() != 0) 
126	{
127		m_Disposed = true;
128	} 
129	else 
130	{
131		delete this;
132	}
133}
134
135void Surface :: SetCurrentContext(Context * context) 
136{
137	m_CurrentContext = context;
138	
139	if (context == 0 && m_Disposed) 
140	{
141		delete this;
142	}
143}
144
145namespace {
146	template <class T> void FillRect(T * base, const Rect & bufferRect,
147									 const Rect & fillRect,
148									 const T& value, const T& mask) 
149	{
150		Rect rect = Rect::Intersect(fillRect, bufferRect);
151		
152		base += fillRect.x + fillRect.y * bufferRect.width;
153		size_t gap = bufferRect.width - fillRect.width;
154		
155		size_t rows = fillRect.height;
156		T inverseMask = ~mask;
157		T maskedValue = value & mask;
158
159		while (rows--) 
160		{
161			for (size_t columns = fillRect.width; columns > 0; columns--) 
162			{
163				*base = (*base & inverseMask) | maskedValue;
164				++base;
165			}
166			
167			base += gap;
168		}
169	}
170
171	template <class T> void FillRect(T * base, const Rect & bufferRect, 
172									 const Rect & fillRect,
173									 const T& value) 
174	{
175		Rect rect = Rect::Intersect(fillRect, bufferRect);
176		
177		base += fillRect.x + fillRect.y * bufferRect.width;
178		size_t gap = bufferRect.width - fillRect.width;
179		
180		size_t rows = fillRect.height;
181		
182		while (rows--) 
183		{
184			for (size_t columns = fillRect.width; columns > 0; columns--) 
185			{
186				*base = value;
187				++base;
188			}
189			
190			base += gap;
191		}
192	}
193}
194
195void Surface :: ClearDepthBuffer(U16 depth, bool mask, const Rect& scissor) 
196{
197	if (!mask || !m_DepthBuffer)
198		return;
199	
200	FillRect(m_DepthBuffer, GetRect(), scissor, depth);
201}
202
203
204void Surface :: ClearStencilBuffer(U32 value, U32 mask, const Rect& scissor) 
205{
206	if (!mask || !m_StencilBuffer)
207		return;
208	
209	if (mask != ~0) 
210	{
211		FillRect(m_StencilBuffer, GetRect(), scissor, value, mask);
212	} 
213	else 
214	{
215		FillRect(m_StencilBuffer, GetRect(), scissor, value);
216	}
217}
218
219/*
220I32 Surface :: DepthBitsFromDepth(GLclampx depth) {
221  I32 result;
222	gppMul_16_32s(EGL_CLAMP(depth, EGL_FIXED_0, EGL_FIXED_1), 0xffffff, &result);
223	return result;
224}
225*/
226
227void Surface :: ClearColorBuffer(const Color & rgba, const Color & mask, 
228								 const Rect& scissor) 
229{
230	U16 color = rgba.ConvertTo565();
231	U16 colorMask = mask.ConvertTo565();
232
233	if (colorMask == 0xffff) 
234	{
235		FillRect(m_ColorBuffer, GetRect(), scissor, color);
236	} 
237	else 
238	{
239		FillRect(m_ColorBuffer, GetRect(), scissor, color, colorMask);
240	}
241
242	if (mask.A() && m_AlphaBuffer)
243		FillRect(m_AlphaBuffer, GetRect(), scissor, rgba.A());
244}
245
246
247/*
248 * For debugging
249 */
250
251#define BI_BITFIELDS 3
252
253typedef struct tagBITMAPINFOHEADER
254{
255	int biSize; 
256	long biWidth; 
257	long biHeight; 
258	short biPlanes; 
259	short biBitCount; 
260	int biCompression; 
261	int biSizeImage; 
262	long biXPelsPerMeter; 
263	long biYPelsPerMeter; 
264	int biClrUsed; 
265	int biClrImportant; 
266} BITMAPINFOHEADER;
267
268struct InfoHeader 
269{
270		BITMAPINFOHEADER bmiHeader;
271		short bmiColors[3];
272};
273
274typedef struct tagBITMAPFILEHEADER { 
275  short bfType; 
276  int bfSize; 
277  short bfReserved1; 
278  short bfReserved2; 
279  int bfOffBits; 
280} BITMAPFILEHEADER;
281
282void InitInfoHeader(struct InfoHeader *h, int width, int height) 
283{
284	h->bmiHeader.biSize = sizeof(h->bmiHeader);
285	h->bmiHeader.biWidth = width;
286	h->bmiHeader.biHeight = height;
287	h->bmiHeader.biPlanes = 1;
288	h->bmiHeader.biBitCount = 16;
289	h->bmiHeader.biCompression = BI_BITFIELDS;
290	h->bmiHeader.biSizeImage = width * height * sizeof(short);
291	h->bmiHeader.biXPelsPerMeter = 72 * 25;
292	h->bmiHeader.biYPelsPerMeter = 72 * 25;
293	h->bmiHeader.biClrUsed = 0;
294	h->bmiHeader.biClrImportant = 0;
295			
296	h->bmiColors[0] = 0xF800;
297	h->bmiColors[1] = 0x07E0;
298	h->bmiColors[2] = 0x001F;
299}
300
301#include <sys/types.h>
302#include <sys/stat.h>
303#include <fcntl.h>
304#include <unistd.h>
305
306bool Surface::Save(const char *filename)
307{
308	struct InfoHeader info;
309	BITMAPFILEHEADER header;
310	int fd= open(filename, O_RDWR|O_CREAT|O_TRUNC, 0666);
311	U16 *pixels;
312	U8 data;
313	int h;
314
315	InitInfoHeader(&info, GetWidth(), GetHeight());
316
317	header.bfType	   = 0x4d42;
318	header.bfSize	   = sizeof(BITMAPFILEHEADER) + sizeof(info) + 
319		info.bmiHeader.biSizeImage;
320	header.bfReserved1 = 0;
321	header.bfReserved2 = 0;
322	header.bfOffBits   = sizeof(BITMAPFILEHEADER) + sizeof(info);
323
324	printf("Saving image %s,  %ux%u, %u\n", filename, info.bmiHeader.biWidth, 
325		   info.bmiHeader.biHeight,
326		   info.bmiHeader.biSizeImage);
327	printf("size %u, offset %u\n", header.bfSize, header.bfOffBits);
328
329	if (fd < 3) 
330	{
331		fprintf(stderr, "Could not open file %s for writing\n", filename);
332		return false;
333	}
334
335	if (write(fd, (const char *)&header, sizeof(header)) != sizeof(header))
336	{
337		fprintf(stderr, "Error writing bitmap %s header\n", filename);
338		close(fd);
339		return false;
340	}
341
342	if (write(fd, (const char *)&info, sizeof(info)) != sizeof(info))
343	{
344		fprintf(stderr, "Error writing bitmap %s info\n", filename);
345		close(fd);
346		return false;
347	}
348
349	pixels = m_ColorBuffer;
350
351	for (h = GetHeight(); h; --h) 
352	{
353		if (write(fd, (const char *)pixels, sizeof(U16)*GetWidth()) !=
354			sizeof(U16)*GetWidth())
355		{
356			fprintf(stderr, "Error writing bitmap %s data\n", filename);
357			close(fd);
358			return false;
359		}
360
361		pixels += GetWidth();
362	}
363
364	close(fd);
365
366	return true;
367}
368