イントロダクション
LWJGL GitBookのChapterを写経しながら理解していきます。Git(ソース)はこちら。。。
前回は、Chapter3をやりました。
今回は、前回やったプログラムの続きです。前回はプログラムの全体的な流れを見ていきましたので、今回は詳細部分描画処理を見ていきます、前回示した目玉の部分です。
Introduction
LWJGL We will understand GitBook ‘s chapter while shooting. Git (source) is here. . . Last time I did Chapter 3 so We will do Chapter 4 this time.
Last time. we have larned rough processing of this program.This time we will learn sight of this program.
https://ahbejarano.gitbook.io/lwjglgamedev/chapter4
シェーダについて
ShaderProgramクラスについて学びます。このクラスはRendererクラスから呼ばれていますので、そこから追いかけます。
Renderer#init()
shaderProgram = new ShaderProgram(); shaderProgram.createVertexShader(Utils.loadResource("/vertex.vs")); shaderProgram.createFragmentShader(Utils.loadResource("/fragment.fs")); shaderProgram.link();
LWJGLフレームワークの部品GL20のメソッド「glCreateProgram」を呼び出しています。
ShaderProgram
public ShaderProgram() throws Exception {
programId = glCreateProgram();
if (programId == 0) {
throw new Exception("Could not create Shader");
}
}
ここでの注意点は、赤字のメソッドがメソッド内のコードだけでは「どのクラスのメソッドかわからない」と言うことです。
結論から言うと「import static」しているので呼び出すことが可能です。
import static org.lwjgl.opengl.GL20.*;
そして、参照しているドキュメントには以下の様な記述があります。
-
- OpenGLプログラム(空のオブジェクト)を作成する:glCreateProgram
- 頂点とフラグメントのシェーダコードファイルをロードします。
-
- シェーダを定義します:glCreateShaderSource
- シェーダをコンパイル(実行できる様にします。上で定義した時のIDでコンパイルする様です。:glCompileShader
-
- 各シェーダーについて、新しいシェーダープログラムを作成し、そのタイプ(頂点、フラグメント)を指定します:glCreateShaderSource
- シェーダをコンパイルします。:glCompileShader
- シェーダをプログラムに接続します。:glAttachShader
- プログラムをリンクします。:glLinkProgram
public class ShaderProgram { private final int programId; private int vertexShaderId; private int fragmentShaderId; public ShaderProgram() throws Exception { /* 1.OpenGLプログラム(空のオブジェクト)を作成する */ programId = glCreateProgram(); if (programId == 0) { throw new Exception("Could not create Shader"); } } /*新しいシェーダープログラムを作成 */ public void createVertexShader(String shaderCode) throws Exception { /*空のシェーダを作成(Vertex(点用)) */ vertexShaderId = createShader(shaderCode, GL_VERTEX_SHADER); } /*新しいシェーダープログラムを作成 */ public void createFragmentShader(String shaderCode) throws Exception { /*空のシェーダを作成(フラグメント用))*/ fragmentShaderId = createShader(shaderCode, GL_FRAGMENT_SHADER); } protected int createShader(String shaderCode, int shaderType) throws Exception { /* 空のシェーダを作成 */ int shaderId = glCreateShader(shaderType); if (shaderId == 0) { throw new Exception("Error creating shader. Type: " + shaderType); } /*頂点とフラグメントのシェーダコードファイルをロード */ glShaderSource(shaderId, shaderCode); /*シェーダをコンパイル */ glCompileShader(shaderId); /* コンパイルができたか確認する */ if (glGetShaderi(shaderId, GL_COMPILE_STATUS) == 0) { throw new Exception("Error compiling Shader code: " + glGetShaderInfoLog(shaderId, 1024)); } /* シェーダとプログラムとを関連付ける(アタッチする) */ glAttachShader(programId, shaderId); return shaderId; } public void link() throws Exception { /* */ glLinkProgram(programId); if (glGetProgrami(programId, GL_LINK_STATUS) == 0) { throw new Exception("Error linking Shader code: " + glGetProgramInfoLog(programId, 1024)); } if (vertexShaderId != 0) { /* アタッチの反対を行います*/ glDetachShader(programId, vertexShaderId); } if (fragmentShaderId != 0) { glDetachShader(programId, fragmentShaderId); } /* シェーダプログラムが使用可能かチェックする */ glValidateProgram(programId); if (glGetProgrami(programId, GL_VALIDATE_STATUS) == 0) { System.err.println("Warning validating Shader code: " + glGetProgramInfoLog(programId, 1024)); } } public void bind() { /* シェーダプログラムをインストール(実行じゅんびOK状態にする) */ glUseProgram(programId); } public void unbind() { /* シェーダプログラムを解放する */ glUseProgram(0); } public void cleanup() { unbind(); if (programId != 0) { /* シェーダプログラムの破棄 */ glDeleteProgram(programId); } } }
<補足>
フラグメントシェーダプログラム
#version 330 out vec4 fragColor; void main() { fragColor = vec4(0.0, 0.5, 0.5, 1.0); }
Vertexシェーダプログラム
#version 330 layout (location =0) in vec3 position; void main() { gl_Position = vec4(position, 1.0); }
シェーダプログラムに関しては触れていなかったので、ちょいと保留します。
今回は、ここまでにしておきます。