JOGL-006 Teapot
Post

JOGL-006 Teapot

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

img