相关疑难解决方法(0)

NULL + int的结果是什么?

我在OpenGL VBO实现中看到了以下宏:

#define BUFFER_OFFSET(i) ((char *)NULL + (i))
//...
glNormalPointer(GL_FLOAT, 32, BUFFER_OFFSET(x));
Run Code Online (Sandbox Code Playgroud)

你能提供一下这个宏的工作原理吗?可以用功能替换吗?更确切地说,递增NULL指针的结果是什么?

c opengl null pointers pointer-arithmetic

19
推荐指数
2
解决办法
5021
查看次数

从`VkVertexInputBindingDescription`中绑定`的目的是什么?

https://www.khronos.org/registry/vulkan/specs/1.0/man/html/VkVertexInputBindingDescription.html

  • binding是此结构描述的绑定号.

我不确定这是什么意思,例如来自https://github.com/SaschaWillems/Vulkan/blob/master/triangle/triangle.cpp

    #define VERTEX_BUFFER_BIND_ID 0
    ....
    vertices.inputAttributes[0].binding = VERTEX_BUFFER_BIND_ID;
    vertices.inputAttributes[0].location = 0;
    vertices.inputAttributes[0].format = VK_FORMAT_R32G32B32_SFLOAT;
    vertices.inputAttributes[0].offset = offsetof(Vertex, position);
    // Attribute location 1: Color
    vertices.inputAttributes[1].binding = VERTEX_BUFFER_BIND_ID;
    vertices.inputAttributes[1].location = 1;
    vertices.inputAttributes[1].format = VK_FORMAT_R32G32B32_SFLOAT;
    vertices.inputAttributes[1].offset = offsetof(Vertex, color);
Run Code Online (Sandbox Code Playgroud)

并且顶点着色器看起来像这样

#version 450

#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable

layout (location = 0) in vec3 inPos;
layout (location = 1) in vec3 inColor;

layout (binding = 0) uniform UBO 
{
    mat4 projectionMatrix;
    mat4 modelMatrix;
    mat4 viewMatrix;
} ubo;

layout …
Run Code Online (Sandbox Code Playgroud)

c++ vulkan

8
推荐指数
1
解决办法
1043
查看次数

OpenGL顶点缓冲区绑定点可以在不同的VAO中重用吗?

假设我使用新的(从OpenGL 4.3开始)glBindVertexBuffer机制设置了两个VAO:

glGenVertexArrays(1, &vaoIndex0);
glGenVertexArrays(1, &vaoIndex1);
Run Code Online (Sandbox Code Playgroud)

...

glBindVertexArray(vaoIndex0)
glBindVertexBuffer(bindingIndex0, ...)
glEnableVertexAttribArray(0)
glVertexAttribFormat(0, ...)
glVertexAttribBinding(0, bindingIndex0)
...
glBindVertexArray(0)
Run Code Online (Sandbox Code Playgroud)

...

glBindVertexArray(vaoIndex1)
glBindVertexBuffer(bindingIndex1, ...)
glEnableVertexAttribArray(0)
glVertexAttribFormat(0, ...)
glVertexAttribBinding(0, bindingIndex1)
...
glBindVertexArray(0)
Run Code Online (Sandbox Code Playgroud)

并且假设两者是独立的,除非它们存在于相同的OpenGL上下文中; 它们绑定不同的缓冲区,用于绘制不同的东西.

bindingIndex0需要与bindingIndex1不同吗?两个指数的平等(或不平等)是否有任何意义?

...

编辑:

在收到答案后,我开始明白,对于一个真正知道"顶点缓冲区绑定点"是什么的人,特别是它的范围是什么,我的问题似乎是在问一些与我的意图不同的东西.也许一个更好的措辞就是" 为了防止冲突,是否需要尽力避免重复使用OpenGL顶点缓冲区绑定点索引,甚至跨多个VAO?" 但无论如何,似乎现在已经回答了这两个问题:不,你不能重复使用"绑定点",并且不需要以这种方式避免索引冲突.

opengl vao

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

glVertexAttribPointer 调用中是否强制转换为 void* 是合法的 C++?

这实际上是一个关于C++的问题,而不是关于OpenGL的问题。我正在关注有关 OpenGL 的教程(我刚刚开始),作者使用 C++(不是 C)。我的问题是glVertexAttribPointer 需要一个偏移参数作为const void*。由于此参数只是告诉 OpenGL 给定的顶点属性第一次出现在使用 复制的顶点数组中的位置glBufferData(),因此我希望它应该是std::ptrdiff_t类型。SO 上的这篇void*文章解释了为什么用作参数类型的原因,但我想知道为什么这种用法在 C++ 中是合法的。例如,提到的教程只是简单地转换为以void*字节为单位的偏移量值,如下面的调用所示:

glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3* sizeof(float)));
Run Code Online (Sandbox Code Playgroud)

在我看来,这种方法不合法,因为cpprefence文档reinterpret_cast

任何整型或枚举类型的值都可以转换为指针类型。转换为足够大小的整数并返回到相同指针类型的指针保证具有其原始值,否则无法安全地取消引用结果指针(不保证相反方向的往返转换,相同的指针可能具有多个整数表示)

因此,如果我正确理解这一点,std::ptrdiff_t偏移量的值(这似乎是这里需要的)在转换为void*. 我想念什么?

c++ opengl

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

OpenGL 顶点数组对象存储顶点缓冲区名称和索引,还是仅存储索引?

创建时,VAO 是否仅跟踪 VBO 索引(通过glBindVertexBuffer),或者还跟踪哪些 VBO 名称绑定到这些索引?如果我使用glVertexAttribBinding指定绑定索引,例如 0,我可以在绘制调用之前将不同的 VBO 绑定到索引 0 并让它使用该 VBO 的内容,还是始终使用任何 VBO创建 VAO 时是否绑定到索引 0?

我问这个问题是因为我发现很多例子都在调用glVertexAttribFormatglVertexAttribBinding之前调用glBindVertexBuffer,如果 VAO 仅跟踪索引(因为绑定索引在 中给出),则不需要调用glVertexAttribBinding

opengl vbo opengl-4 vao

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

使用相同的着色器但不具有相同的纹理或颜色来绘制多个 VAO 的最佳方法是什么

我想知道如果我想使用相同的着色器绘制超过 6000 个不同的 VAO,最好的做法是什么。

目前我绑定了我的着色器,然后给它所有需要的信息(统一),然后循环遍历每个 VAO 来绑定和绘制它们。

这段代码使我的电脑下降到 ~ 200 fps 而不是 3000 或 4000。根据https://learnopengl.com/Advanced-OpenGL/Instancing,使用 glDrawElementsInstanced 可以让我处理大量相同的 VAO 但因为我有 ~ 6000个不同的VAO 好像用不上。

有人可以向我证实这一点吗?你们会怎么做才能绘制这么多VAO并尽可能节省性能?

c++ opengl

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

与基本逻辑代码相比,OpenGL glDrawElements() 调用有多繁重?

我计划对我的 OpenGL 程序进行一些优化(它不需要优化,但我是为了优化而这样做)。出于好奇,OpenGL 绘图函数与基本逻辑代码相比有多昂贵?目前,我正在开始一个游戏,屏幕上充满了方块,以代表 2D 块状景观。这意味着正方形(两个三角形)的绘制调用被调用多次。目前,我计划添加一些代码来查看当前帧中块的位置,并将它们分组在一起。例如,如果有一列有 7 个块高,我可以调用一个函数来绘制一个 1 x 7 的矩形,而不是执行 7 个单独的 drawBlock() 函数(其中包含 glDrawElements() 调用),等等开,整个屏幕。

如果计算绘制内容的代码实际上比单独绘制块占用更多的 CPU,我就不会费心这样做。

c++ opengl

2
推荐指数
1
解决办法
1917
查看次数

渲染一个包含两个 VBO 的 VAO

我正在尝试在 OpenGL 3.3 的窗口中绘制两个三角形。我正在为窗口系统使用 GLFW 库。

据我所知,我应该有两个 VBO(每个三角形一个)和一个包含这两个 VBO 的VAO。这就是我所做的。

但是,我不知道应该进行哪些调用来呈现这两个 VBO。事实上,无论我做什么,只有第一个VBO(第一个三角形)被绘制。第二个永远不会出现。

int main()
{
    GLFWwindow *window = setupWindow();
    GLfloat triangle1Vertices[] = {
        -0.5f, -0.5f, 0.0f,
        0.5f, -0.5f, 0.0f,
        0.0f,  0.5f, 0.0f
    };
    GLfloat triangle2Vertices[] = {
        0.f, -0.5f, 0.0f,
        0.8f, -0.5f, 0.0f,
        0.0f,  0.5f, 0.0f
    };
    GLuint vao, vbo[2];

    glGenVertexArrays(1, &vao);
    glGenBuffers(2, vbo);

    glBindVertexArray(vao);

    glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(triangle1Vertices), triangle1Vertices, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
    glEnableVertexAttribArray(0); …
Run Code Online (Sandbox Code Playgroud)

c opengl vbo glfw vao

2
推荐指数
1
解决办法
3216
查看次数

D3D 输入槽到底是什么以及 OpenGL 的等效项是什么?

D3D11_INPUT_ELEMENT_DESC在 Direct3D 中,当我们使用和 调用指定顶点着色器的输入时IASetVertexBuffers,我们必须指定“输入槽”。这些输入槽到底是什么?OpenGL 等效项是什么?这些输入槽似乎与layout(location = K)GLSL 中指定的“位置”和glVertexAttribPointer.

opengl direct3d

2
推荐指数
1
解决办法
1380
查看次数

标签 统计

opengl ×8

c++ ×4

vao ×3

c ×2

vbo ×2

direct3d ×1

glfw ×1

null ×1

opengl-4 ×1

pointer-arithmetic ×1

pointers ×1

vulkan ×1