SDL / OpenGL纹理透明度

时间:2010-08-25 00:46:01

标签: opengl transparency sdl textures

我只是想知道如何转换SDL_Surface(通过IMG_Load从png加载)并将其粘贴在四边形上。这就是我所拥有的(大多数只是从我发现的教程中粘贴的复制品)。

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

纹理渲染,但应该有透明度,只有黑色。

5 个答案:

答案 0 :(得分:5)

我没有看到你在任何地方启用混音。你需要一些变化:

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

见这里:http://www.opengl.org/resources/faq/technical/transparency.htm

答案 1 :(得分:1)

要保持透明度,你需要在纹理上使用alpha通道,但更重要的是,在帧缓冲区中。这是通过SDL_GL_SetAttribute完成的,例如:

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

这将请求至少具有这些尺寸的帧缓冲,并且您将能够使用混合。请记住启用混合并设置混合功能。

答案 2 :(得分:0)

查看您的来电glTexImage2D( GL_TEXTURE_2D, 0, 3, surface->w, surface->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels );。您为内部格式指定3个颜色组件。尝试4(使用Alpha通道)或GL_RGBA(more about this)。

答案 3 :(得分:0)

我一直在我的计算机上检查你的代码并且运行正常。您是否在链接器中设置了“opengl32.lib”?

答案 4 :(得分:0)

作为一个聪明的头脑我,我的问题是我有glEnable(GL_DEPTH_TEST)。删除该行使一切正常,我担心以后的问题。玩得开心!