Browse Source

Added first review of vrld's FBO patch

Bart van Strien 15 years ago
parent
commit
f87738edb5

+ 2 - 0
src/common/types.h

@@ -52,6 +52,7 @@ namespace love
 		GRAPHICS_PARTICLE_SYSTEM_ID,
 		GRAPHICS_SPRITE_BATCH_ID,
 		GRAPHICS_VERTEX_BUFFER_ID,
+		GRAPHICS_FBO_ID,
 
 		// Image
 		IMAGE_IMAGE_DATA_ID,
@@ -116,6 +117,7 @@ namespace love
 	const bits GRAPHICS_PARTICLE_SYSTEM_T = (bits(1) << GRAPHICS_PARTICLE_SYSTEM_ID) | GRAPHICS_DRAWABLE_T;
 	const bits GRAPHICS_SPRITE_BATCH_T = (bits(1) << GRAPHICS_SPRITE_BATCH_ID) | GRAPHICS_DRAWABLE_T;
 	const bits GRAPHICS_VERTEX_BUFFER_T = (bits(1) << GRAPHICS_VERTEX_BUFFER_ID) | GRAPHICS_DRAWABLE_T;
+	const bits GRAPHICS_FBO_T = (bits(1) << GRAPHICS_FBO_ID) | GRAPHICS_DRAWABLE_T;
 
 	// Image.
 	const bits IMAGE_IMAGE_DATA_T = (bits(1) << IMAGE_IMAGE_DATA_ID) | DATA_T;

+ 103 - 0
src/modules/graphics/opengl/Fbo.cpp

@@ -0,0 +1,103 @@
+#include "Fbo.h"
+#include <common/Matrix.h>
+
+namespace love
+{
+namespace graphics
+{
+namespace opengl
+{
+
+	Fbo::Fbo(int width, int height) :
+		width(width), height(height)
+	{
+		// world coordinates
+		vertices[0].x = 0;     vertices[0].y = 0;
+		vertices[1].x = 0;     vertices[1].y = height;
+		vertices[2].x = width; vertices[2].y = height;
+		vertices[3].x = width; vertices[3].y = 0;
+
+		// texture coordinates
+		vertices[0].s = 0;     vertices[0].t = 1;
+		vertices[1].s = 0;     vertices[1].t = 0;
+		vertices[2].s = 1;     vertices[2].t = 0;
+		vertices[3].s = 1;     vertices[3].t = 1;
+
+		// generate depth buffer
+		glGenRenderbuffers(1, &depthbuffer);
+		glBindRenderbuffer(GL_RENDERBUFFER, depthbuffer);
+		glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
+		glBindRenderbuffer(GL_RENDERBUFFER, 0);
+
+		// generate texture save target
+		glGenTextures(1, &img);
+		glBindTexture(GL_TEXTURE_2D, img);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height,
+				0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+		glBindTexture(GL_TEXTURE_2D, 0);
+
+		// create framebuffer
+		glGenFramebuffers(1, &fbo);
+		glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+				GL_TEXTURE_2D, img, 0);
+		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+				GL_RENDERBUFFER, depthbuffer);
+		status_ = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+
+		// unbind buffers and texture
+		glBindFramebuffer(GL_FRAMEBUFFER, 0);
+	}
+
+	Fbo::~Fbo()
+	{
+		glDeleteTextures(1, &fbo);
+		glDeleteRenderbuffers(1, &depthbuffer);
+		glDeleteFramebuffers(1, &img);
+	}
+
+	GLenum Fbo::status() const
+	{
+		return status_;
+	}
+
+	void Fbo::bind()
+	{
+		glPushAttrib(GL_VIEWPORT_BIT | GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+		glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+		glViewport(0, 0, width, height);
+	}
+
+	void Fbo::unbind()
+	{
+		glBindFramebuffer(GL_FRAMEBUFFER, 0);
+		glPopAttrib();
+	}
+
+	void Fbo::draw(float x, float y, float angle, float sx, float sy, float ox, float oy) const
+	{
+		static Matrix t;
+		t.setTransformation(x, y, angle, sx, sy, ox, oy);
+
+		glPushMatrix();
+		glMultMatrixf((const GLfloat*)t.getElements());
+
+		glBindTexture(GL_TEXTURE_2D, img);
+
+		glEnableClientState(GL_VERTEX_ARRAY);
+		glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+		glVertexPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid*)&vertices[0].x);
+		glTexCoordPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid*)&vertices[0].s);
+		glDrawArrays(GL_QUADS, 0, 4);
+		glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+		glDisableClientState(GL_VERTEX_ARRAY);
+
+		glPopMatrix();
+	}
+
+} // opengl
+} // graphics
+} // love

