Чтобы научиться делать opengl, у меня есть минималистская система сборки и игрушечная программа. Мой makefile выдает следующие команды:
g++ -O1 -std=c++17 -Wall -Wextra -pedantic -c -o main.o main.cpp
g++ main.o -lglfw -lGLEW -lGL -o main
В этом каталоге у меня есть одинокий файл main.cpp. Вопреки многим вопросам здесь, на SO, это действительно работает. Он компилируется и компонуется без проблем. Однако, когда я запускаю программу, она просто отображает цвет фона, который я пишу с помощью glClear
, но не мой тестовый треугольник.
Я проверил, что это не проблема с моим кодом, потому что, если я скомпилирую его с помощью (довольно сложной и раздутой) системы сборки, которую я нашел в учебнике, она, кажется, работает. Однако я хочу понять, как на самом деле создать программу opengl самостоятельно. Я подозреваю, что мне не хватает какой-то библиотеки или чего-то еще, но я ожидаю, что программа вылетит, а не просто (почти) ничего не сделает.
У меня самый новый дебиан.
Как это может быть, что он отлично компилируется и компонуется, но работает некорректно?
Отказ от ответственности: я абсолютно новичок в opengl и оконных приложениях. Я не уверен на 100 %, зачем мне нужен блеск.
Код:
#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
bool install_shader(GLuint where, std::string const& code, GLuint* attach_to) {
GLuint shader_id = glCreateShader(where);
{
auto const p = code.c_str();
glShaderSource(shader_id,1,&p,nullptr); // nullptr indicates null-termination here
}
glCompileShader(shader_id);
GLint out;
glGetShaderiv(shader_id, GL_COMPILE_STATUS, &out);
if (out == GL_FALSE) {
// something went wrong with the shader compilation
glGetShaderiv(shader_id, GL_INFO_LOG_LENGTH, &out);
if (out == 0) {
std::cout << "Unknown Error during shader compilation\n";
} else {
std::string error;
error.resize(out-1);
glGetShaderInfoLog(shader_id, out, nullptr, error.data());
std::cout << "Shader Compilation failed with error: " << error;
}
return false;
} else {
std::cout << "shader(" << int(shader_id) << "@" << int(where) << ") compiled fine\n";
if (attach_to) {
glAttachShader(*attach_to, shader_id);
}
// XXX THE SHADERS SHOULD BE DELETED AFTER LINKING !!!!
// glDeleteShader(shader_id)
return true;
}
}
bool install_program(GLuint program_id) {
glLinkProgram(program_id);
GLint out;
glGetProgramiv(program_id, GL_LINK_STATUS, &out);
if (out == GL_FALSE) {
// something went wrong with the program linking
glGetProgramiv(program_id, GL_INFO_LOG_LENGTH, &out);
if (out == 0) {
std::cout << "Unknown link-Error in shader program\n";
} else {
std::string error;
error.resize(out-1);
glGetProgramInfoLog(program_id, out, nullptr, error.data());
std::cout << "Program linking failed with error: " << error;
}
return false;
} else {
std::cout << "program(" << int(program_id) << ") compiled fine\n";
return true;
}
}
int main() {
if (glfwInit()) {
std::cout << "Initialisation fine\n";
} else {
std::cout << "Initialisation failed\n";
return 1;
}
glfwWindowHint(GLFW_SAMPLES, 4); // 4x antialiasing
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // We want OpenGL 3.3
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
if (GLFWwindow* window = glfwCreateWindow(800,600,"testwindow",nullptr,nullptr)) {
glfwMakeContextCurrent(window);
if (glewInit() == GLEW_OK) {
std::cout << "GLEW also fine\n";
} else {
std::cout << "GLEW says nope!\n";
goto die;
return 2;
}
//std::cout << "Ensure we can capture the escape key being pressed below...\n";
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
/*business*/
// (1) specify the triangle to draw
// An array of 3 vectors which represents 3 vertices
GLfloat g_vertex_buffer_data[] = {
-0.4f, -0.8f, 0.f,
0.4f, -0.8f, 0.f,
0.0f, 0.8f, 0.f,
};
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
GLuint program_id = glCreateProgram();
// (3) vertex shader
std::string vshader_code = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\n";
if (!install_shader(GL_VERTEX_SHADER,vshader_code,&program_id)) {
goto die;
}
std::string fshader_code = "#version 330 core\n"
"out vec3 color;\n"
"\n"
"void main()\n"
"{\n"
" color = vec3(0.9,0.8,0.1);\n"
"}\n";
if (!install_shader(GL_FRAGMENT_SHADER,fshader_code,&program_id)) {
goto die;
}
if (!install_program(program_id)) {
goto die;
}
glClearColor(0.3, 0.5, 0.5, 1.0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
do {
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(program_id);
glEnableVertexAttribArray(0); // this 0 also refes to 'layout (location = 0)' in the vertex shader
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
glVertexAttribPointer(
0, // this refes to 'layout (location = 0)' in the vertex shader
3, // each vertex has 3 coordinates (2d data is also possible)
GL_FLOAT, // coordinates are of type GLfloat (GL_FLOAT)
GL_FALSE, // we don't need the input data to be nomalised,
0, //&g_vertex_buffer_data[3] - &g_vertex_buffer_data[0], // stride
nullptr // offset ptr
);
// Draw the triangle !
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
glfwSwapBuffers(window);
glfwPollEvents();
} // Check if the ESC key was pressed or the window was closed
while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS && glfwWindowShouldClose(window) == 0 );
} else {
std::cout << "Could not create window\n";
}
die:
glfwTerminate();
std::cout << "Terminated\n";
}
I have verified that it's not a problem with my code, because if I compile it with a (quite complex and bloated) build system I found in a tutorial it seems to work.
это не обязательно означает, что код правильный. На самом деле у вас может иметь место какое-то неопределенное поведение, а другая система сборки может иметь другие параметры компиляции или по какой-то другой причине привести к другому расположению памяти, что может привести к тому, что код будет работать правильно, даже если технически это не так. действительный. - person t.niese   schedule 26.12.2019