Dreieck via Vertex Buffer erstellen



  • Hallo zusammen

    Ich hoffe jemand kann mir bei dem Problem helfen.
    Bei folgender Funktion kommt eine BAD Acces

    void DrawNew(void)
    {
    GLfloat vertexData[] {
    // X Y Z
    -0.6f, 0.4f, 0.f,
    0.6f, -0.4f, 0.f,
    0.f, 0.6f, 0.f
    };
    glGenBuffers(1, &gVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, gVBO);
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

    //draw
    glDrawArrays(GL_TRIANGLES, 0, 3);
    }

    Bin sehr dankbar um hilfe.



  • Welche OpenGL Version? Bei 4.0 und höher sind Vertex Array Objects Pflicht.

    floorball



  • Hallo floorball

    Ich arbeite nun unter Linux (vorhin Mac OSX 10.9) und die Version ist nach glxinfo

    Core profile 4.3 NVIDIA
    OpenGL Version 4.4 NVIDIA 331.38

    Wenn ich mein Programm compiliere dann findet er den glGenVertexArrays und andere die mit den VBO und den VAO zusammenhängen.

    Danke für deine Hilfe.

    Gruss
    Tinu



  • DinoTinu schrieb:

    Hallo floorball

    Ich arbeite nun unter Linux (vorhin Mac OSX 10.9) und die Version ist nach glxinfo

    Core profile 4.3 NVIDIA
    OpenGL Version 4.4 NVIDIA 331.38

    Wenn ich mein Programm compiliere dann findet er den glGenVertexArrays und andere die mit den VBO und den VAO zusammenhängen.

    Danke für deine Hilfe.

    Gruss
    Tinu

    Hmm komisch

    Ich finde die Funktion glGenVertexArrays auch nicht in der gl.h.
    Auf meinem Mac finde ich in der gl3.h die Funktion aber das Programm meldet den gleichen Fehler...

    Reicht da nicht das Packet mesa_common?

    😕

    Gruss Tino



  • DinoTinu schrieb:

    Ich arbeite nun unter Linux (vorhin Mac OSX 10.9) und die Version ist nach glxinfo

    Ist glxinfo das hier (oder eine Funktion in einem OpenGL-Framework das du benutzt)? Das gibt dir dann nicht die OpenGL Version die du benutzt, sondern die "highest available".
    Ich kenn mich jetzt mit Linux (und Macs) nicht aus, aber benutzt du ein Framework (sowas wie glut) zur Erzeugung deines OpenGL-Contexts? Oder erstellst du ihn selber.
    Wenn du ihn selber erstellst, dann ist es das einfachste du prüfst mal mit welcher OpenGL Version du ihn erstellst. Unter Windows zumindest kann man bei wglCreateContextAttribs noch eine OpenGL Version angeben, vielleicht gibt es was entsprechendes unter Linux, Mac was du benutzt.
    Ansonsten: mit glGetIntegerv und GL_MAJOR_VERSION und GL_MINOR_VERSION kannst du die von dir benutzte OpenGL Version bekommen. Bzw. je nach Implementierung und der von dir benutzen OpenGL Version geht das auch mit glGetString und GL_VERSION, wobei ich schon erlebt habe das glGetString(GL_VERSION) manchmal die benutzte OpenGL Version zurückgibt und manchmal die highest available. Also nicht empfehlenswert.

    DinoTinu schrieb:

    Ich finde die Funktion glGenVertexArrays auch nicht in der gl.h.
    Auf meinem Mac finde ich in der gl3.h die Funktion aber das Programm meldet den gleichen Fehler...

    1. Hast du auf deinem Mach auch glBindVertexArray aufgerufen?
    2. Das du die entsprechende Funktion nicht in gl.h findest spricht nicht grad dafür, das du OpenGL 4.0 oder höher verwendest.
    Ansonsten kannst du vielleicht auch nochmal den Fehler den du bekommst näher beschreiben, also nähere Fehlerbeschreibung, vielleicht gibt dir glGenBuffers kein gültigen Wert. Und mit glGetError mal nach Fehlern suchen.

    floorball



  • Ja ich hatte das glxinfo mesa_tools. Danke für den Tip.

    Den Context erzeuge ich mit glfw3 www.glfw.org).
    wenn ich mit glGetString(GL_VERSION) die Vesion auslese bekomme ich nur: INTEL-8.24.112.1 (auf dem Mac)
    Bei der erzeugung des Contexts habe ich nun die Version festgelegt:
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);

    Ja, auch die Funktion rufe ich auf, aber ich bekomme wieder die gleiche Meldung das die Funktion nicht gefunden wird.
    Ich habe in der gl3.h (Apple) die ensprechenden Funktionen gefunden.
    Auf der Linux gl.h leider nicht.
    Muss ich da die von der Khronos nehmen. Passt die? NVIDIA liefert da keine mit.

    Danke für die Hilfe.



  • Oh Mann ich bin ein Idiot, dass mir das auch erst jetzt auffällt... Hab aber auch schon länger kein OpenGL mehr gemacht.

    DinoTinu schrieb:

    void DrawNew(void) 
    { 
     [...] 
     glGenBuffers(1, &gVBO); 
     glBindBuffer(GL_ARRAY_BUFFER, gVBO); //glBindBuffer hat vor glBufferData zu stehen!!
     glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW); 
    
    // glBindBuffer(GL_ARRAY_BUFFER, gVBO); Das kommt vor glBufferData!!!!
     glEnableVertexAttribArray(0); 
    
    [...]
    }
    

    EDIT: Und setz die OpenGL Version auf 3.3 damit du die VAOs nicht brauchst

    floorball



  • floorball schrieb:

    Oh Mann ich bin ein Idiot, dass mir das auch erst jetzt auffällt... Hab aber auch schon länger kein OpenGL mehr gemacht.

    DinoTinu schrieb:

    void DrawNew(void) 
    { 
     [...] 
     glGenBuffers(1, &gVBO); 
     glBindBuffer(GL_ARRAY_BUFFER, gVBO); //glBindBuffer hat vor glBufferData zu stehen!!
     glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW); 
    
    // glBindBuffer(GL_ARRAY_BUFFER, gVBO); Das kommt vor glBufferData!!!!
     glEnableVertexAttribArray(0); 
    
    [...]
    }
    

    EDIT: Und setz die OpenGL Version auf 3.3 damit du die VAOs nicht brauchst

    floorball

    Super, der Compiler motzt mich nicht mehr an.
    Das heisst ich brauche ab 3.3 nur noch den glGenBuffers?

    Danke dir für deine super schnelle Hilfe.

    Nun kriege ich noch ein Bad Access bei der Funktion glDrawElements.
    glDrawElements(GL_TRIANGLES, sizeof(vertexData), GL_UNSIGNED_INT, 0);

    Hast du da eine Idee?

    Gruss Tinu



  • DinoTinu schrieb:

    Super, der Compiler motzt mich nicht mehr an.
    Das heisst ich brauche ab 3.3 nur noch den glGenBuffers?

    Richtig, bei OpenGL Versionen unter 4.0 sind Vertex Array Objects optional.

    DinoTinu schrieb:

    Nun kriege ich noch ein Bad Access bei der Funktion glDrawElements.
    glDrawElements(GL_TRIANGLES, sizeof(vertexData), GL_UNSIGNED_INT, 0);

    In deinem Code ist nur ein glDrawArrays, wo jetzt ein glDrawElements bei dir steht kann ich nicht sagen ==> Fehlerdiagnose unmöglich.

    floorball



  • Sorry. Hier der Codeausschnitt.

    GLfloat vertexData[] ={
    // X Y Z
    -0.6f, 0.4f, 0.f,
    0.6f, -0.4f, 0.f,
    0.f, 0.6f, 0.f
    };

    glGenBuffers(1, &gVBO);
    glBindBuffer(GL_ARRAY_BUFFER, gVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);

    glEnableVertexAttribArray(0);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

    //draw
    glDrawArrays(GL_TRIANGLES, 0, 3);

    if (gVBO !=0) {
    glEnableClientState(GL_VERTEX_ARRAY);
    glBindVertexArray(gVBO);
    glDrawElements(GL_TRIANGLES, sizeof(vertexData), GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);
    glDisableClientState(GL_VERTEX_ARRAY);
    }



  • 1. Benutz Code Tags!!

    if (gVBO !=0) { 
     glEnableClientState(GL_VERTEX_ARRAY); 
     glBindVertexArray(gVBO); 
     glDrawElements(GL_TRIANGLES, sizeof(vertexData), GL_UNSIGNED_INT, 0); 
     glBindVertexArray(0); 
     glDisableClientState(GL_VERTEX_ARRAY); 
     }
    

    Ok, so viel Ahnung hab ich von OpenGL auch nicht, aber stammt glEnableClientState nicht aus der Zeit als man auf dem Weg weg von veralteten hin zu modernem war?
    Außerdem, warum benutzt du glDrawElements und nicht glDrawArrays. glDrawElements ist für indexed Draws gedacht ==> Wenn du es benutzen willst, dann brauchst du einen index Buffer.

    floorball



  • Hmm Interessanter Punkt mit dem ClientState. Aber später... J

    Nun habe ich den DrawElements mit folgendem ersetz:

    glVertexPointer(3, GL_FLOAT, 0, vertexData);
    glDrawArrays(GL_TRIANGLES, 0, 3);

    Das habe ich aus einem anderen Forum. Aber das Bad access bekomme ich immernoch.
    Was ist hier krumm....

    Grüsse
    Tinu



  • Dann Streich doch mal das glEnableClientState und glDisableClientState, wenn ich es richtig verstehe sagt diese Methode OpenGL nämlich, dass ein Vertex Array Object vorhanden ist.

    floorball



  • Hab ich gemacht, aber der Bad Access besteht noch immer.

    Tinu



  • Also ein bissl was musst du selber machen! Ein ich hab ein Fehler ist nicht unbedingt genug. Was für eine Fehlermeldung kommt genau? Wo genau kommt die Fehlermeldung? Was sagt der Debugger?
    Außerdem, wo kommt dein Code her? Ich meine glBindVertexBuffer wird aufgerufen
    1. Wo es aufgerufen wird ist vollkommen unsinnig
    2. Ich hab gedacht du hast kein Vertex Array Object

    Auch das du die zwei Code Zeilen aus einem Forum kopieren musst, zeigt nicht gerade, dass du ein grundlegendes Verständnis von OpenGL hast. Dein Buch/Tutorial/anderweitiges Lernmittel ist einfach nur schlecht.
    Schau mal bei www.opengl-tutuorial.org und http://ogldev.atspace.co.uk/ vorbei, um dir ein wenig Verständniss anzueignen.

    floorball



  • Guten morgen

    Ich habe nun die Fehler raus, aber das Fenster bleibt leer.

    Hier der ganze Code, da ich nicht weiter komme:

    #include <GLFW/glfw3.h>
    #include <OpenGL/gl3.h>
    #include <iostream>
    
    void Draw();
    void DrawNew();
    void initScene();
    
    void render();
    float rotateX, rotateY, rotateZ = 0.f;
    float transX,transY = 0.f;
    
    GLuint gVBO = 0;
    
    static void key_handler(GLFWwindow *window, int key, int scancode,  int action,int code)
    {
        if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS ) {
            glfwSetWindowShouldClose(window, GL_TRUE);
        }
        if (key == GLFW_KEY_A && action ==GLFW_REPEAT) {
            rotateX++;
        }
        if (key == GLFW_KEY_S && action ==GLFW_REPEAT) {
            rotateX--;
        }
        if (key == GLFW_KEY_Q && action ==GLFW_REPEAT) {
            rotateY++;
        }
        if (key == GLFW_KEY_W && action ==GLFW_REPEAT) {
            rotateY--;
        }
        if (key == GLFW_KEY_Z && action ==GLFW_REPEAT) {
            rotateZ++;
        }
        if (key == GLFW_KEY_X && action ==GLFW_REPEAT) {
            rotateZ--;
        }
        if (key == GLFW_KEY_R && action ==GLFW_PRESS) {
            rotateX =0.f;
            rotateY = 0.f;
            rotateZ = 0.f;
            transX = 0.f;
            transY = 0.f;
        }
        if (key == GLFW_KEY_RIGHT && action == GLFW_REPEAT) {
            transX += 0.01;
        }
        if (key == GLFW_KEY_LEFT && action == GLFW_REPEAT) {
            transX -=0.01;
        }
        if (key == GLFW_KEY_UP && action == GLFW_REPEAT) {
            transY +=0.01;
        }
        if (key == GLFW_KEY_DOWN && action == GLFW_REPEAT) {
            transY -= 0.01;
        }
    
    }
    
    int main(void){
        GLFWwindow *glw;
    
        if (!glfwInit()){
            return -1;
        }
        glw =glfwCreateWindow(600, 400, "Opengl", NULL, NULL);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
        glfwWindowHint (GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    
        glfwMakeContextCurrent(glw);
    
        glfwSetKeyCallback(glw, key_handler);
        while (!glfwWindowShouldClose(glw)) {
    
            int ratio;
            int width, height;
    
            glfwGetFramebufferSize(glw, &width, &height);
            ratio = width/(float) height;
    
            glViewport(0, 0, width, height);
            glClear(GL_COLOR_BUFFER_BIT);
            glClearColor(0,0,0,1);
            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
            //glOrtho(-ratio, ratio, -1.f, 1.f, 1.f, -1.f);
            glMatrixMode(GL_MODELVIEW);
            //----------------------------
            initScene();
            render();
            glfwSwapBuffers(glw);
            glfwPollEvents();
    
        }
        glfwDestroyWindow(glw);
        glfwTerminate();
        return 0;
    }
    
    /*void Draw(void)
    {
        glLoadIdentity();
        glRotatef(rotateX, 1.f, 0.f, 0.f);
        glRotatef(rotateY, 0.f, 1.f, 0.f);
        glRotatef(rotateZ, 0.f, 0.f, 1.f);
        glTranslatef(transX, transY, 0.f);
        glBegin(GL_TRIANGLES);
        glColor3f(1.f, 0.f, 0.f);
        glVertex3f(-0.6f, -0.4f, 0.f);
        glColor3f(0.f, 1.f, 0.f);
        glVertex3f(0.6f, -0.4f, 0.f);
        glColor3f(0.f, 0.f, 1.f);
        glVertex3f(0.f, 0.6f, 0.f);
        glEnd();
    
    } 
    */
    
    void initScene()
    {
        GLint vertexData[] ={
            //   X    Y  Z
            -6, 4, 0,
            6, 4, 0,
            0, 6, 0
        };
    
        glGenBuffers(1, &gVBO);
        glBindBuffer(GL_ARRAY_BUFFER, gVBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
    
        glVertexAttribPointer(0, 3, GL_INT, GL_FALSE, 8, 0);
        glEnableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
    }
    
    void render()
    {
        if (gVBO !=0) {
            glBindBuffer(GL_ARRAY_BUFFER, gVBO);
            glDrawElements(GL_TRIANGLES, 8, GL_INT, NULL);
            glBindBuffer(GL_ARRAY_BUFFER, 0);
        }
    }
    

    Danke für eure Hilfe

    Tinu



  • Zum zweiten Mal! Benutze Code-Tags! Einfach deinen Kompletten Code mit der Maus Markieren und dann den C++ Button unter dem 😮 Smiley drücken. Anschließend noch unter den ganzen Sonderzeichen Buttons das Häkchen bei "BBCode in diesem Beitrag deaktivieren rausnehmen.
    Keiner wird sich deinen Code so ansehen, weil sch**** zu lesen ist.

    floorball



  • Tut mir leid das der Code so nicht lesbar ist. Werde es in Zukunft so machen,
    Danke für die Mahnung.

    Gruss Tinu



  • Sagen wir es mal so: Nimm die beiden Tutorials auf die ich oben verlinkt habe und arbeite die durch! Mit Try & Error kommst du nicht weiter! Dein Code hat vor allem Logische Fehler (aber auch eine ganze Menge andere), die zu erklären würde Jahre brauchen. Das zeigt auch das du mit deiner bisherigen Lernmethode (Try & Error) alles andere als Erfolgreich bist. Du hast einfach kein Grundverständnis von OpenGL, das ist hier das eigentliche Problem, nicht das kein Dreieck auf deinem Fenster erscheint.
    Auch musst du mal selber ein bisschen Anfangen zu denken ( in dem Sinne das du 1. mal damit anfangen sollst und 2. es ein bisschen ausgeprägter machen musst), ich weis das hört sich jetzt hart an, aber anders weis ich hier auch nicht mehr weiter. Ich meine schauen wir uns mal deinen Code an.

    floorball schrieb:

    glDrawElements ist für indexed Draws gedacht ==> Wenn du es benutzen willst, dann brauchst du einen index Buffer.

    Das hab ich oben noch geschrieben und was steht jetzt in deinem Code schon wieder.

    DinoTinu schrieb:

    //In der Funktion Render()
     glDrawElements(GL_TRIANGLES, 8, GL_INT, NULL);
    

    Das ist es was ich mit "zu denken Anfangen" meine! Du musst dir auch mal überlegen welchen Eindruck das macht, nämlich den, du hast kein Bock dich mit Fehlern zu beschäftigen (was man auch an deiner Fehlerbeschreibung ein wenig merkt) und denkst das Forum könnte hier den besch*** Job für dich machen. So läuft das aber nicht! Ich fühl mich einfach grad ein wenig verarscht von dir.
    Aber weiter im Code:

    DinoTinu schrieb:

    while (!glfwWindowShouldClose(glw)) {
            
            [...]        
            glViewport(0, 0, width, height);
            glClear(GL_COLOR_BUFFER_BIT);
            glClearColor(0,0,0,1);
            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
            //glOrtho(-ratio, ratio, -1.f, 1.f, 1.f, -1.f);
            glMatrixMode(GL_MODELVIEW);
            //----------------------------
            initScene();
           
    [...]
            
        }
    

    InitScene(), da sagt einem doch schon der Name (den du der Funktion verpasst hast, also irgendwas musst du dir dabei doch gedacht haben, oder??) das die nur einmal aufgerufen wird! Außerdem erstellst du dadurch in jedem Frame einen Vertex Buffer der aber niergends gelöscht wird.
    Wieder so ein Fall von "denken Anfangen"
    Außerdem hat das komplette Matrix zeug ebenfalls nichts in der while Schleife zu suchen (mit Ausnahme von glLoadIdentity). In Projection bzw. Modelview Matrix liegt vermutlich auch der "Fehler".

    ABER: bevor du jetzt anfängst und meine Tipps hier umsetzt, kann ich dir gleich sagen das wird wieder nicht funktionieren! Um die richtige Matrix zu finden brauchst du mal wieder Grundverständnisse von OpenGL (das du nicht hast). Und auch sonst hat dein Code noch dermaßen viele Fehler da kommt man nicht nach.
    Es wär wahrscheinlich am besten du fokussierst dich erstmal auf C++ (denn das du das besonders gut kannst bezweifle ich hier einfach mal (schaut auch nicht so aus)) und dann nimm dir die beiden Tutorials auf die ich oben verlinkt habe zur Hand um OpenGL zu lernen.
    So geht das hier nicht weiter und ich wird dir bei diesem Problem auch nicht weiterhelfen, denn es hat einfach keinen Zweck, das hier führt zu nichts.

    floorball



  • Danke für deine netten Worte

    Ich postete mein Problem aus der Hoffnung eine kleine Hilfestellung zu bekommen, stattdessen krige ich nette Worte was ich alles nicht kann und nicht denke. Ich hoffe es gibt im Internet andere Menschen welche lieber helfen als du. Was ich an C und OpenGL nicht kann, kannst du nicht mit anderen Menschen.
    das Programm mit der Methode Draw OpenGL 1 oder so lief super, da ist es doch naheliegend (Für einen Anfänger) dass das auch weiter so geht. Aber das ist hier nicht mehr wichtig und du brauchst auch keinen Kommentar mehr an mich zu schreiben, denn ich komme hier nicht wieder hin.

    Gruss Tinu



  • Hätte ich schreiben sollen das alles richtig ist und du der OpenGL-Master schlechthin bist und dein Code super-dupa richtigist? Überleg dir mal mit welcher Antwort dir mehr geholfen ist!

    DinoTinu schrieb:

    Ich postete mein Problem aus der Hoffnung eine kleine Hilfestellung zu bekommen, stattdessen krige ich nette Worte was ich alles nicht kann und nicht denke.

    Ich hab dir bereits mehr als nur eine Hilfestellung gegeben, aber um deinen Code richtig zu bekommen, und alle deine Probleme zu klären müsste man ein komplettes Buch über OpenGL schreiben. Außerdem: Wo ist denn das Problem wenn ich schreibe, dass du etwas nicht kannst? Ich hab das an mehr als nur einem Beispiel belegt und ich hätte noch 100 weitere. Ich hab dich auch mehr als nur ienmal auf Tutorials verwiesen, viel mehr kann ich da auch nicht machen. Und das du dich mit deinem eigenen Problem nicht beschäftigt hast und dir keine Sekunde lang einen Gedanken darüber gemacht hast kann ich dir auch an 100 weiteren Beispielen zeigen.

    DinoTinu schrieb:

    das Programm mit der Methode Draw OpenGL 1 oder so lief super, da ist es doch naheliegend (Für einen Anfänger) dass das auch weiter so geht.

    Ein Anfänger würde sich dann die beiden Methoden anschauen und unterschiede feststellen, die dermaßen offensichtlich sind (Tipp: Weist du was der unterschied zwischen float und int ist?), das fällt einem auf, anders geht das gar nicht!
    Deine Antwort ist einfach nur eins: Nämlich eine große Unverschämtheit! Wenn du mit der Wahrheit nicht leben kannst, wirst du auch in anderen Foren keine Hilfe bekommen.

    floorball


Anmelden zum Antworten