Я пишу и приложение OpenGL, где у меня есть класс GrassPatch, который представляет участки травы на сцене. Я не хочу, чтобы обеспечить все ненужные детали, так что GrassPatch.cpp выглядит примерно так:Ошибка при нарушении доступа при вызове glDrawArrays
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);
}
Короче говоря, объект массива вершин (ВАО) для каждой травы патча генерируется внутри generatVertices. Мои данные плотно упакованы, а атрибуты для каждой вершины находятся в индексах 0, 3, 5, 8, где каждая вершина состоит из 16 float
. Каждая травинка состоит из 4-х вершин, следовательно, quadVertexCount устанавливается на 64. вершинных шейдеров я использую довольно straighforward и выглядит следующим образом:
#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 Community Edition. Графическая карта, которую я использую, - это NVIDIA GTX 770, и все драйверы обновлены.