Просмотр исходного кода

Merge pull request #280 from CIB/cleanup

Image updates
Ivan Safrin 12 лет назад
Родитель
Сommit
7cad49d2ad

+ 35 - 20
Core/Contents/Include/PolyImage.h

@@ -23,6 +23,7 @@ THE SOFTWARE.
 #pragma once
 #include "PolyGlobals.h"
 #include "PolyColor.h"
+#include "PolyRectangle.h"
 
 namespace Polycode {
 
@@ -103,16 +104,13 @@ namespace Polycode {
 			* @param width Width of the image to create.
 			* @param height Height of the image to create.			
 			*/ 						
-			void createEmpty(unsigned int width, unsigned int height);
-			
+			void createEmpty(int width, int height);
+
 			/**
 			* Fills the image with the specified color values.
-			* @param r Red value 0-1.
-			* @param g Green value 0-1
-			* @param b Blue value 0-1
-			* @param a Alpha value 0-1									
+			* @param color The color to fill it with.
 			*/ 									
-			void fill(Number r, Number g, Number b, Number a);
+			void fill(Color color);
 			
 			/**
 			* Sets a pixel at specified coordinates to specified color.
@@ -151,21 +149,21 @@ namespace Polycode {
 			* @param y1 Ending y position.
 			* @param col Color to use.						
 			*/						
-			void line(int x0, int y0, int x1, int y1, Color col);
+			void drawLine(int x0, int y0, int x1, int y1, Color col);
 
 			/**
 			* Moves brush to specified position
 			* @param x New brush position X
 			* @param y New brush position Y
 			*/									
-			void moveTo(int x, int y);
+			void moveBrushTo(int x, int y);
 			
 			/**
 			* Translates brush a specified amount relative to its current position.
 			* @param x Amount to translate on X axis
 			* @param y Amount to translate on Y axis
 			*/												
-			void move(int x, int y);
+			void moveBrush(int x, int y);
 			
 			/**
 			* Draws a line to specified position.
@@ -173,7 +171,7 @@ namespace Polycode {
 			* @param y Ending y position.
 			* @param col Color to use.						
 			*/												
-			void lineTo(int x, int y, Color col);
+			void drawLineTo(int x, int y, Color col);
 			
 			/**
 			* Draws a rectangle with specified color.
@@ -183,7 +181,7 @@ namespace Polycode {
 			* @param h Rectangle height.
 			* @param col Color to use.						
 			*/									
-			void drawRect(int x, int y, int w, int h, Color col);
+			void fillRect(int x, int y, int w, int h, Color col);
 			
 			/**
 			* Draws perlin noise in the image
@@ -218,9 +216,19 @@ namespace Polycode {
 			* @param x X position of the area to return.
 			* @param y Y position of the area to return.
 			* @param width Width of the area to return.
-			* @param height Height of the area to return.					
+			* @param height Height of the area to return.
+			* @return Raw image data, in the format specified by the constructor.
 			*/			
-			char *getPixelsInRect(unsigned int x, unsigned int y, unsigned int width, unsigned int height);
+			char *getPixelsInRect(int x, int y, int width, int height);
+
+			/**
+			* Returns a copy of the specified subRect part of the image.
+			*
+			* @param subRect The part of the image to copy. (0, 0) refers to the top left of the image.
+			* @return A pointer to an Image object allocated with new. You have to manually delete this
+			*         object using free.
+			*/
+			Image *getImagePart(Rectangle subRect);
 			
 			/**
 			* Returns the x position of the brush.
@@ -241,16 +249,16 @@ namespace Polycode {
 			/**
 			* Returns the width of the image.
 			*/			
-			unsigned int getWidth() const;
+			int getWidth() const;
 			
 			/**
 			* Returns the height of the image.
 			*/						
-			unsigned int getHeight() const;
+			int getHeight() const;
 			
 			/**
 			* Returns the raw image data
-			* @return Pointer to raw image data.
+			* @return Pointer to raw image data, in the format specified by the constructor.
 			*/						
 			char *getPixels();
 			
@@ -262,7 +270,14 @@ namespace Polycode {
 		
 		protected:
 		
-			void setPixelType(int type);		
+			void setPixelType(int type);
+
+			// transform coordinates from external topleft position mode
+			// to internal bottomleft position mode
+			//
+			// results are written directly into the pointers
+			void transformCoordinates(int *x, int *y);	
+			void transformCoordinates(int *x, int *y, int *w, int *h);	
 		
 		int imageType;
 		int pixelSize;
@@ -274,8 +289,8 @@ namespace Polycode {
 		int brushPosY;
 		
 		char *imageData;
-		unsigned int width;
-		unsigned int height;
+		int width;
+		int height;
 	};
 
 }

+ 36 - 30
Core/Contents/Source/PolyImage.cpp

@@ -27,6 +27,7 @@
 #include "PolyLogger.h"
 #include "OSBasics.h"
 #include "PolyPerlin.h"
+#include <algorithm>
 
 using namespace Polycode;
 
@@ -117,38 +118,34 @@ char *Image::getPixels() {
 	return imageData;
 }
 
-char *Image::getPixelsInRect(unsigned int x, unsigned int y, unsigned int width, unsigned int height) {
+char *Image::getPixelsInRect(int x, int y, int width, int height) {
+	transformCoordinates(&x, &y, &width, &height);
 	char *retBuf = (char*) malloc(pixelSize * width * height);
 	memset(retBuf, 0, pixelSize * width * height);
 	
 	if(x < this->width-1 && y < this->height-1) {
-		
-		unsigned int xAmt;
-		unsigned int yAmt;	
-		if(x + width > this->width) {
-			xAmt = this->width - x;
-		} else {
-			xAmt = width;
-		}
 
-		if(y + height > this->height) {
-			yAmt = this->height - y;
-		} else {
-			yAmt = height;
-		}
+		width = std::min(width, this->width - x);
+		height = std::min(height, this->height - y);
 
-		for(int i=0; i < yAmt; i++) {
+		for(int i=0; i < height; i++) {
 			long srcOffset = ((pixelSize*this->width) * (y+i)) + (pixelSize*x);
-			long dstOffset = (pixelSize*xAmt) * i;
-			memcpy(retBuf + dstOffset, imageData+srcOffset, pixelSize * xAmt);
+			long dstOffset = (pixelSize*width) * i;
+			memcpy(retBuf + dstOffset, imageData+srcOffset, pixelSize * width);
 		}	
 	}
 		
 	return retBuf;
 }
 
+Image *Image::getImagePart(Rectangle subRect) {
+	char *newData = getPixelsInRect( (int) subRect.x, (int) subRect.y, (int) subRect.w, (int) subRect.h);
+	return new Image(newData, subRect.w, subRect.h, this->imageType);
+}
+
 
 Color Image::getPixel(int x, int y) {
+	transformCoordinates(&x, &y);
 	if(x < 0 || x >= width || y < 0 || y >= height)
 		return Color(0,0,0,0);
 	unsigned int *imageData32 = (unsigned int*)imageData;	
@@ -162,22 +159,22 @@ Color Image::getPixel(int x, int y) {
 	return Color(((Number)tr)/255.0f, ((Number)tg)/255.0f, ((Number)tb)/255.0f,((Number)ta)/255.0f);
 }
 
-unsigned int Image::getWidth() const {
+int Image::getWidth() const {
 	return width;
 }
 
-unsigned int Image::getHeight() const {
+int Image::getHeight() const {
 	return height;
 }
 
-void Image::createEmpty(unsigned int width, unsigned int height) {
+void Image::createEmpty(int width, int height) {
 	free(imageData);
 		
 	imageData = (char*)malloc(width*height*pixelSize);
 	this->width = width;
 	this->height = height;
 	
-	fill(0,0,0,0);
+	fill(Color(0,0,0,0));
 }
 
 void Image::perlinNoise(int seed, bool alpha) {
@@ -203,7 +200,7 @@ void Image::writeBMP(const String& fileName) const {
 //	SDL_SaveBMP(image, fileName.c_str());
 }
 
-void Image::drawRect(int x, int y, int w, int h, Color col) {
+void Image::fillRect(int x, int y, int w, int h, Color col) {
 	for(int i=0; i < w; i++) {
 		for(int j=0; j < h; j++) {
 			setPixel(x+i,y+j,col);
@@ -212,6 +209,7 @@ void Image::drawRect(int x, int y, int w, int h, Color col) {
 }
 
 void Image::setPixel(int x, int y, Color col) {
+	transformCoordinates(&x, &y);
 	if(x < 0 || x >= width || y < 0 || y >= height)
 		return;
 
@@ -220,12 +218,12 @@ void Image::setPixel(int x, int y, Color col) {
 }
 
 
-void Image::move(int x, int y) {
+void Image::moveBrush(int x, int y) {
 	brushPosX += x;
-	brushPosY += y;
+	brushPosY -= y;
 }
 
-void Image::moveTo(int x, int y) {
+void Image::moveBrushTo(int x, int y) {
 	brushPosX = x;
 	brushPosY = y;
 }
@@ -239,11 +237,12 @@ int Image::getBrushY() const {
 	return brushPosY;
 }
 
-void Image::lineTo(int x, int y, Color col) {
-	line(brushPosX, brushPosY, brushPosX+x, brushPosY+y, col);
+void Image::drawLineTo(int x, int y, Color col) {
+	drawLine(brushPosX, brushPosY, brushPosX+x, brushPosY+y, col);
 }
 
 void Image::setPixel(int x, int y, Number r, Number g, Number b, Number a) {
+	transformCoordinates(&x, &y);
 	if(x < 0 || x > width || y < 0 || y > height)
 		return;
 
@@ -617,7 +616,7 @@ void Image::swap(int *v1, int *v2) {
 	*v2 = tv;
 }
 
-void Image::line(int x0, int y0, int x1, int y1, Color col) {
+void Image::drawLine(int x0, int y0, int x1, int y1, Color col) {
 	bool steep = abs(y1 - y0) > abs(x1 - x0);
 	if(steep) {
 		swap(&x0, &y0);
@@ -654,8 +653,7 @@ void Image::line(int x0, int y0, int x1, int y1, Color col) {
 	}
 }
 
-void Image::fill(Number r, Number g, Number b, Number a) {
-	Color color = Color(r,g,b,a);
+void Image::fill(Color color) {
 	unsigned int val = color.getUint();
 	unsigned int *imageData32 = (unsigned int*) imageData;
 	for(int i=0; i< width*height; i++) {
@@ -883,3 +881,11 @@ bool Image::loadPNG(const String& fileName) {
 	imageData = image_data;
 	return true;
 }
+
+void Image::transformCoordinates(int *x, int *y) {
+	*y = this->height - *y - 1;
+}
+
+void Image::transformCoordinates(int *x, int *y, int *w, int *h) {
+	*y = this->height - *h - *y - 1;
+}

+ 1 - 1
Core/Contents/Source/PolyMaterialManager.cpp

@@ -130,7 +130,7 @@ Texture *MaterialManager::createFramebufferTexture(int width, int height, int ty
 
 Texture *MaterialManager::createNewTexture(int width, int height, bool clamp, bool createMipmaps, int type) {
 	Image *newImage = new Image(width, height, type);
-	newImage->fill(1,1,1,1);
+	newImage->fill(Color(1,1,1,1));
 	Texture *retTexture = createTextureFromImage(newImage, clamp, createMipmaps);
 	delete newImage;
 	return retTexture;