Browse Source

Merge something (?)

vrld 12 years ago
parent
commit
03518d51ac

+ 16 - 0
changes.txt

@@ -10,6 +10,14 @@ LOVE 0.8.1 [Rubber Piggy]
   * Added love.mouse.setX/setY.
   * Added love.filesystem.getIdentity.
   * Added HDR canvas support.
+  * Added Source:isPlaying.
+  * Added mipmapping support (has isSupported test).
+  * Added Font:getAscent/getDescent/getBaseline.
+  * Added Canvas:getPixel.
+  * Added vertex shader support.
+  * Added boolean support to Shader:send.
+  * Added support for UTF-8 ImageFonts.
+  * Added SoundData:getDuration.
   * OPTIONAL: Added support for GME.
 
   * Fixed crashes with font drawing on some ATI cards.
@@ -26,18 +34,26 @@ LOVE 0.8.1 [Rubber Piggy]
   * Fixed multiplicative blend mode.
   * Fixed Box2D exception in World:update.
   * Fixed spacing for the last character in an ImageFont.
+  * Fixed crash when locking SpriteBatches multiple times.
+  * Fixed File:read reading past end of file.
+  * Fixed keyrepeat settings being lost after (indirect) setMode.
 
   * Moved love's startup to modules/love.
 
   * Renamed love's boot script to 'love.boot', which can be required.
+  * Renamed PixelEffect to Shader (but now with vertex shaders).
 
   * Removed love.joystick.open and friends.
+  * Removed love.graphics.drawTest.
 
   * Updated allocation for SoundData, it's more efficient and less wasteful.
   * Updated Source:set* functions to default z to 0.
   * Updated the windows console, it now tries to re-use an active one first.
   * Updated love.image memory handling, improves errors and thread-safety.
   * Updated order of sleep/present in love.run (now draws, *then* sleeps).
+  * Updated the setFilter and setWrap methods, the second argument is now optional.
+  * Updated font rendering code, now more performant.
+  * Updated error handling, error handlers now get resolved when the error occurs.
 
 LOVE 0.8.0 [Rubber Piggy]
 -------------------------

+ 5 - 1
platform/msvc2010/liblove.vcxproj

@@ -112,11 +112,13 @@
     <OutDir>$(SolutionDir)\bin\$(PlatformShortName)\Debug\MD\</OutDir>
     <IntDir>$(ProjectName)\$(PlatformShortName)\Debug\</IntDir>
     <GenerateManifest>false</GenerateManifest>
+    <TargetName>love</TargetName>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Dynamic|x64'">
     <OutDir>$(SolutionDir)\bin\$(PlatformShortName)\Debug\MD\</OutDir>
     <IntDir>$(ProjectName)\$(PlatformShortName)\Debug\</IntDir>
     <GenerateManifest>false</GenerateManifest>
+    <TargetName>love</TargetName>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Static|Win32'">
     <OutDir>$(SolutionDir)\bin\$(PlatformShortName)\Release\MT\</OutDir>
@@ -130,11 +132,13 @@
     <OutDir>$(SolutionDir)\bin\$(PlatformShortName)\Release\MD\</OutDir>
     <IntDir>$(ProjectName)\$(PlatformShortName)\Release\</IntDir>
     <GenerateManifest>false</GenerateManifest>
+    <TargetName>love</TargetName>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Dynamic|x64'">
     <OutDir>$(SolutionDir)\bin\$(PlatformShortName)\Release\MD\</OutDir>
     <IntDir>$(ProjectName)\$(PlatformShortName)\Release\</IntDir>
     <GenerateManifest>false</GenerateManifest>
+    <TargetName>love</TargetName>
   </PropertyGroup>
   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Dynamic|Win32'">
     <ClCompile>
@@ -733,4 +737,4 @@
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>

BIN
platform/msvc2010/love.rc


+ 90 - 66
src/modules/graphics/opengl/Image.cpp

@@ -37,7 +37,8 @@ Image::Image(love::image::ImageData *data)
 	: width((float)(data->getWidth()))
 	, height((float)(data->getHeight()))
 	, texture(0)
