Commits

Alex Szpakowski committed 2636692

Improved performance of Image:refresh

Comments (0)

Files changed (3)

src/modules/graphics/opengl/Image.cpp

 Image::Image(love::image::ImageData *data)
 	: data(data)
 	, cdata(0)
-	, width((float)(data->getWidth()))
-	, height((float)(data->getHeight()))
+	, width(data->getWidth())
+	, height(data->getHeight())
+	, paddedWidth(width)
+	, paddedHeight(height)
 	, texture(0)
-	, texCoordScale(1.0, 1.0)
 	, mipmapSharpness(defaultMipmapSharpness)
 	, mipmapsCreated(false)
 	, compressed(false)
 Image::Image(love::image::CompressedData *cdata)
 	: data(0)
 	, cdata(cdata)
-	, width((float)(cdata->getWidth(0)))
-	, height((float)(cdata->getHeight(0)))
+	, width(cdata->getWidth(0))
+	, height(cdata->getHeight(0))
+	, paddedWidth(width)
+	, paddedHeight(height)
 	, texture(0)
-	, texCoordScale(1.0, 1.0)
 	, mipmapSharpness(defaultMipmapSharpness)
 	, mipmapsCreated(false)
 	, compressed(true)
 	unload();
 }
 
-float Image::getWidth() const
+int Image::getWidth() const
 {
 	return width;
 }
 
-float Image::getHeight() const
+int Image::getHeight() const
 {
 	return height;
 }
 {
 	bind();
 
-	if (texCoordScale.x < 1.0f || texCoordScale.y < 1.0f)
+	if (width != paddedWidth || height != paddedHeight)
 	{
 		// NPOT image padded to POT size, so the texcoords should be scaled.
 		glMatrixMode(GL_TEXTURE);
 		glPushMatrix();
-		glScalef(texCoordScale.x, texCoordScale.y, 0.0f);
+		glScalef(float(width) / float(paddedWidth), float(height) / float(paddedHeight), 0.0f);
 		glMatrixMode(GL_MODELVIEW);
 	}
 }
 
 void Image::postdraw() const
 {
-	if (texCoordScale.x < 1.0f || texCoordScale.y < 1.0f)
+	if (width != paddedWidth || height != paddedHeight)
 	{
 		glMatrixMode(GL_TEXTURE);
 		glPopMatrix();
 	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[1].y = (float) height;
+	vertices[2].x = (float) width;
+	vertices[2].y = (float) height;
+	vertices[3].x = (float) width;
 	vertices[3].y = 0;
 
 	vertices[0].s = 0;
 	gl.setTextureWrap(wrap);
 	setMipmapSharpness(mipmapSharpness);
 
-	float texwidth = width;
-	float texheight = height;
+	paddedWidth = width;
+	paddedHeight = height;
 
 	if (!hasNpot())
 	{
 		// NPOT textures will be padded to POT dimensions if necessary.
-		texwidth = next_p2(width);
-		texheight = next_p2(height);
+		paddedWidth = next_p2(width);
+		paddedHeight = next_p2(height);
 	}
 
 	// Use a default texture if the size is too big for the system.
-	if (texwidth > gl.getMaxTextureSize() || texheight > gl.getMaxTextureSize())
+	if (paddedWidth > gl.getMaxTextureSize() || paddedHeight > gl.getMaxTextureSize())
 	{
 		uploadDefaultTexture();
 		return true;
 	}
 
-	texCoordScale.x = width / texwidth;
-	texCoordScale.y = height / texheight;
-
 	// Mutex lock will potentially cover texture loading and mipmap creation.
 	love::thread::EmptyLock lock;
 	if (data)
 
 	while (glGetError() != GL_NO_ERROR); // Clear errors.
 
-	if (hasNpot() || (texwidth == width && texheight == height))
+	if (hasNpot() || (width == paddedWidth && height == paddedHeight))
 		uploadTexture();
 	else
-		uploadTexturePadded(texwidth, texheight);
+		uploadTexturePadded();
 
 	GLenum glerr = glGetError();
 	if (glerr != GL_NO_ERROR)
 	return true;
 }
 
-void Image::uploadTexturePadded(float p2width, float p2height)
+void Image::uploadTexturePadded()
 {
 	if (isCompressed() && cdata)
 	{
 		glTexImage2D(GL_TEXTURE_2D,
 		             0,
 		             GL_RGBA8,
-		             (GLsizei)p2width,
-		             (GLsizei)p2height,
+		             (GLsizei)paddedWidth,
+		             (GLsizei)paddedHeight,
 		             0,
 		             GL_RGBA,
 		             GL_UNSIGNED_BYTE,
 	if (texture == 0)
 		return false;
 
-	while (glGetError() != GL_NO_ERROR); // clear errors
+	if (usingDefaultTexture)
+	{
+		uploadDefaultTexture();
+		return true;
+	}
 
 	// We want this lock to potentially cover mipmap creation as well.
 	love::thread::EmptyLock lock;
 
 	bind();
 
-	if (isCompressed() && cdata)
-	{
-		GLenum format = getCompressedFormat(cdata->getFormat());
-		glCompressedTexSubImage2DARB(GL_TEXTURE_2D,
-		                             0,
-		                             0, 0,
-		                             cdata->getWidth(0),
-		                             cdata->getHeight(0),
-		                             format,
-		                             GLsizei(cdata->getSize(0)),
-		                             cdata->getData(0));
-	}
-	else if (data)
-	{
+	if (data && !isCompressed())
 		lock.setLock(data->getMutex());
-		glTexSubImage2D(GL_TEXTURE_2D,
-		                0,
-		                0, 0,
-		                (GLsizei)width,
-		                (GLsizei)height,
-		                GL_RGBA,
-		                GL_UNSIGNED_BYTE,
-		                data->getData());
-	}
+
+	while (glGetError() != GL_NO_ERROR); // Clear errors.
+
+	if (hasNpot() || (width == paddedWidth && height == paddedHeight))
+		uploadTexture();
+	else
+		uploadTexturePadded();
 
 	if (glGetError() != GL_NO_ERROR)
 		uploadDefaultTexture();

src/modules/graphics/opengl/Image.h

 	 **/
 	virtual ~Image();
 
-	float getWidth() const;
-	float getHeight() const;
+	int getWidth() const;
+	int getHeight() const;
 
 	const Vertex *getVertices() const;
 
 	love::image::CompressedData *cdata;
 
 	// Width and height of the hardware texture.
-	float width, height;
+	int width, height;
+
+	// Real dimensions of the texture, if it was auto-padded to POT size.
+	int paddedWidth, paddedHeight;
 
 	// OpenGL texture identifier.
 	GLuint texture;
 	// The source vertices of the image.
 	Vertex vertices[4];
 
-	// The scale applied to texcoords for NPOT images without NPOT support.
-	love::Vector texCoordScale;
-
 	// Mipmap texture LOD bias (sharpness) value.
 	float mipmapSharpness;
 
 
 	void preload();
 
-	void uploadTexturePadded(float p2width, float p2height);
+	void uploadTexturePadded();
 	void uploadTexture();
 
 	void uploadCompressedMipmaps();

src/modules/graphics/opengl/ParticleSystem.cpp

 	, spinStart(0)
 	, spinEnd(0)
 	, spinVariation(0)
-	, offsetX(image->getWidth()*0.5f)
-	, offsetY(image->getHeight()*0.5f)
+	, offsetX(float(image->getWidth())*0.5f)
+	, offsetY(float(image->getHeight())*0.5f)
 {
 	if (size == 0 || size > MAX_PARTICLES)
 		throw love::Exception("Invalid ParticleSystem size.");