텍스쳐 입히기( 이미지 덮어 씌우기 )
아래 내용은 100% 정확한 것이 아니며, 여기저기서 보고 실행해본 결과를 토대로 작성하였다.

기존 소스에서 몇 부분만 추가. Triangle 클래스는 사용하지 않고 Quad 클래스만 사용하여 연습해본다.


Quad.java
import java.nio.*;
import javax.microedition.khronos.opengles.*;
import android.content.*;
import android.graphics.*;
import android.opengl.*;

public class Quad extends Shape {
	
	private FloatBuffer vertexBuffer;
	private ShortBuffer indexBuffer;
	private FloatBuffer textureBuffer;
	
	private int[] textureName;
	
	private float[] vertices = {
			-0.5f	, 0.5f	, 0.0f, // 0, Left Top
			0.5f	, 0.5f	, 0.0f,	// 1, Right Top
			0.5f	, -0.5f	, 0.0f,	// 2, Right Bottom
			-0.5f	, -0.5f	, 0.0f	// 3, Left Bottom
	};

	private short[] index = {
		0, 1, 2,
		0, 2, 3
	};
	
	private float[] texture = {
		0.0f, 0.0f,
		0.0f, 1.0f,
		1.0f, 1.0f,
		1.0f, 0.0f
	};
	
	public Quad() {
		textureName = new int[1];

		vertexBuffer = getFloatBufferFromFloatArray(vertices);
		indexBuffer = getByteBufferFromByteArray(index);
		textureBuffer = getFloatBufferFromTextureArray(texture);
	}

	/* Draw */
	public void draw(GL10 gl) {

		gl.glFrontFace(GL10.GL_CW);
		
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
		gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
		
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
		
		gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, index.length, GL10.GL_UNSIGNED_SHORT, indexBuffer);
		
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);		
		gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
	}
	
	/* Initialize Texture */
	public void InitTexture(GL10 gl, Context context) {

		Bitmap imgPanda = BitmapFactory.decodeResource(context.getResources(), R.drawable.panda);

		gl.glGenTextures(1, textureName, 0);					// 텍스쳐 포인터 설정
		gl.glBindTexture(GL10.GL_TEXTURE_2D, textureName[0]);	// 텍스쳐 사용 연결

		gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
		gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, imgPanda, 0);
		
		imgPanda.recycle();
	}
}
우선 추가된 부분을 보면.
FloatBuffer textureBuffer;
 텍스쳐 버퍼.
 
int[] textureName;
 텍스쳐 포인터를 담는다.
 
float[] texture;
 텍스쳐 좌표. 좌표를 어떻게 하느냐에 따라 이미지가 이상하게 붙어버린다.
 어떤 순서로 붙는지 모르겠다. 


InitTexture();
  GLGameRenderer.java 에서 접근.
  우선 Bitmap 이미지를 가져온다.
  주의할점!! 이미지의 가로, 세로 길이가 '2의 배수'가 아니면 이미지가 나오지않는다.
 
 gl.glGenTextures(1, textureName, 0);
  텍스쳐 포인터 생성.
 
 gl.glBindTexture(GL10.GL_TEXTURE_2D, textureName[0]);
  텍스쳐 연결.
 
 gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
 gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); 
  이미지 자동 확대, 축소.

 GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, imgPanda, 0); 
  비트맵을 OpenGL 텍스쳐로 변경.

 
Draw();
 gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
  텍스쳐 좌표 설정.
 
 gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
  텍스쳐 활성화.
 
 gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
  비활성화.




이전까지와는 다르게 텍스쳐 버퍼가 추가되었다.

Shape.java
import java.nio.*;

public class Shape {

	FloatBuffer getFloatBufferFromFloatArray(float array[]) {
		ByteBuffer tempBuffer = ByteBuffer.allocateDirect(array.length * 4);
		tempBuffer.order(ByteOrder.nativeOrder());
		FloatBuffer buffer = tempBuffer.asFloatBuffer();
		buffer.put(array);
		buffer.position(0);
		return buffer;
	}
	
	ShortBuffer getByteBufferFromByteArray(short[] index) {
		ByteBuffer b = ByteBuffer.allocateDirect(index.length * 2);
		b.order(ByteOrder.nativeOrder());
		ShortBuffer buffer = b.asShortBuffer();
		buffer.put(index);
		buffer.position(0);
		return buffer;
	}
	
	FloatBuffer getFloatBufferFromTextureArray(float texture[]) {
		ByteBuffer tbb = ByteBuffer.allocateDirect(texture.length * 4);
		tbb.order(ByteOrder.nativeOrder());
		FloatBuffer buffer = tbb.asFloatBuffer();
		buffer.put(texture);
		buffer.position(0);
		return buffer;
	}
}
버퍼............



GLGameRenderer.java
@Override
	public void onDrawFrame(GL10 gl) {
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT);//|GL10.GL_DEPTH_BUFFER_BIT);
		gl.glLoadIdentity();
		
	//	mTriangle.draw(gl);
		mQuad.draw(gl);
	}

	@Override
	public void onSurfaceCreated(GL10 gl, EGLConfig arg1) {
		mQuad.InitTexture(gl, context);

		gl.glClearColor(0, 1, 0, 0.5f);										// RGBA
		gl.glEnable(GL10.GL_TEXTURE_2D);									// 텍스쳐 활성
		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);	// ??	
	}
onSurfaceCreated();
 mQuad.InitTexture(gl, context);   텍스쳐 초기화.
 
gl.glEnable(GL10.GL_TEXTURE_2D);   텍스쳐를 활성화 시킨다.



+ Recent posts