c++ - 调用 glDrawArrays 时出现访问冲突错误

标签 c++ opengl glsl vertex-shader

我正在编写 OpenGL 应用程序,其中有一个 GrassPatch 类,它代表场景中的草 block 。我不想提供任何不必要的细节,因此 GrassPatch.cpp 大致如下所示:

GrassPatch::GrassPatch(GLuint density)
{
    m_density = density;
    generateVertices();
}

void GrassPatch::generateVertices()
{
    const int quadVertexCount = 64;
    GLfloat bladeWidth, bladeHeight, r;
    GLfloat randomX, randomZ;
    m_vertices = new GLfloat[quadVertexCount * m_density];
    srand(time(NULL));
    for (int i = 0; i < m_density; i++)
    {
        // generate 64 float values and put them into their respective indices in m_vertices
    }

    glGenBuffers(1, &m_VBO);
    glGenVertexArrays(1, &m_VAO);

    glBindVertexArray(m_VAO);

    glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * m_density * quadVertexCount, m_vertices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 16 * sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 16 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
    glEnableVertexAttribArray(1);

    glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 16 * sizeof(GLfloat), (GLvoid*)(5 * sizeof(GLfloat)));
    glEnableVertexAttribArray(2);

    glVertexAttribPointer(3, 8, GL_FLOAT, GL_FALSE, 16 * sizeof(GLfloat), (GLvoid*)(8 * sizeof(GLfloat)));
    glEnableVertexAttribArray(3);

    glBindVertexArray(0);
}

void GrassPatch::draw()
{
    glBindVertexArray(m_VAO);
    glPatchParameteri(GL_PATCH_VERTICES, 4);
    glDrawArrays(GL_PATCHES, 0, 4 * m_density);
    glBindVertexArray(0);
}

简而言之,每个草 block 的顶点数组对象(VAO)是在generatVertices内部生成的。我的数据是紧密包装的,每个顶点的属性位于索引 0、3、5、8 处,其中每个顶点由 16 个浮点组成。每个草叶由 4 个顶点组成,因此quadVertexCount 设置为 64。我使用的顶点着色器非常简单,如下所示:

#version 440 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 texCoord;
layout (location = 2) in vec3 centerPos;
layout (location = 3) in float randomValues[8];

out vec2 TexCoord_CS;

void main()
{
    TexCoord_CS = texCoord;

    gl_Position = vec4(position, 1.0f);
}

这里的问题是,当我尝试使用 draw() 方法绘制每个草叶时,出现访问冲突错误。但是,如果我将属性索引稍微更改为 0、4、8、12,并在顶点着色器中进行必要的变量类型更改,问题就会消失,一切都会呈现良好。

我在这里缺少什么,什么会导致这样的问题?我在互联网上花了几个小时试图找到原因,但还没有找到任何答案。我正在使用 Visual Studio 2015 社区版。我使用的显卡是 NVIDIA GTX 770,所有驱动程序都是最新的。

最佳答案

这不是一个有效的调用:

glVertexAttribPointer(3, 8, GL_FLOAT, GL_FALSE, 16 * sizeof(GLfloat), (GLvoid*)(8 * sizeof(GLfloat)));

第二个参数(大小)需要为 1、2、3 或 4。如果您调用 glGetError(),您应该会看到 GL_INVALID_VALUE 此调用的错误代码。

顶点属性最多只能有 4 个组件,与着色器代码中的 vec4 类型匹配。如果某个属性需要 8 个值,则必须将其拆分为 2 个属性,每个属性 4 个值,或者使用统一而不是属性。

关于c++ - 调用 glDrawArrays 时出现访问冲突错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34668652/

相关文章:

opengl - 为了向后兼容,您是否应该使用 ARB 扩展而不是核心调用?

opengl - Cuda 和 OpenGL 互操作的类型

java - Opengl ES glGetAttribLocation问题! 0x0502 错误

.net - 如何将 double* 转换为数组<double>(6)

c++ - 如果项目仅使用 OpenMP 构建,会发生什么差异

c - OpenGL 顶点数组

View 空间中的 openGL 立方体贴图反射是错误的

c++ - 绘图期间未处理的异常 (nvoglv32.dll)(裂缝)

c++ - 是否可以将任何类对象作为任何测试表达式的测试表达式传递,例如 if,while like ifstream 对象。

c++ - 在CUDA中处理4D张量的内核