Browse Source

Added working SpriteBatch.

rude 16 years ago
parent
commit
4f32377efa

+ 16 - 0
platform/msvc2008/love.vcproj

@@ -961,6 +961,14 @@
 						RelativePath="..\..\src\modules\graphics\opengl\ImageFont.h"
 						>
 					</File>
+					<File
+						RelativePath="..\..\src\modules\graphics\opengl\SpriteBatch.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\src\modules\graphics\opengl\SpriteBatch.h"
+						>
+					</File>
 					<File
 						RelativePath="..\..\src\modules\graphics\opengl\TrueTypeFont.cpp"
 						>
@@ -1081,6 +1089,14 @@
 						RelativePath="..\..\src\modules\graphics\opengl\wrap_Image.h"
 						>
 					</File>
+					<File
+						RelativePath="..\..\src\modules\graphics\opengl\wrap_SpriteBatch.cpp"
+						>
+					</File>
+					<File
+						RelativePath="..\..\src\modules\graphics\opengl\wrap_SpriteBatch.h"
+						>
+					</File>
 				</Filter>
 			</Filter>
 			<Filter

+ 0 - 2
src/modules/graphics/opengl/Graphics.cpp

@@ -428,12 +428,10 @@ namespace opengl
 		return font;
 	}
 
-	/*
 	SpriteBatch * Graphics::newSpriteBatch(Image * image, int size, int usage)
 	{
 		return new SpriteBatch(image, size, usage);
 	}
-	*/
 
 	void Graphics::setColor(Color c)
 	{

+ 2 - 1
src/modules/graphics/opengl/Graphics.h

@@ -37,6 +37,7 @@
 #include "TrueTypeFont.h"
 #include "ImageFont.h"
 #include "Frame.h"
+#include "SpriteBatch.h"
 
 namespace love
 {
@@ -250,7 +251,7 @@ namespace opengl
 		**/
 		Font * newImageFont(Image * image, const char * glyphs, float spacing = 1);
 		
-		//SpriteBatch * newSpriteBatch(Image * image, int size, int usage);
+		SpriteBatch * newSpriteBatch(Image * image, int size, int usage);
 			
 		/**
 		* Sets the foreground color.

+ 149 - 0
src/modules/graphics/opengl/SpriteBatch.cpp

@@ -0,0 +1,149 @@
+/**
+* Copyright (c) 2006-2009 LOVE Development Team
+* 
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* 
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 
+* 1. The origin of this software must not be misrepresented; you must not
+*    claim that you wrote the original software. If you use this software
+*    in a product, an acknowledgment in the product documentation would be
+*    appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+*    misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+**/
+
+#include "SpriteBatch.h"
+
+// STD
+#include <iostream>
+
+// LOVE
+#include "Image.h"
+
+namespace love
+{
+namespace graphics
+{
+namespace opengl
+{
+	SpriteBatch::SpriteBatch(Image * image, int size, int usage)
+		: image(image), size(size), next(0), usage(usage)
+	{
+		image->retain();
+
+		vertices = new vertex[size*4];
+		indices = new GLushort[size*6];
+
+		for(int i = 0; i<size; i++)
+		{
+			indices[i*6+0] = 0+(i*4);
+			indices[i*6+1] = 1+(i*4);
+			indices[i*6+2] = 2+(i*4);
+
+			indices[i*6+3] = 0+(i*4);
+			indices[i*6+4] = 2+(i*4);
+			indices[i*6+5] = 3+(i*4);
+		}
+
+		// Find out which OpenGL VBO usage hint to use.
+		gl_usage = GL_STREAM_DRAW;
+		gl_usage = (usage == USAGE_DYNAMIC) ? GL_DYNAMIC_DRAW : gl_usage;
+		gl_usage = (usage == USAGE_STATIC) ? GL_STATIC_DRAW : gl_usage;
+		gl_usage = (usage == USAGE_STREAM) ? GL_STREAM_DRAW : gl_usage;
+
+		glGenBuffers(2, vbo);
+
+		glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
+		glBufferData(GL_ARRAY_BUFFER, sizeof(vertex)*size*4, vertices, gl_usage);
+		glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[1]);
+		glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*size*6, indices, GL_STATIC_DRAW);
+		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+	}
+
+	SpriteBatch::~SpriteBatch()
+	{
+		image->release();
+
+		if(vbo[0] != 0 && vbo[1] != 0)
+			glDeleteBuffers(2, vbo);
+
+		delete [] vertices;
+		delete [] indices;
+	}
+
+	void SpriteBatch::add(float x, float y, float a, float sx, float sy, float ox, float oy)
+	{
+		// Only do this if there's a free slot.
+		if(next < size)
+		{
+			// Get a pointer to the correct insertion position.
+			vertex * v = vertices + next*4;
+
+			memcpy(v, image->getVertices(), sizeof(vertex)*4);
+
+			// Transform.
+			Matrix t;
+			t.translate(x, y);
+			t.scale(sx, sy);
+			t.rotate(a);
+			t.transform(v, v, 4);
+
+			glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
+			glBufferSubData(GL_ARRAY_BUFFER, (next*4)*sizeof(vertex), sizeof(vertex)*4, v);
+			glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+			// Increment counter.
+			next++;			
+		}
+	}
+
+	void SpriteBatch::clear()
+	{
+		// Reset the position of the next index.
+		next = 0;
+	}
+
+	void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float ox, float oy) const
+	{
+		glPushMatrix();
+		glTranslatef(x, y, 0);
+
+		image->bind();
+
+		// Enable vertex arrays.
+		glEnableClientState(GL_VERTEX_ARRAY);
+		glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+		glEnableClientState(GL_COLOR_ARRAY);
+
+		// Bind the VBO buffer.
+		glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
+		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[1]);
+		glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(vertex), (GLvoid*)0);
+		glVertexPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid*)(sizeof(unsigned char)*4));
+		glTexCoordPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid*)(sizeof(unsigned char)*4+sizeof(float)*2));
+		
+		glDrawElements(GL_TRIANGLES, next*6, GL_UNSIGNED_SHORT, 0);
+
+		// Disable vertex arrays.
+		glDisableClientState(GL_COLOR_ARRAY);
+		glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+		glDisableClientState(GL_VERTEX_ARRAY);
+
+		glBindBuffer(GL_ARRAY_BUFFER, 0);
+		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+		glPopMatrix();
+	}
+
+} // opengl
+} // graphics
+} // love