-	, mipmapsharpness(0.0f)
+	, mipmapSharpness(0.0f)
+	, mipmapsCreated(false)
 {
 	data->retain();
 	this->data = data;
@@ -143,36 +144,55 @@ void Image::drawq(love::graphics::Quad *quad, float x, float y, float angle, flo
 	drawv(t, v);
 }
 
-void Image::checkMipmapsCreated() const
+void Image::checkMipmapsCreated()
 {
-	if (filter.mipmap != FILTER_NEAREST && filter.mipmap != FILTER_LINEAR)
+	if (mipmapsCreated || (filter.mipmap != FILTER_NEAREST && filter.mipmap != FILTER_LINEAR))
 		return;
 
 	if (!hasMipmapSupport())
-		throw love::Exception("Mipmap filtering is not supported on this system!");
+		throw love::Exception("Mipmap filtering is not supported on this system.");
 
-	// some old GPUs/systems claim support for NPOT textures, but fail when generating mipmaps
-	// we can't detect which systems will do this, so we fail gracefully for all NPOT images
+	// Some old drivers claim support for NPOT textures, but fail when creating mipmaps.
+	// we can't detect which systems will do this, so we fail gracefully for all NPOT images.
 	int w = int(width), h = int(height);
 	if (w != next_p2(w) || h != next_p2(h))
-		throw love::Exception("Could not generate mipmaps: image does not have power of two dimensions!");
+		throw love::Exception("Cannot create mipmaps: image does not have power of two dimensions.");
 
 	bind();
 
-	GLint mipmapscreated;
-	glGetTexParameteriv(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, &mipmapscreated);
-
-	// generate mipmaps for this image if we haven't already
-	if (!mipmapscreated)
+	if (hasNpot() && (GLEE_VERSION_3_0 || GLEE_ARB_framebuffer_object))
+	{
+		// AMD/ATI drivers have several bugs when generating mipmaps,
+		// re-uploading the entire base image seems to be required.
+		glTexImage2D(GL_TEXTURE_2D,
+		             0,
+		             GL_RGBA8,
+		             (GLsizei)width,
+		             (GLsizei)height,
+		             0,
+		             GL_RGBA,
+		             GL_UNSIGNED_BYTE,
+		             data->getData());
+
+		// More bugs: http://www.opengl.org/wiki/Common_Mistakes#Automatic_mipmap_generation
+		glEnable(GL_TEXTURE_2D);
+		glGenerateMipmap(GL_TEXTURE_2D);
+	}
+	else
 	{
 		glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
-
-		if (GLEE_VERSION_3_0 || GLEE_ARB_framebuffer_object)
-			glGenerateMipmap(GL_TEXTURE_2D);
-		else
-			// modify single texel to trigger mipmap chain generation
-			glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data->getData());
+		glTexSubImage2D(GL_TEXTURE_2D,
+		                0,
+		                0,
+		                0,
+		                (GLsizei)width,
+		                (GLsizei)height,
+		                GL_RGBA,
+		                GL_UNSIGNED_BYTE,
+		                data->getData());
 	}
+
+	mipmapsCreated = true;
 }
 
 void Image::setFilter(const Image::Filter &f)
@@ -180,8 +200,8 @@ void Image::setFilter(const Image::Filter &f)
 	filter = f;
 
 	bind();
-	checkMipmapsCreated();
 	setTextureFilter(f);
+	checkMipmapsCreated();
 }
 
 const Image::Filter &Image::getFilter() const
@@ -208,15 +228,15 @@ void Image::setMipmapSharpness(float sharpness)
 		return;
 
 	// LOD bias has the range (-maxbias, maxbias)
-	mipmapsharpness = std::min(std::max(sharpness, -maxmipmapsharpness + 0.01f), maxmipmapsharpness - 0.01f);
+	mipmapSharpness = std::min(std::max(sharpness, -maxMipmapSharpness + 0.01f), maxMipmapSharpness - 0.01f);
 
 	bind();
-	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -mipmapsharpness); // negative bias is sharper
+	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -mipmapSharpness); // negative bias is sharper
 }
 
 float Image::getMipmapSharpness() const
 {
-	return mipmapsharpness;
+	return mipmapSharpness;
 }
 
 void Image::bind() const
@@ -240,7 +260,7 @@ void Image::unload()
 bool Image::loadVolatile()
 {
 	if (hasMipmapSharpnessSupport())
-		glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS, &maxmipmapsharpness);
+		glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS, &maxMipmapSharpness);
 
 	if (hasNpot())
 		return loadVolatileNPOT();
@@ -253,11 +273,8 @@ bool Image::loadVolatilePOT()
 	glGenTextures(1,(GLuint *)&texture);
 	bindTexture(texture);
 
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-
-	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+	setTextureFilter(filter);
+	setTextureWrap(wrap);
 
 	float p2width = next_p2(width);
 	float p2height = next_p2(height);
@@ -269,29 +286,34 @@ bool Image::loadVolatilePOT()
 	vertices[2].s = s;
 	vertices[3].s = s;
 
+	while (glGetError() != GL_NO_ERROR); // clear errors
+
 	glTexImage2D(GL_TEXTURE_2D,
-				 0,
-				 GL_RGBA8,
-				 (GLsizei)p2width,
-				 (GLsizei)p2height,
-				 0,
-				 GL_RGBA,
-				 GL_UNSIGNED_BYTE,
-				 0);
+	             0,
+	             GL_RGBA8,
+	             (GLsizei)p2width,
+	             (GLsizei)p2height,
+	             0,
+	             GL_RGBA,
+	             GL_UNSIGNED_BYTE,
+	             0);
 
 	glTexSubImage2D(GL_TEXTURE_2D,
-					0,
-					0,
-					0,
-					(GLsizei)width,
-					(GLsizei)height,
-					GL_RGBA,
-					GL_UNSIGNED_BYTE,
-					data->getData());
-
-	setMipmapSharpness(mipmapsharpness);
-	setFilter(filter);
-	setWrap(wrap);
+	                0,
+	                0,
+	                0,
+	                (GLsizei)width,
+	                (GLsizei)height,
+	                GL_RGBA,
+	                GL_UNSIGNED_BYTE,
+	                data->getData());
+
+	if (glGetError() != GL_NO_ERROR)
+		throw love::Exception("Cannot create image: size may be too large for this system.");
+
+	mipmapsCreated = false;
+	checkMipmapsCreated();
+	setMipmapSharpness(mipmapSharpness);
 
 	return true;
 }
@@ -301,25 +323,27 @@ bool Image::loadVolatileNPOT()
 	glGenTextures(1,(GLuint *)&texture);
 	bindTexture(texture);
 
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+	setTextureFilter(filter);
+	setTextureWrap(wrap);
 
-	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+	while (glGetError() != GL_NO_ERROR); // clear errors
 
 	glTexImage2D(GL_TEXTURE_2D,
-				 0,
-				 GL_RGBA8,
-				 (GLsizei)width,
-				 (GLsizei)height,
-				 0,
-				 GL_RGBA,
-				 GL_UNSIGNED_BYTE,
-				 data->getData());
-
-	setMipmapSharpness(mipmapsharpness);
-	setFilter(filter);
-	setWrap(wrap);
+	             0,
+	             GL_RGBA8,
+	             (GLsizei)width,
+	             (GLsizei)height,
+	             0,
+	             GL_RGBA,
+	             GL_UNSIGNED_BYTE,
+	             data->getData());
+
+	if (glGetError() != GL_NO_ERROR)
+		throw love::Exception("Cannot create image: size may be too large for this system.");
+
+	mipmapsCreated = false;
+	checkMipmapsCreated();
+	setMipmapSharpness(mipmapSharpness);
 
 	return true;
 }
