🔒 Locked
Masking
Advertisement
Original Post
Hi, I received a document from someone when I last talked here with them on masking. It turned out, however, that it was not self-explaining enough for me. (I'm somewhat new to OpenGL). I am using python and PyOpenGL. I need to know the code to mask part of a texture. I want to mask (see though) one color in the texture. I believe that there was something about using a black and white image and having the texture be drawn on the white part later. How exactly this translates into python code is my problem. Thx, Geometrian
I believe what you are referring to is called "colour-key transparency" - where you designate one colour to be the transparent parts of the image - like a blue-screen effect.
OpenGL (or Direct3D) won't do this for you. What you need to do is convert your RGB image to an RGBA image on the fly.
something like this psudocode:
OpenGL (or Direct3D) won't do this for you. What you need to do is convert your RGB image to an RGBA image on the fly.
something like this psudocode:
srcPixels = Colour[width][height] //load RGB image from a file etc...dstPixels = new ColourWithAlpha[width][height] //make a new RGBA image in memorycolourKey = Colour(0,255,0) //green shall be our transparent colour//for each pixelfor x=0 ; x<width; ++x{ for y=0 ; y<height; ++y { //copy the RGB components to the new image dstPixels[x][y].red = srcPixels[x][y].red dstPixels[x][y].green = srcPixels[x][y].green dstPixels[x][y].blue = srcPixels[x][y].blue //check if the pixel is a "transparent" pixel, and set the alpha if( srcPixels[x][y] == colourKey ) dstPixels[x][y].alpha = 0 else dstPixels[x][y].alpha = 255 }}
How would this work in python? Sorry, I'm terrible in C++.
Its been a few years since I touched python, and havent used PyOpenGL, so I probably can't help you much, but...
How are you loading your textures in the first place?
Is there somewhere in your code where you have access to an array which represents your texture? If so, then this is the place where you need to implement the above idea...
Your texture will be an array of bytes "3 x Width x Height" large (RGB), you need to make a new array that is "4 x Width x Height" large (RGBA). and for each pixel (group of 3 bytes) in the original array, copy them into the new array followed by an alpha value (which is determined by comparing the RGB values with the colour-key value). You can then throw away the original RGB array and use the RGBA one instead.
If you post some texture-loading code I might be able to help more :(
How are you loading your textures in the first place?
Is there somewhere in your code where you have access to an array which represents your texture? If so, then this is the place where you need to implement the above idea...
Your texture will be an array of bytes "3 x Width x Height" large (RGB), you need to make a new array that is "4 x Width x Height" large (RGBA). and for each pixel (group of 3 bytes) in the original array, copy them into the new array followed by an alpha value (which is determined by comparing the RGB values with the colour-key value). You can then throw away the original RGB array and use the RGBA one instead.
If you post some texture-loading code I might be able to help more :(
Here: (this is python)
File = os.path.join('Data/Final','Image.bmp')
Surface = pygame.image.load(File)
Data = pygame.image.tostring(Surface, "RGBX", 1)
File = os.path.join('Data/Final','Image.bmp')
Surface = pygame.image.load(File)
Data = pygame.image.tostring(Surface, "RGBX", 1)
Thanks,
This code looks promising. I want to use (255,255,255) white. I substituted white in for green and it replaces all white parts of my texture with black- you still can't see through it. I set it up like this:
key = pygame.color.Color('white')
File = os.path.join('Data/Final','Image.bmp')
Surface = pygame.image.load(File)
Surface.set_colorkey(key)
Surface = pygame.Surface.convert_alpha(Surface)
Data = pygame.image.tostring(Surface, "RGBX", 1)
[Edited by - Geometrian on April 12, 2007 3:17:15 PM]
This code looks promising. I want to use (255,255,255) white. I substituted white in for green and it replaces all white parts of my texture with black- you still can't see through it. I set it up like this:
key = pygame.color.Color('white')
File = os.path.join('Data/Final','Image.bmp')
Surface = pygame.image.load(File)
Surface.set_colorkey(key)
Surface = pygame.Surface.convert_alpha(Surface)
Data = pygame.image.tostring(Surface, "RGBX", 1)
[Edited by - Geometrian on April 12, 2007 3:17:15 PM]
ok, sounds like you are creating the RGBA texture properly, but alpha blending isn't turned on when you render it..
Not sure how to enable alpha blending in pygame, but If i were to have a guess:
in C i would write something like this before I drew the image...
Not sure how to enable alpha blending in pygame, but If i were to have a guess:
Surface = pygame.Surface((Surface.get_width(), Surface.get_height()), SRCALPHA, Surface)in C i would write something like this before I drew the image...
glEnable( GL_BLEND );glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );//... draw somethingglDisable( GL_BLEND );
Question: How do I put in one of those scrolling subwindows in a post, like you do to show code?
OK... I put it in like this:
key = pygame.color.Color('white')
File = os.path.join('Data/Final','Image.bmp')
Surface = pygame.image.load(File)
Surface.set_colorkey(key)
Surface=pygame.Surface((Surface.get_width(Surface),Surface.get_height(Surface)),SRCALPHA,Surface)
Surface = pygame.Surface.convert_alpha(Surface)
Data = pygame.image.tostring(Surface, "RGBX", 1)
...I get a blank (black) screen? I think that the problem lies in the order of these three lines?:
Surface.set_colorkey(key)
Surface=pygame.Surface((Surface.get_width(Surface),Surface.get_height(Surface)),SRCALPHA,Surface)
Surface = pygame.Surface.convert_alpha(Surface)
OK... I put it in like this:
key = pygame.color.Color('white')
File = os.path.join('Data/Final','Image.bmp')
Surface = pygame.image.load(File)
Surface.set_colorkey(key)
Surface=pygame.Surface((Surface.get_width(Surface),Surface.get_height(Surface)),SRCALPHA,Surface)
Surface = pygame.Surface.convert_alpha(Surface)
Data = pygame.image.tostring(Surface, "RGBX", 1)
...I get a blank (black) screen? I think that the problem lies in the order of these three lines?:
Surface.set_colorkey(key)
Surface=pygame.Surface((Surface.get_width(Surface),Surface.get_height(Surface)),SRCALPHA,Surface)
Surface = pygame.Surface.convert_alpha(Surface)
Quote:
Original post by Geometrian
Question: How do I put in one of those scrolling subwindows in a post, like you do to show code?
[*source*] and [/source*] (without the *'s)
Hmm I'm not sure, maybe try:
Surface=pygame.Surface((Surface.get_width(Surface),Surface.get_height(Surface)),SRCALPHA,Surface)
Surface.set_colorkey(key)
Surface = pygame.Surface.convert_alpha(Surface)
maybe you should try the pygame mailing list, there doesnt seem to be any pygame experts around at the moment :(
Sorry, that didn't work either. Because of your help, I can now understand at least part of the documentation. I'm now writing a test program as a separate project. If I get this program to work, I'll let everyone know here. Thanks for your help! I'll check back a few times later in case you wanted to add anything.
Ok... That didn't take very long. Hodgman's instruction let me see what the basic idea of masking is. Thanks! Here is the winning code: (In the code format too!)
Note that these are just the basic lines of code. In reality, they would be spread out over your program. Thanks again Hodgman!
Geometrian
surface = pygame.display.get_surface()MaskFile = os.path.join('Data','Image.bmp')MaskSurface = pygame.image.load(MaskFile).convert()MaskSurface.set_colorkey( (color), 0 )MaskedSurface = MaskSurface.convert_alphasurface.blit( (MaskSurface), ((x1,y1),(x2,y2)) )Note that these are just the basic lines of code. In reality, they would be spread out over your program. Thanks again Hodgman!
Geometrian
It doesn't appear to need this line of code...
so you get:
I'm rechecking my program because while a basic pygame program (like this one) works, PyOpenGL does not. I put the same code into it but it doesn't work. I think that it's because PyOpenGL requires images to be in string format. i.e. :
Note the Data = pygame.image.tostring() command. I did all of this like in the nehe.gamedev.net tutorials but it looks the same as if I had never tried to do any masking.
[Edited by - Geometrian on April 13, 2007 11:02:40 AM]
MaskedSurface = MaskSurface.convert_alphaso you get:
surface = pygame.display.get_surface()MaskFile = os.path.join('Data','Data1.bmp')MaskSurface=pygame.image.load(MaskFile).convert()MaskSurface.set_colorkey((255,255,255),0)surface.blit((MaskSurface), ((blitx),(blity)))I'm rechecking my program because while a basic pygame program (like this one) works, PyOpenGL does not. I put the same code into it but it doesn't work. I think that it's because PyOpenGL requires images to be in string format. i.e. :
surface = pygame.display.get_surface()MaskFile = os.path.join('Data','Data1.bmp')MaskSurface = pygame.image.load(MaskFile).convert()MaskSurface.set_colorkey((255,255,255),0)Data = pygame.image.tostring(MaskSurface, "RGBA", 1)#Later: PyOpenGL drawingglBindTexture(GL_TEXTURE_2D, textures[texturenumber])glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, MaskSurface.get_width(), MaskSurface.get_height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, Data );glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)glBegin(GL_QUADS)glTexCoord2f(0.0, 0.0); glVertex3f( x, y, z) glTexCoord2f(1.0, 0.0); glVertex3f( x, y, z)glTexCoord2f(1.0, 1.0); glVertex3f( x, y, z)glTexCoord2f(0.0, 1.0); glVertex3f( x, y, z)glEnd();Note the Data = pygame.image.tostring() command. I did all of this like in the nehe.gamedev.net tutorials but it looks the same as if I had never tried to do any masking.
[Edited by - Geometrian on April 13, 2007 11:02:40 AM]
Alright. Here's how it's done. If you want SIMPLIFIED code, here it is:
That's your entire program! But remember this: It will ONLY WORK if you save you mask to the alpha channel! Do this when you create your image in a paint program. (I have 'Paint Shop Pro 6', so I go "masks->new->from image", then a window pops up and click OK. Then "masks->save to alpha channel". Save it as anything and you are good to go)! Thx to _neutrin0_for these lines:
Geometrian
import osfrom OpenGL.GL import *from OpenGL.GLU import *import pygame, pygame.imagefrom pygame.locals import *textures = [0]def resize((width, height)): if height==0: height=1 glViewport(0, 0, width, height) glMatrixMode(GL_PROJECTION) glLoadIdentity() gluPerspective(45, 1.0*width/height, 0.1, 100.0) glMatrixMode(GL_MODELVIEW) glLoadIdentity()def init(): glEnable(GL_TEXTURE_2D) glShadeModel(GL_SMOOTH) glClearColor(0.0, 0.0, 0.0, 0.0) glClearDepth(1.0) glEnable(GL_DEPTH_TEST) glDepthFunc(GL_LEQUAL) glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)def main(): video_flags = OPENGL|DOUBLEBUF pygame.init() surface = pygame.display.set_mode((640,480), video_flags) resize((640,480)) init() BackgroundFile = os.path.join('Data','Background.png') ImageFile = os.path.join('Data','Image1.png') BackgroundSurface = pygame.image.load(BackgroundFile).convert() ImageSurface = pygame.image.load(ImageFile).convert() ImageSurface.set_colorkey((0,0,0), 0) BackgroundData = pygame.image.tostring(BackgroundSurface, "RGBA", 1) ImageData = pygame.image.tostring(ImageSurface, "RGBA", 1) while 1: glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glLoadIdentity() glTranslatef(0.0,0.0,-5.0) glRotatef(xrot,1.0,0.0,0.0) glRotatef(yrot,0.0,1.0,0.0) glRotatef(zrot,0.0,0.0,1.0) glBindTexture(GL_TEXTURE_2D, textures[0]) glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, BackgroundSurface.get_width(), BackgroundSurface.get_height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, BackgroundData ); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glBegin(GL_QUADS) glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, -2.0) glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, -2.0) glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, -2.0) glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, -2.0) glEnd(); glBindTexture(GL_TEXTURE_2D, textures[2]) glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, ImageSurface.get_width(), ImageSurface.get_height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, ImageData ); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) glBegin(GL_QUADS) glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, 2.0) glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, -1.0, 2.0) glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, 1.0, 2.0) glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, 2.0) glEnd(); event = pygame.event.poll() if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE): break pygame.display.flip()if __name__ == '__main__': main()That's your entire program! But remember this: It will ONLY WORK if you save you mask to the alpha channel! Do this when you create your image in a paint program. (I have 'Paint Shop Pro 6', so I go "masks->new->from image", then a window pops up and click OK. Then "masks->save to alpha channel". Save it as anything and you are good to go)! Thx to _neutrin0_for these lines:
glEnable(GL_BLEND);glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);Geometrian
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement