Einstieg in OpenGL, Anfängerprobleme



  • Tobiking2 schrieb:

    Was machst du da denn jetzt genau? Weder das glGenBuffers noch das glBindBuffer hat etwas mit deinen Vertex Daten zu tun, daher verstehe ich nicht was da überschrieben werden soll.

    Also mein Code sieht jetzt so aus:

    void OpenGL::init(void) {
    	vertices[0].x = 0;
    	vertices[0].y = 30;
    	vertices[1].x = 800;
    	vertices[1].y = 30;
    	vertices[2].x = 400;
    	vertices[2].y = 60;
        pindices[0] = 0;
        pindices[1] = 1;
        pindices[2] = 2;	
        glGenBuffers(1, &vertexvbo);
    	glGenBuffers(1, &indexvbo);
    	glBindBuffer(GL_ARRAY_BUFFER, vertexvbo);
    	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexvbo);
    	// 4 Byte * 3 Vertex * 2 Elemente
    	glBufferData(GL_ARRAY_BUFFER, 4*3*2, &vertices, GL_STATIC_DRAW);
    	// 2 Byte * 3 Vertex
    	glBufferData(GL_ELEMENT_ARRAY_BUFFER, 2*3, pindices, GL_STATIC_DRAW);
    };
    
    void OpenGL::draw(void) {
    	glEnableClientState(GL_VERTEX_ARRAY);
    	glBindBuffer(GL_ARRAY_BUFFER, vertexvbo);
    	glVertexPointer(2, GL_INT, sizeof(MyVertex), BUFFER_OFFSET(0));
    	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexvbo);
    	glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, &indexvbo);
    	glDisableClientState(GL_VERTEX_ARRAY);
    };
    

    Sobald jetzt das erste glBindBuffer aufgerufen wird, werden ALLE Daten in der Klasse, egal ob die irgendwas mit VBO etc. zu tun haben sinnlos überschrieben. Kurz gesagt ist die ganze Klasse nachher nurnoch Datenschrott.
    Mein Code habe ich hierher



  • Du meinst es kracht schon in Zeile 11? Also wenn vertexvbo ein GLint ist wüsste ich nicht was dort für ein Problem auftreten sollte.

    Allerdings ist dort ein Fehler in der Zeile 16. Das vertices ist bereits die Adresse, weswegen der Adress Operator zu viel ist.

    Davon auszugehen das ein struct/class genau die Größe seiner Elemente hat kann auch kritisch werden, da der Compiler padding Bytes einfügen darf. Das dürfte hier wahrscheinlich nicht der Fall sein, aber wenn man wie in dem Beispiele sizeof benutzt, ist man auf der sicheren Seite.



  • Tobiking2 schrieb:

    Allerdings ist dort ein Fehler in der Zeile 16. Das vertices ist bereits die Adresse, weswegen der Adress Operator zu viel ist.

    Habs geändert, hat aber nicht viel gebracht. Ich hab mal nen paar Screens vom Debugger gemacht:

    Vor allen GL Funktionen:
    Bild 1

    Nach glGenBuffers():
    Bild 2
    Man sieht, das bei pindices und vertices einige Werte, aber nicht alle geändert wurden.

    Nach glBindBuffer():
    Bild 3
    Danach sieht man nurnoch misst im Debugger...

    Und dann nach glBufferData():
    Bild 4
    Jetzt sieht man nurnoch Fragezeichen...

    Bei glDrawElements(), dort wo die Zugriffverletzung geschieht, siehts dann so aus:
    Bild 5

    Und jetzt habe ich keine Ahnung, wieso die Daten so verhunzt werden...



  • Ich mal eine komplett neue Klasse erstellt nur für die VBO's und das Problem ist das gleiche.
    Bei einem Testprojekt, welches ich auf das minimum reduziert habe, und nur VBO's gezeichnet werden besteht auch das gleiche Problem. Also muss der Fehler ja irgendwie im Code liegen.



  • openglnoob schrieb:

    Ich mal eine komplett neue Klasse erstellt nur für die VBO's und das Problem ist das gleiche.
    Bei einem Testprojekt, welches ich auf das minimum reduziert habe, und nur VBO's gezeichnet werden besteht auch das gleiche Problem. Also muss der Fehler ja irgendwie im Code liegen.

    Kann die Graka das überhaupt? Mal nen ARB-String abgefragt und nachgeschaut?



  • Ja hab ich gemacht, und die GraKa sollte das können. Hier mal die glewinfo.txt die glew erstellt:
    http://www.file-upload.net/download-2834265/glewinfo.txt.html

    EDIT: Hab sie beim Filehoster hochgeladen, da die Datei zu lang für Forum oder Pastebin war.



  • So ich bin etzt glaube ich einen Schritt weiter.
    Also ich hab diese beiden globalen Variablen:

    GLuint vboid;
    GLint vertices[] = {0,0,50,0,50,50,0,50};
    

    Dann hab ich das in meiner Initialisierungfunktion:

    glGenBuffers(1, &vboid);
    glBindBuffer(GL_ARRAY_BUFFER, vboid);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    

    Das klappt auch alles soweit.

    Dann steht das hier in meiner Zeichenmethode:

    glBindBuffer(GL_ARRAY_BUFFER, vboid);
    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(2, GL_INT, 0, BUFFER_OFFSET(0));
    glDrawArrays(GL_QUADS, 0, 8);
    glDisableClientState(GL_VERTEX_ARRAY);
    

    Da ist dann bei glDrawArrays eine Zugriffsverletzung, aber Debugger sieht ganz konform aus und ohne VBO klappt auch alles.



  • Hab bei glVertexPointer jetzt mal einige größen ausprobiert.
    Was genau ist da die richtige?
    Und außerdem ist die Zugriffsverletzung an Position 0x00000000.
    Heißt das jetzt, dass die Funktion wirklich von dieser Position lesen will, und der Buffer ignoriert wird?



  • openglnoob schrieb:

    Dann steht das hier in meiner Zeichenmethode:
    [cpp]
    glBindBuffer(GL_ARRAY_BUFFER, vboid);
    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(2, GL_INT, 0, BUFFER_OFFSET(0));
    glDrawArrays(GL_QUADS, 0, 8);
    glDisableClientState(GL_VERTEX_ARRAY);
    [/cpp]

    Du zeichnest aber nur 4 Vertices und nicht 8.



  • Hmm, da hab ich die Doku falsch verstanden, ohne VBO zeichnet der bei 4 auch noch alles. Allerdings hat das nichts gebracht. Ich hab meinen Code der Zeichenmethode noch ein bisschen aktualisiert:

    glBindBuffer(GL_ARRAY_BUFFER, vboid);
    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(2, GL_INT, sizeof(vertices), BUFFER_OFFSET(0));
    glDrawArrays(GL_QUADS, 0, 4);
    glDisableClientState(GL_VERTEX_ARRAY);
    

    Aber irgendwas muss ich doch falsch machen, ansonsten würde es doch funktionieren 😕



  • Ich hab jetzt mal bei einem Freund ausprobiert, der eine neuere GraKa hat, und bei ihm funktionierts. Aber wieso klappt es bei mir nicht, die glewinfo spuckt duch das hier aus:

    glewinfo schrieb:

    GL_VERSION_1_5: OK
    ---------------
    glBeginQuery: OK
    glBindBuffer: OK
    glBufferData: OK
    glBufferSubData: OK
    glDeleteBuffers: OK
    glDeleteQueries: OK
    glEndQuery: OK
    glGenBuffers: OK
    glGenQueries: OK
    glGetBufferParameteriv: OK
    glGetBufferPointerv: OK
    glGetBufferSubData: OK
    glGetQueryObjectiv: OK
    glGetQueryObjectuiv: OK
    glGetQueryiv: OK
    glIsBuffer: OK
    glIsQuery: OK
    glMapBuffer: OK
    glUnmapBuffer: OK

    und meine GraKa müsste laut Herstellerinformationen mindestens OpenGL 2.0 unterstützen.



  • Glew hast du aber über glewInit(); initialisiert?

    Dann solltest du den VertexPointer noch ändern, da du die Daten vom Pointer ja garnicht nutzen willst, sondern die des VBOs.
    glVertexPointer(2, GL_INT,0,0);

    Vielleicht hilft das.



  • glewInit() ist drin, und BUFFER_OFFSET(i) ist so definiert:

    #define BUFFER_OFFSET(i) ((char *)NULL + (i))
    

    Steht so auf opengl.org



  • Mit deinem momentanen VertexPointer glVertexPointer(2, GL_INT, sizeof(vertices), BUFFER_OFFSET(0)) gibst du als stride aber den Wert 32 an. D.h. es wird angenommen, dass zwischen jedem Vertex 32byte liegen, die immer übersprungen werden. Da bei dir die Vertex-Daten aber direkt hintereinander stehen muss hier der Wert 0 angegeben werden.

    Den Wert für stride wäre nicht 0, wenn du in deinem array auch noch Textur-Koordinaten und / oder Normalen-Koordinaten abgelegt hast. Dann müsstest du diese überspringen.



  • Noch nie hab ich mir mit der Doku so schwer getan wie hier. Jetzt versteh ich auch mal endlich was das heißt, denn es wird oft immer mit dem Zusammenhang von einem offset gebracht.
    Aber wie schon ein paar Posts vorher geschrieben, habe ich da schon alle Werte ausprobiert, gerade auch mal wieder die Null, klappt aber alles nicht. Ich denkees liegt eher an der Hardware (?) nur habe ich keinen Plan was ich da machen soll.



  • Poste einfach mal deinen kompletten code, falls er nicht gerade zig-hunder Zeilen lang ist, wovon ich jetzt mal ausgehe wenn du nur ein kleines Quadrat zeichnest.

    Als Anfänger gleich mit VBOs anzufangen ist allerdings auch nicht gerade vorteilhaft denke ich 🙂
    Klar wird man komplexe Szenen nicht mit 1000000 mal glVertex3f(x,y,z) aufrufen - aber zum lernen der Grundlagen denke ich wäre das geeigneter.
    So erkennt man später auch den Zusammenhang zwischen Texturkorrdinaten, Normalen und Vertexkorrdinaten besser.



  • Ja, würde ich auch gern sehen.



  • So hier ist der Quelltext:

    // vbo.cpp
    
    #include "stdafx.h"
    
    GLint vertices[] = {0,0,50,0,50,50,0,50};
    
    void VBO::init(void) {
    	glGenBuffersARB(1, &vboid);
    	glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboid);
    	glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vertices), vertices, GL_STATIC_DRAW_ARB);
    };
    
    void VBO::draw(void) {
    	glBindBufferARB(GL_ARRAY_BUFFER, vboid);
    	glEnableClientState(GL_VERTEX_ARRAY);
    	glVertexPointer(2, GL_INT, 0, BUFFER_OFFSET(0));
    	glDrawArrays(GL_QUADS, 0, 4);
    	glDisableClientState(GL_VERTEX_ARRAY);
    
    };
    
    // vbo.h
    
    class VBO {
    public:
    	void					init(void);
    	void					draw(void);
    private:
    	GLuint vboid;
    };
    
    // ganze OpenGL initialisierung
    
    bool OpenGL::init() {
    glewInit();
    vbo.init();									glShadeModel(GL_SMOOTH);						
    glClearColor(1.0, 1.0f, 1.0f, 1.0f);
    glEnable(GL_CULL_FACE);	glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);				
    };
    

    Das zeichnen wird dann eben in einer Endlosschleife gemacht.
    Es ist auch egal, ob die ARB Versionen der Funktionen nehme oder nicht, kommt das selbe raus.



  • Hm - gesetzt der Fall, das das nur ein Auszug deines Programms bzw der Dateien ist / sind (was ich schwer hoffe :D) - kann ich keinen Fehler erkennen.

    In der vbo.cpp wäre ein include des headers nicht verkehrt 🙂

    *grübel*

    Ich frag einfach mal ganz vorsichtig:
    Das steht so nicht alles in einer Datei drin? Und ist auch nicht alles oder?



  • inter2k3 schrieb:

    Hm - gesetzt der Fall, das das nur ein Auszug deines Programms bzw der Dateien ist / sind (was ich schwer hoffe :D) - kann ich keinen Fehler erkennen.

    Der Rest ist ist einfach nur Standardcode, um ein Fenster zu erzeugen etc.

    inter2k3 schrieb:

    In der vbo.cpp wäre ein include des headers nicht verkehrt 🙂

    In der stdafx.h ist alles drin.

    inter2k3 schrieb:

    Ich frag einfach mal ganz vorsichtig:
    Das steht so nicht alles in einer Datei drin? Und ist auch nicht alles oder?

    Das steht so drin, ist aber nicht alles.

    Ich hab jetzt mal versucht, die Funktionspointer zu bekommen und das sah dann so aus:

    PFNGLGENBUFFERSARBPROC m_glGenBuffersARB;							// VBO Name Generation Procedure
    	PFNGLBINDBUFFERARBPROC m_glBindBufferARB;							// VBO Bind Procedure
    	PFNGLBUFFERDATAARBPROC m_glBufferDataARB;							// VBO Data Loading Procedure
    m_glGenBuffersARB = reinterpret_cast<PFNGLGENBUFFERSARBPROC>(wglGetProcAddress("glGenBuffersARB"));
    	m_glBindBufferARB = reinterpret_cast<PFNGLBINDBUFFERARBPROC>(wglGetProcAddress("glBindBufferARB"));
    	m_glBufferDataARB = reinterpret_cast<PFNGLBUFFERDATAARBPROC>(wglGetProcAddress("glBufferDataARB"));
    

    Und die haben auch alle einen Wert. Nur klappts immernoch nicht.
    Aber bei der Binary von songho klappts auch mit VBO, und ich bin gerade dabei den Quellcode zu studieren.


Anmelden zum Antworten