Warsztat.GDCompo!ProjektyMediaArtykułyQ&AForumOferty pracyPobieranie

Opisz napotkaną sytuację, a redakcja niezwłocznie znajdzie rozwiązanie!

wyślij anuluj

SDL OpenGL HOWTO

Parę słów wstępu

To jest mój pierwszy artykuł, więc chcialbym prosić o wyrozumialość. ;)
Początkowo ten artykuł miał opisywac zarówno łączenie OpenGL z SDL, jak i samą bibliotekę SDL, ale skoro Jarek Pelczar(agent_J) napisał już znakomite artykuły dotyczące tej biblioteki, nie będę o niej pisał.
Artykuły agenta_J powinny znajdować się na warsztacie (gamedev.pl).

A więc teraz do rzeczy. Zajmiemy się dzisiaj programowaniem grafiki w OpenGL, podczas gdy będziemy obsługiwać klawiaturę, myszkę, a także rysować okno przy użyciu SDL. Nie jest to zbyt trudne, wiec artykuł nie będzie za dlugi. ;)

Zaczynamy

#include <SDL/SDL.h>
#include <stdlib.h>
#include <GL/gl.h>
 
#include <GL/glu.h>
 
void init();
void resize(int width, int height);
void draw();
 
int main (int argc, char *argv[])
{
SDL_Surface* screen;
bool done=false;
SDL_Event event;
if(SDL_Init(SDL_INIT_VIDEO)<0)
{
printf("Nie mozna zainicjalizowac SDL\n");
return 1;
}
atexit(SDL_Quit);
screen = SDL_SetVideoMode(800, 600, 32, SDL_OPENGL|SDL_RESIZABLE);

Tutaj inicjalizujemy SDL, deklarujemy także naszą powierzchnię. Dodajemy flagi SDL_OPENGL i SDL_RESIZABLE, ponieważ chcemy współpracować z OpenGLem i mieć rozszerzalne okno.

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 );
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

Inicjalizujemy tryb graficzny. SDL_OPENGL oznacza, że będziemy tworzyć powierzchnię współpracująca z OpenGL. Jak pewnie już wiesz SDL_RESIZABLE powoduje, że będziemy mogli zmieniać rozmiar naszego okna.

Funkcja SDL_GL_SetAttribute służy do ustawiania kilku "warunków współpracy" z OpenGL. Argumenty SDL_GL_RED_SIZE, SDL_GL_GREEN_SIZE, SDL_GL_BLUE_SIZE oznaczają, że chcemy CO NAJMNIEJ tyle bitów we framebufferze przeznaczonych na składowanie każdego z kolorów ile podajemy w drugim argumencie.

SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 ) -informuje SDL, że chcemy używać co najmniej 16 bitów pamięci na bufor głębi.

Natomiast SDL_GL_DOUBLEBUFFER służy do włączania/wyłączania podwójnego bufforowania. Gdy drugi argument będzie równy 0 wtedy będzie on wyłączony, jeśli 1 to włączony.

Pamiętaj, że jeśli piszesz aplikację używającą opengl i sdl to ustawiaj podwójne buforowanie zawsze poprzez SDL_GL_SetAttribute, a nie podczas inicjalizowania powierzchni przez użycie SDL_DOUBLEBUF.

Do funkcji SDL_GL_SetAttribute możemy przesłać także kilka innych argumentów, które nie są tu jednak wykorzystywane:

SDL_GL_BUFFER_SIZE - Rozmiar framebuffera w bitach

SDL_GL_STENCIL_SIZE - Rozmiar stencil buffera (bufora powielania) w bitach

SDL_GL_ACCUM_RED_SIZE - Rozmiar czerwonego koloru w buforze akumulacji w bitach

SDL_GL_ACCUM_GREEN_SIZE - Rozmiar zielonego koloru w buforze akumulacji w bitach

SDL_GL_ACCUM_BLUE_SIZE - Rozmiar niebieskiego koloru w buforze akumulacji w bitach

SDL_GL_ACCUM_ALPHA_SIZE - Rozmiar kanalu alpha  w buforze akumulacji w bitach

