ARGENTO CUORE

 May the code be with you.

--.--.--[--] スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

2010.02.24[水] JOGLでシェーダープログラミング

Javaは、jarファイルにまとめることで、ダブルクリックもしくは、

$java -jar Hoge.jar

で起動することができますが、JOGLのような外部ライブラリを使用している場合には、

$jar -cvf Hoge.jar Hoge.class

として出来たjarファイル内の/META-INF/MANIFEST.MFを開き、

Manifest-Version: 1.0
Created-By: 1.6.0_0 (Sun Microsystems Inc.)
Class-Path: ここに外部ライブラリのパスを記述。複数ある場合にはスペースで区切る

としなければならず、でもこのパスってユーザーによって違うので、配布するときに困るという……。
外部ライブラリも一緒に配布するか(でもこれは、jarでまとめられているものを全て展開してまとめなければならないのと、容量が増える問題と、ライブラリによっては再配布を禁じているのもあるだろうからetc……)、AppletやWebStartにしてしまうのが一番なのかもしれません(でも、JOGLのUserguideにしたがってextension行を記述したJNLPファイルを使ってWebStartを試みたらなぜか起動できず、JOGL公式サイトに存在しているWebStartのデモもうちの環境だと起動せず……。JFrameでウインドウを出すだけのプログラムだとWebStart成功するんだけどなー)。

今作っているのは個人的に使うツールで、配布したとしても開発者しか使わないだろうから別に問題ないと思いつつ、慣習的に決まっている外部ライブラリの設置場所とかあるのだろうかと調べてみるも、よくわからないという結果に。

外部ライブラリを使わなくても済むようなものがほとんどかもしれないし、うーん……。

続いてJOGLの話題。

JOGLの解説サイトを見ていると、JOGLのバージョン、AWTを使うのか、それともSwingを使うのか、等によって様々なサンプルコードが散在していて、さらにOpenGLのバージョンとかも加わってくるから面倒。
あと、ほとんどの日本語の説明は1.xを対象にしているので、GL2とかの解説が見つからないのと、JOGLのspecも翻訳されてないようで、頑張って英語のドキュメントを読まないとだめみたい(英語は赤点多かったですよ……)。

とりあえず、このブログを見てくれている奇特な方で、且つJOGLを触ろうとしている方に向けて以下。

・このサイト上で、現時点(2010年2月)で自分の扱っているJOGLのバージョンは2.0-beta10です。
・英語わかんない+馬鹿なので間違い多いかも。最初に謝っておこう「ごめんね☆」
・Swing大好きなのでAWTは使いません。GLCanvasではなく、GLJPanelを使います。

ということで、調べたことメモに続きます。

GL_MODELVIEWが定義されているのがGL2だったからということで、GL2.GL_MODELVIEWとかやっていたのですが、このGL2というのは、specによるとOpenGL3.0のメソッドを含むインターフェースらしいです(OpenGL3.1はGL3)。
で、他にも色々種類があって、まとめると以下のような感じに。

GL - GL3、GL2、GLES1、GLES2のサブセットを含むインターフェース
GL2 - OpenGL3.0
GL3 - OpenGL3.1以降
GL2ES1 - GL2、GLES1のサブセットを含むインターフェース
GL2ES2 - GL3、GL2、GLES2のサブセットを含むインターフェース
GL2GL3 - GL3、GL2のサブセットを含むインターフェース
GLES1 - GLES1.x系
GLES2 - GLES2.x系

見てなんとなく理解した気になる図を、http://michael-bien.com/mbien/entry/jogl_2_opengl_profiles_explainedで発見しました。

GL2(OpenGL3.0)まではOpenGL1.x~OpenGL2.xの全機能を使うことができるので、GL2を使えば良いのかな。
ちなみにOpenGL3.1は、シェーダーで置き換え可能な機能が削除されたりしていて、今まで使用できていたものが使用できなくなったようでいろんな人から不満が続出したらしく、OpenGL3.2では削除された機能をプロファイルとして復活させたようです。OpenGLのバージョン毎の特徴は、http://www.asahi-net.or.jp/~yw3t-trns/opengl/version/index.htmに詳しくまとめられています。

