Adjust alpha values in an image

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
AlphaDingDong
Posts: 29
Joined: Fri Mar 21, 2008 2:51 pm
Location: The interwebs

Adjust alpha values in an image

Post by AlphaDingDong »

Okay. I've got everything installed and set up. I've completed the tutorials at psp-programming.com and all the C I learned in college is starting to trickle back into my brain after 10 long years of neglect. I've created a small demo project to start myself out and it's going well. I've been easily able to look up any information I've needed either on google or in one of my programming books from college.

However, I do seem to be stuck one one small detail.

I've been using a graphics package that I downloaded for lesson 4 of the tutorials (link) and it seems to handle alpha values. I'm only working with .png images, using zlib and libpng from this site's svn server.

svn://svn.pspdev.org/psp/trunk/zlib
svn://svn.pspdev.org/psp/trunk/libpng

There's a function in it to draw text to an image and of course a function to alpha-blit an image to the screen.

What I'm trying to do is make some text that will slowly fade out. I figure if I create an empty image and draw the text to it and then lower the image's alpha by 1 each frame until it hits 0 then it should look pretty nice and use less cpu than redrawing the text every frame (the alpha for the text drawing doesn't seem to work anyway).

The problem is that I don't know how to adjust the alpha values of an image. I've looked through graphics.c a few times and I can't make head nor tail of the blit functions.

Could anyone give me some advice? I would have thought I could just sweep through the image with some nested while()'s and set the alpha for each pixel. Can this be done?

Many thanks for everyone's time.
Insert_witty_name
Posts: 376
Joined: Wed May 10, 2006 11:31 pm

Post by Insert_witty_name »

Hi ADD.

What you need to do cannot be done using the graphics.c file from that tutorial.

I would suggest starting to learn GU.

Using GU, all you need to do is change a few init params.

Code: Select all

sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_FIX, 0xffffffff, 0xffffffff);
Then when you build your vert array, ensure it has a color member, and use this to set the alpha you need.

Code: Select all

vertices[0].color = GU_RGBA(255, 255, 255, alpha);
Then when you draw using something like:

Code: Select all

sceGuDrawArray(GU_SPRITES, GU_COLOR_8888|GU_TEXTURE_32BITF|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 2, 0, vertices);
The texture will appear with alpha that you have specified.

Looping through the texture and altering it's data to give you the required alpha is not good practice.

There are plenty of GU samples in the SDK, and even a set of 11 simple tutorials aimed at a beginner here: http://www.psp-programming.com/code/dok ... :tutorials

I really would recommend to learn GU, instead of using the graphics.c supplied in the tutorial.

Hope this helps.
AlphaDingDong
Posts: 29
Joined: Fri Mar 21, 2008 2:51 pm
Location: The interwebs

Post by AlphaDingDong »

Awesome. I will definitely check out the tuts there. Thanks, man. I did sort of have an uneasy feeling about manually adjusting the pixels, but I figured it would be okay since the image was so small. Much better if the GU can handle it, though.

Thanks again.
moonlight
Posts: 567
Joined: Wed Oct 26, 2005 7:46 pm

Post by moonlight »

Alternatively, you can use a simple sceGuColor, that is what sce tends to do (for whatever reason, they never set the color in vertex).

The blitAlphaImageToScree function with the parameter "alpha" added to the end would be like:

Code: Select all

