PDA

View Full Version : Some texture colors turning transparent?



johannesprix
08-20-2003, 09:35 AM
Hi guys!

I'm a newbie, so expect I'm making the dumbest mistake, but just don't know where to look any more.

My problem is this:

I can load images and draw them correctly via glDrawPixels.

But then (for better speed) I load (several) surfaces and make them textures.

Because I need alpha, there is either blending or alpha text in use, makes no difference to the strange result, which is: Some colors are turning out tranparent in the final image, so that part of it appears, but some spots are removed, and I can't find out why and how.

It also seems to vary depending on what of the following I use, but some parts are always missing and the colors appear a bit shifted. But my OpenGL installation is ok, I've tested it.

// glTexEnvi ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );
// glTexEnvi ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND );
// glTexEnvi ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
// glTexEnvi ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );

Any clues where to look, what to try, what else to post? Well, as I'm a newbie, there might be some really dumb mistake behind all this.

Thanks a lot for anything, cause I don't know where to look any more.

See ya, Johannes.

Deiussum
08-20-2003, 11:42 AM
Do your textures have dimensions which are a power of two?

Deiussum
08-20-2003, 11:44 AM
Also, have you tried displaying the texture part with blending and alpha test disabled?

johannesprix
08-20-2003, 10:42 PM
Do your textures have dimensions which are a power of two?

Yes, I've written a padding function that will make the surface bigger by adding transparent parts outside the interesting image. I've also double-checked by glDrawPixel, that the generated surface is still ok, got the right transparency and also the colors after that operation still seem to be ok. The problem must be somewhere introduced with the generation or the display of the texture.

So I'll display the code used to generate the texture here: It's a loop for 25 or so such textures of (after padding) format 256x128. The function inside the loop is this:

void
make_texture_out_of_surface ( iso_image* our_image )
{
SDL_Surface* right_sized_image ;

//--------------------
// This fill up the image with transparent material, so that
// it will have powers of 2 as the dimensions, which is a requirement
// for textures on most OpenGL capable cards.
//
right_sized_image = pad_image_for_texture ( our_image -> surface ) ;

// Create The Texture
glGenTextures( 1, & our_image -> texture );

// Typical Texture Generation Using Data From The Bitmap
glBindTexture( GL_TEXTURE_2D, our_image -> texture );

glDisable(GL_LIGHTING);

// Generate The Texture

glTexImage2D( GL_TEXTURE_2D, 0, 4, right_sized_image ->w,
right_sized_image -> h, 0, GL_RGBA,
GL_UNSIGNED_BYTE, right_sized_image -> pixels );


SDL_FreeSurface ( right_sized_image );

};

I've also experimented around with the display of the texture some more. In fact, if I use alpha testing and set the threshold very low (0.1), then (almost?) all of the really visible part of the image is displayed, but alas, it's completely in red. The parts, that should be very red, appear to be correct. Here is the code used to display the texture:

void
blit_this_floor_tile_to_screen ( iso_image our_floor_iso_image ,
float our_col, float our_line )
{
SDL_Rect target_rectangle;

if ( use_open_gl )
{
//--------------------
// At first we need to enable texture mapping for all of the following.
// Without that, we'd just get (faster, but plain white) rectangles.
//
glEnable( GL_TEXTURE_2D );

//--------------------
// Linear Filtering is slow and maybe not nescessary here, so we
// stick to the faster 'nearest' variant.
//
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );

//--------------------
// We disable depth test for all purposes.
//
glDisable(GL_DEPTH_TEST);

//--------------------
// Blending can be used, if there is no suitable alpha checking so that
// I could get it to work right....
//
// But alpha check functions ARE a bit faster, even on my hardware, so
// let's stick with that possibility for now, especially with the floor.
//
// glEnable(GL_BLEND);
// glBlendFunc( GL_SRC_ALPHA , GL_ONE );
//
glEnable( GL_ALPHA_TEST );
glAlphaFunc ( GL_GREATER , 0.1 ) ;

//--------------------
// Now of course we need to find out the proper target position.
//
target_rectangle . x =
translate_map_point_to_screen_pixel ( our_col , our_line , TRUE ) +
our_floor_iso_image . offset_x ;
target_rectangle . y =
translate_map_point_to_screen_pixel ( our_col , our_line , FALSE ) +
our_floor_iso_image . offset_y ;

//--------------------
// Now we can begin to draw the actual textured rectangle.
//
glBindTexture( GL_TEXTURE_2D, our_floor_iso_image . texture );
glBegin(GL_QUADS);
glTexCoord2i( 0.0f, 1.0f );
glVertex2i( target_rectangle . x , target_rectangle . y );
glTexCoord2i( 1.0f, 1.0f );
glVertex2i( target_rectangle . x , target_rectangle . y + 127 );
glTexCoord2i( 1.0f, 0.0f );
glVertex2i( target_rectangle . x + 255 , target_rectangle . y + 127 );
glTexCoord2f( 0.0i, 0.0i );
glVertex2i( target_rectangle . x + 255 , target_rectangle . y );
glEnd( );

//--------------------
// But for the rest of the drawing function, the peripherals and other
// things that are to be blitted after that, we should not forget to
// disable the texturing things again, or HORRIBLE framerates will result...
//
// So we revert everything that we might have touched to normal state.
//
glDisable( GL_TEXTURE_2D );
glDisable( GL_BLEND );
glEnable( GL_ALPHA_TEST );
glAlphaFunc ( GL_GREATER , 0.5 ) ;

}
else
{
blit_iso_image_to_map_position ( our_floor_iso_image , our_col , our_line ) ;
}
}; //


I must admit, this code as a whole might be a bit braindamaged. I create padded textures of size 256x128 and then display them with a size of 256x128 so that the interesting small part of the texture will appear. Maybe that could be done somehow more efficiently.

And yes, I should have given more details in the beginning: My program is a pure 2D application. It is working well using SDL for graphics output but for speed purposes, there's also an OpenGL output which I started to write this week. So for 2d, this is the initialisation I use:


int
initGL( GLvoid )
{
/* Load in the texture */
// if ( !LoadGLTextures( ) )
// return FALSE;

glViewport(0,0,640,480);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0f,640.0f,480.0f,0.0f,-1.0f,1.0f);
glMatrixMode(GL_MODELVIEW);

glEnable( GL_ALPHA_TEST );
glAlphaFunc ( GL_GREATER , 0.5 ) ;

return( TRUE );
}; // int initGL( GLvoid )


And this is the code for opening the window.

if ( use_open_gl )
{
/* the flags to pass to SDL_SetVideoMode */
video_flags = SDL_OPENGL; /* Enable OpenGL in SDL */
video_flags |= SDL_GL_DOUBLEBUFFER; /* Enable double buffering */
video_flags |= SDL_HWPALETTE; /* Store the palette in hardware */
video_flags |= SDL_RESIZABLE; /* Enable window resizing */

/* This checks to see if surfaces can be stored in memory */
if ( vid_info->hw_available )
video_flags |= SDL_HWSURFACE;
else
video_flags |= SDL_SWSURFACE;

/* This checks if hardware blits can be done */
if ( vid_info->blit_hw )
video_flags |= SDL_HWACCEL;

/* Sets up OpenGL double buffering */
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

/* get a SDL surface */
Screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, vid_bpp , video_flags );

/* Verify there is a surface */
if ( !Screen )
{
fprintf( stderr, "Video mode set failed: %s\n", SDL_GetError( ) );
Terminate ( ERR ) ;
}

/* initialize OpenGL */
initGL( );

}


Well, it's all pieced together without real understanding of the matter of OpenGL, but I've only started this week with doing some OpenGL at all, so I guess I really qualify as a newbie http://www.opengl.org/discussion_boards/ubb/smile.gif



Also, have you tried displaying the texture part with blending and alpha test disabled?


Yes, just tried that. As expected, you can hardly see a thing any more, cause the black 'padded' spaces overlap much, so only a small edge of the images is visible, but that again features the stong redness, looking fairly identical to the cases with alpha test, as far as I can tell. Well, thanks for your thoughts so far.
I'd be so much delighted if I could finally get rid of this problem somehow.

Thanks a lot again and see ya, Johannes.

errno
08-20-2003, 11:06 PM
when rendering, lighting is enabled ?
are you calling glColor or glMaterial somewhere ?
did you set the tex environment correctly ?
=> glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

it seems that you don't use glBindTexture correctly.
the parameter that you register with glTexEnv or glTexParameter are associated with the current bound texture, so you have to call glBindTexture before each glTex* calls.

johannesprix
08-21-2003, 12:06 AM
Thanks!

The matter is solved now. It was all my fault. My padding code must have had a bug. I created 32bit surfaces using SDL_CreateRBGSurface and then the test if that padding code works also used SDL, which can work with this. However when building the texture, OpenGL seems not to do the right thing (because my X11 display is 16 bit?). When I convert the surface from SDL_CreateRBGSurface ( ... 32 , ...) later via SDL_DisplayFormatAlpha and then do the padding, that seems to work, finally.
Horray! Horray!

Thanks all who bothered to think about my issue. A big thanks also to the guys having answered questions in the past. The archive and search function is simply a treasure.

Thanks and see ya, Johannes.