Hello-Window.html (44092B)
1 <!DOCTYPE html> 2 <html lang="ja"> 3 <head> 4 <meta charset="utf-8"/> 5 <title>LearnOpenGL</title> 6 <link rel="shortcut icon" type="image/ico" href="/favicon.ico" /> 7 <link rel="stylesheet" href="../static/style.css" /> 8 <script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"> </script> 9 <script src="/static/functions.js"></script> 10 </head> 11 <body> 12 <nav> 13 <ol> 14 <li id="Introduction"> 15 <a href="https://learnopengl.com/Introduction">はじめに</a> 16 </li> 17 <li id="Getting-started"> 18 <span class="closed">入門</span> 19 <ol> 20 <li id="Getting-started/OpenGL"> 21 <a href="https://learnopengl.com/Getting-started/OpenGL">OpenGL </a> 22 </li> 23 <li id="Getting-started/Creating-a-window"> 24 <a href="https://learnopengl.com/Getting-started/Creating-a-window">ウィンドウの作成</a> 25 </li> 26 <li id="Getting-started/Hello-Window"> 27 <a href="https://learnopengl.com/Getting-started/Hello-Window">最初のウィンドウ</a> 28 </li> 29 <li id="Getting-started/Hello-Triangle"> 30 <a href="https://learnopengl.com/Getting-started/Hello-Triangle">最初の三角形</a> 31 </li> 32 <li id="Getting-started/Shaders"> 33 <a href="https://learnopengl.com/Getting-started/Shaders">シェーダー</a> 34 </li> 35 <li id="Getting-started/Textures"> 36 <a href="https://learnopengl.com/Getting-started/Textures">テクスチャ</a> 37 </li> 38 <li id="Getting-started/Transformations"> 39 <a href="https://learnopengl.com/Getting-started/Transformations">座標変換</a> 40 </li> 41 <li id="Getting-started/Coordinate-Systems"> 42 <a href="https://learnopengl.com/Getting-started/Coordinate-Systems">座標系</a> 43 </li> 44 <li id="Getting-started/Camera"> 45 <a href="https://learnopengl.com/Getting-started/Camera">カメラ</a> 46 </li> 47 <li id="Getting-started/Review"> 48 <a href="https://learnopengl.com/Getting-started/Review">まとめ</a> 49 </li> 50 </ol> 51 </li> 52 <li id="Lighting"> 53 <span class="closed">Lighting </span> 54 <ol> 55 <li id="Lighting/Colors"> 56 <a href="https://learnopengl.com/Lighting/Colors">Colors </a> 57 </li> 58 <li id="Lighting/Basic-Lighting"> 59 <a href="https://learnopengl.com/Lighting/Basic-Lighting">Basic Lighting </a> 60 </li> 61 <li id="Lighting/Materials"> 62 <a href="https://learnopengl.com/Lighting/Materials">Materials </a> 63 </li> 64 <li id="Lighting/Lighting-maps"> 65 <a href="https://learnopengl.com/Lighting/Lighting-maps">Lighting maps </a> 66 </li> 67 <li id="Lighting/Light-casters"> 68 <a href="https://learnopengl.com/Lighting/Light-casters">Light casters </a> 69 </li> 70 <li id="Lighting/Multiple-lights"> 71 <a href="https://learnopengl.com/Lighting/Multiple-lights">Multiple lights </a> 72 </li> 73 <li id="Lighting/Review"> 74 <a href="https://learnopengl.com/Lighting/Review">Review </a> 75 </li> 76 </ol> 77 </li> 78 <li id="Model-Loading"> 79 <span class="closed">Model Loading </span> 80 <ol> 81 <li id="Model-Loading/Assimp"> 82 <a href="https://learnopengl.com/Model-Loading/Assimp">Assimp </a> 83 </li> 84 <li id="Model-Loading/Mesh"> 85 <a href="https://learnopengl.com/Model-Loading/Mesh">Mesh </a> 86 </li> 87 <li id="Model-Loading/Model"> 88 <a href="https://learnopengl.com/Model-Loading/Model">Model </a> 89 </li> 90 </ol> 91 </li> 92 <li id="Advanced-OpenGL"> 93 <span class="closed">Advanced OpenGL </span> 94 <ol> 95 <li id="Advanced-OpenGL/Depth-testing"> 96 <a href="https://learnopengl.com/Advanced-OpenGL/Depth-testing">Depth testing </a> 97 </li> 98 <li id="Advanced-OpenGL/Stencil-testing"> 99 <a href="https://learnopengl.com/Advanced-OpenGL/Stencil-testing">Stencil testing </a> 100 </li> 101 <li id="Advanced-OpenGL/Blending"> 102 <a href="https://learnopengl.com/Advanced-OpenGL/Blending">Blending </a> 103 </li> 104 <li id="Advanced-OpenGL/Face-culling"> 105 <a href="https://learnopengl.cm/Advanced-OpenGL/Face-culling">Face culling </a> 106 </li> 107 <li id="Advanced-OpenGL/Framebuffers"> 108 <a href="https://learnopengl.com/Advanced-OpenGL/Framebuffers">Framebuffers </a> 109 </li> 110 <li id="Advanced-OpenGL/Cubemaps"> 111 <a href="https://learnopengl.com/Advanced-OpenGL/Cubemaps">Cubemaps </a> 112 </li> 113 <li id="Advanced-OpenGL/Advanced-Data"> 114 <a href="https://learnopengl.com/Advanced-OpenGL/Advanced-Data">Advanced Data </a> 115 </li> 116 <li id="Advanced-OpenGL/Advanced-GLSL"> 117 <a href="https://learnopengl.com/Advanced-OpenGL/Advanced-GLSL">Advanced GLSL </a> 118 </li> 119 <li id="Advanced-OpenGL/Geometry-Shader"> 120 <a href="https://learnopengl.com/Advanced-OpenGL/Geometry-Shader">Geometry Shader </a> 121 </li> 122 <li id="Advanced-OpenGL/Instancing"> 123 <a href="https://learnopengl.com/Advanced-OpenGL/Instancing">Instancing </a> 124 </li> 125 <li id="Advanced-OpenGL/Anti-Aliasing"> 126 <a href="https://learnopengl.com/Advanced-OpenGL/Anti-Aliasing">Anti Aliasing </a> 127 </li> 128 </ol> 129 </li> 130 <li id="Advanced-Lighting"> 131 <span class="closed">Advanced Lighting </span> 132 <ol> 133 <li id="Advanced-Lighting/Advanced-Lighting"> 134 <a href="https://learnopengl.com/Advanced-Lighting/Advanced-Lighting">Advanced Lighting </a> 135 </li> 136 <li id="Advanced-Lighting/Gamma-Correction"> 137 <a href="https://learnopengl.com/Advanced-Lighting/Gamma-Correction">Gamma Correction </a> 138 </li> 139 <li id="Advanced-Lighting/Shadows"> 140 <span class="closed">Shadows </span> 141 <ol> 142 <li id="Advanced-Lighting/Shadows/Shadow-Mapping"> 143 <a href="https://learnopengl.com/Advanced-Lighting/Shadows/Shadow-Mapping">Shadow Mapping </a> 144 </li> 145 <li id="Advanced-Lighting/Shadows/Point-Shadows"> 146 <a href="https://learnopengl.com/Advanced-Lighting/Shadows/Point-Shadows">Point Shadows </a> 147 </li> 148 </ol> 149 </li> 150 <li id="Advanced-Lighting/Normal-Mapping"> 151 <a href="https://learnopengl.com/Advanced-Lighting/Normal-Mapping">Normal Mapping </a> 152 </li> 153 <li id="Advanced-Lighting/Parallax-Mapping"> 154 <a href="https://learnopengl.com/Advanced-Lighting/Parallax-Mapping">Parallax Mapping </a> 155 </li> 156 <li id="Advanced-Lighting/HDR"> 157 <a href="https://learnopengl.com/Advanced-Lighting/HDR">HDR </a> 158 </li> 159 <li id="Advanced-Lighting/Bloom"> 160 <a href="https://learnopengl.com/Advanced-Lighting/Bloom">Bloom </a> 161 </li> 162 <li id="Advanced-Lighting/Deferred-Shading"> 163 <a href="https://learnopengl.com/Advanced-Lighting/Deferred-Shading">Deferred Shading </a> 164 </li> 165 <li id="Advanced-Lighting/SSAO"> 166 <a href="https://learnopengl.com/Advanced-Lighting/SSAO">SSAO </a> 167 </li> 168 </ol> 169 </li> 170 <li id="PBR"> 171 <span class="closed">PBR </span> 172 <ol> 173 <li id="PBR/Theory"> 174 <a href="https://learnopengl.com/PBR/Theory">Theory </a> 175 </li> 176 <li id="PBR/Lighting"> 177 <a href="https://learnopengl.com/PBR/Lighting">Lighting </a> 178 </li> 179 <li id="PBR/IBL"> 180 <span class="closed">IBL </span> 181 <ol> 182 <li id="PBR/IBL/Diffuse-irradiance"> 183 <a href="https://learnopengl.com/PBR/IBL/Diffuse-irradiance">Diffuse irradiance </a> 184 </li> 185 <li id="PBR/IBL/Specular-IBL"> 186 <a href="https://learnopengl.com/PBR/IBL/Specular-IBL">Specular IBL </a> 187 </li> 188 </ol> 189 </li> 190 </ol> 191 </li> 192 <li id="In-Practice"> 193 <span class="closed">In Practice </span> 194 <ol> 195 <li id="In-Practice/Debugging"> 196 <a href="https://learnopengl.com/In-Practice/Debugging">Debugging </a> 197 </li> 198 <li id="In-Practice/Text-Rendering"> 199 <a href="https://learnopengl.com/In-Practice/Text-Rendering">Text Rendering </a> 200 </li> 201 <li id="In-Practice/2D-Game"> 202 <span class="closed">2D Game </span> 203 <ol> 204 <li id="In-Practice/2D-Game/Breakout"> 205 <a href="https://learnopengl.com/In-Practice/2D-Game/Breakout">Breakout </a> 206 </li> 207 <li id="In-Practice/2D-Game/Setting-up"> 208 <a href="https://learnopengl.com/In-Practice/2D-Game/Setting-up">Setting up </a> 209 </li> 210 <li id="In-Practice/2D-Game/Rendering-Sprites"> 211 <a href="https://learnopengl.com/In-Practice/2D-Game/Rendering-Sprites">Rendering Sprites </a> 212 </li> 213 <li id="In-Practice/2D-Game/Levels"> 214 <a href="https://learnopengl.com/In-Practice/2D-Game/Levels">Levels </a> 215 </li> 216 <li id="In-Practice/2D-Game/Collisions"> 217 <span class="closed">Collisions </span> 218 <ol> 219 <li id="In-Practice/2D-Game/Collisions/Ball"> 220 <a href="https://learnopengl.com/In-Practice/2D-Game/Collisions/Ball">Ball </a> 221 </li> 222 <li id="In-Practice/2D-Game/Collisions/Collision-detection"> 223 <a href="https://learnopengl.com/In-Practice/2D-Game/Collisions/Collision-detection">Collision detection </a> 224 </li> 225 <li id="In-Practice/2D-Game/Collisions/Collision-resolution"> 226 <a href="https://learnopengl.com/In-Practice/2D-Game/Collisions/Collision-resolution">Collision resolution </a> 227 </li> 228 </ol> 229 </li> 230 <li id="In-Practice/2D-Game/Particles"> 231 <a href="https://learnopengl.com/In-Practice/2D-Game/Particles">Particles </a> 232 </li> 233 <li id="In-Practice/2D-Game/Postprocessing"> 234 <a href="https://learnopengl.com/In-Practice/2D-Game/Postprocessing">Postprocessing </a> 235 </li> 236 <li id="In-Practice/2D-Game/Powerups"> 237 <a href="https://learnopengl.com/In-Practice/2D-Game/Powerups">Powerups </a> 238 </li> 239 <li id="In-Practice/2D-Game/Audio"> 240 <a href="https://learnopengl.com/In-Practice/2D-Game/Audio">Audio </a> 241 </li> 242 <li id="In-Practice/2D-Game/Render-text"> 243 <a href="https://learnopengl.com/In-Practice/2D-Game/Render-text">Render text </a> 244 </li> 245 <li id="In-Practice/2D-Game/Final-thoughts"> 246 <a href="https://learnopengl.com/In-Practice/2D-Game/Final-thoughts">Final thoughts </a> 247 </li> 248 </ol> 249 </li> 250 </ol> 251 </li> 252 <li id="Guest-Articles"> 253 <span class="closed">Guest Articles </span> 254 <ol> 255 <li id="Guest-Articles/How-to-publish"> 256 <a href="https://learnopengl.com/Guest-Articles/How-to-publish">How to publish </a> 257 </li> 258 <li id="Guest-Articles/2020"> 259 <span class="closed">2020 </span> 260 <ol> 261 <li id="Guest-Articles/2020/OIT"> 262 <span class="closed">OIT </span> 263 <ol> 264 <li id="Guest-Articles/2020/OIT/Introduction"> 265 <a href="https://learnopengl.com/Guest-Articles/2020/OIT/Introduction">Introduction </a> 266 </li> 267 <li id="Guest-Articles/2020/OIT/Weighted-Blended"> 268 <a href="https://learnopengl.com/Guest-Articles/2020/OIT/Weighted-Blended">Weighted Blended </a> 269 </li> 270 </ol> 271 </li> 272 <li id="Guest-Articles/2020/Skeletal-Animation"> 273 <a href="https://learnopengl.com/Guest-Articles/2020/Skeletal-Animation">Skeletal Animation </a> 274 </li> 275 </ol> 276 </li> 277 <li id="Guest-Articles/2021"> 278 <span class="closed">2021 </span> 279 <ol> 280 <li id="Guest-Articles/2021/CSM"> 281 <a href="https://learnopengl.com/Guest-Articles/2021/CSM">CSM </a> 282 </li> 283 <li id="Guest-Articles/2021/Scene"> 284 <span class="closed">Scene </span> 285 <ol> 286 <li id="Guest-Articles/2021/Scene/Scene-Graph"> 287 <a href="https://learnopengl.com/Guest-Articles/2021/Scene/Scene-Graph">Scene Graph </a> 288 </li> 289 <li id="Guest-Articles/2021/Scene/Frustum-Culling"> 290 <a href="https://learnopengl.com/Guest-Articles/2021/Scene/Frustum-Culling">Frustum Culling </a> 291 </li> 292 </ol> 293 </li> 294 <li id="Guest-Articles/2021/Tessellation"> 295 <span class="closed">Tessellation </span> 296 <ol> 297 <li id="Guest-Articles/2021/Tessellation/Height-map"> 298 <a href="https://learnopengl.com/Guest-Articles/2021/Tessellation/Height-map">Height map </a> 299 </li> 300 </ol> 301 </li> 302 </ol> 303 </li> 304 </ol> 305 </li> 306 <li id="Code-repository"> 307 <a href="https://learnopengl.com/Code-repository">Code repository </a> 308 </li> 309 <li id="Translations"> 310 <a href="https://learnopengl.com/Translations">Translations </a> 311 </li> 312 <li id="About"> 313 <a href="https://learnopengl.com/About">About </a> 314 </li> 315 </ol> 316 </nav> 317 <main> 318 <h1 id="content-title">Hello Window</h1> 319 <h1 id="content-title">はじめてのウィンドウ</h1> 320 <h1 id="content-url" style='display:none;'>Getting-started/Hello-Window</h1> 321 <p> 322 Let's see if we can get GLFW up and running. First, create a <code>.cpp</code> file and add the following includes to the top of your newly created file. 323 GLFWを立ち上げ実行できるかどうか確認しましょう。はじめに<code>.cpp</code>ファイルを作成し、一番上に以下のインクルードディレクティブを書いてください: 324 </p> 325 326 <pre><code> 327 #include <glad/glad.h> 328 #include <GLFW/glfw3.h> 329 </code></pre>。 330 331 <warning> 332 Be sure to include GLAD before GLFW. The include file for GLAD includes the required OpenGL headers behind the scenes (like <code>GL/gl.h</code>) so be sure to include GLAD before other header files that require OpenGL (like GLFW). 333 必ずGLADをGLFWより前にインクルードしてください。GLADをインクルードすると、必要なOpenGLのヘッダーファイルを一緒にインクルードしてくれます(たとえば<code>GL/gl.h</code>のようなものです)。そのためGLFWのようなOpenGLを必要とするヘッダーのまえに、GLADをインクルードする必要があるのです。 334 </warning> 335 336 <p> 337 Next, we create the <fun>main</fun> function where we will instantiate the GLFW window: 338 続いて<fun>main</fun>関数を作成し、GLFWをインスタンス化します: 339 </p> 340 341 <pre><code> 342 int main() 343 { 344 <function id='17'>glfwInit</function>(); 345 <function id='18'>glfwWindowHint</function>(GLFW_CONTEXT_VERSION_MAJOR, 3); 346 <function id='18'>glfwWindowHint</function>(GLFW_CONTEXT_VERSION_MINOR, 3); 347 <function id='18'>glfwWindowHint</function>(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 348 //<function id='18'>glfwWindowHint</function>(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); 349 350 return 0; 351 } 352 </code></pre>。 353 354 <p> 355 In the main function we first initialize GLFW with <fun><function id='17'>glfwInit</function></fun>, after which we can configure GLFW using <fun><function id='18'>glfwWindowHint</function></fun>. The first argument of <fun><function id='18'>glfwWindowHint</function></fun> tells us what option we want to configure, where we can select the option from a large enum of possible options prefixed with <code>GLFW_</code>. The second argument is an integer that sets the value of our option. A list of all the possible options and its corresponding values can be found at <a href="http://www.glfw.org/docs/latest/window.html#window_hints" target="_blank">GLFW's window handling</a> documentation. If you try to run the application now and it gives a lot of <em>undefined reference</em> errors it means you didn't successfully link the GLFW library. 356 main関数のはじめに<fun><function id='17'>glfwInit</function></fun>を使ってGLFWを初期化します。続いて<fun><function id='18'>glfwWindowHint</function></fun>によりGLFWの設定を行います。<fun><function id='18'>glfwWindowHint</function></fun>のひとつめの変数は設定したい項目で、頭に<code>GLFW_</code>がついた大きなenumのなかから選べます。ふたつめの変数は選んだオプションを設定する整数です。利用可能なオプションと対応する整数値は<a href="http://www.glfw.org/docs/latest/window.html#window_hints" target="_blank">GLFW's window handling</a>において確認できます。この時点でアプリケーションを実行して大量の<em>undefined reference</em>がでた場合、GLFWライブラリをうまくリンクできていないということです。 357 </p> 358 359 <p> 360 Since the focus of this book is on OpenGL version 3.3 we'd like to tell GLFW that 3.3 is the OpenGL version we want to use. This way GLFW can make the proper arrangements when creating the OpenGL context. This ensures that when a user does not have the proper OpenGL version GLFW fails to run. We set the major and minor version both to <code>3</code>. We also tell GLFW we want to explicitly use the core-profile. Telling GLFW we want to use the core-profile means we'll get access to a smaller subset of OpenGL features without backwards-compatible features we no longer need. Note that on Mac OS X you need to add <code><function id='18'>glfwWindowHint</function>(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);</code> to your initialization code for it to work. 361 われわれはOpenGLのversion 3.3を利用したいので、GLFWにそのことを伝えます。こうすることで、OpenGLコンテクストを作成するにあたりGLFWが適切な変数を作成できるようになります。また、ユーザーのコンピュータにOpenGLの適切なバージョンが入っていない場合、GLFWの実行が失敗することが保証されます。メジャーバージョンとマイナーバージョンの両方を3に設定しましょう。さらに、core-profileを利用することを明記します。こうすることでわれわれには必要のない下位互換性を捨て、OpenGLをコンパクトに利用できます。あなたがMac OS Xを利用している場合、<code><function id='18'>glfwWindowHint</function>(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);</code>を追加する必要があります。 362 </p> 363 364 <note> 365 Make sure you have OpenGL versions 3.3 or higher installed on your system/hardware otherwise the application will crash or display undefined behavior. To find the OpenGL version on your machine either call <strong>glxinfo</strong> on Linux machines or use a utility like the <a href="http://download.cnet.com/OpenGL-Extensions-Viewer/3000-18487_4-34442.html" target="_blank">OpenGL Extension Viewer</a> for Windows. If your supported version is lower try to check if your video card supports OpenGL 3.3+ (otherwise it's really old) and/or update your drivers. 366 あなたのシステム/ハードウェアにOpenGLバージョン3.3より新しいものがインストールされていることを確認してください。さもなければアプリケーションがクラッシュしたり、不定義の動作をすることがあります。コンピュータにインストールされたOpenGLのバージョンを調べるには、Linuxにおいては<strong>glxinfo</strong>を、Windowsにおいては<a href="http://download.cnet.com/OpenGL-Extensions-Viewer/3000-18487_4-34442.html" target="_blank">OpenGL Extension Viewer</a>のようなものを利用してください。OpenGLのバージョンが古い場合、ビデオカードがOpenGLの3.3以上をサポートしていないか確認し、ドライバをアップデートしてください(サポートしていないビデオカードは相当古いです)。 367 </note> 368 369 <p> 370 Next we're required to create a window object. This window object holds all the windowing data and is required by most of GLFW's other functions. 371 次はウィンドウオブジェクトの作成です。ウィンドウオブジェクトはウィンドウにかかるすべてのデータを保持しており、GLFWのほとんどの関数を利用するうえで必要となります。 372 </p> 373 374 <pre><code> 375 GLFWwindow* window = <function id='20'>glfwCreateWindow</function>(800, 600, "LearnOpenGL", NULL, NULL); 376 if (window == NULL) 377 { 378 std::cout << "Failed to create GLFW window" << std::endl; 379 <function id='25'>glfwTerminate</function>(); 380 return -1; 381 } 382 <function id='19'>glfwMakeContextCurrent</function>(window); 383 </code></pre> 384 385 <p> 386 The <fun><function id='20'>glfwCreateWindow</function></fun> function requires the window width and height as its first two arguments respectively. The third argument allows us to create a name for the window; for now we call it <code>"LearnOpenGL"</code> but you're allowed to name it however you like. We can ignore the last 2 parameters. The function returns a <fun>GLFWwindow</fun> object that we'll later need for other GLFW operations. After that we tell GLFW to make the context of our window the main context on the current thread. 387 <fun><function id='20'>glfwCreateWindow</function></fun>関数はウィンドウの幅と高さをそれぞれ第一および第二引数としてとります。三番目の引数はウィンドウの名前です。ここでは<code>"LearnOpenGL"</code>としていますが、あなたの好きな名前でかまいません。あとのふたつの引数はここでは無視します。この関数は<fun>GLFWwindow</fun>オブジェクトを返します。このオブジェクトはGLFWでほかの操作をするときに必要なものです。ウィンドウオブジェクトを作成したあとは、コンテクストの作成です。先程作ったウィンドウのコンテクストをこれから利用するコンテクストとして宣言します。 388 </p> 389 390 <h2>GLAD</h2> 391 <p> 392 In the previous chapter we mentioned that GLAD manages function pointers for OpenGL so we want to initialize GLAD before we call any OpenGL function: 393 前の章でGLADが関数のポインタを制御するといいました。OpenGLの関数を呼びだすまえにGLADを初期化する方法を見ていきましょう。 394 </p> 395 396 <pre><code> 397 if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) 398 { 399 std::cout << "Failed to initialize GLAD" << std::endl; 400 return -1; 401 } 402 </code></pre> 403 404 <p> 405 We pass GLAD the function to load the address of the OpenGL function pointers which is OS-specific. GLFW gives us <fun>glfwGetProcAddress</fun> that defines the correct function based on which OS we're compiling for. 406 GLADを上記の関数で処理することにより、OpenGLの関数へのポインタのアドレスをロードします。GLFWは<fun>glfwGetProcAddress</fun>により利用しているOSにあった関数を正確に定義します。 407 </p> 408 409 <h2>Viewport</h2> 410 <h2>ビューポート</h2> 411 <p> 412 Before we can start rendering we have to do one last thing. We have to tell OpenGL the size of the rendering window so OpenGL knows how we want to display the data and coordinates with respect to the window. We can set those <em>dimensions</em> via the <fun><function id='22'>glViewport</function></fun> function: 413 描画をはじめる前に、もうひとつしておかなければならないことがあります。OpenGLに描画するウィンドウのサイズを伝え、ウィンドウ中にデータと座標をどのように表示させるかを決定することです。<fun><function id='22'>glViewport</function></fun>により画面の<em>寸法</em>を設定できます: 414 </p> 415 416 <pre class="cpp"><code> 417 <function id='22'>glViewport</function>(0, 0, 800, 600); 418 </code></pre> 419 420 <p> 421 The first two parameters of <fun><function id='22'>glViewport</function></fun> set the location of the lower left corner of the window. The third and fourth parameter set the width and height of the rendering window in pixels, which we set equal to GLFW's window size. 422 <fun><function id='22'>glViewport</function></fun>のはじめのふたつの引数はウィンドウ左下の角の場所です。あとのふたつの引数で、ウィンドの幅と高さをピクセル単位で指定します。ここではGLFWのウィンドウと同じサイズにしましょう。 423 </p> 424 425 <p> 426 We could actually set the viewport dimensions at values smaller than GLFW's dimensions; then all the OpenGL rendering would be displayed in a smaller window and we could for example display other elements outside the OpenGL viewport. 427 ビューポートの寸法をGLFWのものより小さくすることも可能です。そうすることで、OpenGLによる描画がウィンドウより小さくなり、あいたところに他のものを配置したりすることも可能になります。 428 </p> 429 430 <note> 431 Behind the scenes OpenGL uses the data specified via <fun><function id='22'>glViewport</function></fun> to transform the 2D coordinates it processed to coordinates on your screen. For example, a processed point of location <code>(-0.5,0.5)</code> would (as its final transformation) be mapped to <code>(200,450)</code> in screen coordinates. Note that processed coordinates in OpenGL are between -1 and 1 so we effectively map from the range (-1 to 1) to (0, 800) and (0, 600). 432 OpenGLは、処理した二次元の座標をスクリーンの座標に変換するために、<fun><function id='22'>glViewport</function></fun>を通してあたえられたデータを利用します。たとえばOpenGLの処理により座標が<code>(-0.5,0.5)</code>になった点は、スクリーン上の<code>(200, 450)</code>に対応します。OpenGLで処理された座標は-1と1の間におさまることに留意してください。この縦横(-1, 1)の区間はそれぞれ(0, 800), (0, 600)に対応しています。 433 </note> 434 435 <p> 436 However, the moment a user resizes the window the viewport should be adjusted as well. We can register a callback function on the window that gets called each time the window is resized. This resize callback function has the following prototype: 437 しかしユーザーがウィンドウのサイズを変更した場合、それにあわせてビューポートも変化するべきです。そのためにコールバック関数をウィンドウに登録して、ウィンドウサイズが変更されるたびに呼ばれるようにできます。次にあげるのがサイズ変更のコールバック関数のプロトタイプです: 438 </p> 439 440 <pre><code> 441 void framebuffer_size_callback(GLFWwindow* window, int width, int height); 442 </code></pre> 443 444 <p> 445 The framebuffer size function takes a <fun>GLFWwindow</fun> as its first argument and two integers indicating the new window dimensions. Whenever the window changes in size, GLFW calls this function and fills in the proper arguments for you to process. 446 この関数は第一引数に<fun>GLFWwindow</fun>をとり、変更されたウィンドウの寸法を第二、第三引数にとります。ウィンドウサイズが変更されれば、GLFWがこの関数を呼び出し、処理に必要な変数を渡します。 447 </p> 448 449 <pre><code> 450 void framebuffer_size_callback(GLFWwindow* window, int width, int height) 451 { 452 <function id='22'>glViewport</function>(0, 0, width, height); 453 } 454 </code></pre> 455 456 <p> 457 We do have to tell GLFW we want to call this function on every window resize by registering it: 458 ウィンドウサイズが変更されるたびにこの関数が呼び出されるよう、以下の通り登録します: 459 </p> 460 461 <pre><code> 462 glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); 463 </code></pre> 464 465 <p> 466 When the window is first displayed <fun>framebuffer_size_callback</fun> gets called as well with the resulting window dimensions. For retina displays <var>width</var> and <var>height</var> will end up significantly higher than the original input values. 467 ウィンドウが初めて表示されたときも、<fun>framebuffer_size_callback</fun>は呼ばれ、実際に表示されたウィンドウの寸法が渡されます。レティナディスプレイでは<var>width</var>や<var>height</var>はもともと入力していた値よりもかなり大きくなります。 468 </p> 469 470 <p> 471 There are many callbacks functions we can set to register our own functions. For example, we can make a callback function to process joystick input changes, process error messages etc. We register the callback functions after we've created the window and before the render loop is initiated. 472 このほかにもコールバック関数として登録できるものはたくさんあります。ジョイスティックの入力値を処理する関数や、エラーメッセージを処理する関数等です。コールバック関数はウィンドウを作成した後、描画ループが始まる前に登録します。 473 </p> 474 475 <h1>Ready your engines</h1> 476 <h1>エンジンの準備</h1> 477 <p> 478 We don't want the application to draw a single image and then immediately quit and close the window. We want the application to keep drawing images and handling user input until the program has been explicitly told to stop. For this reason we have to create a while loop, that we now call the <def>render loop</def>, that keeps on running until we tell GLFW to stop. The following code shows a very simple render loop: 479 アプリケーションがある画像を表示したあとすぐに終了してウィンドウを閉じてしまってはおもしろくありません。プログラムが終了するまで映像を出力し続け、ユーザーからの入力を処理してほしいものです。そのために<def>描画ループ</def>と呼ばれるwhileループを作成し、ユーザーがGLFWに終了を命じるまで動き続けるようにします。以下のコードは単純な描画ループの例です: 480 </p> 481 482 <pre><code> 483 while(!<function id='14'>glfwWindowShouldClose</function>(window)) 484 { 485 <function id='24'>glfwSwapBuffers</function>(window); 486 <function id='23'>glfwPollEvents</function>(); 487 } 488 </code></pre> 489 490 <p> 491 The <fun><function id='14'>glfwWindowShouldClose</function></fun> function checks at the start of each loop iteration if GLFW has been instructed to close. If so, the function returns <code>true</code> and the render loop stops running, after which we can close the application.<br/> 492 The <fun><function id='23'>glfwPollEvents</function></fun> function checks if any events are triggered (like keyboard input or mouse movement events), updates the window state, and calls the corresponding functions (which we can register via callback methods). 493 The <fun><function id='24'>glfwSwapBuffers</function></fun> will swap the color buffer (a large 2D buffer that contains color values for each pixel in GLFW's window) that is used to render to during this render iteration and show it as output to the screen. 494 <fun><function id='14'>glfwWindowShouldClose</function></fun>はループごとに、GLFWが終了の信号を受けとっていないか確認します。終了の信号を受けとっていればこの関数は<code>true</code>を返し描画ループが終了し、アプリケーションを終了させることができます。<fun><function id='23'>glfwPollEvents</function></fun>はキーボードからの入力やマウスの移動といったイベントが発生していないか確認し、ウィンドウの状態を更新し、コールバックとして登録した関数を呼び出します。<fun><function id='24'>glfwSwapBuffers</function></fun>はカラーバッファを入れ替えます。カラーバッファというのは大きな2次元のバッファで、GLFWウィンドウの各ピクセルの色を保持しており、この描画ループの中での描画および、その結果をスクリーンに出力するのに利用します。 495 </p> 496 497 <note> 498 <strong>Double buffer</strong><br/> 499 <strong>ダブルバッファ</strong><br/> 500 When an application draws in a single buffer the resulting image may display flickering issues. This is because the resulting output image is not drawn in an instant, but drawn pixel by pixel and usually from left to right and top to bottom. Because this image is not displayed at an instant to the user while still being rendered to, the result may contain artifacts. To circumvent these issues, windowing applications apply a double buffer for rendering. The <strong>front</strong> buffer contains the final output image that is shown at the screen, while all the rendering commands draw to the <strong>back</strong> buffer. As soon as all the rendering commands are finished we <strong>swap</strong> the back buffer to the front buffer so the image can be displayed without still being rendered to, removing all the aforementioned artifacts. 501 アプリケーションがバッファをひとつだけ使って画像を表示すると、画面にチラつきが発生します。出力された画像がすぐに表示されるのではなく、一般的には左から右へ、上から下へと1ピクセルずつ表示されるためです。描画処理が完了していない画像がじわじわと表示されるので、不自然な結果になるのです。この問題を回避するためにアプリケーションの描画にダブルバッファを利用します。<strong>フロント</strong>バッファが最終的にスクリーンに表示される出力を保持し、描画処理は<strong>バック</strong>バッファにおいて行われます。描画処理がすべて終了すれば前後のバッファが<strong>交換</strong>されます。こうすることで描画処理が完了していない状態の画像を表示させないようにでき、前述の不具合が解消できます。 502 </note> 503 504 <h2>One last thing</h2> 505 <h2>最後にひとつ</h2> 506 <p> 507 As soon as we exit the render loop we would like to properly clean/delete all of GLFW's resources that were allocated. We can do this via the <fun><function id='25'>glfwTerminate</function></fun> function that we call at the end of the <fun>main</fun> function. 508 描画ループからぬけたあと、確保したメモリを開放するのがいいでしょう。この作業は<fun><function id='25'>glfwTerminate</function></fun>によって<fun>main</fun>関数の最後に行うことができます。 509 </p> 510 511 <pre><code> 512 <function id='25'>glfwTerminate</function>(); 513 return 0; 514 </code></pre> 515 516 <p> 517 This will clean up all the resources and properly exit the application. Now try to compile your application and if everything went well you should see the following output: 518 この関数により、メモリをすべて開放しアプリケーションを適切に終了させることができます。それではいちどアプリケーションをコンパイルしてみましょう。すべてうまくいっていれば以下のような出力が得られるはずです: 519 </p> 520 521 <img src="/img/getting-started/hellowindow.png" width="600px" class="clean" alt="Image of GLFW window output as most basic example"/> 522 523 <p> 524 If it's a very dull and boring black image, you did things right! If you didn't get the right image or you're confused as to how everything fits together, check the full source code <a href="/code_viewer_gh.php?code=src/1.getting_started/1.1.hello_window/hello_window.cpp" target="_blank">here</a> (and if it started flashing different colors, keep reading). 525 真っ黒でつまらない画像が表示された場合ここまでの作業がうまくいっているということです。黒い画面が表示されない場合や、各コードをどのように配置すればいいのかわからない場合は、<a href="/code_viewer_gh.php?code=src/1.getting_started/1.1.hello_window/hello_window.cpp" target="_blank">ここ</a>から完全なソースコードを確認してください(もし違う色の画像が表示された場合、とりあえずこの先を読み進んでください)。 526 </p> 527 528 <p> 529 If you have issues compiling the application, first make sure all your linker options are set correctly and that you properly included the right directories in your IDE (as explained in the previous chapter). Also make sure your code is correct; you can verify it by comparing it with the full source code. 530 コンパイルが通らなければ、まずは前章で説明した通りリンカのオプションがすべて正しく設定されているか、正しいインクルードディレクトリがIDEに読み込まれているか確認してください。そしてソースコードが正しく記述されているか確かめてください。上にあげた完全なソースコードとあなたのものを比較することで間違いがないか確認できます。 531 </p> 532 533 <h2>Input</h2> 534 <h2>入力</h2> 535 <p> 536 We also want to have some form of input control in GLFW and we can achieve this with several of GLFW's input functions. We'll be using GLFW's <fun>glfwGetKey</fun> function that takes the window as input together with a key. The function returns whether this key is currently being pressed. We're creating a <fun>processInput</fun> function to keep all input code organized: 537 GLFWにおいて入力の処理は、GLFWのいくつかの関数によって行うことができます。ここでは<fun>glfwGetKey</fun>を利用します。この関数はウィンドウと入力されたキーを引数にとり、そのキーが押されているかどうかを返します。<fun>processInput</fun>という関数を作成し、入力の処理を一元化しましょう: 538 </p> 539 540 <pre><code> 541 void processInput(GLFWwindow *window) 542 { 543 if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) 544 glfwSetWindowShouldClose(window, true); 545 } 546 </code></pre> 547 548 <p> 549 Here we check whether the user has pressed the escape key (if it's not pressed, <fun>glfwGetKey</fun> returns <var>GLFW_RELEASE</var>). If the user did press the escape key, we close GLFW by setting its <var>WindowShouldClose</var> property to <code>true</code> using <fun>glfwSetwindowShouldClose</fun>. The next condition check of the main <code>while</code> loop will then fail and the application closes. 550 ここではユーザーがエスケープキーを押したかどうかを確認しています(押されていなければ<fun>glfwGetKey</fun>は<var>GLFW_RELEASE</var>を返します)。エスケープが押されていた場合、<fun>glfwSetwindowShouldClose</fun>を通して<var>WindowShouldClose</var>を<code>true</code>にすることで、GLFWを終了させるようにします。こうすることで、<code>while</code>が次のループに進むかどうかの判定で偽が返り、ループから抜けだしアプリケーションが終了します。 551 </p> 552 553 <p> 554 We then call <fun>processInput</fun> every iteration of the render loop: 555 それでは<fun>processInput</fun>を描画ループがまわるたびに呼び出すようにしましょう: 556 </p> 557 558 <pre><code> 559 while (!<function id='14'>glfwWindowShouldClose</function>(window)) 560 { 561 processInput(window); 562 563 <function id='24'>glfwSwapBuffers</function>(window); 564 <function id='23'>glfwPollEvents</function>(); 565 } 566 </code></pre> 567 568 <p> 569 This gives us an easy way to check for specific key presses and react accordingly every <def>frame</def>. An iteration of the render loop is more commonly called a <def>frame</def>. 570 これが、<def>フレーム</def>ごとになんらかのキーが入力されたかどうかを確認する簡単な方法です。描画ループの一回は一般に<def>フレーム</def>と呼ばれます。 571 </p> 572 573 <h2>Rendering</h2> 574 <h2>描画</h2> 575 <p> 576 We want to place all the rendering commands in the render loop, since we want to execute all the rendering commands each iteration or frame of the loop. This would look a bit like this: 577 各フレームごとに描画処理を行いたいので、描画命令はすべて描画ループの中におきます。以下のような感じです: 578 </p> 579 580 <pre><code> 581 // 描画ループ 582 while(!<function id='14'>glfwWindowShouldClose</function>(window)) 583 { 584 // 入力 585 processInput(window); 586 587 // 描画処理 588 ... 589 590 // check and call events and swap the buffers 591 // イベントの処理およびバッファの交換 592 <function id='23'>glfwPollEvents</function>(); 593 <function id='24'>glfwSwapBuffers</function>(window); 594 } 595 </code></pre> 596 597 <p> 598 Just to test if things actually work we want to clear the screen with a color of our choice. At the start of frame we want to clear the screen. Otherwise we would still see the results from the previous frame (this could be the effect you're looking for, but usually you don't). We can clear the screen's color buffer using <fun><function id='10'>glClear</function></fun> where we pass in buffer bits to specify which buffer we would like to clear. The possible bits we can set are <var>GL_COLOR_BUFFER_BIT</var>, <var>GL_DEPTH_BUFFER_BIT</var> and <var>GL_STENCIL_BUFFER_BIT</var>. Right now we only care about the color values so we only clear the color buffer. 599 ほんとうにうまくいっているのか確認するために、スクリーンの色を変更してみましょう。各フレームのはじめにスクリーンに表示されたものをすべて消します。そうしないと前のフレームで表示されていたものが次のフレームでもみえたままになります(ときにはこのわざとそうしたいこともありますが、多くの場合これは望まない結果でしょう)。スクリーンのカラーバッファは<fun><function id='10'>glClear</function></fun>を用いて削除します。バッファビットを通して消したいバッファを指定しましょう。選べるバッファビットは<var>GL_COLOR_BUFFER_BIT</var>、<var>GL_DEPTH_BUFFER_BIT</var>および<var>GL_STENCIL_BUFFER_BIT</var>です。 600 </p> 601 602 <pre><code> 603 <function id='13'><function id='10'>glClear</function>Color</function>(0.2f, 0.3f, 0.3f, 1.0f); 604 <function id='10'>glClear</function>(GL_COLOR_BUFFER_BIT); 605 </code></pre> 606 607 <p> 608 Note that we also specify the color to clear the screen with using <fun><function id='13'><function id='10'>glClear</function>Color</function></fun>. Whenever we call <fun><function id='10'>glClear</function></fun> and clear the color buffer, the entire color buffer will be filled with the color as configured by <fun><function id='13'><function id='10'>glClear</function>Color</function></fun>. This will result in a dark green-blueish color. 609 <fun><function id='13'><function id='10'>glClear</function>Color</function></fun>により、バッファを削除したあとの色も指定していることに注意してください。<fun><function id='10'>glClear</function></fun>を呼んでバッファを削除したときは<fun><function id='13'><function id='10'>glClear</function>Color</function></fun>により指定された色でバッファが満たされます。今回は深い青緑を指定しています。 610 </p> 611 612 <note> 613 As you may recall from the <em>OpenGL</em> chapter, the <fun><function id='13'><function id='10'>glClear</function>Color</function></fun> function is a <em>state-setting</em> function and <fun><function id='10'>glClear</function></fun> is a <em>state-using</em> function in that it uses the current state to retrieve the clearing color from. 614 <em>OpenGL</em>の章で状態遷移関数と状態利用関数について言及しました。ここにでてきた<fun><function id='13'><function id='10'>glClear</function>Color</function></fun>は<em>状態遷移</em>関数で、<fun><function id='10'>glClear</function></fun>は<em>状態利用</em>関数です。<fun><function id='10'>glClear</function></fun>が「バッファ削除後の色」という状態を利用しています。 615 </note> 616 617 <img src="/img/getting-started/hellowindow2.png" width="600px" class="clean" alt="Image of GLFW's window creation with <function id='13'><function id='10'>glClear</function>Color</function> defined"/> 618 619 <p> 620 The full source code of the application can be found <a href="/code_viewer_gh.php?code=src/1.getting_started/1.2.hello_window_clear/hello_window_clear.cpp" target="_blank">here</a>. 621 今回作ったアプリケーションの完全なソースコードは<a href="/code_viewer_gh.php?code=src/1.getting_started/1.2.hello_window_clear/hello_window_clear.cpp" target="_blank">こちら</a>にあります。 622 </p> 623 624 <p> 625 So right now we got everything ready to fill the render loop with lots of rendering calls, but that's for the <a href="https://learnopengl.com/Getting-started/Hello-Triangle" target="_blank">next</a> chapter. I think we've been rambling long enough here. 626 描画ループにおいて様々なものを描くうえで必要な準備はすべて整いました。 <a href="https://learnopengl.com/Getting-started/Hello-Triangle" target="_blank">次</a>の章では実際に描画しましょう。 627 </p> 628 629 </div> 630 </body> 631 </html> 632 </main> 633 </body> 634 </html>