Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411574 Posts in 69386 Topics- by 58444 Members - Latest Member: darkcitien

May 04, 2024, 05:41:02 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)2D display with SDL+OpenGL
Pages: [1]
Print
Author Topic: 2D display with SDL+OpenGL  (Read 7749 times)
giann
Level 0
**


View Profile WWW
« on: May 08, 2009, 12:35:43 AM »

Hi,

I started a little 2D engine in SDL for my upcoming project. I wanted to add some light effects so I assumed I had to use OpenGL. I didn't wanted to rewrite my whole work with Gl primitives so I found a way to write my SDL_Surface to a texture and put it on an gl shape. The problem is that I can't manage to have a correct point of view so that my surface takes the whole screen like before. Here is what I get with SDL alone and then with OpenGL:




Do you guys know a way to set the correct point of view ?

Giann
« Last Edit: May 08, 2009, 12:41:30 AM by giann » Logged
Alex May
...is probably drunk right now.
Level 10
*


hen hao wan


View Profile WWW
« Reply #1 on: May 08, 2009, 01:13:38 AM »

Post your code!
Logged

giann
Level 0
**


View Profile WWW
« Reply #2 on: May 08, 2009, 01:31:59 AM »

Here it is:

Code:
int SCREEN_WIDTH = 640;
int SCREEN_HEIGHT = 480;

SDL_Surface *sdl_screen;

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

  if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) < 0) {
    printf("Unable to init SDL: %s", SDL_GetError());
    exit(1);
  }
 
  atexit(SDL_Quit);

  SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
  SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 32);
  screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT,
    32, SDL_HWSURFACE|/*SDL_DOUBLEBUF|*/SDL_OPENGL);
  if (screen == NULL) {
    printf("Unable to set SCREEN_WIDTHxSCREEN_HEIGHT video: %s\n", SDL_GetError());
    exit(1);
  }
  SDL_WM_SetCaption("Giann's 2D Engine", 0);
 
  glEnable(GL_TEXTURE_2D);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 1);
  glMatrixMode(GL_MODELVIEW);

  int done = 0;
  while (!done) {
    ... a bunch of drawing to a SDL_Surface ...
     
    // Convert the SDL_Surface to a texture (see http://twomix.devolution.com/pipermail/sdl/2002-September/049078.html)
    SDL_GL_LoadTexture(sdl_screen, texcoord);

    glBegin( GL_QUADS );
    glTexCoord2d(0.0,0.0); glVertex2d(0.0,0.0);
    glTexCoord2d(1.0,0.0); glVertex2d(SCREEN_WIDTH,0.0);
    glTexCoord2d(1.0,1.0); glVertex2d(SCREEN_WIDTH,SCREEN_HEIGHT);
    glTexCoord2d(0.0,1.0); glVertex2d(0.0,SCREEN_HEIGHT);
    glEnd();

    glFlush();
    SDL_GL_SwapBuffers();
  }

  return 0;
}
   
Logged
Ishi
Pixelhead
Level 10
******


coffee&coding


View Profile WWW
« Reply #3 on: May 08, 2009, 01:48:29 AM »

Looks like the texture created from the screen has power-of-two sizes, since those are much faster on most graphics cards. So the 640x480 screen will be put on a texture of 1024x512, so you'll need to adjust the texture coords to (640/1024.f, 480/512.f).
Logged

Alex May
...is probably drunk right now.
Level 10
*


hen hao wan


View Profile WWW
« Reply #4 on: May 08, 2009, 02:17:06 AM »

AFAIK, updating the graphics in the texture and uploading the result to the card every time it changes might be quite slow. If you're not concerned about frame rate and user input lag, (e.g. your game is turn based) it is probably okay, although you may still encounter annoying input lag for interfaces.

Additionally, I don't understand how this step helps you use lighting effects. What kind of lighting effects are you talking about using?
Logged

giann
Level 0
**


View Profile WWW
« Reply #5 on: May 08, 2009, 02:38:35 AM »

Thx Ishi, changing the coordinates did the trick.

Quote
AFAIK, updating the graphics in the texture and uploading the result to the card every time it changes might be quite slow. If you're not concerned about frame rate and user input lag, (e.g. your game is turn based) it is probably okay, although you may still encounter annoying input lag for interfaces.

Do you know a better way of doing without rewriting all my SDL code ?

Quote
Additionally, I don't understand how this step helps you use lighting effects. What kind of lighting effects are you talking about using?

I was using pure SDL and I plan on using OpenGL lights that's all.
Logged
Alex May
...is probably drunk right now.
Level 10
*


hen hao wan


View Profile WWW
« Reply #6 on: May 08, 2009, 02:45:36 AM »

Quote
Additionally, I don't understand how this step helps you use lighting effects. What kind of lighting effects are you talking about using?

I was using pure SDL and I plan on using OpenGL lights that's all.
Yeah, but I mean what kind of lighting effect do you want to achieve? Can you describe it?

Quote
AFAIK, updating the graphics in the texture and uploading the result to the card every time it changes might be quite slow. If you're not concerned about frame rate and user input lag, (e.g. your game is turn based) it is probably okay, although you may still encounter annoying input lag for interfaces.

Do you know a better way of doing without rewriting all my SDL code ?
Not as such... but you may be able to minimise the work you need to do by writing a drawing class that has the same kind of interface as the way you are drawing things using SDL now.
Logged

giann
Level 0
**


View Profile WWW
« Reply #7 on: May 08, 2009, 02:59:29 AM »

Quote
Yeah, but I mean what kind of lighting effect do you want to achieve? Can you describe it?

Don't know precisely yet. But my game will be sort of a RTS so maybe a smooth light so that not discovered field would be in the fog of war.
Logged
Alex May
...is probably drunk right now.
Level 10
*


hen hao wan


View Profile WWW
« Reply #8 on: May 08, 2009, 03:08:20 AM »

I'm not sure OpenGL lights is what you want here.

Lights are used to shade geometry. The idea is that the polygons you draw will be shaded in a certain way depending on their distance from and angle to the light. Since you are just drawing one polygon (a single quad with your game display written to the texture on it), lighting will just change the shading on that entire polygon - that is, the whole thing will change colour at once.

If you want to do lights on your 2D display, it might be better to fake it using overlaid semi-transparent glow sprites. You will need to use some OpenGL immediate mode code for this, at the least.

To do fog of war in the way you describe, you could do some tricks with the Z buffer (e.g. apply depth information to each light, then read out the Z buffer and write it back to the screen as a darkened texture), which might be quite slow, or use some pixel shader technology to do something similar. Alternatively you could do fog of war by drawing tiles which couldn't be seen in a darker shade. Using OpenGL to draw your tiles instead of writing them to the texture might help you here, as IIRC SDL won't help you change the shading of things you draw? Using OpenGL will also allow you to blend out the corners of tiles so that the fog of war looks smooth.
Logged

giann
Level 0
**


View Profile WWW
« Reply #9 on: May 08, 2009, 03:15:58 AM »

Thanks for the advices I'll look into that.
Logged
birdcloud
Level 0
**



View Profile
« Reply #10 on: May 08, 2009, 06:05:19 PM »

as IIRC SDL won't help you change the shading of things you draw?

SDL supports per-surface & per-pixel alpha-blending with blits. For fog of war, one could first clear the screen to color of the fog, then call SDL_SetAlpha(tile_surface, SDL_SRCALPHA, alpha) before drawing each tile, where alpha is 0 for fully unknown/fogged and 255 for fully known/unfogged.
Logged
Alex May
...is probably drunk right now.
Level 10
*


hen hao wan


View Profile WWW
« Reply #11 on: May 09, 2009, 04:26:50 AM »

Ah that's cool - should be able to do it purely in SDL then.
Logged

giann
Level 0
**


