Как правильно добавить код OpenGL во внешнюю функцию

#c #opengl

#c #opengl

Вопрос:

Я пытаюсь получить некоторый код OpenGL, который извлекает объекты из массива вершин, и добавить его в файл класса. Однако код выполняется только в настоящее время, когда он у меня есть в моем main.cpp досье. Я вызываю init() из моей функции main(), прежде чем перейти к моему циклу рисования.

 init(){
    GLuint containerVAO, VBO;
    glGenVertexArrays(1, amp;containerVAO);
    glGenBuffers(1, amp;VBO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glBindVertexArray(containerVAO);
    // Position attribute
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(0);
    // Normal attribute
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat),(GLvoid*)(3 * sizeof(GLfloat)));
    glEnableVertexAttribArray(1);
    glBindVertexArray(0);
}
 

Соответствующий код в моем цикле рисования:

 glUseProgram(noTextureShaderID);
glBindVertexArray(containerVAO);
///many different uniforms added here
glDrawArrays(GL_TRIANGLES, 0, 36);
 

Это не создает проблем с кубом.
Теперь, когда я заменяю код внутри моей функции init() (которая инициализирует все объекты, а не только этот, я меняю его на это:

 init(){
    square.init(noTextureShaderID, vertices[], NULL, 36);
    //Square is a global variable within my main.cpp file
}
 

И затем я использую эту функцию:

 void Mesh::init(const GLuintamp; shaderid, GLfloat vertices[], const char* tex_file, int num_vertices)
{
GLuint VBO;
vao = NULL;    //This is a variable within the Mesh class
g_point_count = num_vertices;
glGenVertexArrays(1, amp;vao);
glGenBuffers(1, amp;VBO);

glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

glBindVertexArray(vao);
// Position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
// Normal attribute
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glBindVertexArray(0);
}
 

Затем в моей функции рисования я вызываю это вместо:

 glUseProgram(noTextureShaderID);
glBindVertexArray(square.vao);
///many different uniforms added here
glDrawArrays(GL_TRIANGLES, 0, g_point_count);
 

Но даже при том, что обе программы, похоже, имеют одинаковый код, только первая версия генерирует куб. Чего мне не хватает в этом отношении?

Ответ №1:

Ваш код не идентичен в обоих случаях, и это не имеет ничего общего с OpenGL:

 void Mesh::init(const GLuintamp; shaderid, GLfloat vertices[], const char* tex_file, int num_vertices)
{
     // ...
     glBufferData(..., sizeof(vertices), ...);
}
 

vertices здесь передается по ссылке, внутренняя функция никогда не увидит массив и sizeof(vertices) будет идентична sizeof(GLfloat*) , что обычно составляет 4 или 8 на современных машинах. Следовательно, ваш буфер содержит только первые один или два числа с плавающей запятой.

Вам либо нужно явно указать размер массива в качестве дополнительного параметра, либо вы используете некоторый (ссылка на) объект более высокого уровня, например std:vector , который полностью управляет внутренним массивом и позволяет запрашивать размер.

Комментарии:

1. Хорошо, поэтому, когда я меняю этот аргумент на «sizeof (GLfloat) * 6 * num_vertices», это работает. И это здорово, за исключением того, что я до сих пор не совсем понимаю, почему именно эти числа работают. Не могли бы вы объяснить мне это или указать мне на ресурс, который мог бы это объяснить?

2. Подождите, теперь я понимаю. Для каждой вершины в массиве имеется 6 разных значений. Мне просто нужно пойти и выяснить, что на самом деле означает каждое из этих значений в контексте моей программы. Спасибо за помощь!