Skip to main content
gamedev.net
🔒 Locked

alpha blending problem

Started by manton Oct 4, 2006 at 2:23 AM 2 replies 600+ views
Original Post
manton
manton
I am having a problem with blending models. I am finding that when alpha is zero then that material is rendered in the glClearColor and in varying scales til it appears in the correct colour when alpha=1. My initialisation code is as follows:
void
FL_controller::init()
{
  initSDL();
  init_openGL();
  scene = new Scene_manager();
  scene->initScene();

  glTexEnvi(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  skybox = loadTexture("textures/skybox.png");
}

void
FL_controller::initSDL()
{
  //initialise context
  if (SDL_Init(subsystems) < 0)
  {
    std::cerr << "Video initialization failed: " << SDL_GetError();
    SDL_Quit();
  }

  //get video information
  const SDL_VideoInfo* info = SDL_GetVideoInfo();
  if ( info == NULL)
  {
    std::cerr << "Video query failed: " << SDL_GetError();
    SDL_Quit();
  }

  //set attributes
  display_bit_depth = info->vfmt->BitsPerPixel;

  //set vid mode
  if (SDL_SetVideoMode(display_width, display_height, display_bit_depth, video_flags) == 0)
      if ( info == NULL)
  {
    std::cerr << "Failed to set video mode  : " << SDL_GetError();
    SDL_Quit();
  }

  //use bit_depth to hold openGL state query results
  GLint bit_depth;
  
  //query openGL for RGB and depth bit size and set in SDL
  glGetIntegerv(GL_RED_BITS, &bit_depth);
  SDL_GL_SetAttribute( SDL_GL_RED_SIZE, bit_depth );
  glGetIntegerv(GL_GREEN_BITS, &bit_depth);
  SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, bit_depth );
  glGetIntegerv(GL_BLUE_BITS, &bit_depth);
  SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, bit_depth );

  glGetIntegerv(GL_ALPHA_BITS, &bit_depth);
  SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, bit_depth );
  
  glGetIntegerv(GL_DEPTH_BITS, &bit_depth);
  SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, bit_depth );

  SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

  //Set the window tile and icon
  SDL_WM_SetCaption("Far Light", "Far Light");
  SDL_WM_SetIcon(SDL_LoadBMP("icon.bmp"), NULL);
  //set cursor
  setCursor();
}


If anyone can suggest where the problem may lie I would love to hear your ideas. Thanks
Kalidor
Kalidor
We'll need to see where you set up blending and your rendering code to notice any problems in that.

I have a feeling your problem may lie in your understanding of blending. Say your blend function is (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA). This corresponds to the following equation...
C<sub>f</sub> = C<sub>s</sub>A<sub>s</sub> + C<sub>d</sub>(1-A<sub>s</sub>)
where Cf is the resulting fragment color sent to the rest of the pipeline, Cs is the source color (color of the incoming fragment), As is the source alpha, and Cd is the destination color (color at the corresponding framebuffer location).

Now let's say all you do in your rendering function is clear the framebuffer, set the blending mode, and render a quad. Cs in the above equation will be the color of the quad and Cd will be the clear color. Now if the alpha of the quad (As) is 1.0, the final color will just be the color of the quad. If alpha is 0.0, the final color will be the clear color. If alpha is 0.5, the final color will be the sum of half the quad color and half the clear color.
manton
manton
thanks Kalidor, I've got it sorted now. The porblem was the order in which objects were being drawn in my scene manager. I guess I have to draw transparent stuff last to avoid this porblem.

As you may have guessed I am not greatly experienced with alpha blending. Any other 'gotchas' I should look out for? If not, thanks agian :)
Kalidor
Kalidor
Quote:
Original post by manton
thanks Kalidor, I've got it sorted now. The porblem was the order in which objects were being drawn in my scene manager. I guess I have to draw transparent stuff last to avoid this porblem.

As you may have guessed I am not greatly experienced with alpha blending. Any other 'gotchas' I should look out for? If not, thanks agian :)
Ah yes, that's certainly a problem. Blending is done with the color that's in the framebuffer at the time something is rendered with blending. This implies needing to render transparent geometry after opaque geometry in back-to-front order. If you're only using additive blending you don't need to sort however. Depth writing (just writing, not depth testing, see glDepthMask) should be disabled when rendering transparent geometry as well.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.