[OpenGL] erg traag met simpele quad en texture

Pagina: 1
Acties:

  • MisterData
  • Registratie: September 2001
  • Laatst online: 11-02 08:33
Ik ben net een beetje aan het knutselen met OpenGL, een beetje uitzoeken hoe alles werkt voor een iets groter project, zegmaar. Nu heb ik een vrij simpel ding geschreven dat een quad laat zien met een texture (die ik met GDI+ maak):

Het venster wordt als volgt opgezet:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    HDC dc = GetDC(_wnd);
    
    // set pixel format
    PIXELFORMATDESCRIPTOR pfd;
    ZeroMemory(&pfd, sizeof(pfd));
    pfd.nSize = sizeof(pfd);
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_GENERIC_ACCELERATED;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 24;
    pfd.cDepthBits = 16;
    pfd.iLayerType = PFD_MAIN_PLANE;
    int iFormat = ChoosePixelFormat(dc,&pfd);

    SetPixelFormat(dc,iFormat,&pfd);
    _rc = wglCreateContext(dc);
    ReleaseDC(_wnd, dc);


Dit lijkt allemaal goed te gaan. Dan worden er wat OpenGL-dingen ingesteld en wordt de texture geladen:

C++:
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
GLPainter p(_rc, _wnd);
        glMatrixMode(GL_PROJECTION);   //changes the current matrix to the projection matrix
        gluPerspective(90.0f,1.0f, 1.0,100.0f);
        glMatrixMode(GL_MODELVIEW_MATRIX);

        // make a nice, large texture
        Gdiplus::Bitmap bmp(L"D:\\Projecten\\tjshow\\Release\\icons\\run.png", TRUE);
        glGenTextures(32,&(_textures[0]));
        glBindTexture(GL_TEXTURE_2D, _textures[0]);

        Gdiplus::BitmapData data;
        Gdiplus::Rect rc(0,0,bmp.GetWidth(), bmp.GetHeight());
        if(bmp.LockBits(&rc, Gdiplus::ImageLockModeRead, PixelFormat32bppRGB, &data)!=Gdiplus::Ok) {
            
            MessageBox(0L, L"Texture error", L"", MB_OK);
        }

        glTexImage2D(GL_TEXTURE_2D, 0, 3, bmp.GetWidth(), bmp.GetHeight(), 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, data.Scan0);
        bmp.UnlockBits(&data);

        // texture settings
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // Linear Filtering
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // Linear Filtering

        glPushMatrix();
        glScalef(1.0f, -1.0f, 1.0f); // so the origin is left-top
        glTranslatef(-1.0f, -1.0f, -1.0f);
        glScalef(2.0f, 2.0f, 1.0f);


(de GLPainter-class zorgt voor wglMakeCurrent). Ook dit gaat allemaal goed en het plaatje wordt ook daadwerkelijk geladen. Dan de paint-functie:

C++:
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
    static float theta = 0.1f;
    glPushMatrix();
    theta += 0.1f;

    float x = 0.5f;
    float y = 0.5f;
    float w = 0.5f;
    float h = 0.5f;

    glTranslatef(1.5f*x, 1.5f*y, 0.0f);
    glRotatef( theta, 0.0f, 0.0f, 1.0f );
    glTranslatef(-0.5f*x, -0.5f*y, 0.0f);
    glScalef(w,h,1.0f);
    glEnable(GL_TEXTURE_2D);
    glBegin( GL_QUADS );
        
    glTexCoord2f(0.0f, 0.0f); glColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); glVertex3f( 0.1f, 0.1f, 0.0f );
    glTexCoord2f(1.0f, 0.0f); glColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); glVertex3f( 0.9f, 0.1f, 0.0f );
    glTexCoord2f(1.0f, 1.0f); glColor4f( 1.0f, 1.0f, 1.0f, 1.0f); glVertex3f( 0.9f, 0.9f, 0.0f );
    glTexCoord2f(0.0f, 1.0f); glColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); glVertex3f( 0.1f, 0.9f, 0.0f );
    

    glEnd();
    glDisable(GL_TEXTURE_2D);
    glPopMatrix();


Nou is het hele translate/rotate-gebeuren misschien niet zo interessant (werkt prima), maar het probleem is dat als ik textures helemaal uitschakel (geen glBindTexture of glEnable) het vierkantje snel genoeg roteert. Schakel ik de texture in (die ongeveer 16x16 pixels is, maar de quad op het scherm is ongeveer 200x200) dan wordt het zo traag dat ik nog net aan de 1 FPS kom. Dat lijkt me erg traag, zelfs met een Radeon X1400 Mobility in deze laptop... de CPU-usage stijgt naar 50% (een hele core) dus dat lijkt me niet helemaal goed... iemand enig idee waarom OpenGL zo traag gaat (hij lijkt wel software rendering te doen ofzo?) Ik kom er met geen mogelijkheid (geen profiler hier, maar met de debugger zie ik niks en alle overige instellingen lijken prima) achter waar de tijd in gaat zitten...

Het verschil in snelheid tussen de 16x16 texture en een texture van 400x300 is trouwens niet zo heel groot...

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Je upload de texture toch niet iedere frame naar je GPU heh? Met glTexImage2D()?

Wat is die 3 ook al weer in glteximage2d? Iets met mipmaps toch, maar die gebruik je niet (GL_LINEAR) Components ja. Daar moet je iets van GL_RGBA van maken. Geen 3. Het is je internal format, voor floating point textures is het bv GL_RGBA32F_ARB. Ik weet niet wat "3" is als GLenum, maar vast niet GL_RGBA.

Het beste is om met integer byte textures je internal format op GL_RGBA te zetten, type op GL_UNSIGNED_BYTE en external format (van je plaatje dus) op GL_BGRA.

Voor floats wordt het: internal: GL_RGBA32F_ARB, external: GL_RGBA, type: GL_FLOAT

[ Voor 99% gewijzigd door Zoijar op 27-09-2006 22:57 ]


  • MisterData
  • Registratie: September 2001
  • Laatst online: 11-02 08:33
Het 'uploaden' van de texture gebeurt maar één keer, eigenlijk meteen na het opzetten van het venster. In de Paint-methode wordt nu nog zelfs geen bind gedaan.

C++:
1
glTexImage2D(GL_TEXTURE_2D, 0, 3, bmp.GetWidth(), bmp.GetHeight(), 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, data.Scan0);


Voorzover ik kan zien is de 3 voor het aantal kleurkanalen :)

glTexImage2D op opengl.org :) Ik heb het even veranderd in GL_RGBA (dat mag ook volgens dat docje) maar hoewel het er íets sneller op wordt is het nog steeds niet echt flitsend...

Hoe zit het uberhaupt met software en hardware-rendering in OpenGL, kan ik dat ergens instellen of zien welke er wordt gebruikt?

[ Voor 36% gewijzigd door MisterData op 27-09-2006 22:59 ]


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    struct Format {
        GLenum internal;
        GLenum external;
        GLenum type;
        size_t tuple_size;

        Format() {}
        Format(GLenum a, GLenum b, GLenum c, size_t d) : internal(a), external(b), type(c), tuple_size(d) {}
        ~Format() {}
    };

    static Format full_float_rgba() {
        return Format(GL_RGBA32F_ARB, GL_RGBA, GL_FLOAT, 4*4);
    }
    static Format half_float_rgba() {
        return Format(GL_RGBA16F_ARB, GL_RGBA, GL_HALF_FLOAT_ARB, 4*2);
    }
    static Format byte_bgra() {
        return Format(GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE, 4);
    }
    static Format depth_24() {
        return Format(GL_DEPTH_COMPONENT24_ARB, GL_DEPTH_COMPONENT, GL_FLOAT, 3);
    }


code:
1
2
3
4
5
6
7
8
void TextureManager::GLTexture::setFormat(const Format& format, unsigned int width, unsigned int height, const GLvoid* pixels) {
    TextureManager::pointer()->bind(this);
    glTexImage2D(target_, 0, format.internal, width, height, 0, format.external, format.type, pixels);
    width_ = width;
    height_ = height;
    current_format_ = format;
    format_set_ = true;
}

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

hardware als het beschikbaar is. Wat wel het geval zal zijn.

  • MisterData
  • Registratie: September 2001
  • Laatst online: 11-02 08:33
Okee, het probleem is 'opgelost'. Ik heb gevonden dat als ik textures gebruik van het formaat a*a (vierkant dus) waarbij a = 2^n (dus bijvoorbeeld 16x16 of zelfs 1024x1024) het allemaal een stúk sneller gaat (ter vergelijking: de 1024x1024 is nog minstens 10 keer sneller dan 400x300). Enig idee hoe dit komt? Hoe kan ik dit op een nette manier afvangen, zodat ik toch textures van 400x300 kan gebruiken? :)

  • Skinkie
  • Registratie: Juni 2001
  • Laatst online: 09-06-2020

Skinkie

Op naar de 500

MisterData schreef op donderdag 28 september 2006 @ 14:21:
Okee, het probleem is 'opgelost'. Ik heb gevonden dat als ik textures gebruik van het formaat a*a (vierkant dus) waarbij a = 2^n (dus bijvoorbeeld 16x16 of zelfs 1024x1024) het allemaal een stúk sneller gaat (ter vergelijking: de 1024x1024 is nog minstens 10 keer sneller dan 400x300). Enig idee hoe dit komt? Hoe kan ik dit op een nette manier afvangen, zodat ik toch textures van 400x300 kan gebruiken? :)
Ik denk dat het met een vector operatie te maken heeft... die niet beschikbaar is voor n*m. Gewoon eerst rescalen :)

Steun Elkaar, Kopieer Nederlands Waar!


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 13-02 18:54

.oisyn

Moderator Devschuur®

Demotivational Speaker

pow2 textures waren nogal een verplichting op oudere hardware. Rescalen dus, doet iedereen :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1