void blitAlphaImageToScreen(int sx, int sy, int width, int height, Image* source, int dx, int dy, u32 alpha)
{
	if (!initialized) return;

	sceKernelDcacheWritebackInvalidateAll();
	guStart();
	sceGuColor&#40;&#40;alpha << 24&#41; | 0xFFFFFF&#41;;
	sceGuTexFunc&#40;GU_TFX_MODULATE, GU_TCC_RGBA&#41;;
	sceGuTexImage&#40;0, source->textureWidth, source->textureHeight, source->textureWidth, &#40;void*&#41; source->data&#41;;
	float u = 1.0f / &#40;&#40;float&#41;source->textureWidth&#41;;
	float v = 1.0f / &#40;&#40;float&#41;source->textureHeight&#41;;
	sceGuTexScale&#40;u, v&#41;;
	
	int j = 0;
	while &#40;j < width&#41; &#123;
		Vertex* vertices = &#40;Vertex*&#41; sceGuGetMemory&#40;2 * sizeof&#40;Vertex&#41;&#41;;
		int sliceWidth = 64;
		if &#40;j + sliceWidth > width&#41; sliceWidth = width - j;
		vertices&#91;0&#93;.u = sx + j;
		vertices&#91;0&#93;.v = sy;
		vertices&#91;0&#93;.x = dx + j;
		vertices&#91;0&#93;.y = dy;
		vertices&#91;0&#93;.z = 0;
		vertices&#91;1&#93;.u = sx + j + sliceWidth;
		vertices&#91;1&#93;.v = sy + height;
		vertices&#91;1&#93;.x = dx + j + sliceWidth;
		vertices&#91;1&#93;.y = dy + height;
		vertices&#91;1&#93;.z = 0;
		sceGuDrawArray&#40;GU_SPRITES, GU_TEXTURE_16BIT | GU_VERTEX_16BIT | GU_TRANSFORM_2D, 2, 0, vertices&#41;;
		j += sliceWidth;
	&#125;
	
	sceGuFinish&#40;&#41;;
	sceGuSync&#40;0, 0&#41;;
&#125;
And a main code sample:

Code: Select all

#include <pspsdk.h>
#include <pspdisplay.h>
#include <pspgu.h>
#include "graphics.h"

PSP_MODULE_INFO&#40;"ModuleName", 0, 1, 0&#41;;
PSP_MAIN_THREAD_ATTR&#40;PSP_THREAD_ATTR_USER&#41;;

int main&#40;&#41;
&#123;
	initGraphics&#40;&#41;;

	Image* image = createImage&#40;200, 8&#41;;
	clearImage&#40;0xFF000000, image&#41;;

	printTextImage&#40;0, 0, "This is a red text", 0xFF0000FF, image&#41;;

	int alpha = 0xFF;

	while &#40;1&#41;
	&#123;
		clearScreen&#40;0&#41;;
		blitAlphaImageToScreen&#40;0, 0, 200, 8, image, 180, 100, alpha&0xFF&#41;;
		sceDisplayWaitVblankStart&#40;&#41;;
		flipScreen&#40;&#41;;

		if &#40;--alpha < 0&#41;
			alpha = 0xFF;
	&#125;


	return 0;
&#125;
Art
Posts: 642
Joined: Wed Nov 09, 2005 8:01 am

Post by Art »

Thanks for that moonlight :) It might be handy.
Now AlphaDingDong will have to change his nick to: (the next problem he has)DingDong.
If not actually, then potentially.
AlphaDingDong
Posts: 29
Joined: Fri Mar 21, 2008 2:51 pm
Location: The interwebs

Post by AlphaDingDong »

XD

Thanks, guys. It's been a busy week, but I'm sitting down in a few minutes to start learning GU and get cookin' on this.

Oh, and lol (@art). :)
AlphaDingDong
Posts: 29
Joined: Fri Mar 21, 2008 2:51 pm
Location: The interwebs

Post by AlphaDingDong »

Sorry to double but it's been a couple days.

GU Lesson 1 - Things I don't understand:

1) There are some variables declared like so:

u32 tickResolution;
u64 fpsTickNow;

Is this unsigned ints of 32 bits and 64 bits respectively?

2) The vertex structs are created with this thingy in the declaration:

__attribute__((aligned(16)))

The tut specifies that this means the data will be 16 bit aligned. Does that mean that the properties of the struct will be stored in 16 bits even if their value only needs 8 bits? IOW, would 0x2F be stored as 0x002F? All hex hacking of RAM for video games I've ever done has had variables stored in this way, so I'm guessing that's what it means.

3) I understand the properties of the vertex struct. It a simply stores RGBA and XYZ. However, the tut author used a notation I'm not familiar with: 1.0f. I'm assuming this means float 1.0, but is that really necessary, since the XYZ are already floats, and how does it work with the RGBA being unsigned ints?

4) I noticed that in both vertex arrays the author used an alpha value of 0.0f, but the objects still appeared onscreen. I thought the alpha may be reversed, so I set it to 1.0f but there was no change. Then I thought maybe it only applies to colors, so I changed to color to red, but with the alpha at 1.0f and 0.0f there was no difference. Am I missing something here?

5) Apparently sceGumDrawArray() needs one of the following types:

Point, Line, Line Strip, Triangles, Triangle Strip, Triangle Fan or Sprites.

What is the difference between these types? I messed around with them a little, but I don't really get what each one does specifically. I _think_ triangle strip uses the first 2 points to create a line, then the next point makes a second line and the third line is automatically between the start and endpoint of the 2 lines, then the next point makes a new line and the whole thing sort of gets shifted down so that line 2 from the previous triangle becomes line 1 and the new line becomes line 2, etc. Whereas I _think_ triangle fan shifts the points instead of the lines such that 2 points is a line and then the third point makes a triangle but then the next point makes the old point 3 become point 2 but keeps the same point 1....

Holy crap, did that make any sense at all?

I think that's all for now. I'm gonna move on to further lessons and see if it makes any more sense. For now all I can do is screw with this guy's code and make my triangle and square do some really uncomfortable things (for polygons). I get really uneasy when I don't understand 80% of the lines in a program that's supposedly mine. :(

Help?

P.S. -- I just realized that inadvertently used my wall-of-text attack there asking for favors and I know none of you owe me a damn thing. Sorry about that.

I'm really eager to learn this stuff because I've always only dealt with 2D sprite-based apps in the past and usually in scripting languages on PC platforms. Now I find myself suddenly able to code for an actual game-device, and not only that, but the possibility of learning to work with 3D models!

So I just want to say that I really do appreciate any and all help that I get from anyone here and I appreciate that there's a place where I can go to ask these questions. Thanks, y'all. Sorry if I get ahead of myself and seem presumptuous.
Tinnus
Posts: 67
Joined: Sat Jul 29, 2006 1:12 am

Post by Tinnus »

You might try taking a look at the NeHe OpenGL tutorials ( nehe.gamedev.net ) or something to learn more about the basics of 3D programming, like those primitive types. Just ignore the OpenGL bits (or better yet, read them too so you learn even more :) )
Let's see what the PSP reserves... well, I'd say anything is better than Palm OS.
AlphaDingDong
Posts: 29
Joined: Fri Mar 21, 2008 2:51 pm
Location: The interwebs

Post by AlphaDingDong »

I'll take a look. Thanks. Know anything about that other stuff?
User avatar
Jim
Posts: 476
Joined: Sat Jul 02, 2005 10:06 pm
Location: Sydney
Contact:

Post by Jim »

Sorry to double but it's been a couple days.

GU Lesson 1 - Things I don't understand:

1) There are some variables declared like so:

u32 tickResolution;
u64 fpsTickNow;

Is this unsigned ints of 32 bits and 64 bits respectively?
Yes.
2) The vertex structs are created with this thingy in the declaration:

__attribute__((aligned(16)))

The tut specifies that this means the data will be 16 bit aligned. Does that mean that the properties of the struct will be stored in 16 bits even if their value only needs 8 bits? IOW, would 0x2F be stored as 0x002F? All hex hacking of RAM for video games I've ever done has had variables stored in this way, so I'm guessing that's what it means.
It just changes the address the object is stored at to be a multiple of 16 BYTES not bits. It doesn't change the size of the object. Some of the PSP custom hardware needs this address alignment.
3) I understand the properties of the vertex struct. It a simply stores RGBA and XYZ. However, the tut author used a notation I'm not familiar with: 1.0f. I'm assuming this means float 1.0, but is that really necessary, since the XYZ are already floats, and how does it work with the RGBA being unsigned ints?
1.0f is a float, 1.0 is a double. floats are way faster than doubles because they are handled in hardware, and they 32bit instead of 64
4) I noticed that in both vertex arrays the author used an alpha value of 0.0f, but the objects still appeared onscreen. I thought the alpha may be reversed, so I set it to 1.0f but there was no change. Then I thought maybe it only applies to colors, so I changed to color to red, but with the alpha at 1.0f and 0.0f there was no difference. Am I missing something here?
If alpha blending is turned off it doesn't matter the value.
5) Apparently sceGumDrawArray() needs one of the following types:

Point, Line, Line Strip, Triangles, Triangle Strip, Triangle Fan or Sprites.

What is the difference between these types?
http://books.google.com.au/books?id=dJo ... n#PPA62,M1

Jim[/url]
sallyxi
Posts: 3
Joined: Fri Apr 25, 2008 12:46 am
Contact:

Post by sallyxi »

Any guys who can display the way to solve it will be highly appeciated.
AlphaDingDong
Posts: 29
Joined: Fri Mar 21, 2008 2:51 pm
Location: The interwebs

Post by AlphaDingDong »

Thanks again, Jim.

I've figured out the primitives now (except the sprite one but I'll get there). My brain hurts at the idea of coding something similar to Crisis Core or another game like it. X|

lol

I think I'll try to figure out the rest of this stuff a piece at a time and then once I've got a bit of a grasp on it I'll start messing with sprite primitives.
Post Reply