Problems with openGL and SDL

Started by
3 comments, last by rjhcomputers 17 years, 11 months ago
Ive been trying to find out how to resize the window and how to load an image with an alpha channel. Ive looked at heaps of examples, but can't get them to work. When I resize the window I can't draw my textures (they just end up white) any more, even though I have reloaded them. When I get a resize event I call my Renderer class's init() function, I think thats where the problem is:

void Renderer::init(Uint16 w, Uint16 h, Uint8 bpp, Uint32 flags, int projection)
{
  // Clear the textures.
  m_textures.clear();
  
  SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);     // Use at least 5 bits of Red
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);   // Use at least 5 bits of Green
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);    // Use at least 5 bits of Blue
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);  // Use at least 16 bits for the depth buffer
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); // Enable double buffering

  // Get video info.
  m_info = SDL_GetVideoInfo();
  
  if (m_info == 0) 
  {
    throw RenderException("Couldn't get SDL video info.");
  }
  
  m_screen = SDL_SetVideoMode(w, h, bpp, SDL_OPENGL | flags);
	if (m_screen == NULL) 
  {
		throw RenderException("Unable to set SDL video mode.");
	}
  
  // Set OpenGL states.
	glShadeModel(GL_SMOOTH);
	glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
	glClearDepth(1.0f);
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  //glHint(GL_FOG_HINT, GL_NICEST);
	glEnable(GL_CULL_FACE);
  
  // Set blending.
  glBlendFunc(GL_SRC_ALPHA, GL_ONE);
  glEnable(GL_BLEND);
  
  // Make textures appear the right way up.
  glMatrixMode(GL_TEXTURE);
  glRotatef(180.0f, 0.0f, 0.0f, 1.0f);
  glScalef(-1.0f, 1.0f, 1.0f);
  
  // Set the OpenGL projection.
  setProjection(projection);
}

void Renderer::setProjection(int projection)
{
  glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	
	switch (projection)
  {
    case RENDERER_PERSPECTIVE:
      glDepthFunc(GL_LEQUAL);
	    glEnable(GL_DEPTH_TEST);
      gluPerspective(45.0f, (GLfloat)m_screen->w/(GLfloat)m_screen->h, 0.1f, 100.0f);
      break;
    case RENDERER_ORTHO:
      glDepthFunc(GL_LEQUAL);
	    glEnable(GL_DEPTH_TEST);
      glOrtho(0.0f, m_screen->w, m_screen->h, 0.0f, -1.0f, 1.0f);
      break;
  }
  
  // Go back to the model view.
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}

For loading images with alpha, I am using this (and passing TEXTURE_MIPMAP_ALPHA):

GLuint Texture::load(const ::std::string& fileName, int type)
{
  SDL_Surface* temp;
  
  if ((temp = IMG_Load(fileName.c_str())) == 0) 
  {
		report("Unable to load image " + fileName + ".");
		return 0;
	}
  
	if (temp->w < 1) 
  {
		report("Image width is invalid (< 1).");
		SDL_FreeSurface(temp);
		return 0;
	}
  
  // Enable 2D texturing.
  glEnable(GL_TEXTURE_2D);
          
  glGenTextures(1, &m_id);
	glBindTexture(GL_TEXTURE_2D, m_id);
	
	switch (type)
	{
    case TEXTURE_NORMAL:
      glTexImage2D(GL_TEXTURE_2D, 0, 3, temp->w, temp->h, 0, GL_BGR, 
      GL_UNSIGNED_BYTE, temp->pixels);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
      break;
    case TEXTURE_ALPHA:
      glTexImage2D(GL_TEXTURE_2D, 0, 4, temp->w, temp->h, 0, GL_RGBA, 
      GL_UNSIGNED_BYTE, temp->pixels);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
      break;
    case TEXTURE_MIPMAP:
      gluBuild2DMipmaps(GL_TEXTURE_2D, 3, temp->w, temp->h, GL_BGR, 
      GL_UNSIGNED_BYTE, temp->pixels);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST);
      break;
    case TEXTURE_MIPMAP_ALPHA:
      gluBuild2DMipmaps(GL_TEXTURE_2D, 4, temp->w, temp->h, GL_RGBA, 
      GL_UNSIGNED_BYTE, temp->pixels);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST);
  }
	
	SDL_FreeSurface(temp);
	return m_id;
}

Advertisement
Quote:Original post by andrew_480
Ive been trying to find out how to resize the window and how to load an image with an alpha channel. Ive looked at heaps of examples, but can't get them to work. When I resize the window I can't draw my textures (they just end up white) any more, even though I have reloaded them. When I get a resize event I call my Renderer class's init() function, I think thats where the problem is:


1st. How are you resizing? Resizing the window or going to fullscreen? SDL Handles them differently. If just resizing the window, you do NOT need to redo all the init stuff. Just the Projection/Ortho part. If going to fullscreen, you MIGHT need to re-init the OGL portion of SDL, but I do not believe so.

2nd.

// Make textures appear the right way up.
glMatrixMode(GL_TEXTURE);
glRotatef(180.0f, 0.0f, 0.0f, 1.0f);
glScalef(-1.0f, 1.0f, 1.0f);

Why do this when you can just invert the texture coords on the models? This might be causing the textures to come up white, but I don't believe so.

And are your textures power-of-2? Maybe someone a bit more expirenced could jump in and clarify this part.

HTH,
Richard
Yeah, thanks for that. I changed it to just changing the view port and it works now. I dont think that textures have to be of a power-of-2 if you mip map them.

Could anyone clarify if it is the way I am loading the SDL_Surface (maybe the alpha-channel isn't loaded?) or the way that I am making the texture that isn't working. File format stuff confuses me. What format does IMG_Load load a png as?
Platform? Windows??
if so the togglescreen func does not work in win32 (to toggle to fullscreen), but you can just create a new sdl surface with the size that you want. The big side effect if the opengl context is lost and all images etc need to be reloaded.
Isnt windows a pain in the arse. :)
Quote:Original post by andrew_480
Yeah, thanks for that. I changed it to just changing the view port and it works now. I dont think that textures have to be of a power-of-2 if you mip map them.


Although they don't have to be, it is best that they are (unless using the hardware EXT). Artifacts could get introduced if they are not.

Quote:
Could anyone clarify if it is the way I am loading the SDL_Surface (maybe the alpha-channel isn't loaded?) or the way that I am making the texture that isn't working. File format stuff confuses me. What format does IMG_Load load a png as?


As for that, do a little bit of research here and here. Those two should give you enough information for you to figure that out, or at least give you a way of knowing if there is an alpha channel loaded.

Another resource would be here. Although I did not find anything regarding alpha issues, I did not look that hard either.

HTH,
Richard

This topic is closed to new replies.

Advertisement