无法在OpenGL中绘制多个对象 [英] Cant draw multiple objects in opengl

查看:65
本文介绍了无法在OpenGL中绘制多个对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法弄清楚以下代码为什么不起作用,我试图绘制2种形状,即红色的三角形和多色的立方体,它们本身可以完美地绘制,但是如果我尝试绘制两种形状一次它产生了怪异的错误,我曾尝试在更改变量的阴影周围更改线条,从而修改了我的着色器,但似乎无法在想要的结果附近找到任何东西,当前代码最终绘制了两个使用立方体颜色的相同三角形.

I cant work out why the following code doesn't work, I am attempting to draw 2 shapes, a triangle that is coloured red and a cube that is multi coloured, by themselves they draw perfectly but if I try to draw both at once it gives weird bugs, I have tried changing lines around changing variable's modifying my shaders and I cant seem to get anywhere near the result I want, the current code ends up drawing 2 identical triangles that use the cubes colours.

GLuint VertexArrayID;

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

GLuint MatrixID = glGetUniformLocation(shader->id(), "MVP");

glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
glm::mat4 View       = glm::lookAt(
glm::vec3(4,2,2), // Camera location
glm::vec3(0,0,0), // and looks at the origin
glm::vec3(0,1,0)  // Head is up (set to 0,-1,0 to look upside-down)
);

glm::mat4 myMatrix = glm::translate(-2.f,0.f,0.f);
glm::mat4 Model = glm::mat4(1.f);
Model= myMatrix * Model;
glm::mat4 MVP = Projection * View * Model;

glm::mat4 myMatrix2 = glm::translate(2.f,0.f,0.f);
glm::mat4 Model2 = glm::mat4(1.f);
Model2= myMatrix2 * Model2;
glm::mat4 MVP2 = Projection * View * Model2;

glViewport(0, 0, windowWidth, windowHeight); // set viewport to the size of the window
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT  | GL_STENCIL_BUFFER_BIT);

shader->bind();
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);

glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0);

glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, colourBuffer);
glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,0,(void*)0);

glDrawArrays(GL_TRIANGLES,0,12*3);

glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);

glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP2[0][0]);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer2);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0);

glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, colourBuffer2);
glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,0,(void*)0);

glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);

SwapBuffers(hdc);

glDeleteBuffers(1, &vertexBuffer);
glDeleteBuffers(1, &vertexBuffer2);
glDeleteBuffers(1, &colourBuffer);
glDeleteBuffers(1, &colourBuffer2);
shader->unbind();
glDeleteVertexArrays(1, &VertexArrayID);

这是主要代码.我基本上通过使用以下3行的变体来插入所有不同的缓冲区名称和数据,以类似的方式创建所有缓冲区,

that's the main code. I create all the buffers in a similar way by basically using variations of the following 3 lines to insert the different buffer names and data,

glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER,sizeof(Cube), Cube, GL_STATIC_DRAW);

片段着色器

#version 330 core
in vec3 fragmentColour;
out vec3 colour;
void main(){
colour = fragmentColour;
}

顶点着色器

  #version 330 core

  uniform mat4 MVP;

  layout(location = 0) in vec3 vertexPosition_modelspace;
  layout(location = 1) in vec3 vertexColour;
  out vec3 fragmentColour;

   void main(){

    gl_Position =  MVP * vec4(vertexPosition_modelspace,1);
    fragmentColour = vertexColour;
   }

推荐答案

我看到您正在尝试使用VAO,但是您只能创建一个.还为什么要准备:

I see you are trying to use VAOs but you create only one.Also why do you prepare:

glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void *)0);

glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0);

glEnableVertexAttribArray(1); glBindBuffer(GL_ARRAY_BUFFER, colourBuffer); glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,0,(void *)0);

glEnableVertexAttribArray(1); glBindBuffer(GL_ARRAY_BUFFER, colourBuffer); glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,0,(void*)0);

并删除:

glDeleteBuffers(1,& vertexBuffer); glDeleteBuffers(1,& vertexBuffer2); glDeleteBuffers(1,& colourBuffer); glDeleteBuffers(1,& colourBuffer2);

glDeleteBuffers(1, &vertexBuffer); glDeleteBuffers(1, &vertexBuffer2); glDeleteBuffers(1, &colourBuffer); glDeleteBuffers(1, &colourBuffer2);

在每次渲染调用中

您的VAO?VAO的全部目的是一次初始化所有所需的缓冲区和属性,然后仅绑定VAO本身进行实际渲染.在初始化设置上进行操作,仅在不执行此操作时删除不再需要这些对象.此处是一个很好的示例,说明了如何正确完成操作.

your VAOs on each render call?The whole purpose of VAOs is to init all the needed buffers and attributes once and then bind only the VAO itself for the actual rendering.Do it on the initialization setup and delete only when you don't need those objects anymore.Here is a good example how it is done properly .

您应该做的是: 只能通过某种init方法初始化您的VAO.然后在render循环中:

What you should do is this: Initiate your VAOs in some init method only once.Then in render loop :

   glBindVertexArray(m_VAO1);

   ///draw geometry here

    glBindVertexArray(0);

对要渲染的每个几何图形执行此操作.

Do this for each geometry you want to render.

在对您的代码进行了更深入的审查之后,我发现您可以这样做:

After deeper review of your code I see you do this :

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

因此您确实要绑定VAO.但是您只能创建和绑定一个!您需要为每个可渲染对象创建一个,将其连接到所有必需的缓冲区,然后按照我上面的说明在渲染循环中使用它们.

So you do bind VAO.But you create and bind only one!You need to create one per renderable object,Attach to it all required buffers and then use them in the render loop as I explained above.

这篇关于无法在OpenGL中绘制多个对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