Welcome! Log In Create A New Profile

Advanced

Question about libwiisprite transparency

Posted by Arikado 
Re: Question about libwiisprite transparency
August 08, 2008 08:21PM
It is a u8. I've overcome most I've my problems by overhauling some of the code. This is the last (and most important) snippet of code I can't get to work.

void DrawableImage::SetAlpha(u32 i, u8 a){

   _pixels[i+3] = a;//This is the problem line

  }

That's the piece that makes the pixel transparent. By the way, this function is only called when a is set to 0. I'm one line away!
Re: Question about libwiisprite transparency
August 09, 2008 08:51AM
Should work...
Re: Question about libwiisprite transparency
August 09, 2008 05:09PM
Here's everything I have. I'm sorry, but I just can't get it working. If anyone wants to, PM me your e-mail address and I'll send you a .zip with all the files. Yes, that includes the code, makefile, image files, .pnproj, .pnps, and the build files.

drawableimage.h

#ifndef LIBWIISPRITE_DRAWABLEIMAGE
#define LIBWIISPRITE_DRAWABLEIMAGE
 
#include

 namespace wsp{ //The namespace used in libwiisprite

  class DrawableImage : public Image{

      public:

	DrawableImage(); //Constructor
	virtual ~DrawableImage(); //Destructor

     u8 GetRed(u32 i);//Retrieve the red value of a designated pixel on the DrawableImage
     u8 GetGreen(u32 i);//Retrieve the blue value of a designated pixel on the DrawableImage
     u8 GetBlue(u32 i);//Retrieve the green value of a designated pixel on the DrawableImage
     u8 GetAlpha(u32 i);//Retrieve the alpha value of a designated pixel on the DrawableImage

     void SetRed(u32 i, u8 r);//Sets the red value of a designated pixel on the DrawableImage
     void SetGreen(u32 i, u8 g);//Sets the blue value of a designated pixel on the DrawableImage
     void SetBlue(u32 i, u8 b);//Sets the green value of a designated pixel on the DrawableImage
     void SetAlpha(u32 i, u8 a);//Sets the alpha value of a designated pixel on the DrawableImage

     bool CheckPixel(u32 i, u8 r, u8 g, u8 b, u8 a);/*Compares the designated pixel on the DrawableImage with the values given to call the function*/

     void SetPixel(u32 i, u8 r, u8 g, u8 b, u8 a);//Sets the color values of the designated pixel on the DrawableImage

     void MakeTransparent(u8 r, u8 g, u8 b, u8 a);//Makes all pixels that match those values in the DrawableImage transparent

    private:

                u8* _pixels;
	u32 _width, _height;
	bool _initialized;
	GXTexObj _texObj;

  };
 };


 #endif

drawableimage.cpp

#include
#include "drawableimage.h"
#include 
#include 
#include 

 namespace wsp{ //Libwiisprite namespace

  DrawableImage::DrawableImage() : _pixels(NULL), _width(0), _height(0), _initialized(false){
  }

  DrawableImage::~DrawableImage(){

    DestroyImage();
  }

  u8 DrawableImage::GetRed(u32 i){
  
   u8 Red;
  
   Red = _pixels;
  
   return Red;
  }

  u8 DrawableImage::GetGreen(u32 i){
  
   u8 Green;

   Green = _pixels[i+1];
  
   return Green;
  }

  u8 DrawableImage::GetBlue(u32 i){
  
   u8 Blue;

   Blue = _pixels[i+2];
  
   return Blue;
  }

  u8 DrawableImage::GetAlpha(u32 i){
  
   u8 Alpha;

   Alpha = _pixels[i+3];
  
   return Alpha;
  }

  void DrawableImage::SetRed(u32 i, u8 r){

   //_pixels = r; Crash Line

  }

  void DrawableImage::SetGreen(u32 i, u8 g){

  //_pixels[i+1] = g; Crash Line

  }

  void DrawableImage::SetBlue(u32 i, u8 b){

   //_pixels[i+2] = b; Crash Line

  }

  void DrawableImage::SetAlpha(u32 i, u8 a){
  
  //_pixels[i+3] = a; Crash Line
   
  }

  bool DrawableImage::CheckPixel(u32 i, u8 r, u8 g, u8 b, u8 a){

   if(GetRed(i) == r && GetGreen(i) == g && GetBlue(i) == b && GetAlpha(i) == a)
     return true;

    else
     return false;

  }

  void DrawableImage::SetPixel(u32 i, u8 r, u8 g, u8 b, u8 a){

     SetRed(i, r);
     SetGreen(i, g);
     SetBlue(i, b);
     SetAlpha(i, a);

   }

   void DrawableImage::MakeTransparent(u8 r, u8 g, u8 b, u8 a){

    u32 height = GetHeight();
    u32 width = GetWidth();
	u32 total = width*height;
	
	_InitializeImage(width, height);

     for(u32 i = 0; i <= total; i++){

        if(CheckPixel(i, r, g, b, a))
         SetPixel(i, r, g, b, 0);

      }
     
    }

  }