View Profile WWW
« Reply #12 on: May 09, 2009, 04:30:02 AM »

Yep, good idea thx !  Smiley
Logged
muku
Level 10
*****


View Profile
« Reply #13 on: May 09, 2009, 05:00:04 AM »

I'm not sure how good a job SDL does of hardware-accelerating its alpha blending, so performance may be something to watch out for if you use that a lot. Looking at the documentation, it does seem that SDL hardware surfaces support hardware accelerated blending, though. Just try it and see if it's fast enough for your purposes.
Logged
Ivan
Owl Country
Level 10
*


alright, let's see what we can see


View Profile
« Reply #14 on: May 09, 2009, 08:51:42 AM »

I'm pretty sure that it's like, 2d hardware acceleration, which is not the same as 3d acceleration and is probably loads slower.
Logged

http://polycode.org/ - Free, cross-platform, open-source engine.
Alex May
...is probably drunk right now.
Level 10
*


hen hao wan


View Profile WWW
« Reply #15 on: May 09, 2009, 09:44:48 AM »

Looking at the shots, I don't think performance is going to be too high on the list of problems - the game doesn't look like it will end up pushing the hardware too far.
Logged

giann
Level 0
**


View Profile WWW
« Reply #16 on: May 09, 2009, 12:23:24 PM »

Yes, it won't be anything else than displaying animated sprites and a simple gui.
Logged
giann
Level 0
**


View Profile WWW
« Reply #17 on: May 10, 2009, 12:56:39 AM »

While I'm at it: I've got several questions about SDL if anybody know the answer it might be useful

  • Since I work on small sprites, is there a way of displaying the screen x2 with scanlines ? I tried zooming it with rotozoom but it slows down the game.
  • Is there a way of switching between fullscreen and windowed while running ? I found the SDL_WM_ToggleFullScreen function but it doesn't seems to work on windows according to SDL doc.
  • In order to put my own cursor I load a sprite with my pointer and make it follow the mouse. But I would also like to lower the framerate with SDL_Delay and doing so makes the pointer movements not smooth. The SDL cursor doesn't seemed influenced by the application framerate is it a better solution to use it (although you have to code it by hand) ?
  • Is there a better way of limiting framerate ?
  • Is there a way of tinting a surface (like with draw_lit_sprite in Allegro)
« Last Edit: May 10, 2009, 01:11:54 AM by giann » Logged
eddietree
Level 6
*



View Profile WWW
« Reply #18 on: May 12, 2009, 01:36:07 PM »

Is there a way of switching between fullscreen and windowed while running ? I found the SDL_WM_ToggleFullScreen function but it doesn't seems to work on windows according to SDL doc.
I used SDL_SetVideoMode for toggleing full screen. Assume screen is the surface you generated using SDL_SetVideoMdoe
Code:
// flags may vary depending on if you're using OpenGL or whatever
int options = SDL_DOUBLEBUF|SDL_HWACCEL|SDL_HWSURFACE|SDL_FULLSCREEN;

// free the old screen
SDL_FreeSurface(screen);

// create new fullscreen
screen = SDL_SetVideoMode( width, height, SCREEN_BPP, options );

You can remove SDL_FULLSCREEN flag to go back to windowed.

For more information on SDL_SetVideoMode, go here: http://www.libsdl.org/cgi/docwiki.cgi/SDL_SetVideoMode

Is there a better way of limiting framerate ?

Check out LazyFoo's tutorial on Regulating frame rate: http://lazyfoo.net/SDL_tutorials/lesson14/index.php

Is there a way of tinting a surface (like with draw_lit_sprite in Allegro)

If you want to tint the entire window using SDL primitives, what I would do is create a black surface, set the alpha level to a tintish color, and just blit it after everything else is blitted to the screen. But for tinting, say, a sprite (in SDL) you might need to do a per pixel shading, which may be a bit complicated. But I'm sure OpenGl has a way, if that is what you're using...
Logged

Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic