Deutsch
Quelltexte/ Codesnippets

OpenGL glDrawArrays: Sehr viele Objekte schnell zeichnen

 

Sven
Bader
Die Methode ist nicht aktuell, kommt dafür aber mit dem zugänglichen Befehlssatz aus. Heutzutage verwendet man VBOs (vertex buffer objects). Die Idee ist die gleiche aber in meinem Beispiel mit glDrawArrays wird anstatt den Video-RAM der herkömmliche Arbeitsspeicher verwendet. Dennoch ist es um ein vielfaches schneller als z.B. eine oGL("DrawList", N) mit tausenden oGL("Sphere", ...) darin.

Ich speichere Vertex-Daten (Punkte) von Kugeln in einen Bereich, welcher dann in einem Arbeitsgang jeden Frame dargestellt wird. Ohne Texturkoordinaten oder ohne Normalen geht es noch schneller. Bei einer schnellen Grafikkarte scheint hier das einzige Nadelöhr der RAM zu sein.

Achtung: die initiale Erstellung dauert möglicherweise sehr lang, danach lassen sich aber mehrere tausend Kugeln mit hoher Framerate darstellen.





Oben im Code können testweise Normalen und Textur ausgeschaltet werden:
usetex& = 1
usenormal& = 1

Hier die verwendete Textur (an das XProfan Icon angelehnt):



Hier das ganze Listing. Wenn man die Funktion für die Kugel und die Input-Abfrage ausklammert, ist der Code sehr überschaubar.
 $H windows.ph
 $H opengl.ph
Declare tex&[5]
Declare xrot!, yrot!, zrot!, xpos!, ypos!, zpos!,xsrot!,ysrot!,zsrot!,xspos!,yspos!,zspos!
Declare smooth%,mb&,mousestartx%,mousestarty%,mousex%,mousey%
Declare ende%,hPic&
Declare sphere&,frame&,time&,fps&, usetex&,usenormal&
usetex& = 1
usenormal& = 1
declare vertex#,normal#,texture#,count&
Dim vertex#         ,200000000
Dim normal#         ,200000000
Dim texture#         ,(200000000/3*2)

proc Sphere

    parameters px!,py!,pz!,fRadius!, iStacks%,iSlices%
    declare t1a!, t1b!, n1a!, n1b!, n1c!, v1a!, v1b!, v1c!, t2a!, t2b!, n2a!, n2b!, n2c!, v2a!, v2b!, v2c!
    declare PI!,PIx2!,drho!,dtheta!,ds!,dt!,t!,s!,x!,y!,z!
    declare rho!,srho!,crho!,srhodrho!,crhodrho!
    declare theta!,stheta!,ctheta!,i%,j%,k%
    PI! =  Pi()
    PIx2! = Pi() * 2.0
    drho! = PI! / iStacks%
    dtheta! = PIx2! / iSlices%
    ds! = 1.0 / iSlices%
    dt! = 1.0 / iStacks%
    t! = 1.0
    s! = 0.0
    k% = 0

    whileloop 0, (iStacks%-1)

        i% = &loop
        rho! = i% * drho!
        srho! =  sin(rho!)
        crho! = cos(rho!)
        srhodrho! = sin(rho! + drho!)
        crhodrho! = cos(rho! + drho!)
        s! = 0.0

        whileloop  0, iSlices%

            inc k%
            j% = &loop
            theta! = if(j% = iSlices%, 0.0, j% * dtheta!)
            stheta! = -sin(theta!)
            ctheta! = cos(theta!)
            x! = stheta! * srho!
            y! = ctheta! * srho!
            z! = crho!

            if   (j% > 1)

                Float vertex#,(count&*24)  = v1a!,v1b!,v1c!
                case usetex& : Float texture#,(count&*16) = t1a!,t1b!
                case usenormal& : Float normal#,(count&*24)  = n1a!,n1b!,n1c!
                inc count&
                Float vertex#,(count&*24)  = v2a!,v2b!,v2c!
                case usetex& : Float texture#,(count&*16) = t2a!,t2b!
                case usenormal& : Float normal#,(count&*24)  = n2a!,n2b!,n2c!
                inc count&

            endif

            v1a! = (x! * fRadius!)+px!
            v1b! = (y! * fRadius!)+py!
            v1c! = (z! * fRadius!)+pz!
            t1a! = s!
            t1b! = t!
            n1a! = x!
            n1b! = y!
            n1c! = z!
            Float vertex#,(count&*24)  = (x! * fRadius!)+px!,(y! * fRadius!)+py!, (z! * fRadius!)+pz!
            case usetex& : Float texture#,(count&*16) = s!,t!
            case usenormal& : Float normal#,(count&*24)  = x!,y!,z!
            inc count&
            x! = stheta! * srhodrho!
            y! = ctheta! * srhodrho!
            z! = crhodrho!

            if   (j% > 0)

                Float vertex#,(count&*24)  = v1a!,v1b!,v1c!
                case usetex& : Float texture#,(count&*16) = t1a!,t1b!
                case usenormal& : Float normal#,(count&*24)  = n1a!,n1b!,n1c!
                inc count&
                Float vertex#,(count&*24)  = v2a!,v2b!,v2c!
                case usetex& : Float texture#,(count&*16) = t2a!,t2b!
                case usenormal& : Float normal#,(count&*24)  = n2a!,n2b!,n2c!
                inc count&

            endif

            t2a! = s!
            t2b! = (t! - dt!)
            n2a! = x!
            n2b! = y!
            n2c! = z!
            v2a! = (x! * fRadius!)+px!
            v2b! = (y! * fRadius!)+py!
            v2c! = (z! * fRadius!)+pz!
            case usetex& : Float texture#,(count&*16 ) = t2a!,t2b!
            s! = s! + ds!
            case usenormal& :  Float normal#,(count&*24)  = n2a!,n2b!,n2c!
            Float vertex#,(count&*24)  = v2a!,v2b!,v2c!
            inc count&

        endwhile

        t! = t! - dt!

    endwhile

endproc

Proc MouseKeyboard

    mousex% = %MouseX
    mousey% = %MouseY

    if mb& = 0

        case isKey(~VK_LBUTTON) : mb& = 1
        case isKey(~VK_RBUTTON) : mb& = 2

    endif

    if (not(isKey(~VK_RBUTTON)) & not(isKey(~VK_LBUTTON)))

        'Startposition fürs rotieren und Zoomwen wieder nullen
        mb& = 0
        mousestartx% = %mousex
        mousestarty% = %mousey
        xsrot! = xrot!
        ysrot! = yrot!
        zspos! =  zpos!

    endif

    'Tastaturrotation
    case isKey(~VK_LEFT)  : yrot! = yrot! - 1.0
    case isKey(~VK_RIGHT) : yrot! = yrot! + 1.0
    case isKey(~VK_UP)    : xrot! = xrot! + 1.0
    case isKey(~VK_DOWN)  : xrot! = xrot! - 1.0
    'Mausrotation

    if (mb& = 1)

        yrot! = ysrot! - (mousestartx% - %mousex) * 0.4
        xrot! = xsrot! - (mousestarty% - %mousey) * 0.4

    endif

    'Mauszoom

    if (mb& = 2) & (abs(mousestarty% - %mousey) > 10)

        zpos! = zspos! + (mousestarty% - %mousey) * 0.03
        'Wenn darüber hinaus bewegt wurde, soll es beim Richtungswechsel trotzdem direkt rückwärts gehen
        'Unschöner Hack, Rechnen wäre der feinere Weg ...

        while (zpos! > -2.0)

            dec mousestarty%
            zpos! = zspos! + (mousestarty% - %mousey) * 0.03

        endwhile

        while (zpos! < -15.0)

            inc mousestarty%
            zpos! = zspos! + (mousestarty% - %mousey) * 0.03

        endwhile

    endif

    'Tastaturzoom
    case isKey(~VK_SUBTRACT)     : zpos! = zpos! - 0.06
    case isKey(~VK_ADD)    : zpos! = zpos! + 0.06
    'Zoom begrenzen
    case (zpos! > -2.0)  : zpos! = -2.0
    case (zpos! < -15.0) : zpos! = -15.0
    'Sonstige Tastatureingaben
    case IsKey(27) : Ende% = 1

Endproc

Proc DrawGLScene

    oGL("Clear")
    ogl("Origin",0,0,-0.2)
    oGL("Move", xpos!, ypos!, zpos!)
    oGL("Rotate", xrot!,yrot!,zrot!)
    oGL("glDrawArrays",~GL_TRIANGLES, 0 ,count&-1)'mode, first, count
    oGL("Show")

