标签: vertex-buffer

OpenGL 3.x:使用顶点缓冲区对象和glDrawElements(...)时的访问冲突

我使用顶点缓冲区对象渲染某些几何体时遇到问题.我打算绘制一个点平面,所以基本上是我空间中每个离散位置的一个顶点.但是,我无法渲染该平面,因为每次调用glDrawElements(...)时,应用程序崩溃都会返回访问冲突异常.我想,在初始化时肯定会有一些错误.

这是我到目前为止:


#define SPACE_X 512
#define SPACE_Z 512

typedef struct{
    GLfloat x, y, z; // position
    GLfloat nx, ny, nz; // normals
    GLfloat r, g, b, a; // colors
} Vertex;

typedef struct{
    GLuint i; // index
} Index;

// create vertex buffer
GLuint vertexBufferObject;
glGenBuffers(1, &vertexBufferObject);

// create index buffer
GLuint indexBufferObject;
glGenBuffers(1, &indexBufferObject);

// determine number of vertices / primitives
const int numberOfVertices = SPACE_X * SPACE_Z;
const int numberOfPrimitives = numberOfVertices; // As I'm going to render …
Run Code Online (Sandbox Code Playgroud)

opengl vertex-buffer opengl-3

5
推荐指数
1
解决办法
4924
查看次数

如何渲染由三角形组成的网格,其中每个三角形具有相同的颜色,而不是每个三角形指定该颜色3次

如何渲染网格(由三角形组成),其中每个三角形具有相同的颜色,而不是在顶点数组中为每个三角形指定该颜色3次.

假设我想绘制2个三角形.三角1:

Vertex 1,  position:(x1,y1) , color: (r1,g1,b1,a1)
Vertex 2,  position:(x2,y2) , color: (r1,g1,b1,a1)
Vertex 3,  position:(x3,y3) , color: (r1,g1,b1,a1)
Run Code Online (Sandbox Code Playgroud)

三角2:

Vertex 4,  position:(x4,y4) , color: (r2,g2,b2,a2)
Vertex 5,  position:(x5,y5) , color: (r2,g2,b2,a2)
Vertex 6,  position:(x6,y6) , color: (r2,g2,b2,a2)
Run Code Online (Sandbox Code Playgroud)

我知道这可以通过创建2个顶点缓冲区来完成:

Vertex Buffer 1:
[x1, y1]
[x2, y2]
[x3, y3]
[x4, y4]
[x5, y5]
[x6, y6]


