Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Vbo如何绘制图元_C++_Opengl - Fatal编程技术网

C++ Vbo如何绘制图元

C++ Vbo如何绘制图元,c++,opengl,C++,Opengl,嗨,我正在尝试使用本教程学习OpenGl 我想说的是,本教程不适合刚开始学习的人。他们展示了许多适用于1个三角形的代码,但没有更多的示例。我正在写一个函数来画。直线或矩形,我有问题,因为这是很难为我的困难。 我想写一个可重用的函数。但我不懂VBO:/我想写函数绘图,它将从主循环执行 class lines{ public: lines(){ } static void draw(GLuint ve){ float vertices[] = {-0.5f,

嗨,我正在尝试使用本教程学习OpenGl 我想说的是,本教程不适合刚开始学习的人。他们展示了许多适用于1个三角形的代码,但没有更多的示例。我正在写一个函数来画。直线或矩形,我有问题,因为这是很难为我的困难。 我想写一个可重用的函数。但我不懂VBO:/我想写函数绘图,它将从主循环执行

class lines{
    public: lines(){
    }
    static void draw(GLuint ve){

        float vertices[] = {-0.5f, -0.5f, 0.5f, 0.5f};
        unsigned int indices[] = {0, 1};

        glEnableClientState(GL_VERTEX_ARRAY);
        glVertexPointer(2, GL_FLOAT, 0, vertices);
        glDrawElements(GL_LINES, 2, GL_UNSIGNED_INT, indices);
    }
};


    // Ensure we can capture the escape key being pressed below
glfwEnable( GLFW_STICKY_KEYS );

// Dark blue background
glClearColor(0.0f, 0.0f, 0.4f, 0.0f);

GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);

// Create and compile our GLSL program from the shaders
GLuint programID = LoadShaders( "SimpleVertexShader.vertexshader", "SimpleFragmentShader.fragmentshader" );


static const GLfloat g_vertex_buffer_data[] = { 
    -0.8f, -1.0f,0.0f,
    0.8f,  -1.0f, 0.0f,
    -0.8f,   1.0f, 0.0f,
    -0.8f, 1.0f, 0.0f,
    0.8f, 1.0f, 0.0f,
    0.8, -1.0f, 0.0f,
};

GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);

do{

    // Clear the screen
    glClear( GL_COLOR_BUFFER_BIT );

    // Use our shader
    glUseProgram(programID);

    // 1rst attribute buffer : vertices
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    glVertexAttribPointer(
        0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
        3,                  // size
        GL_FLOAT,           // type
        GL_FALSE,           // normalized?
        0,                  // stride
        (void*)0            // array buffer offset
    );

    glDrawArrays(GL_TRIANGLES, 0, 6); 

    glDisableVertexAttribArray(0);
    lines::draw(vertexbuffer);
    // Swap buffers
    glfwSwapBuffers();

} // Check if the ESC key was pressed or the window was closed
while( glfwGetKey( GLFW_KEY_ESC ) != GLFW_PRESS &&
       glfwGetWindowParam( GLFW_OPENED ) );

要绘制基本体,请向OpenGL提供顶点列表以及连接它们的模式(例如形成直线、三角形等)。最简单的方法是立即模式(
glBegin
/
glVertex3f
/
glEnd
)。即时模式非常慢,通过“顶点数组”(不是顶点数组对象(VAO),它们是不同的)一次传递所有顶点的速度要快得多,它们在一维数组中按顺序排列,就像您的
g_vertex_buffer_data
一样。顶点数组是指将指向主内存中数组的指针传递到
glvertexinter
。这会更快,但每次绘制时都会将整个阵列发送到GPU。顶点缓冲区对象(VBO)允许您在GPU内存中发送和存储阵列。使用VBO,只需发送一个draw调用,并且数据已经在GPU上,因此无需传输,速度更快。VAOs将
glVertexPointer
参数分组以加快绑定速度,并且
glDraw*Indirect
允许使用GPU内存中已有的参数进行绘图,但我将这些留到以后

大多数教程从硬编码顶点开始,但对于最终应用程序来说,这当然不实用。您希望存储任意几何体的许多位。与
行类似的网格类非常常见。关键点是网格有一个顶点列表。可以添加索引数组以重新引用现有顶点以形成基本体,从而节省重复顶点的内存和计算

但我现在要从即时模式渲染开始,这样可以减少出错的情况

首先

struct vec3f {
    float x, y, z;
    vec3f(float nx, float ny, float nz) : x(nx), y(ny), z(nz) {}
};

class Mesh {
    std::vector<vec3f> vertices;
public:
    void add(float x, float y, float z)
    {
        vertices.push_back(vec3f(x, y, z));
    }
    void draw()
    {
        glBegin(GL_LINE_STRIP);
        for (size_t i = 0; i < vertices.size(); ++i)
            glVertex3f(vertices[i].x, vertices[i].y, vertices[i].z);
        glEnd();
    }
};
这个想法允许你有一个全局的
std::列表行例如。您可以在初始化时、从文件中或在运行时向其添加一次行。然后,绘图代码只需对每个元素调用draw。稍后,您可以扩展此想法,以支持三角形(例如,使
GL\u LINE\u STRIP
a
primitive
member)。稍后,您可以添加索引、法线(这里您需要使用
gl*Pointer
函数的
stride
参数查找交错顶点/法线数据)、颜色/材质等

关于使用VBOs的问题
glGenBuffers
将为您提供一个引用VBO的唯一句柄-简单地说是一个整数。当您修改或使用VBO时,您需要绑定它

glBufferData(GL\u ARRAY\u BUFFER…
对当前绑定的
GL\u ARRAY\u BUFFER
(如果尚未)进行实际初始化/调整大小,并在数据参数非空时传输数据

glVertexAttribPointer
将假定您在主存中为上面提到的“顶点数组”传递一个数组,除非您
glBindBuffer(GL\u array\u BUFFER,vbo)
,在这种情况下,最后一个参数成为该vbo的偏移量。调用
glVertexAttribPointer

所以

这就搞定了。继续画画

3. glVertexAttribPointer (while the buffer is bound)
然后

因此,要扩展mesh类,您至少需要一个
GLuint vertexBuffer;
。可以添加一个函数
upload()
,以生成句柄并缓冲当前数据。然后可以调用
Vertex.clear()
(实际上,用于std::vector使用)假设您不再需要主存中的顶点数据。然后更改draw函数以绑定vbo,调用
glVertexPoint
,取消绑定并
glDrawArrays
(从
numVertices
成员中,将
vertex.size()
设为零)

以下是一些相关帖子:

  • 从你的教程中

要绘制基本体,您需要给OpenGL一个顶点列表以及连接它们的模式(例如形成直线、三角形等)。最简单的方法是立即模式(
glBegin
/
glVertex3f
/
)。立即模式非常慢,通过“顶点数组”一次传递所有顶点要快得多(不是顶点数组对象(VAO),它们是不同的),它们在一维数组中按顺序排列,就像您的
g_vertex\u buffer\u data
一样。当您将指向主内存中数组的指针传递到
glvertexpointinter
时,顶点数组就出现了。这样速度更快,但每次绘制时都会将整个数组发送到GPU。顶点缓冲区对象(VBO)允许您发送数组并将其存储在GPU内存中。使用VBO,只需发送一个绘图调用,并且数据已经在GPU上,因此无需传输,而且速度更快。VAOs将
glvertexinter
参数分组以加快绑定速度,并
glDraw*Indirect
允许使用GPU内存中已有的参数进行绘图,但我会把这些留到以后

大多数教程从硬编码顶点开始,但对于最终应用程序来说,这当然不实用。您需要存储许多任意几何体。类似于
线的网格类非常常见。关键点是网格有一个顶点列表。您可以添加一组索引来重新引用现有顶点形成基本体,节省重复顶点的内存和计算

但我现在要从即时模式渲染开始,这样可以减少出错的情况

首先

struct vec3f {
    float x, y, z;
    vec3f(float nx, float ny, float nz) : x(nx), y(ny), z(nz) {}
};

class Mesh {
    std::vector<vec3f> vertices;
public:
    void add(float x, float y, float z)
    {
        vertices.push_back(vec3f(x, y, z));
    }
    void draw()
    {
        glBegin(GL_LINE_STRIP);
        for (size_t i = 0; i < vertices.size(); ++i)
            glVertex3f(vertices[i].x, vertices[i].y, vertices[i].z);
        glEnd();
    }
};
例如,这个想法允许您拥有一个全局的
std::list lines;
。您可以在初始化时、从文件中或在运行时向其中添加一次行。然后,您的绘图代码只需调用e
3. glVertexAttribPointer (while the buffer is bound)
4. glDrawArrays
4. glDrawElements (while an element array buffer is bound, containing the order in which to draw the vertices)