Я занимаюсь созданием движка игры/рендеринга, и я обнаружил, что у меня может быть класс для объекта шейдера, но если я оберну его VAO в классе, он не будет отображаться.Почему у меня есть класс шейдеров OpenGL, но не класс VAO?
Шейдеры не возвращают ошибок, а VAO и шейдеры являются действительными объектами OpenGL.
Полный Repo находится (см снизу для упрощенной версии) https://github.com/nunziotocci/stackoverflow-question-1
UPDATE
Проблема эта линия:
glBufferData(GL_ARRAY_BUFFER, sizeof(arrFVertex), arrFVertex, GL_STATIC_DRAW);
Как @BDL предложил в комментариях, я подумал об этом, и я понял, что это должно быть:
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * intNumVertex * 3, arrFVertex, GL_STATIC_DRAW);
UPDATE 2 В ответ на который должен быть помещен на удержание, вот Минимальный полный и проверяемый Пример:
#include <OpenGL/gl3.h>
#include <SDL2/SDL.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
SDL_Window *window = NULL;
SDL_GLContext openGLRenderer;
bool bolRunning = true;
int intGLVersionMajor, intGLVersionMinor;
GLfloat arrFVertex[] = {
0.5f, 0.5f, 0.0f, // Top Right
0.5f, -0.5f, 0.0f, // Bottom Right
-0.5f, 0.5f, 0.0f, // Top Left
0.5f, -0.5f, 0.0f, // Bottom Right
-0.5f, -0.5f, 0.0f, // Bottom Left
-0.5f, 0.5f, 0.0f // Top Left
};
GLuint intVAO;
GLuint intVBO;
GLuint intShaderAttribPosition;
GLuint intShaderProgram;
GLuint intNumVertex = 6;
void loadShaders(const char *strVertexShaderSource, const char *strFragmentShaderSource) {
intShaderProgram = glCreateProgram();
GLuint intVertexShader;
intVertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(intVertexShader, 1, &strVertexShaderSource, NULL);
glCompileShader(intVertexShader);
GLuint intFragmentShader;
intFragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(intFragmentShader, 1, &strFragmentShaderSource, NULL);
glCompileShader(intFragmentShader);
glAttachShader(intShaderProgram, intVertexShader);
glAttachShader(intShaderProgram, intFragmentShader);
glLinkProgram(intShaderProgram);
glDeleteShader(intVertexShader);
glDeleteShader(intFragmentShader);
}
void buildVAO(GLfloat *arrFVertex) {
intShaderAttribPosition = glGetAttribLocation(intShaderProgram, "f3Position");
glGenVertexArrays(1, &intVAO);
glBindVertexArray(intVAO);
glGenBuffers(1, &intVBO);
glBindBuffer(GL_ARRAY_BUFFER, intVBO);
glVertexAttribPointer(intShaderAttribPosition, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid *)0);
glEnableVertexAttribArray(intShaderAttribPosition);
glBufferData(GL_ARRAY_BUFFER, sizeof(arrFVertex), arrFVertex, GL_STATIC_DRAW);
glBindVertexArray(0);
}
int main(int argc, char **argv) {
SDL_Init(SDL_INIT_EVERYTHING);
window = SDL_CreateWindow("GSEngine",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
640, 480,
SDL_WINDOW_OPENGL);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
if (window == NULL) {
printf("Could not create window: %s\n", SDL_GetError());
exit(1);
}
openGLRenderer = SDL_GL_CreateContext(window);
SDL_GL_MakeCurrent(window, openGLRenderer);
glViewport(0, 0, 640, 480);
loadShaders("#version 330 core\n\
in vec3 f3Position;\n\
void main() {\n\
gl_Position = vec4(f3Position, 1.0);\n\
}", "#version 330 core\n\
out vec4 f4Color;\n\
void main() {\n\
f4Color = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n\
}");
buildVAO(arrFVertex);
while (bolRunning) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
bolRunning = false;
}
}
SDL_GL_MakeCurrent(window, openGLRenderer);
glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(intShaderProgram);
glDrawArrays(GL_TRIANGLES, 0, intNumVertex);
SDL_GL_SwapWindow(window);
}
glDeleteBuffers(1, &intVBO);
glDeleteVertexArrays(1, &intVAO);
glDeleteShader(intShaderProgram);
SDL_GL_DeleteContext(openGLRenderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
Приобретение кода в классе или его отсутствие не имеет значения, пока вызываются все правильные команды OpenGL. Я думаю, вам стоит попытаться сделать [MCVE] (http://stackoverflow.com/help/mcve) вместо того, чтобы ожидать, что мы загрузим весь ваш репозиторий. Кроме того, когда вы меняете код, эти вопросы становятся бесполезными для будущих читателей. – vesan
Я планировал оставить это репо в одиночку, и я не уверен, как сделать его более минимальным, но я попробую. –
ОК, справедливо. Вы отмечаете, что это не сработает, когда вы завершаете свое VAO в классе. Означает ли это, что вы пробовали версию без класса VAO, и это сработало? Если это так, может быть полезно найти различия в этом коде. – vesan