+ 46 - 0
src/modules/graphics/opengl/Fbo.h

@@ -0,0 +1,46 @@
+#ifndef LOVE_GRAPHICS_FBO_H
+#define LOVE_GRAPHICS_FBO_H
+
+#include <graphics/Drawable.h>
+#include <graphics/Volatile.h>
+#include <common/math.h>
+#include "GLee.h"
+
+namespace love
+{
+namespace graphics
+{
+namespace opengl
+{
+
+	class Fbo : public Drawable // Fbo vs. FBO?
+	{
+	public:
+		Fbo(int width, int height);
+		virtual ~Fbo();
+
+		GLenum status() const; //SERIOUS DISLIKE HERE
+
+		void bind(); //DOUBTFUL ABOUT NAME
+		void unbind(); //Maybe start/stop?
+		//And what about clearing, clear() isn't entirely what I want either
+		//maybe make bind/start autoclear?
+
+		virtual void draw(float x, float y, float angle, float sx, float sy, float ox, float oy) const;
+
+	private:
+		GLsizei width;
+		GLsizei height;
+		GLuint fbo;
+		GLuint depthbuffer;
+		GLuint img;
+		GLenum status_;
+
+		vertex vertices[4];
+	};
+
+} // opengl
+} // graphics
+} // love
+
+#endif // LOVE_GRAPHICS_FBO_H

+ 6 - 1
src/modules/graphics/opengl/Graphics.cpp

@@ -306,7 +306,7 @@ namespace opengl
 	{
 		SDL_GL_SwapBuffers();
 	}
-	
+
 	void Graphics::setIcon(Image * image)
 	{
 		Uint32 rmask, gmask, bmask, amask;
@@ -470,6 +470,11 @@ namespace opengl
 		return new ParticleSystem(image, size);
 	}
 