現状のAndroidのOpenGLAPIではOpenGLES1.0と1.1の一部を使うようになっていて、シェーダー記述言語が利用可能になるGLES2.0は使えないのですが、JOGLであればシェーダー記述言語を利用可能らしいので、まずはそのことについて調べてみました(学生のときに触っていたOpenGLのバージョンは1.5だったのでまったく未知の世界)。

調べると、シェーダー記述言語としてOpenGLではGLSLというものが用意されている。シェーダーにはバーテックスシェーダーとフラグメントシェーダーという二つの種類がある。Wikipediaの説明へのリンクを以下。

バーテックスシェーダー
フラグメント(ピクセル)シェーダー

バーテックスシェーダーは頂点単位の処理、フラグメントシェーダーはピクセル単位の処理を行う(らしい)。で、プログラマブルシェーダーと言われる所以は、従来グラフィックスハードウェアが固定で用意していた様々なシェーダー処理を、ソフトウェア側で実現可能にしたみたいです(シェーダー記述言語は当初、アセンブラしか用意されておらず、OpenGL1.5の拡張機能としてOpenGL Shading Language(GLSL)が登場し、OpenGL2.0で標準機能に組み込まれた)。

頂点単位の処理は、頂点座標、頂点座標の色、法線などに対して指示を与えることができ、ピクセル単位の処理は、バンプマップ、フォグ、アニメ調などのエフェクト系の処理を指示することができる。

でも具体的にどうするんだろう?
英語は嫌だ読みたくないと一心に祈りながら、ウェブ上で情報を探すとJOGLの日本語情報はないものの、OpenGLの情報はザックザクなので助かった。床井研究室というOpenGLを扱ったサイトに、シェーダープログラミングが説明とコード付きで載っているのを発見。

バーテックスシェーダーとフラグメントシェーダーのオブジェクトをまず作成するらしい。glCreateShaderという関数を使って作っているので、同じようなメソッドをJOGLで探す。

JOGLのspecを見ると、GL2のメソッドに
int glCreateShader(int type)

というのを発見。
specの説明には、C言語の関数へのインターフェースと書かれており、C言語の関数定義は
GLuint glCreateShader(GLenum type)

となっている。GLuintという型をJOGLでは扱わないみたい。上記サイトに従って、JOGLを使ったコードにするとたぶん↓みたいな感じになるだろうと思いつつ、glShaderSourceの5番目の引数が何を意味するのかわかってない……調べなきゃ……。

書き途中のコードの一部

vertex_shader = gl.glCreateShader(GL2.GL_VERTEX_SHADER);
fragment_shader = gl.glCreateShader(GL2.GL_FRAGMENT_SHADER);

String[] vertex_source = readShaderSource("vertex_shader.glsl");
gl.glShaderSource(vertex_shader, 1, vertex_source, (int[])null,0);
gl.glCompileShader(vertex_shader);

String[] fragment_source = readShaderSource("fragment_shader.glsls");
gl.glShaderSource(fragment_shader, 1, fragment_source, (int[])null,0);
gl.glCompileShader(fragment_shader);

shader_program = gl.glCreateProgram();
gl.glAttachShader(shader_program, vertex_shader);
gl.glAttachShader(shader_program, fragment_shader);
gl.glLinkProgram(shader_program);
gl.glValidateProgram(shader_program);

gl.glUseProgram(shader_program);


String[] readShaderSource(String filename)メソッド(ファイル読んでるだけ)

private String[] readShaderSource(String filename){
String buff="";
String line;
try{
BufferedReader br = new BufferedReader(new FileReader(filename));
while((line=br.readLine()) != null){
buff += line + "\n";
}
}catch(IOException e){}
String[] ret = new String[10];
ret[0] = buff;

return ret;
}


長くなったので次回に続く!(かも)
スポンサーサイト

Comment






(編集・削除用)


管理者にだけ表示を許可

Trackback

http://ronor.blog81.fc2.com/tb.php/46-4ecb65c1

この記事にトラックバック(FC2Blog User)

Scala Feed

scala feed

FC2カウンター

プロフィール

RoNor

Author:RoNor
得意呪文はScalaですって言えるようになるのが夢です。
デスマーチ中、パーティメンバーの防御力を向上させたりさせなかったり。

検索フォーム

QRコード

QRコード

Copyright © 2009-2010 ARGENTO CUORE and RoNor All rights reserved.

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。