@@ -360,12 +384,12 @@ bool Image::hasNpot()
 
 bool Image::hasMipmapSupport()
 {
-	return (GLEE_VERSION_1_4 || GLEE_SGIS_generate_mipmap) != 0;
+	return GLEE_VERSION_1_4 || GLEE_SGIS_generate_mipmap;
 }
 
 bool Image::hasMipmapSharpnessSupport()
 {
-	return (GLEE_VERSION_1_4 || GLEE_EXT_texture_lod_bias) != 0;
+	return GLEE_VERSION_1_4 || GLEE_EXT_texture_lod_bias;
 }
 
 } // opengl

+ 8 - 5
src/modules/graphics/opengl/Image.h

@@ -142,11 +142,14 @@ private:
 	// The source vertices of the image.
 	vertex vertices[4];
 
-	// Mipmap texture LOD bias value
-	float mipmapsharpness;
+	// Mipmap texture LOD bias (sharpness) value.
+	float mipmapSharpness;
 
-	// Implementation-dependent maximum/minimum mipmap sharpness values
-	float maxmipmapsharpness;
+	// Implementation-dependent min/max mipmap sharpness values.
+	float maxMipmapSharpness;
+
+	// True if mipmaps have been created for this Image.
+	bool mipmapsCreated;
 
 	// The image's filter mode
 	Image::Filter filter;
@@ -157,7 +160,7 @@ private:
 	bool loadVolatilePOT();
 	bool loadVolatileNPOT();
 
-	void checkMipmapsCreated() const;
+	void checkMipmapsCreated();
 
 }; // Image
 

+ 8 - 77
src/modules/graphics/opengl/SpriteBatch.cpp

@@ -20,9 +20,6 @@
 
 #include "SpriteBatch.h"
 
-// STD
-#include <algorithm> // std::find
-
 // OpenGL
 #include "OpenGL.h"
 