+ 97 - 0
src/modules/graphics/opengl/SpriteBatch.h

@@ -0,0 +1,97 @@
+/**
+* Copyright (c) 2006-2009 LOVE Development Team
+* 
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* 
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 
+* 1. The origin of this software must not be misrepresented; you must not
+*    claim that you wrote the original software. If you use this software
+*    in a product, an acknowledgment in the product documentation would be
+*    appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+*    misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+**/
+
+#ifndef LOVE_GRAPHICS_OPENGL_SPRITE_BATCH_H
+#define LOVE_GRAPHICS_OPENGL_SPRITE_BATCH_H
+
+// C
+#include <cstring>
+
+// LOVE
+#include <common/math.h>
+#include <common/Object.h>
+#include <common/Vector.h>
+#include <common/Matrix.h>
+#include <graphics/Drawable.h>
+
+// OpenGL
+#include "GLee.h"
+#include <SDL/SDL_opengl.h>
+
+namespace love
+{
+namespace graphics
+{
+namespace opengl
+{
+	// Forward declarations.
+	class Image;
+
+	class SpriteBatch : public Drawable
+	{
+	private:
+
+		Image * image;
+
+		// Max number of sprites in the batch.
+		int size;
+
+		// The next free element.
+		int next;
+
+		GLuint vbo[2];
+
+		// Vertex Buffer.
+		vertex * vertices;
+
+		// Index buffer.
+		GLushort * indices;
+
+		// The uage hint for the vertex buffer.
+		int usage;
+		int gl_usage;
+
+	public:
+
+		enum UsageHint
+		{
+			USAGE_DYNAMIC,
+			USAGE_STATIC,
+			USAGE_STREAM
+		};
+
+		SpriteBatch(Image * image, int size, int usage);
+		virtual ~SpriteBatch();
+
+		void add(float x, float y, float a, float sx, float sy, float ox, float oy);
+		//void adds(float x, float y, float a, float sx, float sy, float ox, float oy, float rx, float ry, float rw, float rh);
+		//void addf(float x, float y, float a, float sx, float sy, float ox, float oy, Frame * frame);
+		void clear();
+
+		// Implements Drawable.
+		void draw(float x, float y, float angle, float sx, float sy, float ox, float oy) const;
+
+	}; // SpriteBatch
+
+} // opengl
+} // graphics
+} // love
+
+#endif // LOVE_GRAPHICS_OPENGL_SPRITE_BATCH_H

