1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import javax.media.opengl.*;
import com.sun.opengl.util.*;
import java.awt.*;
import java.awt.event.*;
public class Test extends Frame {
public Test() {
this.setSize(400, 300);
this.setTitle("Test1");
GLCapabilities glCaps = new GLCapabilities();
glCaps.setRedBits(8);
glCaps.setBlueBits(8);
glCaps.setGreenBits(8);
glCaps.setAlphaBits(8);
GLCanvas canvas = new GLCanvas(glCaps);
canvas.addGLEventListener(new Render());
this.add(canvas);
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
Animator anim = new Animator(canvas); //에니메이션 등록
anim.start(); //에니메이션 시작(GLEventListener 의 display(...) 지속적인 호출)
}
public static void main(String args[]) {
Test test = new Test();
test.setVisible(true);
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import javax.media.opengl.*;
import javax.media.opengl.glu.*;
import com.sun.opengl.util.*;
public class Render implements GLEventListener {
private GL gl;
private GLU glu = new GLU();
private GLUT glut = new GLUT();
private GLSLUtil glsl;
//########################################################################################
//# GLEventListener 클래스의 추상 메소드
//########################################################################################
public void display(GLAutoDrawable drawable) {
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
gl.glTranslatef(0, 0, -5);
glut.glutSolidTeapot(1.0f);
gl.glRasterPos3f(1.0f, 1.0f, 0.0f); //현재 perspective 이므로
//z값에 따라 위치가 달라진다.
glut.glutBitmapString(GLUT.BITMAP_8_BY_13, "Hello~~ ");
}
//########################################################################################
//# GLEventListener 클래스의 추상 메소드
//########################################################################################
public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
}
//########################################################################################
//# GLEventListener 클래스의 추상 메소드
//########################################################################################
public void init(GLAutoDrawable drawable) {
gl = drawable.getGL();
glsl = new GLSLUtil(gl); //#! GLSL 설정을 위한 클래스
gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}
//########################################################################################
//# GLEventListener 클래스의 추상 메소드
//########################################################################################
public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) {
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
gl.glViewport(0, -10, w, h); //-10은 제목표시줄 두께
glu.gluPerspective(45.0f, (float) w / (float) h, 1.0f, 60.0f);
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import javax.media.opengl.*;
import javax.media.opengl.glu.*;
import com.sun.opengl.util.*;
import java.io.*;
public class GLSLUtil {
public GLSLUtil(GL gl) {
int vs = gl.glCreateShader(GL.GL_VERTEX_SHADER); //vs 생성.
int fs = gl.glCreateShader(GL.GL_FRAGMENT_SHADER); //fs 생성.
String strVS = readShaderFile("VertexShader.vs"); //파일 읽기.
String strFS = readShaderFile("FragmentShader.fs"); //파일 읽기.
String strAryVS[] = {strVS}; //vs 배열 생성.
String strAryFS[] = {strFS}; //fs 배열 생성.
int intAryVS[] = {strVS.length()}; //vs 파일의 문자수.
int intAryFS[] = {strFS.length()}; //fx 파일의 문자수.
gl.glShaderSource(vs, 1, strAryVS, intAryVS, 0); //vs 컴파일 준비
gl.glShaderSource(fs, 1, strAryFS, intAryFS, 0); //fs 컴파일 준비
gl.glCompileShader(vs); //컴파일
gl.glCompileShader(fs); //컴파일
int progID = gl.glCreateProgram(); //prog 생성.
gl.glAttachShader(progID, vs); //prog에 vs 적용
gl.glAttachShader(progID, fs); //prog에 fs 적용
gl.glLinkProgram(progID); //링크
gl.glUseProgram(progID); //사용
}
//###############################################################################
//# GLSL 파일을 읽어 들인다.
//###############################################################################
private String readShaderFile(String path) {
try {
File f = new File(path); //파일 객체 생성.
FileReader fr = new FileReader(f); //파일 리더 객체 생성.
int size = (int) f.length(); //파일 크기 얻기.
char buf[] = new char[size]; //파일 크기 만큼 버퍼 생성.
int len = fr.read(buf); //버퍼(buf)에 파일 내용 담음.
fr.close(); //파일 닫기
return new String(buf, 0, len); //!! 파일 내용을 문자열로 변환하여 리턴.
} catch (Exception e) {
System.err.println(e);
System.exit(0);
}
return null;
}
public int getProgID() { //프로그램 ID를 리턴.
return progID;
}
}
버텍스 셰이더
는 편의상 ftransform
만 수행하도록 함.
1
2
3
void main() {
gl_Position = ftransform();
}
플래그먼트 셰이더
는 편의상 단일 색상을 반환하도록 함.
1
2
3
void main() {
gl_FragColor = vec4(1.0, 0.4, 0.8, 1.0);
}