testprogram.cpp

#include 
#include 
#include 
#include 
#include 

#include  // The main libwiisprite header.
using namespace wsp; // To not make us type this again and again

#include "drawableimage.h"


// libwiisprite uses wsp as it's namespace
using namespace wsp;

int main(int argc, char **argv)
{

    int x = 320;
	int y = 240;
	int speed = 8;
	
	fatInitDefault();
	
	// Create the game window and initalise the VIDEO subsystem
	GameWindow gwd;
	gwd.InitVideo();
	
	

	// Initialise Wiimote
	WPAD_Init();
	
	Image *image1 = new Image();
    image1->LoadImage("data/background.png");
	
	DrawableImage *image2 = new DrawableImage();
    image2->LoadImage("data/pointer.png");
	image2->MakeTransparent(255, 0, 255, 0xFF);
	
	
	Sprite *background = new Sprite();
	background->SetImage(image1);
	background->Draw();
	
	Sprite *bat = new Sprite();
	bat->SetImage(image2, 48, 48);

	for(;;)
	{
		WPAD_ScanPads();
		
		background->Draw();
		
		bat->SetPosition(x, y);
		bat->Draw();
		bat->NextFrame();
		
		if(WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_UP)
		x -= speed;
		
		if(WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_DOWN)
		x += speed;
		
		if(WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_RIGHT)
		y -= speed;
		
		if(WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_LEFT)
		y += speed;
		
		if((WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_UP) && (WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_RIGHT)){
		x -= speed/2;
		y -= speed/2;
		}
		
		if((WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_UP) && (WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_LEFT)){
		x -= speed/2;
		y += speed/2;
		}
		
		if((WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_DOWN) && (WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_RIGHT)){
		x += speed/2;
		y -= speed/2;
		}
		
		if((WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_DOWN) && (WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_LEFT)){
		x += speed/2;
		y += speed/2;
		}
		
		if(WPAD_ButtonsDown(WPAD_CHAN_0)&WPAD_BUTTON_HOME)
			break;
		
		if(y < 0)
		y = 0;
		
		if(y > 480)
		y = 480;
		
		if(x < 0)
		x = 0;
		
		if(x > 640)
		x = 640;
		
		gwd.Flush();
	}
	return 0;
}

Tell me if you get it working.

EDIT: I've worked at it all day, and still can't get it working. When uncommented, those "crash lines" cause the screen to go black and the wiimote to unsync. I have truly, absolutely, no idea why. If anyone tries to run this (with "crash lines" uncommented) please tell me the results. And yes, the .dol has the same effect. I can't give up, this is an important feature to libwiisprite... and yet... I just can't seem to get it working. I've spent 2 days on those "crash lines" with no effect. I really have used up every last idea I have, except for posting the code. Please help me.



Edited 2 time(s). Last edit at 08/10/2008 02:05AM by Arikado.
Re: Question about libwiisprite transparency
August 10, 2008 12:32PM
... the "crash lines" look good... i think you need to ask chaosteil for more info about the handling of _pixel by the base-class, Image.

You may want to add, and if you've time left, more overloads, because, if the user doesn't want to check on alpha, he needs to do CheackPixel 256 times:
  bool DrawableImage::CheckPixel(u32 i, u8 r, u8 g, u8 b){

   if(GetRed(i) == r && GetGreen(i) == g && GetBlue(i) == b)
     return true;

    else
     return false;

  }


void DrawableImage::SetPixel(u32 i, u8 r, u8 g, u8 b, u8 a){

     SetRed(i, r);
     SetGreen(i, g);
     SetBlue(i, b);
     SetAlpha(i, a);

   }

   void DrawableImage::MakeTransparent(u8 r, u8 g, u8 b){

    u32 height = GetHeight();
    u32 width = GetWidth();
	u32 total = width*height;
	
	_InitializeImage(width, height);

     for(u32 i = 0; i <= total; i++){

        if(CheckPixel(i, r, g, b))
         SetPixel(i, r, g, b, 0);

      }
     
    }

Re: Question about libwiisprite transparency
August 10, 2008 06:08PM
Quote
chaosteil
_pixels is an array of u8. Or, as declared in the header file:

u8* _pixels; //!< Stores the pixeldata of this image. Use carefully.

So it shouldn't crash. At all. In fact, this is a wtf situation right here :/
Re: Question about libwiisprite transparency
August 10, 2008 08:11PM
First of all, chaosteil is plain wrong since he is confused and remembers wrong. _pixels is NOT just (x*width+y)*4, but an extremely fucked up texture format used by GX. Yes, the comment in the source is wrong too.

Long story short, it is saved in pairs of blocks of 4x4 pixels, the first block being the pixel values in AR order and the second block being the pixel values for GB.
Or as in c code:
struct GX_block1_pixel {
u8 A,R;
};

struct GX_block2_pixel {
u8 G,B
};

struct GX_block {
GX_block1_pixel block1[4*4];
GX_block2_pixel block2[4*4];
};

GX_block *_pixels;

Also see my Canvas class that hides away this mess and already comes with a few of the basic drawing operators.



Edited 1 time(s). Last edit at 08/10/2008 08:14PM by henke37.
Re: Question about libwiisprite transparency
August 10, 2008 10:26PM
Thank you for clearing that up. That is the worst texture format I've ever seen! I didn't know anything about GX so that explains alot. How would you reccomend I solve my transparency problem?
Re: Question about libwiisprite transparency
August 11, 2008 08:47AM
So...
u8 R = _pixel[((pixel - (pixel%16)) / 16) * 64 + (pixel%16) * 32]
Wild, not checked guess.. but try, maybe it works.



Edited 1 time(s). Last edit at 08/11/2008 08:48AM by Dykam.
Re: Question about libwiisprite transparency
August 11, 2008 03:11PM
To get transparency, just use the alpha channel in the png format.
Re: Question about libwiisprite transparency
August 11, 2008 03:32PM
I believe thats what I'm trying to do. See SetAlpha() in my code above.
Re: Question about libwiisprite transparency
August 11, 2008 04:25PM
That method is for the global alpha, but what you want is the real alpha channel in the png file. So get a better png file creator that allows you to specify the alpha channel.
Re: Question about libwiisprite transparency
August 11, 2008 06:56PM
So I rewrote the testprogram.cpp so that MakeTransparent is called when you press the A button. This intentionally crashed the Wii and it responded by giving me a code dump. I'm analyzing the dump to see if I can fix the problem without having to use the "real alpha channel".
Re: Question about libwiisprite transparency
August 11, 2008 07:44PM
Quote
henke37
That method is for the global alpha, but what you want is the real alpha channel in the png file. So get a better png file creator that allows you to specify the alpha channel.
I know, that's what I do, but Arikado wanted it to solve it this way, so I help- thinikng :D.
Re: Question about libwiisprite transparency
August 12, 2008 02:24AM
And I really appreciate your help Dykam :) Still analyzing binaries right now...
Re: Question about libwiisprite transparency
August 12, 2008 11:35PM
I finished the analysis of the code dump and this appears to be the offender:

void DrawableImage::SetAlpha(u32 i, u8 a){
  
  _pixels[i+3] = a; //This is the offending line of code
   
  }

I have no idea why. I'm really just out of ideas at this point. Please help me!
Re: Question about libwiisprite transparency
August 13, 2008 04:09PM
... can you see when it hits the line? I mean, when the error occured. Isn't it something like i+3 is more then _pixels[]-lenght?
Re: Question about libwiisprite transparency
August 13, 2008 07:44PM
Actually, the binaries were only able to tell me what the bad line was. I switched the line to this and got the ame results:

_pixels[0+3] = 0;
So since raw numbers don't work, I'm out of ideas.

EDIT: One last idea, maybe it's just my Wii this doesn't work on. Would anyone else like to try my program? If so, post or PM me your e-mail address.



Edited 1 time(s). Last edit at 08/13/2008 11:01PM by Arikado.
Re: Question about libwiisprite transparency
August 14, 2008 03:01AM
What is the length of _pixels?
Re: Question about libwiisprite transparency
August 14, 2008 05:02AM
Actually, its an array with one member for each pixel.
Re: Question about libwiisprite transparency
August 14, 2008 05:17AM
I can see it's an array. Can you still not get it to work?
Sorry, only registered users may post in this forum.

Click here to login