+ 4 - 5
src/modules/graphics/opengl/wrap_Graphics.cpp

@@ -17,6 +17,7 @@
 *    misrepresented as being the original software.
 * 3. This notice may not be removed or altered from any source distribution.
 **/
+
 #include "wrap_Graphics.h"
 
 namespace love
@@ -218,17 +219,15 @@ namespace opengl
 		return 1;
 	}
 
-	/*
 	int _wrap_newSpriteBatch(lua_State * L)
 	{
 		Image * image = luax_checktype<Image>(L, 1, "Image", LOVE_GRAPHICS_IMAGE_BITS);
 		int size = luaL_optint(L, 2, 1000);
-		int usage = luaL_optint(L, 3, USAGE_ARRAY);
+		int usage = luaL_optint(L, 3, SpriteBatch::USAGE_DYNAMIC);
 		SpriteBatch * t = instance->newSpriteBatch(image, size, usage);
 		luax_newtype(L, "SpriteBatch", LOVE_GRAPHICS_SPRITE_BATCH_BITS, (void*)t);
 		return 1;
 	}
-	*/
 
 	int _wrap_setColor(lua_State * L)
 	{
@@ -686,7 +685,7 @@ namespace opengl
 		{ "newFrame", _wrap_newFrame },
 		{ "newFont", _wrap_newFont },
 		{ "newImageFont", _wrap_newImageFont },
-		//{ "newSpriteBatch", _wrap_newSpriteBatch },
+		{ "newSpriteBatch", _wrap_newSpriteBatch },
 
 		{ "setColor", _wrap_setColor },
 		{ "getColor", _wrap_getColor },
@@ -757,7 +756,7 @@ namespace opengl
 		wrap_Font_open, 
 		wrap_Image_open, 
 		wrap_Frame_open, 
-		//wrap_SpriteBatch_open, 
+		wrap_SpriteBatch_open, 
 		0		
 	};
 

+ 1 - 3
src/modules/graphics/opengl/wrap_Graphics.h

@@ -25,6 +25,7 @@
 #include "wrap_Font.h"
 #include "wrap_Image.h"
 #include "wrap_Frame.h"
+#include "wrap_SpriteBatch.h"
 #include "Graphics.h"
 
 namespace love
@@ -46,14 +47,11 @@ namespace opengl
 	int _wrap_isCreated(lua_State * L);
 	int _wrap_setScissor(lua_State * L);
 	int _wrap_getScissor(lua_State * L);
-	int _wrap_newColor(lua_State * L);
 	int _wrap_newImage(lua_State * L);
 	int _wrap_newFrame(lua_State * L);
