[OpenGLES 의 도형그리기 기본]
OpenGLES 는 다음과 같은 방법으로 점, 선, 도형을 그려나간다.
[사각형 그리기]
보통 삼각형 두개를 합쳐서 그린다.
아래는 사각형을 그릴때 필요한 두개의 삼각형을 반시계 방향으로그려보고, 좌표를 생각해 본 것이다.
[소스코드] 는 이전의 Trangle 소스코드에서 Triangle.java 의 다음 파란색 부분만 수정하면 된다.
package com.samman.myapplication;
import android.opengl.GLES20;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
public class Triangle {
//삼사각형 정점 3개의 좌표
static float triangleCoords[] = {
-0.5f, 0.5f, 0.0f, //top left
-0.5f, -0.5f, 0.0f, // bottom left
0.5f, -0.5f, 0.0f //bottom right
0.5f, 0.5f, 0.0f // top right
};
private float color[] = {0.5f, 0.5f,0.5f, 0.5f};
//Vertex Shader ( Shader: 정점에 처리할 연산을 정의하는 메소드 )
private final String mVertexShaderCode = // Vertex로 포현할 position 프로그램 코드
"attribute vec4 vPosition;"+ // 객체의 위치를 저장하기 위한 vec4 자료형(4개의 int로 이루어진 벡터)
"void main(){"+ // 셰이더함수
"gl_Position = vPosition;"+ // 현재 vertex의 좌표 값을 저장함
"}";
//Fragment Shader ( 픽셀에 색상을 넣음 )
private final String mFragmenetShaderCode =
"precision mediump float;\n" +
"uniform vec4 vColor;\n" +
"void main() {\n" +
" gl_FragColor = vColor;\n" +
"}\n";
// vertex를 그리는 순서를 입력한 소스코드
private short mDrawOrder[] = { 0, 1, 2, 0, 2, 3};
ByteBuffer dlb = ByteBuffer.allocateDirect(mDrawOrder.length *2);
dlb.order(ByteOrder.nativeOrder());
mDrawListBuffer = dlb.asShortBuffer();
mDrawListBuffer.put(mDrawOrder);
mDrawListBuffer.position(0);
//정점을 이루는 좌표의 갯수
static final int COORDS_PER_VERTEX = 3;
//정점(꼭지점) 갯수
private final int vertextCount = triangleCoords.length /COORDS_PER_VERTEX;
//정점을 이루는 크기(Bytes)( 정점의 좌표값들은 보통 Float 으로 표현됨 )
private final int vertexStride = COORDS_PER_VERTEX * 4;
private final int mProgram;
private FloatBuffer mVertexBuffer;
private int mPositionHandle;
private int mColorHandle;
public Triangle() {
//버퍼 셋팅
ByteBuffer bb = ByteBuffer.allocateDirect(triangleCoords.length * 4); //바이트버퍼 할당: 정점 3개 * 각 정점의 좌표 3개 * 4Bytes
bb.order(ByteOrder.nativeOrder()); //리틀엔디언,빅엔디언 셋팅
mVertexBuffer = bb.asFloatBuffer(); //FloatBuffer로 변환
mVertexBuffer.put(triangleCoords); //Float으로 이루어진 삼각형좌표 배열을 삽입
mVertexBuffer.position(0); //첫번째 좌표부터 읽도록 positioning
//Shader 셋팅
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, mVertexShaderCode);
int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, mFragmenetShaderCode);
//프로그램 생성 -> 쉐이더 붙이기 -> 프로그램 링크 ( 쉐이더간의 인터페이스를 생성해주고, 최종 결과물까지 나오도록 내부 파이프라인을 연결해준다. )
mProgram = GLES20.glCreateProgram();
GLES20.glAttachShader(mProgram, vertexShader);
GLES20.glAttachShader(mProgram, fragmentShader);
GLES20.glLinkProgram(mProgram); // 링크된 프로그램은 GLES20.glUseProgram()을 이용해서 사용된다. (아래참고)
}
public void draw(){
GLES20.glUseProgram(mProgram); // VertexShader, FragmentShader가 셋팅되고 링크된 프로그램을 사용한다.
//쉐이더내에서 Handler 로 좌표값 셋팅//
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");// VertexShader를 통해 셋팅된 정점을 읽어들일수 있는 positionHandle을 가져옴
GLES20.glEnableVertexAttribArray(mPositionHandle); //좌표들을 쓸수 있도록 핸들을 기동시킴
GLES20.glVertexAttribPointer( //움직이는 PositionHandle이 float형의 VertexBuffer를 타고다니면서 좌표를 얻어냄
mPositionHandle,
COORDS_PER_VERTEX,
GLES20.GL_FLOAT,
false,
vertexStride,
mVertexBuffer);
//쉐이더내에서 Handler 로 색상 셋팅//
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor"); // Fragment Shader 를 통해 셋팅된 컬러 값을 읽어들일수 있는 positionHandle을 가져옴
GLES20.glUniform4fv(mColorHandle, 1, color, 0 ); // 색상을 설정함
//그리기 및 종료 GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertextCount); // 그리기
GLES20.glDrawElement(GLES20.GL_TRIANGLES, mDrawOrder.length, GLES20.GL_UNSINGED_SHORT, mDrawListBuffer);
GLES20.glDisableVertexAttribArray(mPositionHandle); //PositionHandle 중지함
}
//쉐이더들을 처리할(컴파일)할 메소드
public static int loadShader(int type, String shaderCode){
int shader = GLES20.glCreateShader(type);
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
return shader;
}
}
'ComputerGraphics [고려대학교_한정현]' 카테고리의 다른 글
6강 OpenGLES 1 (0) | 2023.04.11 |
---|---|
Android + OpenGLES로 삼각형 그리기 (0) | 2023.04.02 |
5강(1) - 랜더링 과정 중에서 View Transform ( World Space -> Camera Space 변환) (0) | 2023.03.26 |
4강(4) 3차원에서 World Transform ( Object Space -> World Space 변환 ) (0) | 2023.03.26 |
4강(2) - Transform 3x3행렬의 L구간, T구간 (0) | 2023.03.25 |