FC2ブログ

ARGENTO CUORE

Category : Java

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

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

2010.04.10[土] XORSHIFT128とJava.util.Random

乱数生成を比較してみた。

random_ss.png

赤がJava.util.Random、青がxorshift128。
あんまり変わらない……?


以下、xorshift128のソース。実装方法これであってるかな……。

public class XorShift128{
private long x=123456789;
private long y=362436069;
private long z=521288629;
private long w=88675123;
public XorShift128(long seed){
w = seed;
}

public int nextInt(int num){
long t = (x^(x<<11));
x = y;
y = z;
z = w;

w = (w=(w^(w>>19))^(t^(t>>8)));

return (int)w%num;
}
}


スポンサーサイト

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

JOGLでシェーダープログラミングしようーと思う前段階で詰まり中。
Teapotを表示させてみたけれども、全然シェーダーいじっても表示が変わらない。
アーマーナイト以下の速度で前進しますorz

import javax.swing.*;
import javax.media.opengl.*;
import javax.media.opengl.awt.GLJPanel;
import javax.media.opengl.glu.GLU;
import java.io.*;
import java.nio.IntBuffer;
import java.nio.ByteBuffer;
import com.sun.opengl.util.gl2.GLUT;
import com.sun.opengl.util.FPSAnimator;

public class Sample02 extends JFrame implements GLEventListener{
GLU glu;

GLCapabilities caps = new GLCapabilities(null);
GLJPanel panel = new GLJPanel();

GLUT glut = new GLUT();

int vertex_shader;
int fragment_shader;
int shader_program;

float[] lightpos = {0.0f,0.0f,5.0f,1.0f};
float[] lightcol = {1.0f,1.0f,1.0f,1.0f};
float[] lightamb = {0.1f,0.1f,0.1f,1.0f};

FPSAnimator anim;
int counter = 0;
public Sample02(){
panel.addGLEventListener(this);
setSize(200,200);
setContentPane(panel);
}

public static void main(String[] args){
Sample02 s = new Sample02();
s.setLocationRelativeTo(null);
s.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
s.setVisible(true);
}

public void init(GLAutoDrawable drawable){
GL2 gl = drawable.getGL().getGL2();
glu = new GLU();

gl.glClearColor(0.0f,0.0f,0.0f,0.0f);

gl.glShadeModel(GL2.GL_SMOOTH);
gl.glEnable(GL2.GL_DEPTH_TEST);
gl.glDisable(GL2.GL_CULL_FACE);

gl.glEnable(GL2.GL_LIGHTING);
gl.glEnable(GL2.GL_LIGHT0);
gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_DIFFUSE, lightcol,0);
gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_SPECULAR, lightcol,0);
gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_AMBIENT, lightamb,0);
gl.glLightModeli(GL2.GL_LIGHT_MODEL_LOCAL_VIEWER, GL2.GL_TRUE);
anim = new FPSAnimator(panel,20,true);
anim.start();

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

String[] vertex_source = readShaderSource("vertex_shader.glsl");
int[] vertex_length = new int[1];
vertex_length[0] = vertex_source[0].length();

//各行の終端がNULLである場合はlengthにnullを渡す。
//そうでない場合は、各行の文字列数を入れたint型の配列を渡す。
gl.glShaderSource(vertex_shader,1,vertex_source,vertex_length,0);
gl.glCompileShader(vertex_shader);

String[] fragment_source = readShaderSource("fragment_shader.glsl");
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);
}

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

public void display(GLAutoDrawable drawable){
GL2 gl = drawable.getGL().getGL2();
gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL2.GL_MODELVIEW);
gl.glLoadIdentity();
glu.gluLookAt(0.0, 0.0, 5.0, 0.0,0.0,0.0, 0.0,1.0,0.0);

float[] diffuse = {0.8f,0.8f,0.8f,1.0f};
float[] specular = {0.3f,0.3f,0.3f,1.0f};
gl.glMaterialfv(GL2.GL_FRONT_AND_BACK, GL2.GL_AMBIENT_AND_DIFFUSE, diffuse,0);
gl.glMaterialfv(GL2.GL_FRONT_AND_BACK, GL2.GL_SPECULAR, specular,0);
gl.glMaterialf(GL2.GL_FRONT_AND_BACK, GL2.GL_SHININESS, 100.0f);

gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_POSITION, lightpos, 0);

gl.glPushMatrix();
gl.glRotatef(counter,0f,1f,0f);
glut.glutSolidTeapot(2.0);
gl.glPopMatrix();
gl.glFlush();

if (counter >= 360){
counter = 0;
}else{
counter++;
}
}

public void dispose(GLAutoDrawable drawable){

}

public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h){
GL2 gl = drawable.getGL().getGL2();
gl.glViewport(0,0,w,h);
gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluPerspective(75.0,(double)w/(double)h,1.0,20.0);
}
}


実行結果
jogl02.png


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;
}


長くなったので次回に続く!(かも)

2010.02.21[日] JOGLでポリゴン表示

Swingでの描画は多少パフォーマンスが落ちるらしいみたいですが、そんなことは気にせずGLJPanelを使って描画しました。

よくわからなかったのが、GL.GL_MODELVIEWなどの定義値を利用できないことで、リファレンスを見たら確かに用意されておらず、代わりにGL2だと使えたのでGL2.GL_MODELVIEWみたいな感じで記述しています。

