- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要用新顶点更新我的网格。我这样创建了 VBO(最初创建时只有一个顶点):
public Mesh(float[] vertex, int size)
{
texture = null;
meshType = 1; //will draw lines
FloatBuffer verticesBuffer = null;
IntBuffer indicesBuffer = null;
int vboID;
try
{
vertexCount = size;
vaoID = glGenVertexArrays();
glBindVertexArray(vaoID);
vboIDList = new ArrayList<>();
// Vertices VBO generation
vboID = glGenBuffers();
vboIDList.add(vboID);
verticesBuffer = MemoryUtil.memAllocFloat(size * 3); // !!! Must Be manually freed!
verticesBuffer.put(vertex).flip();
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferData(GL_ARRAY_BUFFER, verticesBuffer, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
vertexAttrArrCount += 1;
// Indices VBO generation
vboID = glGenBuffers();
vboIDList.add(vboID);
indicesBuffer = MemoryUtil.memAllocInt(size); // !!! Must be manually freed!
indicesBuffer.put(new int[]{0}).flip();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL_STATIC_DRAW);
// unbinding
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
finally
{
if (verticesBuffer != null)
{
MemoryUtil.memFree(verticesBuffer); // Freeing vertex buffer
}
if (indicesBuffer != null)
{
MemoryUtil.memFree(indicesBuffer); // Freeing indices buffer
}
}
}
然后我想更新 VBO 缓冲区并向其中写入新顶点。请注意,我确实创建了 VBO,以便为我的新顶点提供足够的空间,并且我确实控制它不会被填满。我还控制每次渲染调用绘制的元素数量,因此我不会绘制空的 0/0/0 顶点。
我的问题是,这段代码可以工作:
public void updateVBO(float[] vertices, int[] indices, int size)
{
if (meshType == 1)
{
lineCount = size;
FloatBuffer subDataF = null;
IntBuffer subDataI = null;
int vboID;
try
{
//System.out.printf("Adding vertex (%f, %f, %f) to position %d\n",vertex.x,vertex.y,vertex.z,position);
vboID = vboIDList.get(0);
//float[] vert = new float[]{vertex.x, vertex.y, vertex.z};
subDataF = MemoryUtil.memAllocFloat(vertices.length); // !!! Must Be manually freed!
subDataF.put(vertices).flip();
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferData(GL_ARRAY_BUFFER, subDataF, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
vboID = vboIDList.get(1);
//int[] index = new int[]{ position };
subDataI = MemoryUtil.memAllocInt(indices.length); // !!! Must Be manually freed!
subDataI.put(indices).flip();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, subDataI, GL_STATIC_DRAW);
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
finally
{
if (subDataF != null)
{
MemoryUtil.memFree(subDataF);
}
if (subDataI != null)
{
MemoryUtil.memFree(subDataI);
}
}
}
}
因此,当我传递整个顶点数组并从头开始重新分配 VBO 内存时,它会准确地绘制我需要的内容。不过我想使用 glBufferSubData,这样我就不会在每次添加新顶点时重新分配内存。这段代码不起作用:
public void addVertex(Vector3f vertex, int position)
{
if (meshType == 1)
{
FloatBuffer subDataF = null;
IntBuffer subDataI = null;
int vboID;
lineCount = position+1;
try
{
System.out.printf("Adding vertex (%f, %f, %f) to position %d\n",vertex.x,vertex.y,vertex.z,position);
vboID = vboIDList.get(0);
float[] vert = new float[]{vertex.x, vertex.y, vertex.z};
subDataF = MemoryUtil.memAllocFloat(3); // !!! Must Be manually freed!
subDataF.put(vert).flip();
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferSubData(GL_ARRAY_BUFFER, position * 3 * 4, subDataF);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
vboID = vboIDList.get(1);
int[] index = new int[]{ position };
subDataI = MemoryUtil.memAllocInt(1); // !!! Must Be manually freed!
subDataI.put(index).flip();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboID);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, position * 4, subDataI);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
finally
{
if (subDataF != null)
{
MemoryUtil.memFree(subDataF);
}
if (subDataI != null)
{
MemoryUtil.memFree(subDataI);
}
}
}
}
此外,我知道它没有优化我创建 floatbuffer 和 intbuffer 的方式,我只是想让它在清理之前工作。我尝试了很多事情,因此最后一段代码很奇怪。
不过,我还是不明白我做错了什么。我确实检查了我是否正确传递了所有数据,并且位置(和偏移量)似乎是按照应有的方式计算的。它只是不绘制任何东西,而当我使用 glBufferData 时它会绘制任何东西。
有人可以解释一下我在哪里犯了错误吗?
经过所有建议,这就是我最终得到的结果,但它仍然根本不起作用:
public void addVertex(Vector3f vertex, int position)
{
if (meshType == 1)
{
FloatBuffer subDataF = null;
IntBuffer subDataI = null;
int vboID;
lineCount = position+1;
try
{
System.out.printf("Adding vertex (%f, %f, %f) to position %d\n",vertex.x,vertex.y,vertex.z,position);
vboID = vboIDList.get(0);
float[] vert = new float[]{vertex.x, vertex.y, vertex.z};
subDataF = MemoryUtil.memAllocFloat(3); // !!! Must Be manually freed!
subDataF.put(vert).flip();
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferSubData(GL_ARRAY_BUFFER, (long)(position * 3 * 4), (FloatBuffer)subDataF);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
vboID = vboIDList.get(1);
int[] index = new int[]{ position };
subDataI = MemoryUtil.memAllocInt(1); // !!! Must Be manually freed!
subDataI.put(index).flip();
glBindVertexArray(vaoID);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, (long)(position * 4), (IntBuffer)subDataI);
}
finally
{
if (subDataF != null)
{
MemoryUtil.memFree(subDataF);
}
if (subDataI != null)
{
MemoryUtil.memFree(subDataI);
}
}
}
}
我确实检查了 VAO ID 是否正确。
最佳答案
正如我所想,这是愚蠢的事情,与 VAO 绑定(bind)等完全无关。
问题是,当我最初创建 VBO 时,我是这样做的:
// Vertices VBO generation
vboID = glGenBuffers();
vboIDList.add(vboID);
verticesBuffer = MemoryUtil.memAllocFloat(size * 3); // !!! Must Be manually freed!
verticesBuffer.put(vertex).flip();
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferData(GL_ARRAY_BUFFER, verticesBuffer, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
vertexAttrArrCount += 1;
我假设因为我为 size*3 float 分配了缓冲区,所以它将具有该大小,并且当我将其放入 VBO 中时 - 它将分配 size*3*4 字节,即足以容纳 size*3 float 。
结果不是!因为我只将一个顶点(3 个浮点)放入缓冲区 - 它只会分配该数量的空间。因此,当我稍后尝试使用 glBufferSubData 时,它在 GPU 上只有 3 个 float 的空间,自然不会将这些值放在我需要的地方。事实上,我很惊讶它并没有完全崩溃。
为了解决这个问题,目前我这样做了:
// Vertices VBO generation
...
verticesBuffer.put(vertex).put(new float[size*3 - 3]).flip();
...
所以基本上我手动将一个空数组放入 FloatBuffer 中,这确保了缓冲区的大小正确。
结果如下:构造函数:
public Mesh(float[] vertex, int size)
{
texture = null;
meshType = 1; //will draw lines
FloatBuffer verticesBuffer = null;
IntBuffer indicesBuffer = null;
int vboID;
try
{
vertexCount = size;
vaoID = glGenVertexArrays();
glBindVertexArray(vaoID);
vboIDList = new ArrayList<>();
// Vertices VBO generation
vboID = glGenBuffers();
vboIDList.add(vboID);
verticesBuffer = MemoryUtil.memAllocFloat(size * 3); // !!! Must Be manually freed!
verticesBuffer.put(vertex).put(new float[size*3 - 3]).flip();
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferData(GL_ARRAY_BUFFER, verticesBuffer, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
vertexAttrArrCount += 1;
// Indices VBO generation
vboID = glGenBuffers();
vboIDList.add(vboID);
indicesBuffer = MemoryUtil.memAllocInt(size); // !!! Must be manually freed!
indicesBuffer.put(new int[size]).flip(); // I need the first element 0 anyway
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL_STATIC_DRAW);
// unbinding
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
finally
{
if (verticesBuffer != null)
{
MemoryUtil.memFree(verticesBuffer); // Freeing vertex buffer
}
if (indicesBuffer != null)
{
MemoryUtil.memFree(indicesBuffer); // Freeing indices buffer
}
}
}
然后更新:
public void addVertex(Vector3f vertex, int position)
{
if (meshType == 1)
{
FloatBuffer subDataF = null;
IntBuffer subDataI = null;
int vboID;
lineCount = position+1;
try
{
vboID = vboIDList.get(0);
float[] vert = new float[]{vertex.x, vertex.y, vertex.z};
subDataF = MemoryUtil.memAllocFloat(vert.length); // !!! Must Be manually freed!
subDataF.put(vert).flip();
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferSubData(GL_ARRAY_BUFFER, (long)(position * 3 * 4), (FloatBuffer)subDataF);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
vboID = vboIDList.get(1);
int[] index = new int[]{ position };
subDataI = MemoryUtil.memAllocInt(index.length); // !!! Must Be manually freed!
subDataI.put(index).flip();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboID);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, (long)(position * 4), (IntBuffer)subDataI);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
finally
{
if (subDataF != null)
{
MemoryUtil.memFree(subDataF);
}
if (subDataI != null)
{
MemoryUtil.memFree(subDataI);
}
}
}
}
而且它有效。请注意,代码有点脏,我在发布答案之前没有清理它。
关于java - OpenGL glBufferSubData - 无法让它工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57955500/
我正在制作一个使用 lwjgl 动态呈现文本的系统。我有一个系统设置为自动生成纹理以用于渲染,图像确实有效。这就是问题所在。 我有这段代码来初始化 2 个 VBO 和一个 VAO,它们都设置为能够处理
我正在做一个渲染,我每帧多次调用 glBufferSubData。 这是我在代码中的做法: glBindBuffer(GL_ARRAY_BUFFER,_vboID); //Buffering
当尝试使用 glBufferSubData 访问 GL_ARRAY_BUFFER 到 128 字节缓冲区大小时,访问最多需要 200 微秒。相反,当使用 glBufferData 再次分配整个缓冲区时
我需要用新顶点更新我的网格。我这样创建了 VBO(最初创建时只有一个顶点): public Mesh(float[] vertex, int size) { texture = null;
移植来自 Superbible OpenGL 7th ed 的第 7 章实例渲染示例。并遇到函数 glBufferSubData 的问题 无论我对它做什么,它都不会接受数据。把它变成一个指针,一个字节
我注意到随着缓冲区大小的增加,更新 VBO 中的少量顶点变得非常缓慢。例如,当我更新时,比如说,512*512 缓冲区中的 2 个顶点比我更新整个 256*256 缓冲区时慢得多,尽管更新的数据量
我实际上正在使用 OpenGL 3.3 渲染引擎,确切地说,我正在尝试在我的场景中创建动态数量的灯光。 为此,我正在使用统一缓冲区对象 (UBO),当我尝试传递数据时遇到问题,而 UBO 将在具有不同
你好, 我正在尝试通过调用 glBufferSubData() 来更新 VBO 的一部分。当我从现有影子缓冲区的开头 (0) 更新时,没有问题,因为缓冲区从 0 开始读取。以下将从缓冲区读取 0 到
我正在尝试使用 vao 和 vbo 制作网格类。 首先我创建 vector 来保存要缓冲的数据: std::vector vertices; std::vector normals; std::vec
我正在使用实例化渲染来渲染大片草地,为此我使用了一个由大量 4x4 变换矩阵组成的实例化数组。 我在草叶上使用 LOD 算法,根据它们与相机的距离来确定渲染哪些叶子。为此,我将实例化数组更新为仅包含相
我正在尝试在 OpenGL 3.3 中渲染 Suzanne(来自 Blender),但缓冲区数据似乎不正确。我明白了: https://gyazo.com/ab82f9acb6854a49fccc52
我不太明白为什么这段代码对于 iOS 上的 GPU 很慢,但这段代码在 Windows 上运行良好,没有任何问题。 基本上我正在做的是我有一个大的动态顶点缓冲区(GL_STREAM_DRAW)并且我尝
为了更新我的统一缓冲区对象,我使用 glBufferSubData .使用速度更快吗glBufferSubData或 glMapBuffer与 glUnmapBuffer ? 最佳答案 关于glMap
我想让我的 VBO 移动,我想知道我是否应该使用 glBufferSubData 更新整个 VBO 的值,或者只使用已弃用的 glTranslatef 来移动我的东西. 如果我只是更新 VBO 中的值
似乎 glBufferSubData 在我的 glDrawArrays 调用之间覆盖或以某种方式破坏数据。我在 Windows 7 64 位系统中工作,使用适用于我的 Nvidia GeForce G
我正在开发一款基于图 block 的物理游戏,例如 Falling Sand Game。我目前正在为顶点使用静态 VBO,为与每种 block 类型关联的颜色使用动态 VBO。对于这种类型的游戏,颜色
我目前正在开发一款使用 Java 1.6 和 LWJGL 编写的 2d 自上而下 RPG。我在我的游戏中实现了 VBO 的使用,现在我维护其中两个:一个用于顶点数据,一个用于纹理坐标。 一切正常,只是
一段时间以来,我一直在减少这个段错误,这是我机器上的一个非常小的可重现示例(如下)。我有一种下沉的感觉,这是一个驱动程序错误,但我对 OpenGL 非常不熟悉,所以更有可能我只是做错了什么。 这是正确
我想在创建 VBO 后更新对象的顶点列表。我都看过 glBufferSubData和 glMapBuffer而且它们似乎都在做类似的事情,这意味着我现在不确定该使用哪一个。 我的伪工作流程是: Cre
在 OpenGL Insights 中,它说“OpenGL 驱动程序必须等待,因为使用了 VBO通过上一帧的 glDrawElements。 这让我很困惑。据我所知, glBufferSubData
我是一名优秀的程序员,十分优秀!