+	Fbo * Graphics::newFbo(int width, int height)
+	{
+		return new Fbo(width, height);
+	}
+
 	void Graphics::setColor(Color c)
 	{
 		glColor4ubv(&c.r);

+ 28 - 25
src/modules/graphics/opengl/Graphics.h

@@ -1,14 +1,14 @@
 /**
 * Copyright (c) 2006-2010 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
@@ -43,6 +43,7 @@
 #include "Quad.h"
 #include "SpriteBatch.h"
 #include "ParticleSystem.h"
+#include "Fbo.h"
 
 namespace love
 {
@@ -95,13 +96,13 @@ namespace opengl
 		// Default values.
 		DisplayState()
 		{
-			color.r = 255; 
-			color.g = 255; 
-			color.b = 255; 
+			color.r = 255;
+			color.g = 255;
+			color.b = 255;
 			color.a = 255;
-			backgroundColor.r = 0; 
-			backgroundColor.g = 0; 
-			backgroundColor.b = 0; 
+			backgroundColor.r = 0;
+			backgroundColor.g = 0;
+			backgroundColor.b = 0;
 			backgroundColor.a = 255;
 			blendMode = Graphics::BLEND_ALPHA;
 			colorMode = Graphics::COLOR_MODULATE;
@@ -126,7 +127,7 @@ namespace opengl
 
 		Graphics();
 		virtual ~Graphics();
-		
+
 		// Implements Module.
 		const char * getName() const;
 
@@ -165,18 +166,18 @@ namespace opengl
 		* when the game reloads.
 		**/
 		void reset();
-			
+
 		/**
 		* Clears the screen.
 		**/
 		void clear();
 
 		/**
-		* Flips buffers. (Rendered geometry is 
+		* Flips buffers. (Rendered geometry is
 		* presented on screen).
 		**/
 		void present();
-		
+
 		/**
 		* Sets the window's icon.
 		**/
@@ -207,13 +208,13 @@ namespace opengl
 		/**
 		* This native Lua function gets available modes
 		* from SDL and returns them as a table on the following format:
-		* 
-		* { 
-		*   { width = 800, height = 600 }, 
+		*
+		* {
+		*   { width = 800, height = 600 },
 		*   { width = 1024, height = 768 },
 		*   ...
 		* }
-		* 
+		*
 		* Only fullscreen modes are returned here, as all
 		* window sizes are supported (normally).
 		**/
@@ -245,7 +246,7 @@ namespace opengl
 		**/
 		Image * newImage(love::filesystem::File * file);
 		Image * newImage(love::image::ImageData * data);
-		
+
 		/**
 		* Creates a Frame
 		**/
@@ -255,11 +256,13 @@ namespace opengl
 		* Creates a Font object.
 		**/
 		Font * newFont(love::font::FontData * data);
-		
+
 		SpriteBatch * newSpriteBatch(Image * image, int size, int usage);
 
 		ParticleSystem * newParticleSystem(Image * image, int size);
-			
+
+		Fbo * newFbo(int width, int height);
+
 		/**
 		* Sets the foreground color.
 		**/
@@ -271,7 +274,7 @@ namespace opengl
 		Color getColor();
 
 		/**
-		* Sets the background Color. 
+		* Sets the background Color.
 		**/
 		void setBackgroundColor(Color c);
 
@@ -383,7 +386,7 @@ namespace opengl
 		PointStyle getPointStyle();
 
 		/**
-		* Gets the maximum point size supported. 
+		* Gets the maximum point size supported.
 		* This may vary from computer to computer.
 		**/
 		int getMaxPointSize();
@@ -406,7 +409,7 @@ namespace opengl
 		void print(const char * str, float x, float y , float angle);
 
 		/**
-		* Draws text at the specified coordinates, with rotation and 
+		* Draws text at the specified coordinates, with rotation and
 		* scaling.
 		* @param x The x-coordinate.
 		* @param y The y-coordinate.
@@ -416,7 +419,7 @@ namespace opengl
 		void print(const char * str, float x, float y , float angle, float s);
 
 		/**
-		* Draws text at the specified coordinates, with rotation and 
+		* Draws text at the specified coordinates, with rotation and
 		* scaling along both axes.
 		* @param x The x-coordinate.
 		* @param y The y-coordinate.
@@ -452,7 +455,7 @@ namespace opengl
 		* @param y2 Second y-coordinate.
 		**/
 		void line(float x1, float y1, float x2, float y2);
-		
+
 		/**
 		* Draws a series of lines connecting the given vertices.
 		* @param ... Vertex components (x1, y1, x2, y2, etc.)

+ 58 - 0
src/modules/graphics/opengl/wrap_Fbo.cpp

@@ -0,0 +1,58 @@
+#include "wrap_Fbo.h"
+
+namespace love
+{
+namespace graphics
+{
+namespace opengl
+{
+	Fbo * luax_checkfbo(lua_State * L, int idx)
+	{
+		return luax_checktype<Fbo>(L, idx, "Fbo", GRAPHICS_FBO_T);
+	}
+
+	int w_Fbo_render(lua_State * L)
+	{
+		Fbo * fbo = luax_checkfbo(L, 1);
+		if (!lua_isfunction(L, 2))
+			return luaL_error(L, "Need a function to render to fbo");
+
+		fbo->bind();
+
+		lua_settop(L, 2); // make sure the function is on top of the stack
+		lua_pcall(L, 0, 0, 0);
+
+		fbo->unbind();
+
+		return 0;
+	}
+
+	int w_Fbo_bind(lua_State * L)
+	{
+		Fbo * fbo = luax_checkfbo(L, 1);
+		fbo->bind();
+		return 0;
+	}
+
+	int w_Fbo_unbind(lua_State * L)
+	{
+		Fbo * fbo = luax_checkfbo(L, 1);
+		fbo->unbind();
+		return 0;
+	}
+
+	static const luaL_Reg functions[] = {
+		{ "render", w_Fbo_render },
+		{ "bind", w_Fbo_bind },
+		{ "unbind", w_Fbo_unbind },
+		{ 0, 0 }
+	};
+
+	int luaopen_fbo(lua_State * L)
+	{
+		return luax_register_type(L, "Fbo", functions);
+	}
+
+} // opengl
+} // graphics
+} // love

+ 25 - 0
src/modules/graphics/opengl/wrap_Fbo.h

@@ -0,0 +1,25 @@
+#ifndef LOVE_GRAPHICS_OPENGL_WRAP_FBO_H
+#define LOVE_GRAPHICS_OPENGL_WRAP_FBO_H
+
+// LOVE
+#include <common/runtime.h>
+#include "Fbo.h"
+
+namespace love
+{
+namespace graphics
+{
+namespace opengl
+{
+	//see Fbo.h
+	Fbo * luax_checkfbo(lua_State * L, int idx);
+	int w_Fbo_render(lua_State * L);
+	int w_Fbo_bind(lua_State * L);
+	int w_Fbo_unbind(lua_State * L);
+	int luaopen_fbo(lua_State * L);
+
+} // opengl
+} // graphics
+} // love
+
+#endif // LOVE_GRAPHICS_OPENGL_WRAP_FBO_H

+ 19 - 2
src/modules/graphics/opengl/wrap_Graphics.cpp

@@ -84,7 +84,7 @@ namespace opengl
 		instance->setIcon(image);
 		return 0;
 	}
-	
+
 	int w_setCaption(lua_State * L)
 	{
 		const char * str = luaL_checkstring(L, 1);
@@ -292,6 +292,21 @@ namespace opengl
 		return 1;
 	}
 
+	int w_newFbo(lua_State * L)
+	{
+		int width, height;
+		width = luaL_checkint(L, 1);
+		height = luaL_checkint(L, 2);
+		Fbo * fbo = instance->newFbo(width, height);
+
+		//and there we go with the status... still disliked
+		GLenum status = fbo->status();
+		if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
+			return luaL_error(L, "Cannot create FBO: %d", status);
+		luax_newtype(L, "Fbo", GRAPHICS_FBO_T, (void*)fbo);
+		return 1;
+	}
+
 	int w_setColor(lua_State * L)
 	{
 		Color c;
@@ -829,6 +844,7 @@ namespace opengl
 		{ "newImageFont", w_newImageFont },
 		{ "newSpriteBatch", w_newSpriteBatch },
 		{ "newParticleSystem", w_newParticleSystem },
+		{ "newFbo", w_newFbo },
 
 		{ "setColor", w_setColor },
 		{ "getColor", w_getColor },
@@ -866,7 +882,7 @@ namespace opengl
 
 		{ "setCaption", w_setCaption },
 		{ "getCaption", w_getCaption },
-		
+
 		{ "setIcon", w_setIcon },
 
 		{ "getWidth", w_getWidth },
@@ -906,6 +922,7 @@ namespace opengl
 		luaopen_frame,
 		luaopen_spritebatch,
 		luaopen_particlesystem,
+		luaopen_fbo,
 		0
 	};
 

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

@@ -1,14 +1,14 @@
 /**
 * Copyright (c) 2006-2010 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
@@ -28,6 +28,7 @@
 #include "wrap_Quad.h"
 #include "wrap_SpriteBatch.h"
 #include "wrap_ParticleSystem.h"
+#include "wrap_Fbo.h"
 #include "Graphics.h"
 
 namespace love
@@ -58,6 +59,7 @@ namespace opengl
 	int w_newImageFont(lua_State * L);
 	int w_newSpriteBatch(lua_State * L);
 	int w_newParticleSystem(lua_State * L);
+	int w_newFbo(lua_State * L); // commetns in function
 	int w_setColor(lua_State * L);
 	int w_getColor(lua_State * L);
 	int w_setBackgroundColor(lua_State * L);