Vertex Buffer 2:
[r1, g1, b1, a1]
[r1, g1, b1, a1]
[r1, g1, b1, a1]
[r2, g2, b2, a2]
[r2, g2, b2, a2]
[r2, g2, …
Run Code Online (Sandbox Code Playgroud)

opengl glsl vertex-buffer

5
推荐指数
1
解决办法
2178
查看次数

如何将int转换为const GLvoid*?

在我的跨平台OpenGL应用程序中,我想使用顶点缓冲区对象进行绘制.但是我遇到了调用glDrawRangeElements的问题.

glDrawRangeElements(GL_TRIANGLES, start, start + count, count, 
            GL_UNSIGNED_INT,  static_cast<GLvoid *>  (start * sizeof(unsigned int)));
Run Code Online (Sandbox Code Playgroud)

编译器(Mac OS X上的CLang)不喜欢最后一个参数"错误:无法从类型'unsigned long'转换为指针类型'GLvoid*'(又名'void*')".OpenGL API将最后一个参数的类型定义为const GLvoid*,并且当此api与顶点数组一起使用时需要一个指针.但是我知道当使用顶点缓冲区对象而不是指针时,应该将一个表示偏移量的整数值传递给缓冲区数据.这就是我想要做的事情,因此我必须施展.如何协调api要求与编译器进行严格的检查?

opengl vertex-buffer c++11

5
推荐指数
3
解决办法
3023
查看次数

带有交错缓冲区的openGL glDrawElements

到目前为止,我只使用了glDrawArrays,并希望转而使用索引缓冲区和索引三角形.我正在绘制一个有点纹理坐标,法线和顶点坐标的复杂对象.所有这些数据都被收集到一个交错的顶点缓冲区中,并使用类似于(假设所有的serup都正确完成)的调用来绘制:

glVertexPointer( 3, GL_FLOAT, 22, (char*)m_vertexData );
glNormalPointer( GL_SHORT, 22, (char*)m_vertexData+(12) );
glTexCoordPointer( 2, GL_SHORT, 22, (char*)m_vertexData+(18) );
glDrawElements(GL_TRIANGLES, m_numTriangles, GL_UNSIGNED_SHORT, m_indexData );
Run Code Online (Sandbox Code Playgroud)

这是否允许m_indexData也与我的法线和纹理坐标以及标准位置索引数组的索引交错?或者它是否假设一个适用于整个顶点格式(POS,NOR,TEX)的线性列表?如果后者为真,那怎么可能用不同的纹理坐标或法线渲染相同的顶点?

我想这个问题也可以改为:如果我有3个单独的索引列表(POS,NOR,TEX),后者2不能重新排列以共享与第一个相同的索引列表,那么渲染它的最佳方法是什么.

c++ opengl vertex-buffer

4
推荐指数
1
解决办法
4750
查看次数

在Open GL ES 2.0(iOS GLKit)中处理多个网格?

我已经设法使用iOS的GLKit在Open GL ES 2.0中创建单个网格.我无法弄清楚的是如何创建第二个网格看起来与第一个网格相同,只是位置不同.

我认为最有帮助的是,如果有人可以简单地提供一些绘制多个网格的示例代码,我认为我认为这完全错了.尽管如此,这里列出了我为完成这项工作所做的工作.

  • 我创建了两个顶点信息的C数组.第一个是我的模板(以0,0,0为中心的硬编码坐标),第二个是我想要显示的模板(最初是空的).
  • 我创建了两个indice信息的C数组.与顶点信息相同的处理.
  • 我有两个全局变量int,vertexCount和indiceCount,最初都是0.
  • 我有ac函数,createAt(float x,float y,float z).此函数将我的顶点模板复制到我的顶点显示数组中,然后将传入的偏移量应用于每个顶点.它还复制索引并应用偏移量,以便它们指向新的显示顶点.

但这不起作用.屏幕上只绘制一个对象.

通过查看其他人的问题和答案,听起来好像我应该有多个顶点缓冲区?我不知道; 我非常困惑.

vertex-buffer opengl-es-2.0 ios5 glkit

4
推荐指数
1
解决办法
2728
查看次数

如何在PyOpenGL中使用glBufferData()?

你如何在PyOpenGL python绑定到OpenGL中使用glBufferData()?

当我运行以下代码时

import sys
from OpenGL.GL import *
from PySide.QtCore import *
from PySide.QtGui import *
from PySide.QtOpenGL import *

class SimpleTestWidget(QGLWidget):

    def __init__(self):
        QGLWidget.__init__(self)

    def initializeGL(self):
        self._vertexBuffer = glGenBuffers(1)
        glBindBuffer(GL_ARRAY_BUFFER, self._vertexBuffer)
        vertices = [0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5]
        glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW)    # Error

    def paintGL(self):
        glViewport(0, 0, self.width(), self.height())
        glClearColor(0.0, 1.0, 0.0, 1.0)
        glClear(GL_COLOR_BUFFER_BIT)

        glEnableClientState(GL_VERTEX_ARRAY)
        glBindBuffer(GL_ARRAY_BUFFER, self._vertexBuffer)
        glVertexPointer(2, GL_FLOAT, 0, 0)
        glColor3f(1.0, 0.0, 0.0)
        glDrawArrays(GL_QUADS, 0, 4)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w …
Run Code Online (Sandbox Code Playgroud)

python opengl pyopengl vertex-buffer

4
推荐指数
1
解决办法
4379
查看次数

glGenVertexArrays 和 glGenBuffers 参数

在有关 OpenGL 3.0+ 的教程中,我们这样创建顶点数组对象和顶点缓冲区对象:

\n\n
GLuint VAO, VBO; \nglGenVertexArrays(1, &VAO);\nglGenBuffers(1, &VBO);\nglBindVertexArray(VAO);\nglBindBuffer(GL_ARRAY_BUFFER, VBO);\n
Run Code Online (Sandbox Code Playgroud)\n\n

这里,VAO 是一个unsigned int( GLuint),我们传递 a\xcc\xb6 \xcc\xb6r\xcc\xb6e\xcc\xb6f\xcc\xb6e\xcc\xb6r\xcc\xb6e\xcc\xb6n\xcc\xb6c\xcc\ xb6e\xcc\xb6 是它在函数中的地址glGenVertexArray。但是,根据文档,函数的第二个参数应该是( )数组 。VBO 和. 我不明白为什么上面的代码适用于这样的参数。unsigned intGLuint*glGenBuffers

\n\n

我尝试用此代码替换上面的代码(并在代码中的其他地方进行必要的修改):

\n\n
GLuint VAO[1];\nGLuint VBO[1];\nglGenVertexArrays(1, VAO);\nglGenBuffers(1, VBO);\nglBindVertexArray(VAO[1]);\nglBindBuffer(GL_ARRAY_BUFFER, VBO[1]);\n
Run Code Online (Sandbox Code Playgroud)\n\n

它编译并执行,但我得到了意想不到的行为:我的纹理矩形使用第一个语法渲染,但不使用第二个语法渲染。我也不明白为什么会发生这种情况。

\n\n

编辑:谢谢。如上所述,第二个代码中存在索引错误。

\n

c++ opengl vertex-buffer vertex-array-object

