差分
このページの2つのバージョン間の差分を表示します。
| 次のリビジョン | 前のリビジョン | ||
| youtube:opengl-training-004 [2025/11/03 23:01] – 作成 freemikan | youtube:opengl-training-004 [2025/11/04 12:57] (現在) – [glad/*] Fix wrong URL freemikan | ||
|---|---|---|---|
| 行 1: | 行 1: | ||
| - | 準備中… | + | ====== OpenGLの修行 #4 - ビルド環境の見直し ====== | 
| + | [[https:// | ||
| + | |||
| + | * 第3回からおよそ1年半の期間を経て再開する。 | ||
| + | * 環境の準備を実演するために、Windows(Vista、VirtualBox)でやってきた。 | ||
| + | * 次回からはLinuxでやっていく。 | ||
| + | * その前に、現在の雑なビルド環境に改善を加えておく。 | ||
| + | |||
| + | |||
| + | ===== メイン目標 ===== | ||
| + | CMakeLists.txtに、GLFWのインクルードパスとライブラリパスがベタ書きされているのを直したい。 | ||
| + | |||
| + | |||
| + | ===== メニュー ===== | ||
| + | * (おまけ) GLFWと動的にリンクする (DLLを利用する) | ||
| + | * GLFWをソースからビルドしてインストールする | ||
| + | * システムの任意の場所にインストールされたGLFWを利用する | ||
| + | * (おまけ) GLADをアプリケーションのソースから分離する | ||
| + | |||
| + | |||
| + | ===== (おまけ) GLFWと動的にリンクする (DLLを利用する) ===== | ||
| + | GLFWのWindows向けコンパイル済みバイナリには、DLLも含まれている。 | ||
| + | |||
| + | |||
| + | ===== GLFWをソースからビルドしてインストールする ===== | ||
| + | インストール場所は[[https:// | ||
| + | |||
| + | 例: | ||
| + |   $ cmake -G "MinGW Makefiles" | ||
| + | |||
| + | |||
| + | ===== システムの任意の場所にインストールされたGLFWを利用する ===== | ||
| + | [[https:// | ||
| + | |||
| + | 例: | ||
| + |   $ cmake -G "MinGW Makefiles" | ||
| + | |||
| + | |||
| + | ===== (おまけ) GLADをアプリケーションのソースから分離する ===== | ||
| + | [[https:// | ||
| + | |||
| + | |||
| + | ====== ソースコード ====== | ||
| + | {{ : | ||
| + | |||
| + | |||
| + | ===== プロジェクトレイアウト ===== | ||
| + | |||
| + | HelloTriangle_2 | ||
| + | ├── CMakeLists.txt | ||
| + | ├── glad | ||
| + | │ ├── CMakeLists.txt | ||
| + | │ ├── include | ||
| + | │ │ ├── KHR | ||
| + | │ │ │ └── khrplatform.h | ||
| + | │ │ └── glad | ||
| + |   │   │    | ||
| + | │ └── src | ||
| + |   │    | ||
| + | ├── shaders | ||
| + | │ ├── hello_triangle.frag | ||
| + | │ └── hello_triangle.vert | ||
| + | └── src | ||
| + | └── main.cpp | ||
| + | |||
| + | ===== CMakeLists.txt ===== | ||
| + | <file cmake> | ||
| + | cmake_minimum_required(VERSION 3.13 FATAL_ERROR) | ||
| + | |||
| + | project(HelloTriangle VERSION 0.1.0 LANGUAGES CXX) | ||
| + | |||
| + | set(CMAKE_CXX_STANDARD 20) | ||
| + | set(CMAKE_CXX_STANDARD_REQUIRED TRUE) | ||
| + | |||
| + | find_package(glfw3 REQUIRED) | ||
| + | |||
| + | add_subdirectory(glad) | ||
| + | |||
| + | add_executable(${PROJECT_NAME} src/ | ||
| + | |||
| + | target_link_libraries(${PROJECT_NAME} glad glfw) | ||
| + | </ | ||
| + | |||
| + | ===== glad/ | ||
| + | <file cmake> | ||
| + | enable_language(C) | ||
| + | |||
| + | add_library(glad OBJECT src/ | ||
| + | |||
| + | target_include_directories( | ||
| + | glad | ||
| + | PUBLIC | ||
| + |         ${CMAKE_CURRENT_SOURCE_DIR}/ | ||
| + | ) | ||
| + | </ | ||
| + | |||
| + | |||
| + | ===== glad/* ===== | ||
| + | [[https:// | ||
| + | |||
| + | |||
| + | ===== shaders/ | ||
| + | |||
| + | <file glsl> | ||
| + | #version 410 core | ||
| + | |||
| + | in vec4 vert_color; | ||
| + | out vec4 color; | ||
| + | |||
| + | void main(void) { | ||
| + | // color = vec4(1.0, 0.0, 0.0, 1.0); | ||
| + |     color = vert_color; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ===== shaders/ | ||
| + | |||
| + | <file glsl> | ||
| + | #version 410 core | ||
| + | |||
| + | out vec4 vert_color; | ||
| + | |||
| + | void main(void) { | ||
| + |     const vec4 positions[3] = vec4[3](vec4(-0.5, | ||
| + | vec4( 0.5, -0.5, 1.0, 1.0), | ||
| + | vec4( 0.5, 0.5, 1.0, 1.0)); | ||
| + |     gl_Position = positions[gl_VertexID]; | ||
| + | |||
| + |     const vec4 colors[3] = vec4[3](vec4(1.0, | ||
| + |                                     | ||
| + |                                     | ||
| + |     vert_color = colors[gl_VertexID]; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ===== src/ | ||
| + | <file cpp> | ||
| + | #include < | ||
| + | // glad.h must be included before glfw3.h | ||
| + | #include < | ||
| + | |||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | |||
| + | namespace fs = std:: | ||
| + | |||
| + | std:: | ||
| + |     if (std:: | ||
| + |         return std:: | ||
| + | } else { | ||
| + |         return std:: | ||
| + | } | ||
| + | } | ||
| + | |||
| + | void print_shader_compilation_errors(GLuint shader, fs::path const &path) { | ||
| + |     GLint log_length; | ||
| + |     glGetShaderiv(shader, | ||
| + | if (log_length > 0) { | ||
| + |         std:: | ||
| + |         glGetShaderInfoLog(shader, | ||
| + |         std::cerr << path.string() << ':' | ||
| + | } | ||
| + | } | ||
| + | |||
| + | std:: | ||
| + |     if (auto shader_source = read_to_string(path); | ||
| + |         GLuint shader = glCreateShader(type); | ||
| + |         GLchar const *srcs[] = { shader_source-> | ||
| + |         glShaderSource(shader, | ||
| + |         glCompileShader(shader); | ||
| + | |||
| + | GLint success; | ||
| + |         glGetShaderiv(shader, | ||
| + | if (success) { | ||
| + | return shader; | ||
| + | } else { | ||
| + |             print_shader_compilation_errors(shader, | ||
| + |             return std:: | ||
| + | } | ||
| + | } else { | ||
| + |         std::cerr << " | ||
| + |         return std:: | ||
| + | } | ||
| + | } | ||
| + | |||
| + | std:: | ||
| + |     GLuint program = glCreateProgram(); | ||
| + |     glAttachShader(program, | ||
| + |     glAttachShader(program, | ||
| + |     glLinkProgram(program); | ||
| + | |||
| + | GLint success; | ||
| + |     glGetProgramiv(program, | ||
| + | if (success) { | ||
| + | return program; | ||
| + | } else { | ||
| + |         return std:: | ||
| + | } | ||
| + | } | ||
| + | |||
| + | std:: | ||
| + |     auto vert = compile_shader(" | ||
| + |     auto frag = compile_shader(" | ||
| + | |||
| + | auto program = vert && frag ? | ||
| + |         link_shaders(*vert, | ||
| + | |||
| + | if (vert) { | ||
| + |         glDeleteShader(*vert); | ||
| + | } | ||
| + | if (frag) { | ||
| + |         glDeleteShader(*frag); | ||
| + | } | ||
| + | |||
| + | return program; | ||
| + | } | ||
| + | |||
| + | int main() { | ||
| + |     glfwInit(); | ||
| + |     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, | ||
| + |     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, | ||
| + |     glfwWindowHint(GLFW_OPENGL_PROFILE, | ||
| + |     glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, | ||
| + | |||
| + |     GLFWwindow *window = glfwCreateWindow(800, | ||
| + | if (!window) { | ||
| + |         std::cerr << "GLFW failed to create window\n" | ||
| + | return 1; | ||
| + | } | ||
| + | |||
| + |     glfwMakeContextCurrent(window); | ||
| + | |||
| + | if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { | ||
| + |         std::cerr << "glad failed to initialize OpenGL context\n"; | ||
| + | return 1; | ||
| + | } | ||
| + | |||
| + |     auto *ver_gl = glGetString(GL_VERSION); | ||
| + |     std::cout << " | ||
| + | |||
| + |     auto shader_program = shader_program_setup(); | ||
| + | if (!shader_program) { | ||
| + |         std::cerr << " | ||
| + | return 1; | ||
| + | } | ||
| + | |||
| + | GLuint VAO; | ||
| + |     glGenVertexArrays(1, | ||
| + |     glBindVertexArray(VAO); | ||
| + | |||
| + | while (!glfwWindowShouldClose(window)) { | ||
| + |         glClearColor(0.0, | ||
| + |         glClear(GL_COLOR_BUFFER_BIT); | ||
| + | |||
| + |         glUseProgram(*shader_program); | ||
| + |         glDrawArrays(GL_TRIANGLES, | ||
| + | |||
| + |         glfwSwapBuffers(window); | ||
| + |         glfwPollEvents(); | ||
| + | } | ||
| + | |||
| + |     std::cerr << " | ||
| + | } | ||
| + | </ | ||