@@ -97,25 +94,9 @@ SpriteBatch::~SpriteBatch()
 int SpriteBatch::add(float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index /*= -1*/)
 {
 	// Only do this if there's a free slot.
-	if ((index == -1 && next >= size && gaps.size() == 0) || index < -1 || index >= size)
+	if ((index == -1 && next >= size) || index < -1 || index >= size)
 		return -1;
 
-	// Determine where in the vertex buffer to insert into, using the gap list
-	// if possible.
-	int realindex;
-	if (index == -1 && gaps.size() > 0)
-	{
-		realindex = gaps.front();
-		gaps.pop_front();
-	}
-	else
-	{
-		realindex = (index == -1) ? next : index;
-		std::deque<int>::iterator it = std::find(gaps.begin(), gaps.end(), realindex);
-		if (it != gaps.end())
-			gaps.erase(it); // This index is no longer a gap.
-	}
-
 	// Needed for colors.
 	memcpy(sprite, image->getVertices(), sizeof(vertex)*4);
 
@@ -128,37 +109,21 @@ int SpriteBatch::add(float x, float y, float a, float sx, float sy, float ox, fl
 		setColorv(sprite, *color);
 	
 
-	addv(sprite, realindex);
+	addv(sprite, (index == -1) ? next : index);
 
 	// Increment counter.
-	if (index == -1 && realindex == next)
+	if (index == -1)
 		return next++;
 
-	return realindex;
+	return index;
 }
 
 int SpriteBatch::addq(Quad *quad, float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index /*= -1*/)
 {
 	// Only do this if there's a free slot.
-	if ((index == -1 && next >= size && gaps.size() == 0) || index < -1 || index >= next)
+	if ((index == -1 && next >= size) || index < -1 || index >= next)
 		return -1;
 
-	// Determine where in the vertex buffer to insert into, using the gap list
-	// if possible.
-	int realindex;
-	if (index == -1 && gaps.size() > 0)
-	{
-		realindex = gaps.front();
-		gaps.pop_front();
-	}
-	else
-	{
-		realindex = (index == -1) ? next : index;
-		std::deque<int>::iterator it = std::find(gaps.begin(), gaps.end(), realindex);
-		if (it != gaps.end())
-			gaps.erase(it); // This index is no longer a gap.
-	}
-
 	// Needed for colors.
 	memcpy(sprite, quad->getVertices(), sizeof(vertex)*4);
 
@@ -170,53 +135,19 @@ int SpriteBatch::addq(Quad *quad, float x, float y, float a, float sx, float sy,
 	if (color)
 		setColorv(sprite, *color);
 
-	addv(sprite, realindex);
+	addv(sprite, (index == -1) ? next : index);
 
 	// Increment counter.
-	if (index == -1 && realindex == next)
+	if (index == -1)
 		return next++;
 
-	return realindex;
-}
-
-void SpriteBatch::remove(int index)
-{
-	if (index < 0 || index >= next || next <= 0)
-		return;
-
-	// If this is the last index in the sprite list, decrease the total sprite
-	// count instead of adding a dummy sprite.
-	if (index == next - 1)
-	{
-		int spritecount = index;
-
-		// Remove all consecutive gaps at the end of the sprite list.
-		std::deque<int>::iterator it;
-		while ((it = std::find(gaps.begin(), gaps.end(), --spritecount)) != gaps.end())
-			gaps.erase(it);
-
-		next = spritecount + 1;
-		return;
-	}
-	else if (std::find(gaps.begin(), gaps.end(), index) != gaps.end())
-		return; // Don't add the same index to the gap list twice.
-
-
-	// OpenGL won't render any primitive whose vertices are all identical.
-	for (int i = 0; i < 4; i++)
-		sprite[i].x = sprite[i].y = 0;
-
-	// Replace the existing sprite at this index with the dummy sprite.
-	addv(sprite, index);
-
-	gaps.push_back(index);
+	return index;
 }
 
 void SpriteBatch::clear()
 {
 	// Reset the position of the next index.
 	next = 0;
-	gaps.clear();
 }
 
 void *SpriteBatch::lock()

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

@@ -23,7 +23,6 @@
 
 // C
 #include <cstring>
-#include <deque>
 
 // LOVE
 #include "common/math.h"
@@ -64,7 +63,6 @@ public:
 
 	int add(float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index = -1);
 	int addq(Quad *quad, float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index = -1);
-	void remove(int index);
 	void clear();
 
 	void *lock();
@@ -127,10 +125,6 @@ private:
 	VertexBuffer *array_buf;
 	VertexIndex *element_buf;
 
-	// List of gaps in the SpriteBatch. Checked when adding sprites, and added
-	// to when removing them.
-	std::deque<int> gaps;
-
 }; // SpriteBatch
 
 } // opengl

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

@@ -101,14 +101,6 @@ int w_SpriteBatch_setq(lua_State *L)
 	return 0;
 }
 
-int w_SpriteBatch_remove(lua_State *L)
-{
-	SpriteBatch *t = luax_checkspritebatch(L, 1);
-	int id = luaL_checkinteger(L, 2);
-	t->remove(id);
-	return 0;
-}
-
 int w_SpriteBatch_clear(lua_State *L)
 {
 	SpriteBatch *t = luax_checkspritebatch(L, 1);
@@ -198,7 +190,6 @@ static const luaL_Reg functions[] =
 	{ "addq", w_SpriteBatch_addq },
 	{ "set", w_SpriteBatch_set },
 	{ "setq", w_SpriteBatch_setq },
-	{ "remove", w_SpriteBatch_remove },
 	{ "clear", w_SpriteBatch_clear },
 	{ "bind", w_SpriteBatch_bind },
 	{ "unbind", w_SpriteBatch_unbind },

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

@@ -36,7 +36,6 @@ int w_SpriteBatch_add(lua_State *L);
 int w_SpriteBatch_addq(lua_State *L);
 int w_SpriteBatch_set(lua_State *L);
 int w_SpriteBatch_setq(lua_State *L);
-int w_SpriteBatch_remove(lua_State *L);
 int w_SpriteBatch_clear(lua_State *L);
 int w_SpriteBatch_lock(lua_State *L);
 int w_SpriteBatch_unlock(lua_State *L);