http://trac.openmicroscopy.org.uk/shoola/changeset/6590/branches/Jogl2.0/src/TestSubImage.java

↑のコードを見てみたら、GL2の機能を使うときにはgetGL().getGL2()等でGL2を取得して使うという感じにしてあるみたいだからこれで良いのかな……。

プログラムは、GLEventListenerを実装したJFrameを継承するクラスを作成する。
GLEventListenerは以下の4つのメソッドを定義しているので実装する(けどdisposeは空欄のままにしてある)。

void display(GLAutoDrawable drawable)
void dispose(GLAutoDrawable drawable)
void init(GLAutoDrawable drawable)
void reshape(GLAutoDrawable drawable, int x, int y, int width, int height)


詳細はJOGLのリファレンスを参照。

import javax.swing.*;
import javax.media.opengl.*;
import javax.media.opengl.awt.GLJPanel;
import javax.media.opengl.glu.GLU;

public class Sample01 extends JFrame implements GLEventListener{
GLU glu;

GLCapabilities caps = new GLCapabilities(null);
GLJPanel panel = new GLJPanel();

public Sample01(){
panel.addGLEventListener(this);
setSize(200,200);
setContentPane(panel);
}
public static void main(String[] args){
Sample01 s = new Sample01();
s.setLocationRelativeTo(null);
s.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
s.setVisible(true);
}

public void init(GLAutoDrawable drawable){
GL2 gl = drawable.getGL().getGL2();
glu = new GLU();

gl.glClearColor(0.0f,0.0f,0.0f,0.0f);
gl.glShadeModel(GL2.GL_FLAT);
}

public void display(GLAutoDrawable drawable){
GL2 gl = drawable.getGL().getGL2();
gl.glClear(GL2.GL_COLOR_BUFFER_BIT);

gl.glMatrixMode(GL2.GL_MODELVIEW);
gl.glLoadIdentity();
glu.gluLookAt(0.0, 0.0, 5.0, 0.0,0.0,0.0, 0.0,1.0,0.0);

gl.glBegin(GL2.GL_POLYGON);
gl.glColor3f(1.0f,1.0f,0.0f);
gl.glVertex3f(0.0f,0.0f,0.0f);
gl.glVertex3f(0.0f,1.0f,0.0f);
gl.glVertex3f(1.0f,0.0f,0.0f);
gl.glEnd();
gl.glFlush();
}

public void dispose(GLAutoDrawable drawable){

}

public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h){
GL2 gl = drawable.getGL().getGL2();
gl.glViewport(0,0,w,h);
gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glLoadIdentity();
glu.gluPerspective(90.0,(double)w/(double)h,1.0,20.0);
}
}

2010.02.20[土] JOGLのインストール

Xubuntu9.10のパッケージマネージャを使ってインストールしたものの、それを利用するのに色々四苦八苦した挙句無理だったので、大人しくJOGLのサイトからダウンロードしてマニュアル通りに設定したらすんなりコンパイル通りました(長かった……)。


以下、メモ。

Java Binding for OpenGL APIからJOGLのパッケージをダウンロードしてくる。
JOGL Archived Builds incl. archived signed webstart bundlesに現在ダウンロードできるパッケージの一覧があり、1.x系と2.0でどんな違いがあるのかわからないけれど、とりあえず最新?のJOGL2.0beta10をダウンロードしてみる。OS、アーキテクチャごとにファイル名で区別してあるので、32bitLinuxだったら、linux-i586をダウンロードする。

ダウンロードしたファイルを解凍すると、ドキュメントとlibディレクトリが作られるので、lib以下を好きな場所にコピー。パッケージマネージャを使っていないので、管理のことを考えて自分のホームディレクトリ以下にjavalib/jogl/というディレクトリを掘って、そこにlib以下をコピー。

あとは、CLASSPATHとLD_LIBRARY_PATHを同梱されている説明にしたがって設定する。


export JOGL=/home/hoge/javalib/jogl/jogl.all.jar
export NATIVEWINDOW=/home/hoge/javalib/jogl/nativewindow.all.jar
export NEWT=/home/hoge/javalib/jogl/newt.all.jar
export GLUEGEN=/home/hoge/javalib/jogl/gluegen-rt.jar
export CLASSPATH=.:$JOGL:$NATIVEWINDOW:$NEWT:$GLUEGEN
export LD_LIBRARY_PATH=/home/hoge/javalib/jogl/


$source ~/.profile

でCLASSPATH、LD_LIBRARY_PATHの設定を適用する。

import javax.media.opengl.*;

でライブラリをインポートする。net.java.games.jogl~っていう記述をネット上で見かけたけれど、古いバージョン?の記述法なのかな……。これから調べよう。


2月21日追記
元々JOGLはJungleというjava.netで開発が進められていたJava向けのOpenGLをベースに開発されていたらしく、おそらくネット上のいろんなコードのimportするパッケージが異なるのはそのためかもしれない。

JSRについて

JSR - Java Specification Requests

オンライン・コンピュータ用語辞典 http://www2.nsknet.or.jp/~azuma/index.htm
JSRの項目 http://www2.nsknet.or.jp/~azuma/j/j0076.htm

Java Community Process内のJSRの全リスト http://jcp.org/en/jsr/all

Scala Feed

scala feed

FC2カウンター

プロフィール

RoNor

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

検索フォーム

QRコード

QRコード

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

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