2010-08-25 14 views
5

Me pregunto cómo puedo convertir una SDL_Surface (cargada desde un png a través de IMG_Load) y pegarla en un quad. Esto es lo que tengo (la mayoría solo copio pegado de un tutorial que encontré).SDL/OpenGL Texture Transparency

#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; 
} 

La textura representa, pero donde debe haber transparencia, solo hay negro.

+1

La próxima vez use el botón Code Sample para los bloques grandes de código. – genpfault

Respuesta

1

HAV a la transparencia, es necesario un canal alfa, en su textura, pero lo más importante, en su uso de este dispositivo. Esto se hace con SDL_GL_SetAttribute, por ejemplo:

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); 

Este solicitará un framebuffer con, al menos, los tamaños, y usted será capaz de utilizar la fusión. Recuerde habilitar la mezcla y establecer una función de fusión.

0

Echa un vistazo a tu llamada glTexImage2D(GL_TEXTURE_2D, 0, 3, surface->w, surface->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels);. Usted especifica 3 componentes de color para el formato interno. Pruebe 4 (con canal alfa) o GL_RGBA (more about this).

+1

Recomiendo simplemente llamar 'surface-> format-> BytesPerPixel' en lugar de escribir manualmente el' 4' como valor. Es más flexible y uno evitará problemas extraños más adelante si por alguna razón los canales del objeto cargado SDL_Surface cambian (entonces tendremos una situación de buscar un solo dígito en probablemente una enorme pila de código, nada de diversión) . – rbaleksandar

0

He estado revisando su código en mi computadora y eso se ha ejecutado correctamente. ¿Ha establecido 'opengl32.lib' en su enlazador?

0

Siendo la mente brillante que soy, mi problema fue que tenía glEnable (GL_DEPTH_TEST) activado. Al eliminar esa línea, todo funcionó y me preocupan los problemas posteriores. ¡Que te diviertas!

Cuestiones relacionadas