4
推荐指数
1
解决办法
9338
查看次数

网格类中损坏的顶点数据

我正在尝试实现模型加载,但遇到一个问题。当我尝试绘制网格(出于测试目的而手工编写的单个纹理四边形)时,由于某种原因,与第一个顶点关联的重复数据被传递到顶点着色器(RenderDoc 屏幕)。

这是一个使用我的类的精简版本的示例,它仍然表现出这种行为:

#define TEST_MESH

#include <glad/glad.h>
#include <GLFW/glfw3.h>

#include <iostream>
#include <vector>

void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);

struct Vertex {
    float position[3];
    float color[3];
};

class Mesh {
public:
    Mesh(std::vector<Vertex> vertices, std::vector<unsigned int> indices);
    ~Mesh();
    Mesh(const Mesh&) = delete;
    Mesh& operator=(const Mesh&) = delete;
    Mesh(Mesh&& other);
    Mesh& operator=(Mesh&& other);

    void Draw(unsigned int program_id);

    std::vector<Vertex> m_Vertices;
    std::vector<unsigned int> m_Indices;

private:
    unsigned int m_VAO, m_VBO, m_EBO;

    void Setup();
    void Release();
};

int main() { …
Run Code Online (Sandbox Code Playgroud)

c++ opengl mesh vertex-buffer

4
推荐指数
1
解决办法
180
查看次数

顶点批次(几何组)和最大 VBO(顶点缓冲区)大小

我做了很多关于如何将顶点数据收集到通常称为批次的组中的研究。

对我来说,这是关于该主题的两篇主要有趣的文章:

https://www.opengl.org/wiki/Vertex_Specification_Best_Practices

http://www.gamedev.net/page/resources/_/technical/opengl/opengl-batch-rendering-r3900
Run Code Online (Sandbox Code Playgroud)

第一篇文章解释了如何操作 VBO 的最佳实践(最大大小、格式等)。

第二个提供了一个关于如何使用批处理管理顶点内存的简单示例。根据作者的说法,每个批次必须包含一个 VBO 实例(加上 VAO),并且他强烈坚持这样一个事实:VBO 的最大大小范围在 1Mo(1000000 字节)到 4Mo(4000000 字节)之间。第一篇文章提出了同样的建议。我引用“根据一份 nVidia 文档,1MB 到 4MB 是一个不错的大小。驱动程序可以更轻松地进行内存管理。对于所有其他实现以及 ATI/AMD、Intel、SiS 来说,情况应该相同。”

我有几个问题:

1)上面提到的最大字节大小是绝对规则吗?分配比 4Mo(例如 10 Mo)更重要的字节大小的 VBO 是否那么糟糕?

2) 对于总顶点字节大小大于 4Mo 的网格我们该怎么办?我需要将几何体分成几批吗?

3)一个批次是否不可避免地存储为一个唯一的VBO属性,或者多个批次可以存储在一个VBO中?(这是两种不同的方式,但第一种似乎是正确的选择)。你同意吗?

根据作者的说法,每个批次处理一个最大尺寸在 1 到 4 Mo 之间的唯一 VBO,并且整个 VBO 必须仅包含共享相同材质和变换信息的顶点数据。因此,如果我必须使用不同的材质对其他网格进行批处理(因此顶点无法与现有浴合并),我必须使用实例化的新 vbo 创建一个新批次。

因此,根据作者的说法,我的第二种方法是不正确的:不建议将多个批次存储到单个 VBO 中。

opengl vbo vertex-buffer

3
推荐指数
1
解决办法
4479
查看次数

在 Vulkan 中更新顶点缓冲区的最普遍正确的方法

假设设备内存中有一个顶点缓冲区,以及一个与主机一致且可见的暂存缓冲区。还假设桌面系统具有独立的 GPU(因此独立的内存)。最后,假设正确的帧间同步。

我看到更新顶点缓冲区的两种常见可能方法:

  1. Map++ memcpyunmap 到暂存缓冲区,然后是包含 的瞬态(单个命令)命令缓冲区vkCmdCopyBuffer,将其提交到图形队列并等待队列空闲,然后释放瞬态命令缓冲区。之后,像往常一样将常规帧绘制队列提交到图形队列。这是https://vulkan-tutorial.com上使用的代码(例如,此 .cpp 文件)。

  2. 与上面类似,只是在暂存缓冲区复制提交后使用额外的信号量发出信号,并在常规帧绘制提交中等待,从而跳过“等待空闲”命令。

#2 对我来说有点意义,我反复阅读不要在 Vulkan 中执行任何“等待空闲”操作,因为它使 CPU 与 GPU 同步,但我从未见过它在任何教程或中使用网上的例子。如果顶点缓冲区必须相对频繁地更新,专业人士通常会做什么?

language-agnostic vertex-buffer vulkan

3
推荐指数
1
解决办法
5180
查看次数