Ara
14
2012

OpenGL ES Android Kare Cizdirme

Merhaba arkadaşlar,bir önceki yazımda OpenGL ES ‘den bahsetmiştim ve bu yazımda da küçük bir uygulama yaparak konuya giriş yapıyorum.

Öncelikle bahsetmek istediğim bir ayrıntı var.Çoğu kişinin bildiği gibi Android üzerinde java ile kodlama yapılır ama OpenGL ES temel uygulama aslında C ile yazılmıştır.Bu ikisinin byte ları depolama aynı olmayabilir.Bu yüzden yeterli büyüklükte  Byte Buffer oluşturulmalıyız.Daha sonra bunu Float Buffer a dönüştürebiliriz.Bu Buffer lar ile ilgili yapılan işlemler OpenGL e verileri aktarabilmemiz için yapmamız gereken ek bir adımdır.Bu  konuda bilgi verdikten sonra kodlamaya başlayabiliriz.

İlk olarak oluşturmak istediğimiz kare için bir square.java isimli bir sınıf oluşturuyoruz.Bu sınıfın içersin de noktaları alan,renklerin değerlerini alan ve üçgenlerin indislerini alan 3 dizi oluşturulur.Byte buffer oluşturularak bunların normal yerel sıra ile buraya aktarılması sağlanır.Daha sonra çizim metodumuz olan draw metodununu yazarız.Kodun içerisinde de yeterli şekilde açıklama satırı mevcut.

 

package com.ftm.deneme;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
//import java.nio.IntBuffer;

import javax.microedition.khronos.opengles.GL10; //opengl es versiyon 1.0 GL10 kullanır
import javax.microedition.khronos.opengles.GL11;

/**
* A vertex shaded square.
*/

class Square {

	private FloatBuffer mFVertexBuffer;
	private ByteBuffer mColorBuffer;
	private ByteBuffer mIndexBuffer;
	public Square()
	{
	float vertices[] = //2D karenin x,y koordinatları 
		{
			-1.0f, -1.0f,
			1.0f, -1.0f,
			-1.0f, 1.0f,
			1.0f, 1.0f
			};
			byte maxColor=(byte)255;
			byte colors[] = // red,blue,green,alpha
			{
			maxColor,maxColor, 0,maxColor, //ilk vertex in rengi. 0-255 arası değer
			0, maxColor,maxColor,maxColor,
			0, 0, 0,maxColor,
			maxColor, 0,maxColor,maxColor
			};
			byte indices[] = //kare çizdirmek için üçgen indisleri verilir
			{
			0, 3, 1,
			0, 2, 3
			};
			//vertices,color ve indices oluşturulduktan sonra bunları opengl e anlayabilmesi için 
			//java formatına dönüştürülür.byte sıralaması bunun doğru olmasını sağlar.
			//aksi takdirde donanıma bağlı olarak,onlar ters sırayla olabilir.
			ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4); 
			vbb.order(ByteOrder.nativeOrder());
			mFVertexBuffer = vbb.asFloatBuffer();
			mFVertexBuffer.put(vertices);
			mFVertexBuffer.position(0);

			mColorBuffer = ByteBuffer.allocateDirect(colors.length);
			mColorBuffer.put(colors);
			mColorBuffer.position(0);

			mIndexBuffer = ByteBuffer.allocateDirect(indices.length);
			mIndexBuffer.put(indices);
			mIndexBuffer.position(0);
}

	public void draw(GL10 gl) //SquareRenderer.drawFrame () tarafından çağrılır.
	{
	gl.glFrontFace(GL11.GL_CW); //vertices yüzeylerinde nasıl sıralandığı opengl e bildirilir.
	//GL_CW saat yönünde 
	//data bufferları için işaretçiler renderer a teslim edilir
	/*Stride sadece sistem anlayacaksınız sonraki bit üzerine atlamak böylece GL veri arasındaki
	 *  paketlenmiş kullanıcı bilgisi bayt sayısıdır.(vertex 0 olan yer stride?)
	 */
	gl.glVertexPointer(2, GL11.GL_FLOAT, 0, mFVertexBuffer); 
	gl.glColorPointer(4, GL11.GL_UNSIGNED_BYTE, 0, mColorBuffer); 
	gl.glDrawElements(GL11.GL_TRIANGLES, 6,GL11.GL_UNSIGNED_BYTE, mIndexBuffer);
	gl.glFrontFace(GL11.GL_CCW); //varsayılan olarak değiştirilir.
	}

	}

Bu sınıfı oluşturduktan sonra sıra geldi SquareRenderer sınıfımızı oluşturmaya.Bu sınıfımızda neler olduğundan kısaca bahsedecek olursak onDrawFrame() metodumuz görüntünün oluşturulmasını sağlayan kodları içerir.Ayrıca glTranslatef kullanarak karemizin yukarı aşağı hareket etmesini sağlayankodumuzu yazdık.onSurfaceChanged(GL10 gl, int width, int height) metodumuz ise yüzey ilk oluşturulduğunda ya da değişiklik yapıldığında çağırılır.onSurfaceCreated(GL10 gl, EGLConfig config)metodu ise yüzey ilk oluşturulduğunda çağırılır yüzey hakkında gerekli ayarlamalar yapılır.


package com.ftm.deneme;

//import javax.microedition.khronos.egl.EGL10; 
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLSurfaceView; 
import java.lang.Math;

class SquareRenderer implements GLSurfaceView.Renderer
{
	private boolean mTranslucentBackground;
	private Square mSquare;
	private float mTransY;

public SquareRenderer(boolean useTranslucentBackground)
{
mTranslucentBackground = useTranslucentBackground;
mSquare = new Square(); 
}
public void onDrawFrame(GL10 gl) //görüntüyü oluşturur
{
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); //tüm ekran temizlenir
gl.glMatrixMode(GL10.GL_MODELVIEW); 
gl.glLoadIdentity(); 
gl.glTranslatef(0.0f,(float)Math.sin(mTransY), -3.0f); //kutunun yukarı ve aşağı hareketi.mTransY değeri
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); //9                            //-1,+1 arası değişir
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
mSquare.draw(gl); 
mTransY += .075f;
}
public void onSurfaceChanged(GL10 gl, int width, int height) //ilk oluşturulduğunda ya da değişiklik olduğunda
{
gl.glViewport(0, 0, width, height); 
float ratio = (float) width / height;
gl.glMatrixMode(GL10.GL_PROJECTION); 
gl.glLoadIdentity();
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10); //near/far, left/right, ve top/bottom.
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) 
{
gl.glDisable(GL10.GL_DITHER); //herhangi titrekliğin kapalı olması için
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
if (mTranslucentBackground) 
{
gl.glClearColor(0,0,0,0);
}
else
{
	gl.glClearColor(1,1,1,1);
	}
	gl.glEnable(GL10.GL_CULL_FACE); 
	gl.glShadeModel(GL10.GL_SMOOTH); 
	gl.glEnable(GL10.GL_DEPTH_TEST); 
	}

}

 

Ve son olarak da defalult olarak ismi MainActivity.java olan dosyamızda değişiklik yapılır.

package com.ftm.deneme;

import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.WindowManager;

public class ftm extends Activity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
GLSurfaceView view = new GLSurfaceView(this);
view.setRenderer(new SquareRenderer(true));
setContentView(view);
}
}

Programı derleyip çalıştırdığımızda şöyle bir görüntü elde ederiz :

kare

 

 

Yazar Hakkında

5 adet yazısı bulunuyor..

Print Friendly