SDL_WM_SetCaption ("SDL+GL", NULL); //zmieniamy tytul okna na SDL+GL
resize(800,600); //ustawiamy rzutowanie
init(); //inicjalizujemy opengl
while(!done)
  {
  SDL_PollEvent (&event); //odbieramy zdarzenia
  switch (event.type)
  {
    case SDL_QUIT: //koniec?
    {
      done=true; //konczymy
      break;
    }
 
    case SDL_VIDEORESIZE:
    {
      //zmieniamy rzutowanie openga poniewaz zmienily sie rozmiary okna
      resize(event.resize.w, event.resize.h);
      break;
    }
    default:
    break;
  }
  draw();
}
return 0;
}

Zwyczajna kolejka komunikatów SDL.

void init()
{
    glShadeModel(GL_SMOOTH);
    glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
    glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}

Inicjalizujemy opengla.

void draw()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    glTranslatef(-1.5f,0.0f,-6.0f);
    glBegin(GL_TRIANGLES);
    glColor3f(1.0f,0.0f,0.0f);
    glVertex3f( 0.0f, 1.0f, 0.0f);
    glColor3f(0.0f,1.0f,0.0f);
    glVertex3f(-1.0f,-1.0f, 0.0f);
    glColor3f(0.0f,0.0f,1.0f);
    glVertex3f( 1.0f,-1.0f, 0.0f);
    glEnd();
    SDL_GL_SwapBuffers( );
}

Tutaj komentarza wymaga tylko funkcja SDL_GL_SwapBuffers( ). Podmienia buffory opengla, jeśli podwójne buforowanie jest włączone. Jeśli programowales kiedyś okno opengla w winapi to ta funkcja dziala tak samo jak SwapBuffers().

void resize(int width, int height)
{
  if (height==0)
   height=1;
 
  glViewport(0,0,width,height);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}

Dostosowuje rzutowanie do wielkości okna.

To chyba byloby na tyle jeżeli chodzi o samą współpracę opengl z sdl. Całkiem proste, nieprawdaż? Ale wartoby jeszcze wspomnieć o możliwości ładowania extensionów przez sdl. Muszę przyznać, że nie używalem tego prawie wcale, bo po co skoro latwiej i przyjemniej jest użycie takiej biblioteki jak glew. ;)

//te zmienne deklarujemy jako globalne
typedef void (*GL_ActiveTextureARB_Func)(unsigned int);
GL_ActiveTextureARB_Func glActiveTextureARB_ptr = 0;
int has_multitexture=1;
 
 
 
//ten kod wklejamy do init()
//pobieramy wskaźnik do funkcji
glActiveTextureARB_ptr=(GL_ActiveTextureARB_Func) SDL_GL_GetProcAddress("glActiveTextureARB");
 
 
//sprawdzamy czy otrzymalismy adres funkcji glActiveTextureARB (moze nasza karta nie obsluguje multitexturingu)
if(!glActiveTextureARB_ptr)
{
  fprintf(stderr, "nie otrzymano adresu funkcji glActiveTextureARB\n");
  has_multitexture=0;
}
 
 
 
//a to w draw()
if(has_multitexture){
glActiveTextureARB_ptr(GL_TEXTURE0_ARB);

To chyba wszystko. Enjoy! ;)

Michał Kurtys znany również jako Mic

Tekst dodał:
tanatos
03.06.2012 00:51

Ostatnia edycja:
tanatos
03.06.2012 00:51


Aby edytować tekst, musisz się zalogować.

# Edytuj Porównaj Czas Autor Rozmiar
#1 edytuj 03.06.2012 00:51 tanatos 13.11 KB
Zwykły
Do sprawdzenia
Do akceptacji
  • Napisz komentarz:
    Aby dodać swój komentarz, musisz się zalogować.
Licencja Creative Commons

Warsztat używa plików cookies. | Copyright © 2006-2017 Warsztat · Kontakt · Regulamin i polityka prywatności
build #ff080b4740 (Tue Mar 25 11:39:28 CET 2014)