Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

 
Advanced search

879728 Posts in 33001 Topics- by 24376 Members - Latest Member: xnothegame1

May 24, 2013, 07:12:22 PM
TIGSource ForumsDeveloperTechnical (Moderators: Glaiel-Gamer, ThemsAllTook)Question: Comparing a colour value of a pixel to another colour value ?
Pages: [1]
Print
Author Topic: Question: Comparing a colour value of a pixel to another colour value ?  (Read 194 times)
ASnogarD
Level 1
*



View Profile
« on: June 13, 2012, 07:03:31 AM »

How do you get the value of a colour of a pixel on a surface so that you can compare it with the colourkey ?
IE find the first none transparent colour in a given area ?

I have tried this code ( note the surface is 32 bit so it returns case 4 ) :

Code:

Uint32 R_Font::GetPixel32(int X, int Y) {

if(SDL_MUSTLOCK(surf_Font)) {
// Lock the surface to access the pixels
SDL_LockSurface(surf_Font);
}

int bpp = surf_Font->format->BytesPerPixel;
    // Here p is the address to the pixel we want to retrieve
    Uint8 *p = (Uint8 *)surf_Font->pixels + Y * surf_Font->pitch + X * bpp;

if(SDL_MUSTLOCK(surf_Font)) {
// Unlock the surface as access is completed
SDL_UnlockSurface(surf_Font);
}

// Return the pixel requested

switch(bpp) {
    case 1:
        return *p;
        break;

    case 2:
        return *(Uint16 *)p;
        break;

    case 3:
        if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
            return p[0] << 16 | p[1] << 8 | p[2];
        else
            return p[0] | p[1] << 8 | p[2] << 16;
        break;

    case 4:
        return *(Uint32 *)p;
        break;

    default:
        return 0;       /* shouldn't happen, but avoids warnings */
    }

}




to get the colour of the pixel at the designated X and Y co-ords to compare it to

Code:

Uint32 bgColor = SDL_MapRGB(surf_Font->format, 0xA3, 0x4D, 0xFD);


in a loop that goes through a cell containing a single character from a bitmap font sheet, the loop works like this:


Code:

int R_Font::GetFontWidth(int X, int Y) {

Uint32 bgColor = SDL_MapRGB(surf_Font->format, 0xA3, 0x4D, 0xFD);

int tWidth = 0;
int tLX = 0;
int tRX = 0;

//Find Left Side
//Go through pixel columns
for( int pCol = 0; pCol < BITMAP_CELLWIDTH; pCol++ ) {

//Go through pixel rows
for( int pRow = 0; pRow < BITMAP_CELLHEIGHT; pRow++ ) {

std::stringstream ss;



//Get the pixel offsets
int pX = X + pCol;
int pY = Y + pRow;

ss << "pX : " << pX << " pY : " << pY << " pCol : " << pCol << " pRow : " << pRow
<< "\n\n pixel32 : " << GetPixel32(pX, pY) << " BG : " << bgColor;

AddText(ss.str(),20, 320, true);

//If a non colorkey pixel is found
if(GetPixel32( pX, pY) != bgColor) {

tLX = pX;

////////////////////////////////////////////////////
// Temp debug value



//
///////////////////////////////////////////////////

//Break the loops
pCol = BITMAP_CELLWIDTH;
pRow = BITMAP_CELLHEIGHT;
}
}
}

return tWidth = tRX - tLX;

}


The code is suppose to find the first none background colour appearance, and then the left side value of my width calculation can be saved... once this part was working I was going to look for the right side and then work out the width of the character.

Its part of Lazy Foo's tutorial but modified , Foo uses a SDL_Rect object to store clips of the font, whereas I modified the code to use sdl tutorials animation code to use work out the point on the sheet to clip out as needed.

The output of the current code is that there is no colour that matches the bgColor, ie the very first pixel in the cell is not a bgColor.
Transparency works and the bitmap font system works in that as long as I specify mono spacing it will put up the text to the screen properly ( with transparency ), but its when I try to work out the width of the individual font character to place the next character in the string that the code plays up.
It runs but the getpixel32 function doesnt return the colour of the current pixel... not sure what its returning to be honest.

I have been stuck on this a few days , checking and researching data on the internet with not much help so I finally had to make a topic  Shrug
Logged

Somethings are painfully obvious, others must be made obvious... painfully.
ASnogarD
Level 1
*



View Profile
« Reply #1 on: June 13, 2012, 10:26:15 AM »

EDIT: Ok it works ... BUT IT COMPLETELY KILLS PERFORMANCE. I mean just a few lines of properly spaced text takes 1 - 2 sec to display, and delays the exit of the application.
Guess its not a good idea to dynamically work out the spacing each time text is rendered as each piece of text is rendered each loop.
I guess that makes a compelling reason to use SDL_Rects to pre-work out the font image dimensions  Facepalm
EDIT ENDS HERE.

I found some code in another site , but it didnt explain why it works but it seems to work in my function, though I cant really say why...

The code I got from the site :

Code:

unsigned int getpixel(SDL_Surface *s, int x, int y) {
return ((unsigned int*)s->pixels)[y*(s->pitch/sizeof(unsigned int)) + x];
}


I modified it to..

Code:

if(SDL_MUSTLOCK(surf_Font)) {
// Lock the surface to access the pixels
SDL_LockSurface(surf_Font);
}

Uint32 pixels = ((unsigned int*)surf_Font->pixels)[Y*(surf_Font->pitch/sizeof(unsigned int)) + X];

if(SDL_MUSTLOCK(surf_Font)) {
// Unlock the surface as access is completed
SDL_UnlockSurface(surf_Font);
}

return pixels;


It seems to be working... well it found the first characters first instance on none background colour.
Will need to test it more to be 100% sure but I wonder why the code worked in Foo's tutorial but not in my modification, and why the seemingly different code works in my modification of Foo's technique.

I'll have to read up a bit more on that but that was the solution in my case if any of you were wondering.
« Last Edit: June 13, 2012, 11:00:21 AM by ASnogarD » Logged

Somethings are painfully obvious, others must be made obvious... painfully.
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic