Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

26.09.2007, 23:27

SDL/OGL Textur Blitten extrem langsam

Hey Leute

ich habe vor einigen Tagen ein SDL Tutorial gemacht, wo später auch auf das laden von Grafiken als Textur in OGL eingegangen wird. Das habe ich jetzt in mein Pong eingebaut, damit ich später auch andere OGL Fähigkeiten benutzen kann.
Da mir etwa 80 FPS sehr wenig vorkamen für 3geblittete texturen hab ich mal meine gesamte Mainloop vermessen. Dabei kam raus, das ich für einen Texturblit durchschnittlich 50ms brauche und das ist doch zuviel.

Hier mal der Source (Der ist 1:1 aus dem Tutorial übernommen, ich hab aber wirklich nur diese 3 Funktionen übernommen, da ich dachte diese wären schon sehr schnell)

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// Blittet eine Textur auf den Bildschirm

void SDLW::Blit(unsigned texture, float x, float y, int w, int h)
{
    
    GL_TexEnable(1);
    GL_Bind(texture);

    glBegin(GL_QUADS);
        glTexCoord2f(0, 0); glVertex2i(x, y);
        glTexCoord2f(1, 0); glVertex2i(x+w, y);
        glTexCoord2f(1, 1); glVertex2i(x+w, y+h);
        glTexCoord2f(0, 1); glVertex2i(x, y+h);
    glEnd(); 
}


// Hier noch GL_TexEnable und GL_Bind


static __inline__ void GL_TexEnable(int enable)
{
    if (SDLW::gl_state_texenable == enable)
        return;

    if (enable)
        glEnable(GL_TEXTURE_2D);
    else
        glDisable(GL_TEXTURE_2D);

    SDLW::gl_state_texenable = enable;
}

/* Bindet eine Textur */
static __inline__ void GL_Bind(unsigned texture)
{
    if (SDLW::gl_state_texture == texture)
        return;

    glBindTexture(GL_TEXTURE_2D, texture);

    SDLW::gl_state_texture = texture;
}


ich hoffe mal ihr könnt mir helfen. Riesen Dankeschön im voraus.

mfG
Eldarion

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

2

26.09.2007, 23:52

Kann eigentlich nicht sein.
*Was* genau dauert 50 ms? Allein der Aufruf?
Wenn das wirklich so ist, dann deutet das darauf hin, dass da keine Hardware am Werk ist, sondern die Software-Emulation von OpenGL. Die kann z.B. aktiviert werden, wenn du Texturen verwendest, deren Breite und Höhe keiner Zweierpotenz ist. Genau das ist mir mal passiert, trotz moderner Grafikkarte, und es hat mich eine halbe Ewigkeit gekostet, um dahinter zu kommen.

3

27.09.2007, 00:21

also die grafiken haben wirklich keine größen mit 2er potenz, das würde einiges erklären.

ich hab einfach mit SDL_GetTicks() vor und nach dem aufruf von Blit gemessen und es war meist ein unterschied um 49ms. Ich werde das mit 2er potenzen mal ausprobieren :)


edit: ist aktuelle hardware denn wirklich nicht in der Lage mit solchen Texturen umzugehen?
edit: hab grade mal die texturen von ball und schläger auf 16x16 bzw. 128x128 erweitert. ich hab jetzt schon etwa das doppelte an fps (zwischen 160-170) und das blitten für die 128x128 tex dauert nur noch 14ms. schon deutlich akzeptabler :)
jetzt kommt natürlich noch blending dazu weil ich dann ja ränder hab an den grafiken, aber darum kümmer ich mich heute früh^^ riesen thx @david.
wenn jemand allerdings noch ne Idee hat wie ich das Blitten schneller machen kann, bin ich dafür gerne offen.

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

4

27.09.2007, 11:37

Grafikkarten können schon mit solchen Texturen umgehen, aber der Standard erlaubt dies wohl nicht. Da muss man wohl die GL_TEXTURE_RECT-Extension nutzen, soweit ich weiß.

Auch 14 ms sind noch viel zu viel. Wenn da die Hardware benutzt würde, würde der Befehl nur weitergeleitet, und das Programm würde dann sofort weiterlaufen (<< 1 ms). Die Hardware arbeitet die Befehle im Hintergrund ab. Erst wenn z.B. das Frame dargestellt werden soll, muss so lange gewartet werden, bis die Hardware fertig ist.

Also könnte da noch was anderes sein, was dazu führt, dass OpenGL alles in Software emuliert.

5

27.09.2007, 11:41

was könnte das seien? also was sollte ich überprüfen?

Noch eine weitere Frage, was würdet ihr für eine GUI mit SDL benutzen? Ich meine jetzt eher weniger eine IngameGUI sondern GUI für Hauptmenü, Optionsmenü, etc...

Kasenoru

Frischling

Beiträge: 79

Beruf: Softwareentwickler

  • Private Nachricht senden

6

27.09.2007, 13:14

Also, du nutzt SDL und OpenGL zusammmen nehme ich an und wahrscheinlich willst du damit 2D Grafik machen.
Wie hast du den ganzen kram eigentlich initialisiert?
Das würde ich gerne mal sehen, vllt. kann ich dir dann etwas helfen.

Mit freundlichen Grüßen

Kasenoru

7

27.09.2007, 13:46

genau so siehts aus ;)

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
void SDLW::Init()
{
/* SDL initialisieren */
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        Log::getInstance()->Write("Fehler beim initialisieren von SDL");
        fprintf(stderr, "SDL konnte nicht initialisiert werden: %s\n",
            SDL_GetError());
        exit(1);
    }
    atexit(SDL_Quit);
    Log::getInstance()->Write("SDL initialisiert");
/* OpenGL-Bildschirmmodus */
    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

    screen = SDL_SetVideoMode(1024, 768, 0, SDL_OPENGL | SDL_FULLSCREEN);
    if (!screen) {
        Log::getInstance()->Write("Fehler beim setzen von Bildschirmmodus");
        fprintf(stderr, "Konnte Bildschirmmodus nicht setzen: %s\n",
            SDL_GetError());
        exit(1);
    }
    Log::getInstance()->Write("Bildschirmmodus gesetzt");
    SDL_EnableKeyRepeat(1, 1);

/* Initialisierung von OpenGL */
    glViewport(0, 0, screen->w, screen->h);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, screen->w, screen->h, 0, -1.0, 1.0);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

}


das ist alles an intialisierung in betracht auf SDL/OGL.

Eldarion

Edit: Wo es schon um Performance geht, ist es eurere Meinung überhaupt sinnvoll SDL im OpenGL modus laufen zulassen, oder sollte ich lieber nur OpenGL verwenden. (Dann würde ich jetzt anfangen NeHe durchzuarbeiten bis ich alles wichtige für 2D Grafik mit OpenGL kann)

Kasenoru

Frischling

Beiträge: 79

Beruf: Softwareentwickler

  • Private Nachricht senden

8

27.09.2007, 14:00

hm...... ich denke nicht das es was hilft aber du könntest noch folgendes Attribut setzen:

Quellcode

1
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);


Wenn du noch VSync möchtest:

Quellcode

1
SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);


Ob das jetzt hilft kann ich nicht sagen.
Ich denke mal schon das du entsprechende Treiber, etc. installierst hast.
Mehr kann ich also auch nicht sagen.

Zitat


Wo es schon um Performance geht, ist es eurere Meinung überhaupt sinnvoll SDL im OpenGL modus laufen zulassen, oder sollte ich lieber nur OpenGL verwenden. (Dann würde ich jetzt anfangen NeHe durchzuarbeiten bis ich alles wichtige für 2D Grafik mit OpenGL kann)

Nimm lieber SDL, das ist einfacher und portabler.
Das macht keinen wirklichen Unterschied, ob du nun SDL nimmst oder nicht.

Mit freundlichen Grüßen

Kasenoru

9

27.09.2007, 14:04

schonmal thx :) ich hab jetzt noch 7ms bei tex mit 2er potenz und deinen zusätzlichen flags :) aber ich frage mich wo jetzt die bremse ist. Weil eig. ist 7ms wirklich etwas viel für das zeichnen einer textur.

hmm, was meinst du denn jetzt, lohnt es sich SDL im OpenGL modus zu betreiben (ich meine, ich kann ja auch einfach die grafik komplett in OGL coden und SDL nur für input und sound benutzen. ich meine damit jetz die SDL Grafik mit OpenGL flag) oder sollte ich lieber etwas zeit investieren und richtig opengl lernen?

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

10

27.09.2007, 14:14

Es könnte auch an deinem 16-Bit-Format liegen.
Wer nutzt denn heute noch 16-Bit-Farbe?? Mach mal 32 Bit.

Werbeanzeige