반응형
1.텍스처 객체 생성
glGenTextures 함수를 사용하여 텍스처 객체를 생성합니다. 이 함수는 생성된 텍스처 객체의 고유 식별자를 반환합니다.
2. 텍스처 바인딩
glBindTexture 함수를 사용하여 텍스처 객체를 바인딩합니다. 이제부터의 텍스처 작업은 해당 텍스처 객체에 대해 이루어집니다.
3. 텍스처 파라미터 설정
glTexParameteri 함수를 사용하여 텍스처의 필터링 및 반복 모드 등을 설정합니다. 필터링 모드는 텍스처를 확대 또는 축소할 때 어떻게 보간할지를 결정하며, 반복 모드는 텍스처 좌표가 텍스처 경계를 넘어갈 때 어떻게 처리할지를 결정합니다.
4. 텍스처 데이터 업로드
glTexImage2D 또는 glTexSubImage2D 함수를 사용하여 텍스처 데이터를 업로드합니다. glTexImage2D 함수는 텍스처의 기본 이미지 데이터를 업로드하고, glTexSubImage2D 함수는 이미 업로드된 텍스처에 추가적인 데이터를 업로드할 때 사용됩니다.
5. 텍스처 사용 설정
텍스처를 사용할 수 있도록 glEnable(GL_TEXTURE_2D) 함수를 호출하여 텍스처 단위를 활성화합니다.
아래는 opengl로 rgba를 gray로 바꾸는 코드
import android.opengl.GLES20;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
public class TextureConverter {
private static final String vertexShaderCode =
"attribute vec4 position;" +
"attribute vec2 texCoord;" +
"varying vec2 vTexCoord;" +
"void main() {" +
" gl_Position = position;" +
" vTexCoord = texCoord;" +
"}";
private static final String fragmentShaderCode =
"precision mediump float;" +
"varying vec2 vTexCoord;" +
"uniform sampler2D textureSampler;" +
"void main() {" +
" vec4 texColor = texture2D(textureSampler, vTexCoord);" +
" float gray = dot(texColor.rgb, vec3(0.299, 0.587, 0.114));" +
" gl_FragColor = vec4(gray, gray, gray, texColor.a);" +
"}";
private int program;
private int textureID;
public TextureConverter() {
// 쉐이더 컴파일
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
// 쉐이더 프로그램 생성 및 링크
program = GLES20.glCreateProgram();
GLES20.glAttachShader(program, vertexShader);
GLES20.glAttachShader(program, fragmentShader);
GLES20.glLinkProgram(program);
// 텍스처 생성
int[] textures = new int[1];
GLES20.glGenTextures(1, textures, 0);
textureID = textures[0];
// 텍스처 바인딩
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureID);
// 텍스처 필터링 설정
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
}
public void convertRGBAtoGray(int width, int height, ByteBuffer rgbaBuffer) {
// RGBA 데이터 업로드
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, width, height, 0,
GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, rgbaBuffer);
// 쉐이더 사용
GLES20.glUseProgram(program);
// 텍스처 바인딩
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureID);
int textureLocation = GLES20.glGetUniformLocation(program, "textureSampler");
GLES20.glUniform1i(textureLocation, 0);
// 정점 좌표 및 텍스처 좌표 설정
FloatBuffer vertexBuffer = ByteBuffer.allocateDirect(4 * 3 * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer();
vertexBuffer.put(new float[] {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
-1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f
});
vertexBuffer.position(0);
FloatBuffer texCoordBuffer = ByteBuffer.allocateDirect(4 * 2 * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer();
texCoordBuffer.put(new float[] {
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f
});
texCoordBuffer.position(0);
int positionLocation = GLES20.glGetAttribLocation(program, "position");
GLES20.glEnableVertexAttribArray(positionLocation);
GLES20.glVertexAttribPointer(positionLocation, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer);
int texCoordLocation = GLES20.glGetAttribLocation(program, "texCoord");
GLES20.glEnableVertexAttribArray(texCoordLocation);
GLES20.glVertexAttribPointer(texCoordLocation, 2, GLES20.GL_FLOAT, false, 0, texCoordBuffer);
// 그리기
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
// 정점 좌표 및 텍스처 좌표 비활성화
GLES20.glDisableVertexAttribArray(positionLocation);
GLES20.glDisableVertexAttribArray(texCoordLocation);
}
private static int loadShader(int type, String shaderCode) {
int shader = GLES20.glCreateShader(type);
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
return shader;
}
}
반응형
댓글