views:

70

answers:

3

So I have a seemingly simple problem, and I've searched around, but none of the solutions I've found have worked (though I probably applied them incorrectly). I'm just wondering how I can convert an SDL_Surface (loaded from a png via IMG_Load) and stick it on a quad. Here is what I have (mostly just copy pasted from a tutorial I found).

#include "SDL.h"
#include "SDL_opengl.h"
#include "SDL_image.h"

#include <stdio.h>

int main(int argc, char *argv[])
{
    SDL_Surface *screen;

    // Slightly different SDL initialization
    if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) {
        printf("Unable to initialize SDL: %s\n", SDL_GetError());
        return 1;
    }

    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // *new*

    screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL ); // *changed*
    if ( !screen ) {
  printf("Unable to set video mode: %s\n", SDL_GetError());
  return 1;
 }

    // Set the OpenGL state after creating the context with SDL_SetVideoMode

 glClearColor( 0, 0, 0, 0 );

 glEnable( GL_TEXTURE_2D ); // Need this to display a texture

  glViewport( 0, 0, 640, 480 );

  glMatrixMode( GL_PROJECTION );
  glLoadIdentity();

  glOrtho( 0, 640, 480, 0, -1, 1 );

  glMatrixMode( GL_MODELVIEW );
  glLoadIdentity();

  // Load the OpenGL texture

  GLuint texture; // Texture object handle
  SDL_Surface *surface; // Gives us the information to make the texture

  if ( (surface = IMG_Load("img/star.png")) ) { 

      // Check that the image's width is a power of 2
      if ( (surface->w & (surface->w - 1)) != 0 ) {
          printf("warning: image.bmp's width is not a power of 2\n");
      }

      // Also check if the height is a power of 2
      if ( (surface->h & (surface->h - 1)) != 0 ) {
          printf("warning: image.bmp's height is not a power of 2\n");
      }

      // Have OpenGL generate a texture object handle for us
      glGenTextures( 1, &texture );

      // Bind the texture object
      glBindTexture( GL_TEXTURE_2D, texture );

      // Set the texture's stretching properties
      glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
      glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

      // Edit the texture object's image data using the information SDL_Surface gives us
      glTexImage2D( GL_TEXTURE_2D, 0, 3, surface->w, surface->h, 0, 
                    GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels );
  } 
  else {
      printf("SDL could not load image.bmp: %s\n", SDL_GetError());
      SDL_Quit();
      return 1;
  }    

  // Free the SDL_Surface only if it was successfully created
  if ( surface ) { 
      SDL_FreeSurface( surface );
  }

  // Clear the screen before drawing
glClear( GL_COLOR_BUFFER_BIT );

  // Bind the texture to which subsequent calls refer to
  glBindTexture( GL_TEXTURE_2D, texture );

  glColor3f(1,0,0);
  glDisable( GL_TEXTURE_2D );
  glBegin( GL_QUADS );
      // Top-left vertex (corner)
      glTexCoord2i( 0, 0 );
      glVertex3f( 0, 0, 0 );

      // Bottom-left vertex (corner)
      glTexCoord2i( 1, 0 );
      glVertex3f( 328, 0, 0 );

      // Bottom-right vertex (corner)
      glTexCoord2i( 1, 1 );
      glVertex3f( 328, 328, 0 );

      // Top-right vertex (corner)
      glTexCoord2i( 0, 1 );
      glVertex3f( 0, 328, 0 );
  glEnd();
  glColor3f(1,1,1);
  glEnable( GL_TEXTURE_2D );

  glBegin( GL_QUADS );
      // Top-left vertex (corner)
      glTexCoord2i( 0, 0 );
      glVertex3f( 100, 100, 0 );

      // Bottom-left vertex (corner)
      glTexCoord2i( 1, 0 );
      glVertex3f( 228, 100, 0 );

      // Bottom-right vertex (corner)
      glTexCoord2i( 1, 1 );
      glVertex3f( 228, 228, 0 );

      // Top-right vertex (corner)
      glTexCoord2i( 0, 1 );
      glVertex3f( 100, 228, 0 );
  glEnd();

  SDL_GL_SwapBuffers();

  // Wait for 3 seconds to give us a chance to see the image
  SDL_Delay(3000);

  // Now we can delete the OpenGL texture and close down SDL
  glDeleteTextures( 1, &texture );

  SDL_Quit();

 return 0;
}

The texture renders, but where there should be transparency, there is just black. Thanks in advance for any tips.

+3  A: 

I don't see you enabling blending anywhere. You'll need some variation of:

glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);

See here: http://www.opengl.org/resources/faq/technical/transparency.htm

Nicholas M T Elliott
+1  A: 

To hav transparency, you need an alpha channel, on your texture, but more important, in your framebuffer. This is done with SDL_GL_SetAttribute, for example:

SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 );
SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 );
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 );
SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8 );

This will request a framebuffer with at least those sizes, and you'll be able to use blending. Remember to enable blending and set a blending function.

Matias Valdenegro
A: 

Have a look at your call glTexImage2D( GL_TEXTURE_2D, 0, 3, surface->w, surface->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels );. You specify 3 color components for the internal format. Try 4 (with alpha channel), or GL_RGBA (more about this).

dep