-	int _wrap_newAnimation(lua_State * L);
 	int _wrap_newFont(lua_State * L);
 	int _wrap_newImageFont(lua_State * L);
 	int _wrap_newSpriteBatch(lua_State * L);
-	int _wrap_newVertexBuffer(lua_State * L);
 	int _wrap_setColor(lua_State * L);
 	int _wrap_getColor(lua_State * L);
 	int _wrap_setBackgroundColor(lua_State * L);

+ 69 - 0
src/modules/graphics/opengl/wrap_SpriteBatch.cpp

@@ -0,0 +1,69 @@
+/**
+* Copyright (c) 2006-2009 LOVE Development Team
+* 
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* 
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 
+* 1. The origin of this software must not be misrepresented; you must not
+*    claim that you wrote the original software. If you use this software
+*    in a product, an acknowledgment in the product documentation would be
+*    appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+*    misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+**/
+
+#include "wrap_SpriteBatch.h"
+
+namespace love
+{
+namespace graphics
+{
+namespace opengl
+{
+	SpriteBatch * luax_checkspritebatch(lua_State * L, int idx)
+	{
+		return luax_checktype<SpriteBatch>(L, idx, "SpriteBatch", LOVE_GRAPHICS_SPRITE_BATCH_BITS); 
+	}
+
+	int _wrap_SpriteBatch_add(lua_State * L)
+	{
+		SpriteBatch * t = luax_checkspritebatch(L, 1);
+		float x = (float)luaL_optnumber(L, 2, 0.0f);
+		float y = (float)luaL_optnumber(L, 3, 0.0f);
+		float angle = (float)luaL_optnumber(L, 4, 0.0f);
+		float sx = (float)luaL_optnumber(L, 5, 1.0f);
+		float sy = (float)luaL_optnumber(L, 6, sx);
+		float ox = (float)luaL_optnumber(L, 7, 0);
+		float oy = (float)luaL_optnumber(L, 8, 0);
+		t->add(x, y, angle, sx, sy, ox, oy);
+		return 0;
+	}
+
+	int _wrap_SpriteBatch_clear(lua_State * L)
+	{
+		SpriteBatch * t = luax_checkspritebatch(L, 1);
+		t->clear();
+		return 0;
+	}
+
+	static const luaL_Reg wrap_SpriteBatch_functions[] = {
+		{ "add", _wrap_SpriteBatch_add },
+		{ "clear", _wrap_SpriteBatch_clear },
+		{ 0, 0 }
+	};
+
+	int wrap_SpriteBatch_open(lua_State * L)
+	{
+		luax_register_type(L, "SpriteBatch", wrap_SpriteBatch_functions);
+		return 0;
+	}
+
+} // opengl
+} // graphics
+} // love

+ 42 - 0
src/modules/graphics/opengl/wrap_SpriteBatch.h

@@ -0,0 +1,42 @@
+/**
+* Copyright (c) 2006-2009 LOVE Development Team
+* 
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+* 
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+* 
+* 1. The origin of this software must not be misrepresented; you must not
+*    claim that you wrote the original software. If you use this software
+*    in a product, an acknowledgment in the product documentation would be
+*    appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+*    misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+**/
+
+#ifndef LOVE_GRAPHICS_OPENGL_WRAP_SPRITE_BATCH_H
+#define LOVE_GRAPHICS_OPENGL_WRAP_SPRITE_BATCH_H
+
+#include <common/runtime.h>
+#include "SpriteBatch.h"
+
+namespace love
+{
+namespace graphics
+{
+namespace opengl
+{
+	SpriteBatch * luax_checkspritebatch(lua_State * L, int idx);
+	int _wrap_SpriteBatch_add(lua_State * L);
+	int _wrap_SpriteBatch_clear(lua_State * L);
+	int wrap_SpriteBatch_open(lua_State * L);
+
+} // opengl
+} // graphics
+} // love
+
+#endif // LOVE_GRAPHICS_OPENGL_WRAP_SPRITE_BATCH_H