Umstellung SDL zu SDL/OpenGL



  • Hallo

    Ich wollte mal fragen, ob Ihr ein paar gute Links zu diesem Thema kennt. Ich würde gerne mein Projekt umstellen, um ein paar Frames haerauszuholen. Ich habe bisher aber noch gar nicht mit OpenGL gearbeite und bräuchte daher eine paar Infos zum Thema Unterschiede beim rendern zwischen SDL und SDL/OpenGL. Ich habe für SDL bereits ein paar Klassen und würde diese gerne weiter nutzen. Lohnt sich ein Umstieg überhaupt? Ist der Umstieg sehr aufwändig? Brauche ich großes Wissen über OpenGL? Ich will bei 2D bleiben, ist dies acuh mit OpenGL möglich?

    Danke für Eure Antworten.

    chrische



  • Hi,
    ansich laeuft das ganze so ab, dass SDL für Fenstererstellung und Eventhandling benutzt wird (ggf. zum Laden von Texturen, Sound usw.), OpenGL fuer die Darstellung.
    Das heisst fuer dein Projekt, dass wahrscheinlich alle Funktionen zur Grafikausgabe neu geschrieben werden muessen.

    Ob sich der Umstieg lohnt kommt sicherlich auf das Projekt an (bei einem sehr grossen Projekt wuerde ich einen Umstieg nicht wirklich durchmachen wollen, dann eher bei dem naechsten Projekt mit gleich OpenGL anfangen). Ein wenig Einarbeitung in OpenGL ist auf jeden Fall noetig. Die Leistung wird in den meisten Faellen aber deutlich zunehmen.
    2D ist auch mit OpenGL ohne weiteres moeglich.

    Links habe ich jetzt keine hier, schau dann mal in meinen Bookmarks 🙂

    Gruss,
    DeSoVoDaMu



  • chrische5 schrieb:

    Lohnt sich ein Umstieg überhaupt? Ist der Umstieg sehr aufwändig? Brauche ich großes Wissen über OpenGL? Ich will bei 2D bleiben, ist dies acuh mit OpenGL möglich?

    Danke für Eure Antworten.

    chrische

    Im 2D Bereich ist der umstieg [mehr oder weniger] nur Textersetzung. Klar wird aus nem

    SDL_Blitsurface(soundso);
    

    eher ein Mehrzeiler (je nachdem welche Features deine SDL Klassen haben), aber wenn du sonst auch schon mit OpenGL gearbeitet hast, sollte das kein großes Problem darstellen.

    Ob es sich lohnt, kann ich gar nicht sagen. Ausführliche Performancetests hab ich noch nicht durchgeführt.

    Edit: Oh, du hast wie ich gerade nochmal lese noch nicht mit OpenGL gearbeitet. Das ist jedoch denke ich auf jedenfall notwendig. nehe.gamedev.net for the win.

    Was dann die Fenstererstellung für einen OpenGL Kontext angeht, so wende dich doch einfach an irgendeins der hunderten SDL Tutorials da draußen. Die meisten von denen bieten am Ende ein Kapitel über "OpenGL with SDL".



  • Im 2D Bereich ist der umstieg [mehr oder weniger] nur Textersetzung. Klar wird aus nem...

    mehr oder weniger! ein projekt umzuschreiben ist schon mit vielen
    komplikationen verbunden!

    images nur im 2^n format... daher positionen verschieben... mehr attribute
    zum merken etc...

    schreib dir am besten erstmal mit hilfe eines tutorials eine anwendung direkt
    in sdl/opengl - dann kommste da schon besser rein.

    und wenn du ein projekt umsetzen willst - mach es doch so das man wahlweise
    SDL oder halt OpenGL nutzen kann - ist auch nicht viel mehr arbeit

    babel

    p.s: wegen der performance lohnt es sich in jedem fall! da haste mehr als "nur ein par" frames mehr^^



  • babelduo schrieb:

    Im 2D Bereich ist der umstieg [mehr oder weniger] nur Textersetzung. Klar wird aus nem...

    mehr oder weniger! ein projekt umzuschreiben ist schon mit vielen
    komplikationen verbunden!

    images nur im 2^n format... daher positionen verschieben... mehr attribute
    zum merken etc...

    schreib dir am besten erstmal mit hilfe eines tutorials eine anwendung direkt
    in sdl/opengl - dann kommste da schon besser rein.

    und wenn du ein projekt umsetzen willst - mach es doch so das man wahlweise
    SDL oder halt OpenGL nutzen kann - ist auch nicht viel mehr arbeit

    babel

    p.s: wegen der performance lohnt es sich in jedem fall! da haste mehr als "nur ein par" frames mehr^^

    nein, er muss nicht das gesamte projekt umschreiben. klar, die bitmaps wird er wohl austauschen müssen wenn sie vorher nicht n^2 waren. Aber am Code selber sollte er nichts ändern müssen, wenn seine Klassen ordentlich designed sind. Diese "grundklassen" (sowas wie sprite usw) muss er natürlich überarbeiten, das wars dann aber auch. (wozu sind Abstraktionsebenen denn sonst da?)



  • Hallo

    Erstmal danke für Eure Antworten. Ich habe mich nun entschloßen alles auf SDL/OpenGL umzustellen, weil ich, wie bereits geschrieben, denke, dass ich nur die Grunklassen ändern muss, aber am grundsätzlichen Spiel alles gleich bleiben kann. Ich habe auch ein kleines Tut durchgearbeit, wo erklärt wurde, wie alles initialisert wird und wie man ein Quadrat auf dem Bildschirm zeigt und bewegt. So weit, so gut. Nun kommen aber meine Frage: Wie lade ich unter OpenGl Bitmaps für meine Spriteklassen. Bisher habe ich das so gelöst:

    void sdl::static_nonanimated_sprite::load(const std::string &file_name, const int pos_x, const int pos_y)
    {
    	p_screen = get_framework()->get_screen();
    	SDL_Surface* p_temp_image = SDL_LoadBMP(file_name.c_str());
    
    	if(!p_temp_image)
    	{
    		std::cout<<"Fehler beim Laden von: "<<file_name<<std::endl<<"Fehlermeldung: "<<SDL_GetError()<<std::endl;
    		get_framework()->quit();
    		exit (1);
    	} // if(!p_image)
    	else
    	{
    		p_image = SDL_DisplayFormat(p_temp_image);
    		SDL_FreeSurface(p_temp_image);
    	}
    	rect.w = p_image->w;
    	rect.h = p_image->h;
    }
    

    Und wie kann ich diese dann rendern? Das funktioniert unter SDL ja sehr einfach mittels:

    void sdl::static_nonanimated_sprite::render()
    {
    	SDL_BlitSurface(p_image, NULL, p_screen, &rect);
    }
    

    Vielen Dank für eure Hilfe

    chrische



  • Hi,
    die Bitmap laedst du genau so in den Speicher. Du musst dann daraus eine Textur erstellen und diese dann nutzen.

    // irgendwo ne Textur erstellen (also das Handle unter dem man die Textur anspricht)
    glGenTextures(1, &id);
    
    // Pixel locken
    			SDLSurfaceLocker locker(tmp_surface);
    			SDL_Surface const* psurface = tmp_surface.GetSurface();
    
    			glBindTexture(GL_TEXTURE_2D, GetId());
    
    			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    
    			Uint8 const bpp = psurface->format->BytesPerPixel;
    			int const width = psurface->w;
    			int const height = psurface->h;
    			void const* pixels = psurface->pixels;
    
    			glTexImage2D(GL_TEXTURE_2D, 0, bpp, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
    

    Da bei OpenGL der Koordinatensystemursprung unten links ist, bei SDL dagegen oben links muss die Surface zurvor noch horizontal gespiegelt werden:

    SDLSurfaceLocker locker(*this);
    
        assert(m_psurface->pixels != 0);
    
        Uint8* ppixels = static_cast<Uint8*>(m_psurface->pixels);
    
        // iterate through all lines of the surface up to the vertical half
        for (int i = 0; i < m_psurface->h / 2; ++i)
        {
            Uint8* psrc = ppixels + i * m_psurface->pitch;
            Uint8* pdest = ppixels + (m_psurface->h - 1 - i) * m_psurface->pitch;
    
            int j = 0;
            while (j < m_psurface->pitch)
            {
                std::swap(*psrc++, *pdest++);
                ++j;
            }
        }
    

    Wie du die Textur jetzt auf den Bildschirm bringst findeste selbst heraus 🙂

    Hier noch paar Links, die vielleicht nuetzlich sind:
    http://www.resourcecode.de/index.php?section=12
    http://wiki.delphigl.com/index.php/Tutorial (zwar in Delphi aber zumindest inhaltlich imho nicht schlecht)
    http://www.robsite.de/tutorials.php?tut=sdl
    http://www.codeworx.org/opengl_tuts.php

    Gruss,
    DeSoVoDaMu



  • Hallo

    Ich habe mittels Tuts nun eine neue Klasse static_nonanimated_sprite geschrieben. Da ich aber viel Code nur kopiert habe, wollte ich diesen euch mal kurz vorstellen uzdn fragen, ob das so in Ordnung ist. Sprites werden angezeigt, aber ich suche nach eventuellen Grundsätzlichen Denkfehlern oder ähnlichem.

    chrische::sdl::opengl::static_nonanimated_sprite::static_nonanimated_sprite()
    {
    
    }
    
    chrische::sdl::opengl::static_nonanimated_sprite::~static_nonanimated_sprite()
    {
    	glDeleteTextures(1, &texture);
    }
    
    void chrische::sdl::opengl::static_nonanimated_sprite::load( const std::string& file_name, const float pos_x, const float pos_y , const bool is_colorkeying, const int r, const int g, const int b)
    {
    	SDL_Surface* p_temp_image = SDL_LoadBMP(file_name.c_str());
    
    	if(!p_temp_image)
    	{
    		std::cout<<"Fehler beim Laden von: "<<file_name<<std::endl<<"Fehlermeldung: "<<SDL_GetError()<<std::endl;
    		get_framework()->quit();
    		exit (1);
    	} // if(!p_image)
    
    	rect_.x = pos_x;
    	rect_.y = pos_y;
    	rect_.h = p_temp_image->h;
    	rect_.w = p_temp_image->w;
    
    	if(is_colorkeying)
    	{
    		Uint32 color = SDL_MapRGB(p_temp_image->format, static_cast<Uint8>(r), static_cast<Uint8>(g), static_cast<Uint8>(b));
    		SDL_SetColorKey(p_temp_image, SDL_SRCCOLORKEY, color);
    	}
    
    	SDL_Surface* p_bitmap = SDL_CreateRGBSurface(SDL_SWSURFACE, p_temp_image->w, p_temp_image->h, 32,
    	#if SDL_BYTEORDER == SDL_BIG_ENDIAN
    		0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
    	#else
    		0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
    	#endif
    	SDL_BlitSurface(p_temp_image, 0, p_bitmap, 0);
    
    	glGenTextures(1, &texture);
    	glBindTexture(GL_TEXTURE_2D, texture);
    	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    	glPixelStorei(GL_UNPACK_ROW_LENGTH, p_bitmap->pitch / p_bitmap->format->BytesPerPixel);
    
    	int format = 0;
    	if (is_colorkeying)
    		format = 4;
    	else
    		format = 3;
    	glTexImage2D(GL_TEXTURE_2D, 0, format, p_bitmap->w, p_bitmap->h, 0, GL_RGBA,
    		GL_UNSIGNED_BYTE, p_bitmap->pixels);
    	glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
    
    	SDL_FreeSurface(p_bitmap);
    	SDL_FreeSurface(p_temp_image);
    }
    
    void chrische::sdl::opengl::static_nonanimated_sprite::render()
    {
    	glColor3ub(255, 255, 255);
    
    	glEnable(GL_TEXTURE_2D);
    	glBindTexture(GL_TEXTURE_2D, texture);
    
    	glBegin(GL_QUADS);
    	glTexCoord2f(0, 0);    glVertex2i(rect_.x, rect_.y);
    	glTexCoord2f(1, 0);    glVertex2i(rect_.w + rect_.x, rect_.y);
    	glTexCoord2f(1, 1);    glVertex2i(rect_.w + rect_.x, rect_.h + rect_.y);
    	glTexCoord2f(0, 1);    glVertex2i(rect_.x, rect_.h + rect_.y);
    	glEnd();
    }
    

    Vielen Dank für eure Mühe.

    chrische


Anmelden zum Antworten