Я довольно новичок в OpenGL, и я следовал этому уроку по шейдерам https://learnopengl.com/Getting-started/Textures. Я не могу заставить мой работать, так как экран в итоге просто черный.Этот код использует glew и glut вместо glfw, как в учебнике.
Что происходит?
- У меня есть список вершин, который я затем сохраняю в VBO, и его атрибуты связываются с помощью VAO
- Установка атрибутов вершин в порядке 3 вершина + 3 цвета + 2 текс-координаты
glEnable(GL_TEXTURE_2D);
- удостоверился, что
GL_TEXTURE0
активен, поэтому следующий вызов к glBindTexture(GL_TEXTURE_2D, texture)
связан с этим текстурным блоком. - Я загружаю текстуру с помощью
stbi_load
function - Загружаю текстуру с
glTexImage2D
с параметрами (width
, height
, texture_data
), которые были переданы в stbi_load
заранее как указатели, так чтозагружает их. - Создание вершинного шейдера, присоединение источника (в VertexShaders.h), компиляция шейдера, ошибки печати шейдера (не отображаются)
- Создание фрагментного шейдера, подключение источника (в FragmentShaders.h), скомпилировать шейдер, вывести ошибки шейдера (не отображаются)
- Создать программу шейдера (
ourShader
), присоединить вершинный шейдер и фрагментный шейдер.Соедините программу «ourShader» и снова напечатайте ошибки (не отображаются).
Замечания:
- Проекция выполняется с
gluPerspective
, около плоскости отсечения 0.1 и далеко1000 (поскольку он смотрит вниз -z, он не должен обрезать объект, я также перевожу объект следующим образом: glTranslatef(0, 0, -10)
) - Текстура загружается (файл существует, он генерирует байтовые данные, когда я загружаю егочто касается изображения текстуры, то это (512x512) https://github.com/JoeyDeVries/LearnOpenGL/blob/master/resources/textures/container.jpg
Это обратный вызов myDisplay:
void myDisplay(void)
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDisable(GL_DEPTH_TEST);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glEnable(GL_TEXTURE_2D);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, 0, -10);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glUseProgram(ourShader);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glutSwapBuffers();
}
Основная настройка
int main(){
//glut initialization stuff...left this out
float vertices[] = {
// positions // colors // texture coords
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // top right
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom left
-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left
};
float texCoords[] = {
0.0f, 0.0f, // lower-left corner
1.0f, 0.0f, // lower-right corner
0.5f, 1.0f // top-center corner
};
unsigned int indices[] = {
0, 1, 3, // first triangle
1, 2, 3 // second triangle
};
//frameBuffer
glGenBuffers(1, &FBO);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
std::cout << "ERROR: Framebuffer not bound" << std::endl;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
//glDeleteFramebuffers(1, &fbo);
//VAO
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// Vertex Attributes
glEnableVertexAttribArray(0); //pozicija
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(0));
glEnableVertexAttribArray(1); //boja
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(2); //boja
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(6 * sizeof(GLfloat)));
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &texture);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
std::string path = "C:\\Projects\\Myproj\\container.jpg";
bool success = loadTexture(path,texture_data,&tex_width, &tex_height, &nchannels);
if (success)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex_width, tex_height, 0, GL_RGB, GL_UNSIGNED_BYTE, texture_data);
glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
std::cout << "ERROR::STBI::FAILED TO LOAD TEXTURE" << std::endl;
}
stbi_image_free(texture_data);
int success_f;
char infoLog[512];
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
getShaderStatus(vertexShader, &success_f, infoLog);
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
getShaderStatus(fragmentShader, &success_f, infoLog);
ourShader = glCreateProgram();
glAttachShader(ourShader, vertexShader);
glAttachShader(ourShader, fragmentShader);
glLinkProgram(ourShader);
getShaderStatus(ourShader, &success_f, infoLog);
glUseProgram(ourShader);
glUniform1i(glGetUniformLocation(ourShader, "ourTexture"), 0);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
glutMainLoop();
}
VertexШейдер
const char* vertexShaderSource =
"#version 330 core\n"
"layout(location = 0) in vec3 aPos;\n"
"layout(location = 1) in vec3 aColor;\n"
"layout(location = 2) in vec2 aTexCoord;\n"
"out vec3 ourColor;\n"
"out vec2 TexCoord;\n"
"void main()\n"
"{\n"
"gl_Position = vec4(aPos, 1.0);\n"
"ourColor = aColor;\n"
"TexCoord = aTexCoord;\n"
"}\n";
Фрагментный шейдер
const char* fragmentShaderSource =
"#version 330 core\n"
"out vec4 FragColor;\n"
"in vec3 ourColor;\n"
"in vec2 TexCoord;\n"
"uniform sampler2D ourTexture;\n"
"void main()\n"
"{\n"
"FragColor = texture(ourTexture, TexCoord);\n"
"}\n";
Журнал обновлений - решено
- Не нужно glEnable (GL_TEXTURE_2D) при реализациишейдер
Преобразование проекции, вида и модели, перейдите внутрь шейдера, используйте
glm::projection
glm::lookat
Включить атрибуты (цвет, текстура)перед рендерингом
- Freeglut поддержка OpenGL API (> = 3.2)
glutInitContextVersion(3, 3);
glutInitContextProfile(GLUT_CORE_PROFILE);
Окончательный код here: [https://pastebin.com/D8DgPqaT]
Психоделические шейдеры: [https://pastebin.com/vtJ3Cr6i]