OpenGL: Wofür glGenBuffers



  • Hallo!

    Ich mache gerade meine Anfänge mit OpenGL.
    Nun habe ich das soweit am Laufen, dass ich einfache Geometrien zeichnen kann.

    In einem Tutorial sehe ich nun, dass dort immer folgendes verwendet wird, um Puffer zu erstellen:

    Tutorial Code:

    glGenBuffers(1, &buffer);
        glBindBuffer(target, buffer);
        glBufferData(target, buffer_size, buffer_data, GL_STATIC_DRAW);
    

    Wofür braucht man das?

    Ich habe es bis jetzt anders gemacht: Im Vertex Shader hab ich verschiedene Attribute. In meinem C++ Programm hole ich mir mit glGetAttribLocation die IDs, und mit glVertexAttribPointer weise ich dem Attribut dann die Werte zu. Schließlich rufe ich glDrawElements auf, und die Dinge werden gezeichnet.
    Funktioniert soweit.

    Also meine Frage: Warum wird in dem Tutorial immer glGenBuffers verwendet, und warum gehts bei mir auch ohne?

    Mein Code:
    Vertex Shader:

    attribute vec4 a_vPosition;
    attribute vec4 a_vColor;
    uniform float a_phi;
    uniform float a_scale;
    varying vec4 v_vColor;
    
    void main()
    {
    	mat4 scaleMat=mat4(a_scale,0,0,0,  0,a_scale,0,0,  0,0,a_scale,0, 0,0,0,1);
    	mat4 rotateMat=mat4(1,0,0,0,  0,cos(a_phi),-sin(a_phi),0,  0,sin(a_phi),cos(a_phi),0,  0,0,0,1);
    	mat4 rotateMatY=mat4(.7,0,.7,0,  0,1,0,0,  -.7,0,.7,0,  0,0,0,1);
    	gl_Position+=vec4(0.0,0.2,0.0,0.0);
    
    	gl_Position = vec4(a_vPosition.xyz, 1.0)*rotateMat;
    	gl_Position = gl_Position*rotateMatY;
    	gl_Position = gl_Position*scaleMat;
    	v_vColor = a_vColor;
    }
    

    C++ Programm:

    POSITION_PARAMETER_INDEX=glGetAttribLocation(engine->programObject, "a_vPosition");
    	COLOR_PARAMETER_INDEX=glGetAttribLocation(engine->programObject, "a_vColor");
    	ANGLE_PARAMETER_INDEX=glGetUniformLocation(engine->programObject, "a_phi");
    	int32_t scaleAttrNr=glGetUniformLocation(engine->programObject,"a_scale");
        glUniform1f(ANGLE_PARAMETER_INDEX, (engine->touchX-0.5)*6.29);
        glUniform1f(scaleAttrNr,engine->touchY);
    
    	// aus dem Vertex Shader Programm: Attribute a_vPosition und a_vColor
    	glEnableVertexAttribArray(POSITION_PARAMETER_INDEX);
    	glEnableVertexAttribArray(COLOR_PARAMETER_INDEX);
    
    	// -- 1. Objekt --
    	GLfloat x=0.5*engine->height/engine->width,y=0.5,z=0.5;
    	GLfloat redColor[]={1,0,0,0};
    	GLfloat greenColor[]={0,1,0,0};
    	GLfloat blueColor[]={0,0,1,0};
    	GLfloat yellowColor[]={1,1,0,0};
    
    	GLfloat myVertexArr[]=
    	{
    			-x,y,0,
    			greenColor[0],greenColor[1],greenColor[2],greenColor[3],
    
    			-x,-y,0,
    			blueColor[0],blueColor[1],blueColor[2],blueColor[3],
    
    			x,-y,0,
    			yellowColor[0],yellowColor[1],yellowColor[2],yellowColor[3],
    
    			0,0,z,
    			redColor[0],redColor[1],redColor[2],redColor[3]
    	};
    
    	// Koordinaten (x,y,z) sind die ersten 3 floats, und beginnen an Stelle idx=n*7
    	glVertexAttribPointer(POSITION_PARAMETER_INDEX, 3, GL_FLOAT, GL_FALSE, sizeof(float)*7, &myVertexArr[0]);
    	// Farben (RGBA) sind ab der 4. Stelle zu finden, idx=n*7+3
    	glVertexAttribPointer(COLOR_PARAMETER_INDEX, 4, GL_FLOAT, GL_FALSE, sizeof(float)*7, &myVertexArr[3]);
    	// Zeichnen
    	GLshort elementIndizes[]={0,1,2, 0,2,3, 1,3,2, 0,3,1};
    	glDrawElements(GL_TRIANGLES,12,GL_UNSIGNED_SHORT,elementIndizes);
    


  • Du benutzt einmal das neuere Vertexbuffeoject (VBO) und das andere mal ein Vertexarray (VA).

    Der Unterschied ist wann Daten kopiert werden, und wo sie gespeichert werden.

    Beim VA werden jedes mal Daten kopiert wenn du einen Draw call machst. Also z.B. glDrawElements. Der Treiber speichert sich die Daten um sie "später" zu benutzen.
    Beim VBO werden nur Daten kopiert wenn du z.B. glBufferData/glBufferSubData aufrufst.
    Der letzte Parameter von glBufferData hat auch Einfluss wo die Daten des VBO gespeichert werden. Meist wird GL_STATIC_DRAW verwenden und die Daten landen im VRAM der Grafikkarte.

    Da sich VBO und VA Funktionen teilen kann der Code sehr ähnlich ausschauen.
    Beim VA zeigt glVertexAttribPointer mit einem normalen Pointer auf den Hauptspeicher.
    Wenn du jedoch ein VBO mit glBindBuffer aktivierst, zeigt glVertexAttribPointer auf die Position in dem VBO Speicher.

    Ich empfehle dir nur VBOs zu verwenden, außer du zielst auf eine ältere OpenGL Version in der VBOs noch keine Core Funktionalität sind.



  • danke für die ausführliche Erklärung!


Log in to reply