1 /*=============================================================================
2 Blobby Volley 2
3 Copyright (C) 2006 Jonathan Sieber (jonathan_sieber@yahoo.de)
4 Copyright (C) 2006 Daniel Knobe (daniel-knobe@web.de)
5 
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 =============================================================================*/
20 
21 /* header include */
22 #include "RenderManagerGL2D.h"
23 
24 /* includes */
25 #include "FileExceptions.h"
26 
27 /* implementation */
28 #if HAVE_LIBGL
29 
Texture(GLuint tex,int x,int y,int width,int height,int tw,int th)30 RenderManagerGL2D::Texture::Texture( GLuint tex, int x, int y, int width, int height, int tw, int th ) :
31 		w(width), h(height), texture(tex)
32 {
33 	assert(x + w <= tw);
34 	assert(y + h <= th);
35 	indices[0] = x / (float)tw;
36 	indices[1] = y / (float)th;
37 	indices[2] = (x + w) / (float)tw;
38 	indices[3] = y / (float)th;
39 	indices[4] = (x + w) / (float)tw;
40 	indices[5] = (y + h) / (float)th;
41 	indices[6] = x / (float)tw;
42 	indices[7] = (y + h) / (float)th;
43 }
44 int debugStateChanges = 0;
45 int debugBindTextureCount = 0;
46 
47 // wrapper functions for debugging purposes
glEnable(unsigned int flag)48 void RenderManagerGL2D::glEnable(unsigned int flag)
49 {
50 	if(mCurrentFlags.find(flag) != mCurrentFlags.end())
51 		return;
52 
53 	debugStateChanges++;
54 	::glEnable(flag);
55 	mCurrentFlags.insert(flag);
56 }
57 
glDisable(unsigned int flag)58 void RenderManagerGL2D::glDisable(unsigned int flag)
59 {
60 	if( mCurrentFlags.find(flag) == mCurrentFlags.end() )
61 		return;
62 
63 	debugStateChanges++;
64 	::glDisable(flag);
65 	mCurrentFlags.erase( mCurrentFlags.find(flag) );
66 }
67 
glBindTexture(GLuint texture)68 void RenderManagerGL2D::glBindTexture(GLuint texture)
69 {
70 	if(mCurrentTexture == texture)
71 		return;
72 
73 	debugBindTextureCount++;
74 	::glBindTexture(GL_TEXTURE_2D, texture);
75 	mCurrentTexture = texture;
76 }
77 
78 
79 
getNextPOT(int npot)80 int RenderManagerGL2D::getNextPOT(int npot)
81 {
82 	int pot = 1;
83 	while (pot < npot)
84 		pot *= 2;
85 
86 	return pot;
87 }
88 
loadTexture(SDL_Surface * surface,bool specular)89 GLuint RenderManagerGL2D::loadTexture(SDL_Surface *surface, bool specular)
90 {
91 	SDL_Surface* textureSurface;
92 	SDL_Surface* convertedTexture;
93 
94 	textureSurface = surface;
95 
96 	// Determine size of padding for 2^n format
97 	int oldX = textureSurface->w;
98 	int oldY = textureSurface->h;
99 	int paddedX = getNextPOT(textureSurface->w);
100 	int paddedY = getNextPOT(textureSurface->h);
101 
102 	SDL_Rect targetRect;
103 	targetRect.w = oldX;
104 	targetRect.h = oldY;
105 	targetRect.x = (paddedX - oldX) / 2;
106 	targetRect.y = (paddedY - oldY) / 2;
107 
108 	SDL_SetColorKey(textureSurface, SDL_TRUE,
109 			SDL_MapRGB(textureSurface->format, 0, 0, 0));
110 	convertedTexture =
111 		SDL_CreateRGBSurface(SDL_SWSURFACE,
112 			paddedX, paddedY, 32,
113 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
114 			0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
115 #else
116 			0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
117 #endif
118 	SDL_BlitSurface(textureSurface, 0, convertedTexture, &targetRect);
119 
120 	if (specular)
121 	{
122 		for (int y = 0; y < convertedTexture->h; ++y)
123 		{
124 			for (int x = 0; x < convertedTexture->w; ++x)
125 			{
126 				SDL_Color* pixel =
127 					&(((SDL_Color*)convertedTexture->pixels)
128 					[y * convertedTexture->w +x]);
129 				int luminance = int(pixel->r) * 5 - 4 * 256 - 138;
130 				luminance = luminance > 0 ? luminance : 0;
131 				luminance = luminance < 255 ? luminance : 255;
132 				pixel->r = luminance;
133 				pixel->g = luminance;
134 				pixel->b = luminance;
135 			}
136 		}
137 	}
138 
139 	GLuint texture;
140 	glGenTextures(1, &texture);
141 	glBindTexture(texture);
142 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
143 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
144 	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,
145 			convertedTexture->w, convertedTexture->h, 0, GL_RGBA,
146 			GL_UNSIGNED_BYTE, convertedTexture->pixels);
147 	SDL_FreeSurface(textureSurface);
148 	SDL_FreeSurface(convertedTexture);
149 
150 	return texture;
151 }
152 
drawQuad(float x,float y,float w,float h)153 void RenderManagerGL2D::drawQuad(float x, float y, float w, float h)
154 {
155 	glEnableClientState(GL_VERTEX_ARRAY);
156 	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
157 
158 	GLfloat vertices[] = {x - w / 2.f, y - h / 2.f,
159 	                      x + w / 2.f, y - h / 2.f,
160 	                      x + w / 2.f, y + h / 2.f,
161 	                      x - w / 2.f, y + h / 2.f};
162 
163 	GLfloat texCoords[] = {0.f, 0.f,
164 	                       1.f, 0.f,
165 	                       1.f, 1.f,
166 	                       0.f, 1.f};
167 
168 	glVertexPointer(2, GL_FLOAT, 0, vertices);
169 	glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
170 	glDrawArrays(GL_QUADS, 0, 4);
171 
172 	glDisableClientState(GL_VERTEX_ARRAY);
173 	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
174 }
175 
drawQuad(float x,float y,const Texture & tex)176 void RenderManagerGL2D::drawQuad(float x, float y, const Texture& tex) {
177 	glBindTexture(tex.texture);
178 
179 	glEnableClientState(GL_VERTEX_ARRAY);
180 	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
181 
182 	float w = tex.w;
183 	float h = tex.h;
184 
185 	GLfloat vertices[] = {x - w / 2.f, y - h / 2.f,
186 	                      x + w / 2.f, y - h / 2.f,
187 	                      x + w / 2.f, y + h / 2.f,
188 	                      x - w / 2.f, y + h / 2.f};
189 
190 	glVertexPointer(2, GL_FLOAT, 0, vertices);
191 	glTexCoordPointer(2, GL_FLOAT, 0, tex.indices);
192 	glDrawArrays(GL_QUADS, 0, 4);
193 
194 	glDisableClientState(GL_VERTEX_ARRAY);
195 	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
196 }
197 
RenderManagerGL2D()198 RenderManagerGL2D::RenderManagerGL2D()
199 	: RenderManager()
200 {
201 }
202 
createRenderManagerGL2D()203 RenderManager* RenderManager::createRenderManagerGL2D()
204 {
205 	return new RenderManagerGL2D();
206 }
207 
init(int xResolution,int yResolution,bool fullscreen)208 void RenderManagerGL2D::init(int xResolution, int yResolution, bool fullscreen)
209 {
210 	glDisable(GL_DEPTH_TEST);
211 	mCurrentFlags.insert(GL_MULTISAMPLE);
212 	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
213 	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
214 	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
215 	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
216 	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
217 
218 	// Set modesetting
219 	Uint32 screenFlags = SDL_WINDOW_OPENGL;
220 	if (fullscreen)
221 		screenFlags |= SDL_WINDOW_FULLSCREEN;
222 
223 	// Create window
224 	mWindow = SDL_CreateWindow(AppTitle,
225 		SDL_WINDOWPOS_UNDEFINED,
226 		SDL_WINDOWPOS_UNDEFINED,
227 		xResolution, yResolution,
228 		screenFlags);
229 
230 	// Set icon
231 	SDL_Surface* icon = loadSurface("Icon.bmp");
232 	SDL_SetColorKey(icon, SDL_TRUE,
233 			SDL_MapRGB(icon->format, 0, 0, 0));
234 	SDL_SetWindowIcon(mWindow, icon);
235 	SDL_FreeSurface(icon);
236 
237 	// Create gl context
238 	mGlContext = SDL_GL_CreateContext(mWindow);
239 
240 	SDL_ShowCursor(0);
241 	glDisable(GL_MULTISAMPLE);
242 
243 	mLeftBlobColor = Color(255, 0, 0);
244 	mRightBlobColor = Color(0, 255, 0);
245 	glEnable(GL_TEXTURE_2D);
246 
247 	// Load background
248 	SDL_Surface* bgSurface = loadSurface("backgrounds/strand2.bmp");
249 	BufferedImage* bgBufImage = new BufferedImage;
250 	bgBufImage->w = getNextPOT(bgSurface->w);
251 	bgBufImage->h = getNextPOT(bgSurface->h);
252 	bgBufImage->glHandle = loadTexture(bgSurface, false);
253 	mBackground = bgBufImage->glHandle;
254 	mImageMap["background"] = bgBufImage;
255 
256 	mBallShadow = loadTexture(loadSurface("gfx/schball.bmp"), false);
257 
258 	for (int i = 1; i <= 16; ++i)
259 	{
260 		char filename[64];
261 		sprintf(filename, "gfx/ball%02d.bmp", i);
262 		GLuint ballImage = loadTexture(loadSurface(filename), false);
263 		mBall.push_back(ballImage);
264 	}
265 
266 	for (int i = 1; i <= 5; ++i)
267 	{
268 		char filename[64];
269 		sprintf(filename, "gfx/blobbym%d.bmp", i);
270 		GLuint blobImage = loadTexture(loadSurface(filename), false);
271 		mBlob.push_back(blobImage);
272 		sprintf(filename, "gfx/blobbym%d.bmp", i);
273 		GLuint blobSpecular = loadTexture(loadSurface(filename), true);
274 		mBlobSpecular.push_back(blobSpecular);
275 		sprintf(filename, "gfx/sch1%d.bmp", i);
276 		GLuint blobShadow = loadTexture(loadSurface(filename), false);
277 		mBlobShadow.push_back(blobShadow);
278 	}
279 
280 	// create text base textures
281 	SDL_Surface* textbase = createEmptySurface(2048, 32);
282 	SDL_Surface* hltextbase = createEmptySurface(2048, 32);
283 
284 	int x = 0;
285 	int sx = 0;
286 
287 	for (int i = 0; i <= 54; ++i)
288 	{
289 		char filename[64];
290 		sprintf(filename, "gfx/font%02d.bmp", i);
291 		SDL_Surface* fontSurface = loadSurface(filename);
292 
293 		SDL_Surface* highlight = highlightSurface(fontSurface, 60);
294 
295 		SDL_Rect r = {(Uint16)x, 0, (Uint16)fontSurface->w, (Uint16)fontSurface->h};
296 		SDL_BlitSurface(fontSurface, 0, textbase, &r);
297 		SDL_BlitSurface(highlight, 0, hltextbase, &r);
298 		r.x = sx;
299 		r.y = 0;
300 		Texture s = Texture(0, x, 0, fontSurface->w, fontSurface->h, 2048, 32);
301 		mFont.push_back(s);
302 		mHighlightFont.push_back(s);
303 
304 		x += fontSurface->w;
305 
306 		SDL_FreeSurface(fontSurface);
307 	}
308 
309 	GLuint texture =  loadTexture(textbase, false);
310 	GLuint hltexture =  loadTexture(hltextbase, false);
311 	for (unsigned int i = 0; i < mFont.size(); ++i)
312 	{
313 		mFont[i].texture = texture;
314 		mHighlightFont[i].texture = hltexture;
315 	}
316 
317 	mParticle = loadTexture(loadSurface("gfx/blood.bmp"), false);
318 
319 	glViewport(0, 0, xResolution, yResolution);
320 	glMatrixMode(GL_PROJECTION);
321 	glLoadIdentity();
322 	glOrtho(0, 800, 600, 0, -1.0, 1.0);
323 	glMatrixMode(GL_MODELVIEW);
324 	glLoadIdentity();
325 
326 	glEnable(GL_TEXTURE_2D);
327 
328 	glAlphaFunc(GL_GREATER, 0.5);
329 	glEnable(GL_ALPHA_TEST);
330 }
331 
deinit()332 void RenderManagerGL2D::deinit()
333 {
334 	glDeleteTextures(1, &mBackground);
335 	glDeleteTextures(mBall.size(), &mBall[0]);
336 	glDeleteTextures(1, &mBallShadow);
337 	glDeleteTextures(mBlob.size(), &mBlob[0]);
338 	glDeleteTextures(mBlobSpecular.size(), &mBlobSpecular[0]);
339 	glDeleteTextures(mBlobShadow.size(), &mBlobShadow[0]);
340 	glDeleteTextures(1/*mFont.size()*/, &mFont[0].texture);
341 	glDeleteTextures(/*mHighlightFont.size()*/1, &mHighlightFont[0].texture);
342 
343 	for (std::map<std::string, BufferedImage*>::iterator iter = mImageMap.begin();
344 		iter != mImageMap.end(); ++iter)
345 	{
346 		glDeleteTextures(1, &(*iter).second->glHandle);
347 		delete iter->second;
348 	}
349 
350 	glDeleteTextures(1, &mParticle);
351 
352 	SDL_GL_DeleteContext(mGlContext);
353 	SDL_DestroyWindow(mWindow);
354 }
355 
draw()356 void RenderManagerGL2D::draw()
357 {
358 	if (!mDrawGame)
359 		return;
360 
361 	// Background
362 	glDisable(GL_ALPHA_TEST);
363 	glColor4f(1.0, 1.0, 1.0, 1.0);
364 	glBindTexture(mBackground);
365 	glLoadIdentity();
366 	drawQuad(400.0, 300.0, 1024.0, 1024.0);
367 
368 
369 	if(mShowShadow)
370 	{
371 		// Generic shadow settings
372 
373 		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
374 		glEnable(GL_BLEND);
375 
376 		// Blob shadows
377 		Vector2 pos;
378 
379 		pos = blobShadowPosition(mLeftBlobPosition);
380 		glColor4ub(mLeftBlobColor.r, mLeftBlobColor.g, mLeftBlobColor.b, 128);
381 		glBindTexture(mBlobShadow[int(mLeftBlobAnimationState)  % 5]);
382 		drawQuad(pos.x, pos.y, 128.0, 32.0);
383 
384 		pos = blobShadowPosition(mRightBlobPosition);
385 		glColor4ub(mRightBlobColor.r, mRightBlobColor.g, mRightBlobColor.b, 128);
386 		glBindTexture(mBlobShadow[int(mRightBlobAnimationState)  % 5]);
387 		drawQuad(pos.x, pos.y, 128.0, 32.0);
388 
389 		// Ball shadow
390 		pos = ballShadowPosition(mBallPosition);
391 		glColor4f(1.0, 1.0, 1.0, 0.5);
392 		glBindTexture(mBallShadow);
393 		drawQuad(pos.x, pos.y, 128.0, 32.0);
394 
395 		glDisable(GL_BLEND);
396 	}
397 
398 	glEnable(GL_ALPHA_TEST);
399 
400 	// General object settings
401 	glBlendFunc(GL_SRC_ALPHA, GL_ONE);
402 	// The Ball
403 
404 	glColor4f(1.0, 1.0, 1.0, 1.0);
405 	glBindTexture(mBall[int(mBallRotation / M_PI / 2 * 16) % 16]);
406 /*
407 	float opacity = 0.0;
408 	for (std::list<Vector2>::iterator iter = mLastBallStates.begin();
409 		iter != mLastBallStates.end(); ++iter)
410 	{
411 //		glColor4f(1.0 / MotionBlurIterations,
412 //			1.0 / MotionBlurIterations, 1.0 / MotionBlurIterations, 1.0 - opacity);
413 		glColor4f(1.0, 1.0, 1.0, opacity);
414 
415 
416 		Vector2& ballPosition = *iter;
417 */
418 		drawQuad(mBallPosition.x, mBallPosition.y, 64.0, 64.0);
419 
420 /*
421 		opacity += 0.1;
422 	}
423 	if (mLastBallStates.size() > MotionBlurIterations)
424 			mLastBallStates.pop_back();
425 	glDisable(GL_BLEND);
426 */
427 
428 	// blob normal
429 	// left blob
430 	glBindTexture(mBlob[int(mLeftBlobAnimationState)  % 5]);
431 	glColor3ubv(mLeftBlobColor.val);
432 	drawQuad(mLeftBlobPosition.x, mLeftBlobPosition.y, 128.0, 128.0);
433 
434 	// right blob
435 	glBindTexture(mBlob[int(mRightBlobAnimationState)  % 5]);
436 	glColor3ubv(mRightBlobColor.val);
437 	drawQuad(mRightBlobPosition.x, mRightBlobPosition.y, 128.0, 128.0);
438 
439 	// blob specular
440 	glEnable(GL_BLEND);
441 	glColor4f(1.0, 1.0, 1.0, 1.0);
442 	// left blob
443 	glBindTexture(mBlobSpecular[int(mLeftBlobAnimationState)  % 5]);
444 	drawQuad(mLeftBlobPosition.x, mLeftBlobPosition.y, 128.0, 128.0);
445 
446 	// right blob
447 	glBindTexture(mBlobSpecular[int(mRightBlobAnimationState)  % 5]);
448 	drawQuad(mRightBlobPosition.x, mRightBlobPosition.y, 128.0, 128.0);
449 
450 	glDisable(GL_BLEND);
451 
452 
453 	// Ball marker
454 	glDisable(GL_ALPHA_TEST);
455 	glDisable(GL_TEXTURE_2D);
456 	GLubyte markerColor = SDL_GetTicks() % 1000 >= 500 ? 255 : 0;
457 	glColor3ub(markerColor, markerColor, markerColor);
458 	drawQuad(mBallPosition.x, 7.5, 5.0, 5.0);
459 
460 	// Mouse marker
461 
462 	// Position relativ zu BallMarker
463 	drawQuad(mMouseMarkerPosition, 592.5, 5.0, 5.0);
464 
465 	glEnable(GL_TEXTURE_2D);
466 	glEnable(GL_ALPHA_TEST);
467 }
468 
setBackground(const std::string & filename)469 bool RenderManagerGL2D::setBackground(const std::string& filename)
470 {
471 	try
472 	{
473 		SDL_Surface* newSurface = loadSurface(filename);
474 		glDeleteTextures(1, &mBackground);
475 		delete mImageMap["background"];
476 		BufferedImage *imgBuffer = new BufferedImage;
477 		imgBuffer->w = getNextPOT(newSurface->w);
478 		imgBuffer->h = getNextPOT(newSurface->h);
479 		imgBuffer->glHandle = loadTexture(newSurface, false);
480 		mBackground = imgBuffer->glHandle;
481 		mImageMap["background"] = imgBuffer;
482 	}
483 	catch (FileLoadException)
484 	{
485 		return false;
486 	}
487 	return true;
488 }
489 
setBlobColor(int player,Color color)490 void RenderManagerGL2D::setBlobColor(int player, Color color)
491 {
492 	if (player == LEFT_PLAYER)
493 		mLeftBlobColor = color;
494 
495 	if (player == RIGHT_PLAYER)
496 		mRightBlobColor = color;
497 }
498 
showShadow(bool shadow)499 void RenderManagerGL2D::showShadow(bool shadow)
500 {
501 	mShowShadow = shadow;
502 }
503 
setBall(const Vector2 & position,float rotation)504 void RenderManagerGL2D::setBall(const Vector2& position, float rotation)
505 {
506 	mBallPosition = position;
507 	mBallRotation = rotation;
508 
509 	static int mbCounter = 0;
510 	mbCounter++;
511 	if (mbCounter > 1)
512 	{
513 		mLastBallStates.push_front(position);
514 		mbCounter = 0;
515 	}
516 }
517 
setBlob(int player,const Vector2 & position,float animationState)518 void RenderManagerGL2D::setBlob(int player, const Vector2& position, float animationState)
519 {
520 	if (player == LEFT_PLAYER)
521 	{
522 		mLeftBlobPosition = position;
523 		mLeftBlobAnimationState = animationState;
524 	}
525 
526 	if (player == RIGHT_PLAYER)
527 	{
528 		mRightBlobPosition = position;
529 		mRightBlobAnimationState = animationState;
530 	}
531 }
532 
drawText(const std::string & text,Vector2 position,unsigned int flags)533 void RenderManagerGL2D::drawText(const std::string& text, Vector2 position, unsigned int flags)
534 {
535 	glEnable(GL_TEXTURE_2D);
536 	glEnable(GL_ALPHA_TEST);
537 	glDisable(GL_BLEND);
538 
539 	glColor4f(1.0, 1.0, 1.0, 1.0);
540 	int FontSize = (flags & TF_SMALL_FONT ? FONT_WIDTH_SMALL : FONT_WIDTH_NORMAL);
541 
542 	float x = position.x - (FontSize / 2);
543 	float y = position.y + (FontSize / 2);
544 
545 	for (auto iter = text.cbegin(); iter != text.cend(); )
546 
547 	{
548 		int index = getNextFontIndex(iter);
549 
550 		if (flags & TF_OBFUSCATE)
551 			index = FONT_INDEX_ASTERISK;
552 
553 		x += FontSize;
554 		if (flags & TF_SMALL_FONT)
555 		{
556 			if (flags & TF_HIGHLIGHT)
557 			{
558 				int charWidth = mHighlightFont[index].w;
559 				int charHeight = mHighlightFont[index].h;
560 				mHighlightFont[index].w = FONT_WIDTH_SMALL;
561 				mHighlightFont[index].h = FONT_WIDTH_SMALL;
562 				drawQuad(x, y, mHighlightFont[index]);
563 				mHighlightFont[index].w = charWidth;
564 				mHighlightFont[index].h = charHeight;
565 			}
566 			else
567 			{
568 				int charWidth = mFont[index].w;
569 				int charHeight = mFont[index].h;
570 				mFont[index].w = FONT_WIDTH_SMALL;
571 				mFont[index].h = FONT_WIDTH_SMALL;
572 				drawQuad(x, y, mFont[index]);
573 				mFont[index].w = charWidth;
574 				mFont[index].h = charHeight;
575 			}
576 		}
577 		else
578 		{
579 			if (flags & TF_HIGHLIGHT)
580 				drawQuad(x, y, mHighlightFont[index]);
581 			else
582 				drawQuad(x, y, mFont[index]);
583 		}
584 	}
585 }
586 
drawImage(const std::string & filename,Vector2 position,Vector2 size)587 void RenderManagerGL2D::drawImage(const std::string& filename, Vector2 position, Vector2 size)
588 {
589 	glEnable(GL_TEXTURE_2D);
590 	glEnable(GL_ALPHA_TEST);
591 	glDisable(GL_BLEND);
592 
593 	BufferedImage* imageBuffer = mImageMap[filename];
594 	if (!imageBuffer)
595 	{
596 		imageBuffer = new BufferedImage;
597 		SDL_Surface* newSurface = loadSurface(filename);
598 		imageBuffer->w = getNextPOT(newSurface->w);
599 		imageBuffer->h = getNextPOT(newSurface->h);
600 		imageBuffer->glHandle = loadTexture(newSurface, false);
601 		mImageMap[filename] = imageBuffer;
602 	}
603 
604 	glColor4f(1.0, 1.0, 1.0, 1.0);
605 	glDisable(GL_BLEND);
606 	//glLoadIdentity();
607 	//glTranslatef(position.x , position.y, 0.0);
608 	glBindTexture(imageBuffer->glHandle);
609 	drawQuad(position.x, position.y, imageBuffer->w, imageBuffer->h);
610 }
611 
drawOverlay(float opacity,Vector2 pos1,Vector2 pos2,Color col)612 void RenderManagerGL2D::drawOverlay(float opacity, Vector2 pos1, Vector2 pos2, Color col)
613 {
614 	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
615 	glDisable(GL_TEXTURE_2D);
616 	glDisable(GL_ALPHA_TEST);
617 	glEnable(GL_BLEND);
618 
619 	glColor4f(col.r, col.g, col.b, opacity);
620 	//glLoadIdentity();
621 	glBegin(GL_QUADS);
622 		glVertex2f(pos1.x, pos1.y);
623 		glVertex2f(pos1.x, pos2.y);
624 		glVertex2f(pos2.x, pos2.y);
625 		glVertex2f(pos2.x, pos1.y);
626 	glEnd();
627 }
628 
drawBlob(const Vector2 & pos,const Color & col)629 void RenderManagerGL2D::drawBlob(const Vector2& pos, const Color& col)
630 {
631 	glEnable(GL_TEXTURE_2D);
632 	glEnable(GL_ALPHA_TEST);
633 	glDisable(GL_BLEND);
634 
635 	glBlendFunc(GL_SRC_ALPHA, GL_ONE);
636 
637 	//glLoadIdentity();
638 	//glTranslatef(pos.x, pos.y, 0.6);
639 	glBindTexture(mBlob[0]);
640 	glColor3ubv(col.val);
641 	drawQuad(pos.x, pos.y, 128.0, 128.0);
642 
643 	glEnable(GL_BLEND);
644 	glColor4f(1.0, 1.0, 1.0, 1.0);
645 	glBindTexture(mBlobSpecular[0]);
646 	drawQuad(pos.x, pos.y, 128.0, 128.0);
647 	glDisable(GL_BLEND);
648 }
649 
startDrawParticles()650 void RenderManagerGL2D::startDrawParticles()
651 {
652 	glEnable(GL_TEXTURE_2D);
653 	glEnable(GL_ALPHA_TEST);
654 	glDisable(GL_BLEND);
655 
656 	glBlendFunc(GL_SRC_ALPHA, GL_ONE);
657 	glBindTexture(mParticle);
658 	glBegin(GL_QUADS);
659 }
660 
drawParticle(const Vector2 & pos,int player)661 void RenderManagerGL2D::drawParticle(const Vector2& pos, int player)
662 {
663 	//glLoadIdentity();
664 	//glTranslatef(pos.x, pos.y, 0.6);
665 
666 	if (player == LEFT_PLAYER)
667 		glColor3ubv(mLeftBlobColor.val);
668 	if (player == RIGHT_PLAYER)
669 		glColor3ubv(mRightBlobColor.val);
670 	if (player > 1)
671 		glColor3ubv(Color(255, 0, 0).val);
672 
673 	float w = 16.0;
674 	float h = 16.0;
675 	glTexCoord2f(0.0, 0.0);
676 	glVertex2f(pos.x - w / 2.0, pos.y - h / 2.0);
677 	glTexCoord2f(1.0, 0.0);
678 	glVertex2f(pos.x + w / 2.0, pos.y - h / 2.0);
679 	glTexCoord2f(1.0, 1.0);
680 	glVertex2f(pos.x + w / 2.0, pos.y + h / 2.0);
681 	glTexCoord2f(0.0, 1.0);
682 	glVertex2f(pos.x - w / 2.0, pos.y + h / 2.0);
683 }
684 
endDrawParticles()685 void RenderManagerGL2D::endDrawParticles()
686 {
687 	glEnd();
688 }
689 
refresh()690 void RenderManagerGL2D::refresh()
691 {
692 	//std::cout << debugStateChanges << "\n";
693 	SDL_GL_SwapWindow(mWindow);
694 	debugStateChanges = 0;
695 	//std::cerr << debugBindTextureCount << "\n";
696 	debugBindTextureCount = 0;
697 
698 }
699 
700 #else
701 
createRenderManagerGL2D()702 RenderManager* RenderManager::createRenderManagerGL2D()
703 {
704 	std::cerr << "OpenGL not available! Falling back to SDL renderer" <<
705 		std::endl;
706 	return RenderManager::createRenderManagerSDL();
707 }
708 
709 
710 #endif
711