Endproc

' Hauptprogramm
' -------------
windowstyle 1+2+4+8+16
windowtitle "Sphere"
window (%maxx *  0.5 -480), (%maxy *  0.5 - 300) - 960,600'kompatible Schreibweise
UseIcon "Gesicht"
oGL("Init", %hWnd, 1,1,1,1)
oGL("PosMode",1)
oGL("glEnable", ~GL_CULL_FACE)
'oGL("glShadeModel", ~GL_FLAT)
case usetex& : oGL("glEnableClientState",~GL_TEXTURE_COORD_ARRAY_EXT)
case usenormal& : oGL("glEnableClientState",~GL_NORMAL_ARRAY_EXT)
oGL("glEnableClientState",~GL_VERTEX_ARRAY_EXT)
case usetex& : oGL("glTexCoordPointer",2,~GL_DOUBLE,0,texture#)
case usenormal& : oGL("glNormalPointer",~GL_DOUBLE,0,normal#)
oGL("glVertexPointer",3,~GL_DOUBLE,0,vertex#)
hPic&=create("hPic",-1,"smile.png")
tex&[1]=ogl("getTextureBmp",hPic&,2)
DeleteObject hPic&
oGL("Texture",tex&[1],1)
'oGL("Texture",0,1)

whileloop 0, 500

    'Sphere(X, Y, Z, Größe, Scheiben, Segmente)
    Sphere((rnd(1000)-500)*0.01,(rnd(1000)-500)*0.01,(rnd(1000)-500)*0.01,0.05,6,6)

endwhile

zpos! = -5
xrot! = -90
yrot! = 0
time& = &gettickcount

WhileNot ende%

    if (frame& MOD 100 = 0)

        time& = ((&gettickcount - time&) * 0.01) + 1
        fps& =  1000 / time&
        setText %hWnd, str$(fps&) + " fps"
        time& = &gettickcount

    endif

    MouseKeyboard()
    DrawGLScene()
    inc frame&

EndWhile

oGL("Done")
End

342 kB
Hochgeladen:16.09.2021
Ladeanzahl70
Herunterladen
339 kB
Hochgeladen:16.09.2021
Ladeanzahl57
Herunterladen
12 kB
Hochgeladen:16.09.2021
Ladeanzahl56
Herunterladen
 
16.09.2021  
 



Zum Quelltext


Thementitel, max. 100 Zeichen.
 

Systemprofile:

Kein Systemprofil angelegt. [anlegen]

XProfan:

 Beitrag  Schrift  Smilies  ▼ 

Bitte anmelden um einen Beitrag zu verfassen.
 

Themenoptionen

1.392 Betrachtungen

Unbenanntvor 0 min.
Sven Bader02.02.2023
Ernst29.05.2022
p.specht18.11.2021
Peter Max Müller18.11.2021
Mehr...

Themeninformationen

Dieses Thema hat 1 Teilnehmer:

Sven Bader (1x)


Admins  |  AGB  |  Anwendungen  |  Autoren  |  Chat  |  Datenschutz  |  Download  |  Eingangshalle  |  Hilfe  |  Händlerportal  |  Impressum  |  Mart  |  Schnittstellen  |  SDK  |  Services  |  Spiele  |  Suche  |  Support

Ein Projekt aller XProfaner, die es gibt!


Mein XProfan
Private Nachrichten
Eigenes Ablageforum
Themen-Merkliste
Eigene Beiträge
Eigene Themen
Zwischenablage
Abmelden
 Deutsch English Français Español Italia
Übersetzungen

Datenschutz


Wir verwenden Cookies nur als Session-Cookies wegen der technischen Notwendigkeit und bei uns gibt es keine Cookies von Drittanbietern.

Wenn du hier auf unsere Webseite klickst oder navigierst, stimmst du unserer Erfassung von Informationen in unseren Cookies auf XProfan.Net zu.

Weitere Informationen zu unseren Cookies und dazu, wie du die Kontrolle darüber behältst, findest du in unserer nachfolgenden Datenschutzerklärung.


einverstandenDatenschutzerklärung
Ich möchte keinen Cookie