如何获取当前绑定的顶点数组对象的名称?
我查看了手册,但找不到与glGet()一起使用的枚举.
在我的代码中,我有一个由两个缓冲区对象和一个顶点数组对象支持的对象的包装类。我在构造函数中使用它生成它们(稍微简化):
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, &ibo);
glGenBuffers(1, &vbo);
printf("Ind buffers %d %d %d\n", vao, ibo, vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
Run Code Online (Sandbox Code Playgroud)
printf 在主线程上的前几个创建中给出了这个。
Ind buffers 1 1 2
Ind buffers 3 4 5
Ind buffers 4 6 7
Ind buffers 5 8 9
Ind buffers 6 10 11
Ind buffers 7 12 13
Run Code Online (Sandbox Code Playgroud)
中间有一个非索引的,它需要 VAO #2 和缓冲区 #3。这对我来说看起来不错。每个数组对象都附有两个唯一的缓冲区。
我稍后也使用此代码加载后台资源(而不是生成它们)。每个线程都有自己的上下文,使用 glfwCreateContext 创建并与主窗口共享资源。首次创建这些资源时,会出现以下输出:
Ind buffers 1 14 15
Ind buffers 1 16 17
Ind buffers 1 18 19
Ind buffers 1 20 24 …Run Code Online (Sandbox Code Playgroud) 我目前这样做来设置我的vao:
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
...
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBindVertexArray(0);
Run Code Online (Sandbox Code Playgroud)
我的问题是:我是否需要绑定空缓冲区以防止我的vbo和ibo在我完成vao之后更改或者绑定null vao时它还解除当前缓冲区的绑定?例如,我会做以下事情:
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
Run Code Online (Sandbox Code Playgroud) 我正在编写一个渲染器,现在正在选择处理 vao/vbo/着色器管理的最终方法。在网上,我发现关于实际推荐内容的信息非常矛盾。目前想法如下:
-一个VBO连续存储所有网格。
-每个“着色器映射”创建一个 VAO 以将特定指针映射存储到 VBO 中。(“着色器映射”,在具有相同输入的不同着色器中保持一致)
然后通过“着色器映射”对实体进行排序,并使用主 VBO 中的偏移量进行渲染,从而最大限度地减少着色器和 VAO 开关。就像是:
for(shaders by mapping)
bindVAO(); //set pointers
for(shader)
for(entity using shader)
entity.setUniforms();
drawArrays(entity.offset, entity.size);
Run Code Online (Sandbox Code Playgroud)
由于这将包括大量的重构,我想问这个解决方案是否是最佳的。我还想知道是否可以在单个 VBO 中拥有多种交错格式。
据我所知:VAO代表某种状态.如果我绑定一个VAO,添加一些VBO和元素缓冲区用于指示和东西我可以保存我想要绘制和激活的对象的某个状态,并在我想要渲染内容时稍后在路上绘制它们.对?
因此,VBO保存实际数据,而VAO只是一个"包装器对象",它保存指向我为其定义的所有缓冲区的指针?
改变VAO是昂贵的(正如改变VBO一样?!).目前我加载Meshes并将它们组合到模型中.每个模型使用它自己的VAO并且具有VBO(带有顶点)和带有索引的元素缓冲区.
现在我理解这一点,这是废话,因为我的世界中的每个对象(有一个模型)都使用它自己的VAO.对于我这个世界中的~30个对象来说不是问题,但是我想要做到这一点,并且将来可能会有数百或数千个对象,然后性能会大幅下降.
因此,就其模型而言,许多对象是"相同的".我的意思是,例如,如果你在世界上有某种树型,你可能会多次使用相同的模型,只是在不同的位置.
现在我该怎么做呢?我应该手动跟踪我的VAO,如:(伪代码跟随!)
treesVAOId = 1;
rabbitsVAOId = 2;
Run Code Online (Sandbox Code Playgroud)
然后,如果我加载一个模型,只需检查ID是否已被绑定(如何?)并在那里添加另一组VBO(甚至添加到正确的VBO?如果是这样,怎么样?)
我在想这里的大型比赛.让我们假设游戏中有数千个角色.当然不是所有这些都是同时渲染的,但我无法为它们中的每一个创建VAO和VBO,是吗?
我觉得有更多的部分缺失...就像实例化和再次使用(或多或少)相同的数据为不同的目的有效.
这是我缺少的一步,如何在现实世界中真正优化VAO和VBO的使用.
我需要创建一个这样的网格:
----------------
| | | | | |
----------------
| | | | | |
----------------
| | | | | |
----------------
Run Code Online (Sandbox Code Playgroud)
并仅用线条渲染它。这就是我创建顶点和索引的方式:
std::vector<glm::vec3> vertices;
std::vector<glm::uvec3> indices;
for(int j=0; j<=slices; ++j) {
for(int i=0; i<=slices; ++i) {
float x = (float)i/(float)slices;
float y = 0;
float z = (float)j/(float)slices;
vertices.push_back(glm::vec3(x, y, z));
}
}
for(int j=0; j<slices; ++j) {
for(int i=0; i<slices; ++i) {
int row1 = j * (slices+1);
int row2 = (j+1) * (slices+1);
indices.push_back(glm::uvec3(row1+i, row1+i+1, row2+i+1)); …Run Code Online (Sandbox Code Playgroud) 创建时,VAO 是否仅跟踪 VBO 索引(通过glBindVertexBuffer),或者还跟踪哪些 VBO 名称绑定到这些索引?如果我使用glVertexAttribBinding指定绑定索引,例如 0,我可以在绘制调用之前将不同的 VBO 绑定到索引 0 并让它使用该 VBO 的内容,还是始终使用任何 VBO创建 VAO 时是否绑定到索引 0?
我问这个问题是因为我发现很多例子都在调用glVertexAttribFormat和glVertexAttribBinding之前调用glBindVertexBuffer,如果 VAO 仅跟踪索引(因为绑定索引在 中给出),则不需要调用glVertexAttribBinding。
我正在尝试使用多个 VAO 和 VBO 在 OpenGL 中渲染多个对象。为了使用相同的顶点渲染多个对象,我已经完成了,但我想要做的是为每个对象使用不同的顶点,例如绘制一个正方形和一个圆形。对于正方形,我只需要 6 个顶点,但对于圆形,我需要 360 个顶点。我在读取或创建着色器时出错。
这是顶点着色器:
#version 330 core
layout (location = 0) in vec4 position;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * position;
}
Run Code Online (Sandbox Code Playgroud)
片段着色器:
#version 330 core
layout(location = 0) out vec4 color;
uniform vec4 u_Color;
void main()
{
color = u_Color;
}
Run Code Online (Sandbox Code Playgroud)
VAO 和 VBO 生成和绑定
// Circle
std::vector<VertexFormat> vertices;
for (int i = 0; i < 360; …Run Code Online (Sandbox Code Playgroud) 我现在的情况是想使用VAO/VBO来回收相同的顶点并使用索引来加速渲染。
一切都很好,除了我的纹理模型使用 UV 坐标,并且对于相同的顶点(大约 >80%),我最终可能会根据我期望渲染的三角形获得不同的 UV 坐标(事实上,我正在使用md2 模型和纹理)。
对于老式的即时模式来说,这种渲染方式非常不错。现在,解决这个问题并通过 VAO/VBO 渲染的最佳方法是什么?
我想到的是分解三角形并创建具有重复顶点的非常大的 VBO,以便我可以将正确的 UV 坐标链接到每个“相同”。
我不得不说我不喜欢这个...有什么想法吗?
诗。对于不了解格式的人:如果您想使用纹理映射,我相信您必须使用基于要渲染的三角形的自定义 UV 坐标。否则纹理颜色都乱了!
下面的代码在linux上编译运行没有错误但是给出了错误
“验证程序时出错:'验证失败:未绑定顶点数组对象。”
在 Mac OS 10.14.2 (Mojave) 上。请注意,程序编译成功,但在运行时出现问题。
MacBook Pro(视网膜显示屏,15 英寸,2015 年中)
我正在编译使用g++ -std=c++11 test.cpp -w -framework OpenGL -lglfw -lGLEW -o p
测试.cpp
#include <bits/stdc++.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
using namespace std;
#define cout(a) cout<<a<<endl
// IDs
GLuint VAO, VBO, VAO2, VBO2, shaderID, uniformModel;
float scale = 1.0, x = 0.0, y = 0.0;
const int numPoints = 50000;
const char* vShader = "shader.vert";
const char* fShader = "shader.frag";
void createSierpinskiGasket() …Run Code Online (Sandbox Code Playgroud)