bab 4 viewing / camera -...
TRANSCRIPT
300
BAB 4 Viewing / Camera
4.1 Pengertian Viewing / Camera
Viewing camera adalah cara mengatur sudut pandang dari pergerakan kamera terhadap objek 2D maupun 3D, sehingga dapat memproyeksikan objek sehingga tampak riil.
4.1.1 Proyeksi Paralel
Proyeksi paralel dapat dikategorikan menurut hubungan antara arah proyeksi dengan vektor normal dari bidang proyeksi, ke dalam dua macam proyeksi. Proyeksi yang di hasilkan belum membentuk object 3D yang tampak riil. Pusat proyeksi pada objek akan bertemu di titik yang tak terhingga.
Gambar 4.1 Proyeksi paralel
4.1.2 Syntax Proyeksi Paralel
Dalam OpenGL terdapat syntax untuk Parallel Projection. Salah satunya dapat menggunakan syntax:
glOrtho(-15.0, 20.0, -10.0, 15.0, -50.0, 70.0); Mendefinisikan besarnya sistem koordinat 3D: dengan range sumbu x adalah [-15,20], range untuk sumbu y adalah [-10,15], range untuk sumbu z adalah [-50,70]
Pusat Proyeksi pada titik tak terhingga
Bidang Proyeksi
B
C
D
A
B’
C’
D’
A’
301
gluOrtho2D(-100,100,-200,200); Mendefinisikan besarnya sistem koordinat 2D: dengan range sumbu x adalah [-100,100] dan range untuk sumbu y adalah [-200,200].
4.1.3 Proyeksi Perspektif
Perspective projection di gunakan untuk memodifikasi gambar 2D pada layar agar terlihat 3D seperti di dunia nyata, gambar terlihat semakin kecil di belakang, mempunyai pusat di satu titik, konsep ini seperti penglihatan di dunia nyata, ketika objek benda semakin jauh maka akan terlihat semakin kecil, ketika di lihat lebih dekat maka benda akan membesar secara konstan satu garis lurus. Untuk menciptakan pandangan perspektif, maka setting kamera perlu diubah dari glOrtho() menjadi gluPerspective(), gluLookAt(), dan glFrustum().
Gambar 4.2 Proyeksi Perspektif
4.1.4 Syntax Proyeksi Perspektif
Dalam OpenGL terdapat syntax untuk Parallel Projection. Salah satunya dapat menggunakan syntax: • gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble near,
GLdouble far) – Fovy adalah sudut di bidang pandang (dalam rentang dari
[0.0, 180]) – Aspect adalah rasio aspek frustrum (lebar jendela di atas
ketinggian jendela) – Near dan far adalah nilai antara sudut pandang dan pesawat
dekat / jauh kliping
302
Gambar 4.3 gluPerspective()
• glFrustum(GLdouble left, GLdouble right, GLdouble bottom,
GLdouble top, GLdouble near, GLdouble far) – left, right, top, and bottom mendefinisikan batas dari near. – near and far menentukan seberapa jauh dari sudut pandang
clipping pane
Gambar 4.4 glFrustum()
• gluLookAt(GLdouble e_x, GLdouble e_y, GLdouble e_z, GLd-
ouble c_x, GLdouble c_y, GLdouble c_z, GLdouble u_x, GLd-ouble u_y, GLdouble u_z) – e_x, e_y, and e_z menentukan sudut pandang yang di-
inginkan (mata) – c_x, c_y, c_z menentukan beberapa titik di sepanjang garis
yang diinginkan sight (pusat) – u_x, u_y, and u_z mendifinisikan vector up dari camera kita
(up) Aktivasi Fungsi:
• gluPerspective() : ………………………
glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(AngleView, Aspek Rasio, Near, Far);
303
……………………………………….. • gluLookAt()
……………………… glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(mata_x, mata_y, mata_z, lihat_x, lihat_y, lihat_z, atas_x, atas_y, atas_z); ………………………………………..
4.2 Matematika Synthetic Camera
Cara kerja kamera sintetik:
Gambar 4.5 Cara Kerja Kamera Sintetik
Objek terletak pada sistem koordinat dunia (x, y, z), lensa ter-letak pada sistem koordinat UVN atau kamera sintetik (u, v, n), dan film sebagai bidang proyeksi.
Sistem koordinat kamera sintetik:
Gambar 4.6 Sistem koordinat kamera sintetik
Sumbu n sebagai arah pandang kamera, dan ditentukan ber-dasarkan vektor normal (nx,ny,nz).
Sumbu v sebagai arah atas, sumbu u sebagai arah horisontal. (v ∟ n), (u ∟ n) dan (u ∟ v)
Titik tengah sumbu u,v,n disebut VRP (Viewing Reference Point), yang ditentukan oleh titik (rx,ry,rz) pada koordinat dunia.
304
Cara mendapatkan sumbu u, v, dan n:
User menentukan titik tengah view/ eye (VRP), pusat titik pan-dang objek /center (lookAt) dan vektor atas (UpVector).
n adalah vektor dari VRP menuju lookAt. Lalu vektor n dinormal-isasi. Contoh : Diketahui VRP di titik r(rx , ry , rz), lookAt di titik la(lax , lay , laz) dan UpVector di titik up(upx,upy,upz). Sehingga,
nxvu
initv
initvvadalahinitvvektorunitnnupupinitv
initn
initnnadalahinitnvektorunitrlainitn
_
_)(_,*_
_
_)(_,_
Memindahkan titik koordinat dunia P(Px,Py,Pz) ke koordinat ka-mera sintetik Q(Qu,Qv,Qn). Titik Q dapat diperoleh melalui : – t(tx,ty,tz) = P - r – Qu = t • u, Qv = t • v dan Qn = t • n
Qu = (P-r) • u = (P • u)-(r • u) Contoh : Diketahui koordinat UVN dengan u=(-1,0,0), v=(0,0.8,0.6), n=(0,-0.6,0.8) dan r = (2,3,-1). Hitunglah lokasi Q(Qu,Qv,Qn) yang merupakan transformasi dari titik P(4,7,2) di koordinat dunia ! Jawab : t(tx,ty,tz) = P - r = (4-2,7-3,2-(-1)) =(2,4,3) Qu = t • u =(2,4,3) • (-1,0,0) = 2*(-1)+4*(0)+3*(0)=-2 Qv = t • v =(2,4,3) • (0,0.8,0.6) = 2*(0)+4*(0.8)+3*(0.6)=5 Qn = t • n =(2,4,3) • (0,-0.6,0.8) = 2*(0)+4*(-0.6)+3*(0.8)=0
Jadi titik Q terletak di koordinat (-2,5,0) pada sistem koordinat UVN.
Matrik transformasi dari koordinat dunia ke UVN:
110001
Pz
Py
Px
nrnnn
vrvvv
uruuu
Qn
Qv
Qu
zyx
zyx
zvx
Synthetic Camera di OpenGL : gluLookAt(eye_x, eye_y, eye_z, cen-ter_x, center_y, center_z, up_x, up_y, up_z )
305
Setelah titik Q diketahui, maka langkah berikutnya adalah melakukan proyeksi perspektif terhadap titik Q, sehingga di-peroleh titik T(u*, v*).
Proyeksi Q ke T dapat diperoleh dengan menggunakan rumus berikut:
n
n
v
n
n
u
e
Q
Qv
e
Q
Qu
1
*,
1
*
Mata/ eye terletak di (0, 0, en), dengan syarat en > nz dan en != 0.
Contoh: dengan menggunakan Tabel 4.1 dan 4.2 berikut: (se-bagai informasi tentang vertex dan permukaan objek)
Vertex X Y Z
0 0.0 -1.0 0.0
1 1.0 -1.0 0.0
2 1.0 -1.0 1.0
3 0.0 -1.0 1.0
4 0.5 0.5 0.5
Surface Index
0 1 4 1 2 4 2 3 4 3 0 4
Diketahui synthetic camera berada di (2, 3, 1) dan melihat kea rah (0, 0, 0). Arah atas didefinisikan melalui up=(0, 1, 0). Hitung dan gambarkan lokasi vertex-vertex seperti yang dilihat oleh syn-thetic camera apabila en=6.
306
Jawab: Mencari sistem koordinat UVN:
)88.0,01.0,46.0())56.032.0(),2.019.0(),16.03.0((
)))8.0(*)7.0((
))6.0(*)53.0(()),38.0(*)53.0(())27.0(*)7.0((),27.0(*)6.0()38.0(*)8.0((
38.06.07.0
27.08.053.0
)38.0,6.0,7.0(
36.0
)23.0,36.0,42.0(
05.013.018.0
)23.0,36.0,42.0(
)23.0()36.0()42.0(
)23.0,36.0,42.0(
|_|
_
)23.0,36.0,42.0()23.0,64.0,42.0()0,1,0(_
))27.0(*8.0),8.0(*8.0),53.0(*8.0()0,1,0()27.0,8.0,53.0)(8.0()0,1,0(_
)27.0,8.0,53.0(*))27.0(*0)8.0(*1)53.0(*0()0,1,0(*)(_
)27.0,8.0,53.0(14
1,
14
3,
14
2
)1()3()2(
)1,3,2(
|_|
_
)1,3,2()1,3,2()0,0,0(_
222
222
u
u
kji
nvu
initv
initvv
initv
initv
nnupupinitv
initn
initnn
rlainitn
la = (0,0,0) dan r = (2,3,1) n = (-0.53,-0.8,-0.27) v = (-0.7,0.6,-0.38) u = (0.46,-0.01,-0.88) Transformasi vertex ke sistem UVN:
Vertex tX=p-r t
Y=p-r t
Z=p-r
0 0-2=-2 -1-3=-4 0-1=-1
1 -1 -4 -1
2 -1 -4 0
3 -2 -4 0
4 -1.5 -2.5 -0.5
Qu=t•u Q
v=t•v Q
n=t•n
0 -0.62 4.53
0.46 -1.32 4
-0.42 -1.7 3.73
-0.88 -1 4.26
-0.23 -0.26 2.93
Gambar synthetic camera dari vertex hasil transformasi perspek-tif (u*,v*):
307
Vertex u* v*
0 0 -2.53
1 1.38 -3.96
2 -1.11 -4.49
3 -3.03 -3.45
4 -0.45 -0.51
Gambar 4.7 Gambar synthetic camera dari vertex hasil trtasformasi perspektif (u*,v*)
4.3 Membuat Multiple View Object
• Satu objek yang dapat dilihat dengan posisi mata yang ber-beda yaitu posisi mata kanan dan mata kiri.
• Didasarkan pada stereokopik alami dari sistem mata. • Masing-masing mata melihat objek dari lokasi yang berbeda.
Gambar 4.8 Ilustrasi Multiple View Object
v*
u*
308
Source Code 4.1 Code Membuat Multiple View Object
ESRender.java
package com.camera_n_viewing_project;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
//import android.opengl.GLU;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLU;
public class ESRender implements Renderer {
private TransObject transobject; // the
primitive object to be drawn
private TransPolarObject transpolarobject;
private TransKubusObject kubus;
private TransPiramidaObject piramida;
int RunMode=1;
float CurrentAngle = 0.0f; //
Angle in degrees
float AnimateStep = 2.0f; //
Rotation step per update
/** Constructor to set the handed over context */
public ESRender() {
this.piramida = new TransPiramidaOb-
ject();
}
@Override
public void onDrawFrame(GL10 gl) {
// clear Screen and Depth Buffer
//gl.glClearColor(1.0f, 1.0f, 1.0f,
1.0f); // set background dgn warna putih
gl.glClear(GL10.GL_COLOR_BUFFER_BIT |
GL10.GL_DEPTH_BUFFER_BIT);
// Reset the Modelview Matrix
gl.glLoadIdentity();
// menampilkan piramida
gl.glPushMatrix();
gl.glTranslatef(0.0f, 0.0f, 0.0f);
// Rotate the object
gl.glTranslatef(0.0f, 0.0f, -
5.0f);
gl.glScalef(0.5f, 0.5f, 0.5f); //
Scale down
309
gl.glRotatef( CurrentAngle, 0.1f,
1.0f, -0.1f );
piramida.draw(gl);
gl.glPopMatrix();
// Update the rotational angle after each
refresh
if (RunMode==1) {
// re-Calculate animation parame-
ters
CurrentAngle += AnimateStep;
if (CurrentAngle > 360.0) {
//CurrentAngle -=
360.0*Math.floor(CurrentAngle/360.0);
CurrentAngle=0.0f;
CurrentAngle += Ani-
mateStep;
}
}
}
@Override
public void onSurfaceChanged(GL10 gl, int width,
int height) {
if (height == 0)
height = 1; // To prevent divide
by zero
float aspect = (float) width / height;
// Set the viewport (display area) to
cover the entire window
gl.glViewport(0, 0, width, height);
// Setup perspective projection, with as-
pect ratio matches viewport
gl.glMatrixMode(GL10.GL_PROJECTION); //
Select projection matrix
gl.glLoadIdentity(); // Reset projection
matrix
// Use perspective projection
GLU.gluPerspective(gl, 45, aspect, 0.1f,
100.f);
//gl.glOrthof(-3.0f, 3.0f, -3.0f, 3.0f, -
3.0f, 3.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW); //
Select model-view matrix
gl.glLoadIdentity(); // Reset
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig
config) {
gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// Set color's clear-value to black
310
gl.glClearDepthf(1.0f); // Set depth's
clear-value to farthest
gl.glEnable(GL10.GL_DEPTH_TEST); // Ena-
bles depth-buffer for hidden
// surface removal
gl.glDepthFunc(GL10.GL_LEQUAL); // The
type of depth testing to do
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
GL10.GL_NICEST); // nice
// perspective
// view
gl.glShadeModel(GL10.GL_SMOOTH); // Ena-
ble smooth shading of color
gl.glDisable(GL10.GL_DITHER); // Disable
dithering for better
// performance
}
public int getRunMode() {
return RunMode;
}
public void setRunMode(int mRunMode) {
RunMode = mRunMode;
}
public float getAnimateStep() {
return AnimateStep;
}
public void setAnimateStep(float mAnimateStep) {
AnimateStep = mAnimateStep;
}
}
ESSurfaceView.java
package com.camera_n_viewing_project;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
/**
* A view container where OpenGL ES graphics can be
drawn on screen.
* This view can also be used to capture touch events,
such as a user
* interacting with drawn objects.
*/
public class ESSurfaceView extends GLSurfaceView {
311
private final ESRender esRender;
public ESSurfaceView(Context context) {
super(context);
// Set the Renderer for drawing on the GLSur-
faceView
esRender = new ESRender();
setRenderer(esRender);
// To enable keypad
this.setFocusable(true);
this.requestFocus();
// To enable touch mode
this.setFocusableInTouchMode(true);
// Render the view only when there is a change
in the drawing data
// merender hanya ketika ada perubahan/ event
//setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
//private final float TOUCH_SCALE_FACTOR = 180.0f /
320;
//private float mPreviousX;
//private float mPreviousY;
@Override
public boolean onTouchEvent(MotionEvent v) {
// MotionEvent reports input details from the
touch screen
// and other input controls. In this case, we
are only
// interested in events where the touch position
changed.
/*float x = e.getX();
float y = e.getY();*/
switch (v.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.v("Test Action Down", "action
down working");
Log.i("Test Action Nilai",
""+Math.abs(esRender.getRunMode()-1));
esRen-
der.setRunMode(Math.abs(esRender.getRunMode()-1));
//break;
requestRender();
//case MotionEvent.ACTION_POINTER_UP:
//Log.v("Test Action
ACTION_POINTER_UP", "action working");
//Log.i("Test Action Nilai",
""+Math.abs(esRender.getAnimateStep()));
312
//esRender.setAnimateStep(esRender.getAnimateStep
()+8.0f);
//requestRender();
//case MotionEvent.ACTION_MOVE:
//Log.v("Test Action
ACTION_POINTER_DOWN", "action working");
//Log.i("Test Action Nilai",
""+Math.abs(esRender.getAnimateStep()));
//esRender.setAnimateStep(esRender.getAnimateStep
()-8.0f);
//requestRender();
//case MotionEvent.ACTION_UP:
//Log.v("Test Action Up", "action
up working");
//esRender.setRunMode(esRender.getRunMode());
//requestRender();
//case MotionEvent.ACTION_MOVE:
//esRender.setRunMode(esRender.getRunMode());
//requestRender();
}
//mPreviousX = x;
// mPreviousY = y;
return true;
//break;
}
// Key-up event handler
@Override
public boolean onKeyUp(int keyCode, KeyEvent
event) {
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_RIGHT: // In-
crease rightward speed
Log.v("Test Action
KEYCODE_DPAD_RIGHT", "action working");
Log.i("Test Action Nilai",
""+Math.abs(esRender.getAnimateStep()));
esRen-
der.setAnimateStep(esRender.getAnimateStep()+8.0f);
requestRender();
//ballSpeedX++;
break;
case KeyEvent.KEYCODE_DPAD_LEFT: // In-
crease leftward speed
esRen-
der.setAnimateStep(esRender.getAnimateStep()-8.0f);
requestRender();
//ballSpeedX--;
break;
case KeyEvent.KEYCODE_DPAD_UP: // In-
crease upward speed
//ballSpeedY--;
break;
case KeyEvent.KEYCODE_DPAD_DOWN: // In-
crease downward speed
313
//ballSpeedY++;
break;
case KeyEvent.KEYCODE_DPAD_CENTER: //
Stop
//ballSpeedX = 0;
//ballSpeedY = 0;
break;
case KeyEvent.KEYCODE_A: // Zoom in
Log.v("Test Action
KEYCODE_DPAD_RIGHT", "action working");
Log.i("Test Action Nilai",
""+Math.abs(esRender.getAnimateStep()));
esRen-
der.setAnimateStep(esRender.getAnimateStep()+8.0f);
requestRender();
// Max radius is about 90% of half
of the smaller dimension
//float maxRadius = (xMax > yMax)
? yMax / 2 * 0.9f : xMax / 2 * 0.9f;
//if (ballRadius < maxRadius) {
//ballRadius *= 1.05; //
Increase radius by 5%
//}
break;
case KeyEvent.KEYCODE_Z: // Zoom out
Log.v("Test Action
KEYCODE_DPAD_RIGHT", "action working");
Log.i("Test Action Nilai",
""+Math.abs(esRender.getAnimateStep()));
esRen-
der.setAnimateStep(esRender.getAnimateStep()-8.0f);
requestRender();
//if (ballRadius > 20) { // Mini-
mum radius
// ballRadius *= 0.95; // De-
crease radius by 5%
//}
break;
}
return true; // Event handled
}
}
MainActivity.java
package com.camera_n_viewing_project;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.Window;
import android.view.WindowManager;
public class MainActivity extends Activity {
/** The OpenGL view */
314
private GLSurfaceView glSurfaceView;
@Override
protected void onCreate(Bundle savedInstanceS-
tate) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
// requesting to turn the title OFF
requestWindowFeature(Window.FEATURE_NO_TITLE);
// making it full screen
getWin-
dow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREE
N,
WindowManag-
er.LayoutParams.FLAG_FULLSCREEN);
// Initiate the Open GL view and
// create an instance with this activity
glSurfaceView = new ESSurfaceView(this);
// set our renderer to be the main renderer with
// the current activity context
//glSurfaceView.setRenderer(new ESRender());
setContentView(glSurfaceView);
}
/**
* Remember to resume the glSurface
*/
@Override
protected void onResume() {
super.onResume();
glSurfaceView.onResume();
}
/**
* Also pause the glSurface
*/
@Override
protected void onPause() {
super.onPause();
glSurfaceView.onPause();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to
the action bar if it is present.
getMenuInflater().inflate(R.menu.main,
menu);
return true;
}
}
315
TransPiramidaObject.java
package com.camera_n_viewing_project;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
public class TransPiramidaObject {
private float[] vertices = { // 5 vertices of the
pyramid in (x,y,z)
-1.0f, -1.0f, -1.0f, // 0. left-
bottom-back
1.0f, -1.0f, -1.0f, // 1. right-
bottom-back
1.0f, -1.0f, 1.0f, // 2. right-
bottom-front
-1.0f, -1.0f, 1.0f, // 3. left-
bottom-front
0.0f, 1.0f, 0.0f // 4. top
};
private float[] colors = { // Colors of the 5
vertices in RGBA
0.0f, 0.0f, 1.0f, 1.0f, // 0. blue
0.0f, 1.0f, 0.0f, 1.0f, // 1.
green
0.0f, 0.0f, 1.0f, 1.0f, // 2. blue
0.0f, 1.0f, 0.0f, 1.0f, // 3.
green
1.0f, 0.0f, 0.0f, 1.0f // 4. red
};
private byte[] indices = { // Vertex indices of
the 4 Triangles
0, 1, 4, // back face
1, 2, 4, // right face
2, 3, 4, // front face (CCW)
3, 0, 4 // left face
};
// Constructor - Set up the buffers
public TransPiramidaObject() {
}
// Point to our vertex buffer, return buffer
holding the vertices
public static FloatBuffer makeFloatBuffer(float[]
arr){
ByteBuffer bb = ByteBuff-
er.allocateDirect(arr.length * 4);
bb.order(ByteOrder.nativeOrder());
FloatBuffer fb = bb.asFloatBuffer();
fb.put(arr);
fb.position(0);
return fb;
}
316
// Setup index-array buffer. Indices in byte.
public static ByteBuffer makeByteBuffer(byte[]
arr){
ByteBuffer bb = ByteBuff-
er.allocateDirect(arr.length);
bb.put(arr);
bb.position(0);
return bb;
}
// Draw the shape
public void draw(GL10 gl) {
gl.glFrontFace(GL10.GL_CCW); // Front
face in counter-clockwise
// orientation
// Enable arrays and define their buffers
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices));
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
gl.glColorPointer(4, GL10.GL_FLOAT, 0,
makeFloatBuffer(colors));
//gl.glDrawElements(GL10.GL_TRIANGLES,
indices.length,
//GL10.GL_UNSIGNED_BYTE,
makeByteBuffer(indices));
gl.glDrawElements(GL10.GL_LINE_STRIP, in-
dices.length,
GL10.GL_UNSIGNED_BYTE,
makeByteBuffer(indices));
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}
}
Gambar 4.9 Multiple View Object
317
BAB 5 Texture Mapping
5.1 Pengertian Texture Mapping
Texture Mapping merupakan metode yang digunakan untuk menambah detail texture pada permukaan objek.
Gambar 5.1 Texture Mapping
Texture merupakan data segi-empat sederhana yang berada pada bidang texture. Bidang texture diwakili oleh dua sumbu koordinat yaitu sumbu s dan sumbu t. Setiap texture akan memenuhi bidang koordinat (0.0,0.0) sd. (1.0,1.0). Nilai individual dari array texture biasanya dikenal dengan istilah texels (texture pixels).Yang membuat texture mapping sedikit rumit adalah bagaimana proses pemetaan antara bentuk segi empat texture ke polygon mengingat secara umum bentuk poligon biasanya non-rectangular. Beberapa contoh penggunaan texture mapping antara lain:
Mensimulasikan aspek visual dari material seperti tampakan kayu, batu bata, atau granit.
Mengurangi kompleksitas (jumlah polygon yang dibutuhkan) dari suatu obyek geometri.
Teknik pemrosesan citra seperti image wraping dan rectification, rotation, dan scaling.
Mensimulasikan berbagai efek permukaan seperti efek reflektif seperti cermin atau lantai yang telah digosok mengkilat, efek tonjolan, dan sebagainya.
318
Salah satu keuntungan dari texture mapping adalah bahwa detail visual itu berada di citra bukan di geometri. Dan sekompleks apapun citra, selama tidak merubah ukuran citra, tidak berpengaruh pada kinerja keseluruhan, yaitu kompleksitas dari citra tidak berpengaruh kepada pipeline geometric (transformasi, clipping) dari OpenGL. Texture ditambahkan saat rasterisasi ketika geometric pipeline dan pixel pipeline bertemu seperti diilustrasikan pada Gambar 5.2. Raster-isasi adalah mengubah gambar dari format vector ke format pixel atau titik.
vertices
image
geometry pipeline
pixel pipeline
rasterizer
Gambar 5.2 Ilustrasi Rasterisasi
Ada dua cara untuk melakukan texture mapping:
Membuat extra polygon untuk membangun detail model pada ob-jek. o Menambah kompleksitas scene sehingga memperlambat
kecepatan rendering grafis. o Beberapa fitur grafis akan sulit untuk dimodelkan.
Membuat texture map pada permukaan (pendekatan yang lebih sering digunakan).
Secara konseptual ada tiga langkah dalam melakukan texture mapping, yaitu: 1. Penentuan texture
Baca image dari file
Generate texture id untuk image tersebut glGenTextures(3, &texture[0])
2. Pemberian koordinat texture ke vertex 3. Penentuan parameter texture (wrapping / filtering)
5.2 Representasi Texture Mapping
Bitmap Texture Gambar dua dimensi yang direpresentasikan dengan array tex-ture dua dimensi [height][width]. Setiap pixel yang disebut dengan texel adalah terletak pada koordinat (s,t). Nilai s dan t bi-asanya dinormalisasi dengan range [0,1]. Untuk setiap koordinat
319
(s,t) yang telah dinormalisasi, terdapat image value [red, green, blue].
Gambar 5.3 Bitmap Texture
Procedural Texture Procedural texture adalah gambar yang dihasilkan computer yang dibuat dengan algoritma untuk menciptakan representasi realistis dari unsur-unsur alam seperti kayu, marmer, granit, logam, batu, dan sebagainya.
5.3 Parameter Texture Mapping
Texture mapping diaktifkan dan di-non-aktifkan menggunakan glEnable() atau glDisable() dengan GL_TEXTURE_1D atau GL_TEXTURE_2D untuk menandakan satu atau dua dimensi. glTexParameter*() digunakan untuk mengatur texture.
Berikut merupakan contoh penggunaan glTexParameter*() un-tuk melakukan magnification dan minification:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
Gambar 5.4 Magnification dan Minification
320
Berikut merupakan contoh penggunakan glTexParameter*() un-tuk melakukan repeating:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
Gambar 5.5 Repeating Texture
Berikut merupakan contoh penggunakan glTexParameter*() un-tuk melakukan clamping:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
Gambar 5.6 Clamping Texture
Berikut merupakan contoh penggunakan glTexParameter*() un-tuk melakukan repeating dan clamping:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
321
Gambar 5.7 Repeating dan Clamping Texture
5.4 Texture Mapping Pada Segitiga
Source Code 5.1 Code Texture Mapping Pada Segitiga
ESRender.java
package com.texture_mapping;
import java.util.Formatter;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLU;
import android.util.Log;
import android.widget.TextView;
public class ESRender implements Renderer {
private ESText glText;
private TextView textview;
private ObjectArena objectarena; // the
primitive object to be drawn
private ObjectBall objectball;
private ObjectBall objectball_hole;
private ObjectBall objectball1;
private ObjectBall objectball2;
private ObjectBall objectball3;
Context context;
322
private int RunMode=1;
private float mAngle = 0.0f; //
Angle in degrees
private float AnimateStep = 2.0f;
// Rotation step per update
private long startTime;
private long fpsStartTime;
private long numFrames;
float radius = 50.0f; // Ball's radius
float x = radius; // Ball's center (x,y)
float y = radius;
float speedX = 5f; // Ball's speed (x,y)
float speedY = 3f;
int xMin, xMax, yMin, yMax;
private int mywidth=0;
private int myheight=0;
/** Constructor to set the handed over context */
public ESRender(Context context) {
//super();
this.context = context;
this.objectarena = new ObjectArena();
this.objectball = new ObjectBall();
this.objectball_hole = new ObjectBall();
this.objectball1 = new ObjectBall();
this.objectball2 = new ObjectBall();
this.objectball3 = new ObjectBall();
}
@Override
public void onDrawFrame(GL10 gl) {
// Draw background color
gl.glClear(GL10.GL_COLOR_BUFFER_BIT |
GL10.GL_DEPTH_BUFFER_BIT);
// segitiga
gl.glPushMatrix();
//GLU.gluLookAt(gl, 0, 0, 0.01f,
0f, 0f, 0f, 0f, 1.0f, 0.0f);
gl.glTranslatef(50.0f, 60.0f,
0.0f);
gl.glScalef(80.0f, 80.0f, 0.0f);
gl.glRotatef(180, 1.0f, 0.0f,
0.0f);
gl.glTranslatef(5.0f, -3.5f,
0.0f);
objectball1.draw_segitiga(gl);
gl.glPopMatrix();
323
// update
moveWithCollisionDetection(this);
set((int)-radius, (int)-radius, mywidth,
myheight);
// Update the rotational angle after each
refresh
if (RunMode==1) {
// re-Calculate animation parame-
ters
mAngle += AnimateStep;
if (mAngle > 360.0) {
//CurrentAngle -=
360.0*Math.floor(CurrentAngle/360.0);
mAngle=0.0f;
mAngle += AnimateStep;
}
}
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig
config) {
gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f); // Set
color's clear-value to black
gl.glClearDepthf(1.0f); // Set depth's clear-
value to farthest
gl.glEnable(GL10.GL_DEPTH_TEST); // Ena-
bles depth-buffer for hidden
// surface removal
gl.glDepthFunc(GL10.GL_LEQUAL); // The
type of depth testing to do
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
GL10.GL_NICEST); // nice
// perspective
// view
gl.glShadeModel(GL10.GL_SMOOTH); // Ena-
ble smooth shading of color
gl.glDisable(GL10.GL_DITHER); // Disable
dithering for better
// performance
// Create the GLText
glText = new ESText( gl, context.getAssets()
);
// Load the font from file (set size + pad-
ding), creates the texture
// NOTE: after a successful call to this the
font is ready for rendering!
glText.load( "Roboto-Regular.ttf", 14, 2, 2
); // Create Font (Height: 14 Pixels / X+Y Padding 2
Pixels)
324
//gl.glDisable(GL10.GL_DITHER); // Disa-
ble dithering for better
// performance
// Setup Texture, each time the surface is
created (NEW)
objectball_hole.loadBallTexture(gl, con-
text,0);
objectball1.loadBallTexture(gl, context,1);
objectball2.loadBallTexture(gl, context,0);
objectball3.loadBallTexture(gl, context,1);
gl.glEnable(GL10.GL_TEXTURE_2D); // Ena-
ble texture (NEW)
}
@Override
public void onSurfaceChanged(GL10 gl, int width,
int height) {
mywidth=width;
myheight=height;
gl.glViewport( 0, 0, width, height );
// Setup orthographic projection
gl.glMatrixMode( GL10.GL_PROJECTION );
// Activate Projection Matrix
gl.glLoadIdentity();
// Load Identity Matrix
gl.glOrthof(
// Set Ortho Projection
(Left,Right,Bottom,Top,Front,Back)
0, width,
0, height,
1.0f, -10.0f
);
// Save width and height
//this.width = width;
// Save Current Width
//this.height = height;
// Save Current Height
gl.glMatrixMode(GL10.GL_MODELVIEW); // Se-
lect model-view matrix
gl.glLoadIdentity(); // Reset
}
public float getxMax() {
return xMax;
}
public void setxMax(int xmax) {
xMax = xmax;
}
325
public float getxMin() {
return xMin;
}
public void setxMin(int xmin) {
xMin = xmin;
}
public float getyMax() {
return yMax;
}
public void setyMax(int ymax) {
yMax = ymax;
}
public float getyMin() {
return yMin;
}
public void setyMin(int ymin) {
yMin = ymin;
}
public float getspeedX() {
return speedX;
}
public void setspeedX(float speedX_) {
speedX = speedX_;
}
public float getspeedY() {
return speedY;
}
public void setspeedY(float speedY_) {
speedY = speedY_;
}
public void moveWithCollisionDetection(ESRender
esRender) {
// Get new (x,y) position
x += speedX;
y += speedY;
// Detect collision and react
if (x + radius > esRender.getxMax()) {
speedX = -speedX;
x = esRender.getxMax() - radius;
}
else if (x - radius < esRender.getxMin())
{
speedX = -speedX;
x = esRender.getxMin() + radius;
}
if (y + radius > esRender.getyMax()) {
speedY = -speedY;
y = esRender.getyMax() - radius;
} else if (y - radius < esRen-
der.getyMin()) {
speedY = -speedY;
y = esRender.getyMin() + radius;
}
}
326
public void set(int x, int y, int width, int
height) {
xMin = x;
//xMax = x + width - 1;
xMax = x + width;
yMin = y;
//yMax = y + height - 1;
yMax = y + height;
}
}
ESSurfaceView.java
package com.texture_mapping;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
/**
* A view container where OpenGL ES graphics can be
drawn on screen.
* This view can also be used to capture touch events,
such as a user
* interacting with drawn objects.
*/
public class ESSurfaceView extends GLSurfaceView {
private final ESRender esRender;
private float previousX;
private float previousY;
public ESSurfaceView(Context context) {
super(context);
// Set the Renderer for drawing on the GLSur-
faceView
esRender = new ESRender(context);
setRenderer(esRender);
// To enable keypad
this.setFocusable(true);
this.requestFocus();
// To enable touch mode
this.setFocusableInTouchMode(true);
// Render the view only when there is a change
in the drawing data
// merender hanya ketika ada perubahan/ event
327
//setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
//private final float TOUCH_SCALE_FACTOR =
getWidth() / getHeight();
private float mPreviousX;
private float mPreviousY;
@Override
public boolean onTouchEvent(MotionEvent v) {
// MotionEvent reports input details from the
touch screen
// and other input controls. In this case, we
are only
// interested in events where the touch posi-
tion changed.
float currentX = v.getX();
float currentY = v.getY();
float deltaX, deltaY;
//float scalingFactor = 0.50f / ((esRen-
der.xMax > esRender.yMax) ? esRender.yMax
//: esRender.xMax);
switch (v.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.v("Test Action Down", "action
down working");
//break;
requestRender();
//case MotionEvent.ACTION_POINTER_UP:
//Log.v("Test Action
ACTION_POINTER_UP", "action working");
//requestRender();
//case MotionEvent.ACTION_MOVE:
//Log.v("Test Action
ACTION_POINTER_DOWN", "action working");
//requestRender();
//case MotionEvent.ACTION_UP:
//Log.v("Test Action Up", "action
up working");
//requestRender();
case MotionEvent.ACTION_MOVE:
// Modify rotational angles according to
movement
deltaX = currentX - previousX;
deltaY = currentY - previousY;
//esRender.setspeedX(esRender.getspeedX()+ (del-
taX/getWidth()));
//esRender.setspeedY(esRender.getspeedY()+ (del-
taY/getHeight()));
esRen-
der.setspeedX(esRender.getspeedX()+ deltaX/100);
328
esRen-
der.setspeedY(esRender.getspeedY()+ deltaY/100);
requestRender();
}
// Save current x, y
previousX = currentX;
previousY = currentY;
return true; // Event handled
//break;
}
// Key-up event handler
@Override
public boolean onKeyUp(int keyCode, KeyEvent
event) {
switch (keyCode) {
case KeyEvent.KEYCODE_A: // mengurangi
kecepatan object
if((esRender.getspeedX()- 0.05f
>0) ){
esRen-
der.setspeedX(esRender.getspeedX()- 0.05f);
}
if((esRender.getspeedX()- 0.05f
<0) ){
esRender.setspeedX(0.0f);
}
if((esRender.getspeedY()- 0.05f
>=0)){
esRen-
der.setspeedY(esRender.getspeedY()- 0.05f);
}
if((esRender.getspeedY()- 0.05f
<0) ){
esRender.setspeedY(0.0f);
}
Log.v("Test Action KEYCODE_A",
"action working");
break;
case KeyEvent.KEYCODE_Z:
Log.v("Test Action KEYCODE_Z",
"action working");
break;
}
return true; // Event handled
}
}
329
MainActivity.java
package com.texture_mapping;
import com.texture_mapping.R;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.Window;
import android.view.WindowManager;
public class MainActivity extends Activity {
/** The OpenGL view */
private GLSurfaceView glSurfaceView;
@Override
protected void onCreate(Bundle savedInstanceS-
tate) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
// requesting to turn the title OFF
requestWindowFeature(Window.FEATURE_NO_TITLE);
// making it full screen
getWin-
dow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCR
EEN,
WindowManag-
er.LayoutParams.FLAG_FULLSCREEN);
// Initiate the Open GL view and
// create an instance with this activity
glSurfaceView = new ESSurfaceView(this);
// set our renderer to be the main renderer
with
// the current activity context
//glSurfaceView.setRenderer(new ESRender());
setContentView(glSurfaceView);
}
/**
* Remember to resume the glSurface
*/
@Override
protected void onResume() {
super.onResume();
glSurfaceView.onResume();
}
/**
* Also pause the glSurface
*/
330
@Override
protected void onPause() {
super.onPause();
glSurfaceView.onPause();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to
the action bar if it is present.
getMenuInflater().inflate(R.menu.main,
menu);
return true;
}
}
ObjectBall.java
package com.texture_mapping;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;
import ja-
vax.microedition.khronos.opengles.GL11ExtensionPack;
import com.texture_mapping.R;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLES20;
import android.opengl.GLUtils;
import android.util.Log;
public class ObjectBall {
private float vertices[] = {
-0.5f, -0.5f, 0.0f, // V1 -
first vertex (x,y,z)
-0.5f, 0.5f, 0.0f, //
V2
0.5f, 0.5f, 0.0f, //
V3
0.5f, -0.5f, 0.0f, // V4
-0.5f, -0.5f, 0.0f //
V5
331
};
private float textCoord_Triagle[]={
1.0f, 1.0f, 0.0f, //
V3
0.0f, 1.0f, 0.0f, //
V2
0.5f, 0.0f, 0.0f, // V1 -
first vertex (x,y,z)
};
float[] texCoords = { // Texture coords for the
above face (NEW)
0.0f, 1.0f, // A. left-bottom
(NEW)
1.0f, 1.0f, // B. right-bottom
(NEW)
0.0f, 0.0f, // C. left-top (NEW)
1.0f, 0.0f // D. right-top (NEW)
};
private float vertices_color[] = {
1.0f, 0.0f, 0.0f, 1.0f, //
CV1 - first color (red,green,blue)
0.0f, 1.0f, 0.0f, 1.0f, //
CV2
0.0f, 0.0f, 1.0f, 1.0f, //
CV3
0.0f, 1.0f, 0.0f, 1.0f, //
CV4
1.0f, 0.0f, 0.0f, 1.0f
// CV5
};
private float vertices_circle[]={0.0f,0.0f,0.0f};
private float verti-
ces_circle_color[]={0.0f,0.0f,0.0f,0.5f};
private float textCoord[],textCoord_hole[];
private float verti-
ces_circle1[],vertices_circle1_hole[];
private int[] imageFileIDs = { // Image file IDs
R.drawable.nature,
R.drawable.mule};
int[] textures_indek = new int[1];
private int batas_sudut=360;
float jari_jari;
float a,b;
float x,y;
float step=3.0f,step_line=0.2f;
float x1,y1;
float x2,y2;
float teta, teta_hole;
private int loop,loop_color;
public ObjectBall() {
332
// ============ start to generate stetch
texture coordinat ==========================
//Inisialisasi
jari_jari=0.5f;
// Titik Pusat
a = 0.5f; b = 0.5f ;
//x=a+jari_jari; y=b;
teta = 0;
// generate stretch texture coordinat
teta=0; teta_hole=0;
textCoord = new float[batas_sudut * 3];
textCoord_hole = new float[batas_sudut *
3];
for (int ii = 0; ii < batas_sudut * 3; ii
+= 3) {
// membentuk textCoord untuk cir-
cle color
textCoord[ii] =
(jari_jari*((float) Math.cos(-teta)))+a;
textCoord[ii + 1] =
(jari_jari*((float) Math.sin(-teta)))+b;
textCoord[ii + 2] = 0.0f;
teta += Math.PI / 90;
// membentuk textCoord untuk cir-
cle hole
textCoord_hole[ii] =
(jari_jari*((float) Math.cos(-teta_hole)))+a;
textCoord_hole[ii + 1] =
(jari_jari*((float) Math.sin(-teta_hole)))+b;
textCoord_hole[ii + 2] = 0.0f;
teta_hole += 15;
}
// ============ start to generate verti-
ces to circle (Cara 1) ==========================
//Inisialisasi
jari_jari=50.0f;
// Titik Pusat
a = 50.0f; b = 50.0f ;
teta=0; teta_hole=0;
vertices_circle1 = new float[batas_sudut
* 3];
vertices_circle1_hole = new
float[batas_sudut * 3];
for (int ii = 0; ii < batas_sudut * 3; ii
+= 3) {
// membentuk vertices_circle1
vertices_circle1[ii] =
(jari_jari*((float) Math.cos(teta)))+a;
vertices_circle1[ii + 1] =
(jari_jari*((float) Math.sin(teta)))+b;
333
vertices_circle1[ii + 2] = 0.0f;
teta += Math.PI / 90;
// membentuk vertices_circle1
vertices_circle1_hole[ii] =
(jari_jari*((float) Math.cos(teta_hole)))+a;
vertices_circle1_hole[ii + 1] =
(jari_jari*((float) Math.sin(teta_hole)))+b;
vertices_circle1_hole[ii + 2] =
0.0f;
teta_hole += 15;
}
// ============ start to generate verti-
ces to circle (Cara 2) ==========================
//Inisialisasi
jari_jari=50.0f;
// Titik Pusat
a = 50.0f; b = 50.0f ;
x=a+jari_jari; y=b;
loop=0;
loop_color=0;
vertices_circle=new
float[(int)(3*batas_sudut/step)*3];
vertices_circle_color=new
float[(int)(3*batas_sudut/step)*4];
for(teta=0;teta<=2*batas_sudut;teta+=step){
vertices_circle[loop] = (float) ((x-
a)*Math.cos((teta/180)*(22/7)) - ((y-
b)*Math.sin((teta/180)*(22/7))) + a);
vertices_circle[loop+1] = (float) ((x-
a)*Math.sin((teta/180)*(22/7)) - ((y-
b)*Math.cos((teta/180)*(22/7))) + b);
vertices_circle[loop+2]=0;
loop+=3;
//mengenerate warna untuk setiap vertex
//vertices_circle_color[loop_color]=(float) ((x-
a)*Math.cos((teta/180)*(22/7)) - ((y-
b)*Math.sin((teta/180)*(22/7))) + a);
//vertices_circle_color[loop_color+1]=(float)
((x-a)*Math.sin((teta/180)*(22/7)) - ((y-
b)*Math.cos((teta/180)*(22/7))) + b);
vertices_circle_color[loop_color]=(float)
(Math.cos((teta/180)*(22/7)) );
verti-
ces_circle_color[loop_color+1]=(float)
(Math.sin((teta/180)*(22/7)));
vertices_circle_color[loop_color+2]=0.5f;
vertices_circle_color[loop_color+3]=0.5f;
334
loop_color+=4;
}
// ============= end for generate vertices to
circle ====================
}
// Point to our vertex buffer, return buffer
holding the vertices
public static FloatBuffer makeFloatBuffer(float[]
arr){
ByteBuffer bb = ByteBuff-
er.allocateDirect(arr.length * 4);
bb.order(ByteOrder.nativeOrder());
FloatBuffer fb = bb.asFloatBuffer();
fb.put(arr);
fb.position(0);
return fb;
}
// Setup index-array buffer. Indices in byte.
public static ByteBuffer makeByteBuffer(byte[]
arr){
ByteBuffer bb = ByteBuff-
er.allocateDirect(arr.length);
bb.put(arr);
bb.position(0);
return bb;
}
/** The draw method for the primitive object with
the GL context */
public void draw_circle(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// set the colour for the object circle
//gl.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
//create VBO from buffer with glBuffer-
Data()
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, make-
FloatBuffer(vertices_circle));
//memetakan warna untuk setiap vertex
gl.glColorPointer(4, GL10.GL_FLOAT, 0, make-
FloatBuffer(vertices_circle_color));
//draw circle as filled shape
//gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 1,
(int) ((int) 2*batas_sudut/step));
//draw circle contours
//gl.glDrawArrays(GL10.GL_LINES, 1, (int)
((int) 2*batas_sudut/step)); // membuat garis putus-
putus pada tepi lingkaran
335
//gl.glDrawArrays(GL10.GL_LINES, 1, (int)
((int) 2*batas_sudut/step));
gl.glDrawArrays(GL10.GL_LINE_STRIP, 1, (int)
((int) 2*batas_sudut/step));
//gl.glDrawArrays(GL10.GL_POINTS, 1, (int)
((int) 2*batas_sudut/step));
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}
public void draw_circle_hole(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//create VBO from buffer with glBuffer-
Data()
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, make-
FloatBuffer(vertices_circle1_hole));
//menempelkan tekstur ke objek
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA,
GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tures_indek[0]); //
gl.glTexCoordPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(textCoord_hole)); //
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRA
Y);
gl.glDrawArrays(GL10.GL_LINE_STRIP, 0, ba-
tas_sudut);
//draw circle contours
//gl.glDrawArrays(GL10.GL_LINES, 1, (int)
((int) 2*batas_sudut/step)); // membuat garis putus-
putus pada tepi lingkaran
//gl.glDrawArrays(GL10.GL_LINE_STRIP, 1,
(int) ((int) 2*batas_sudut/step));
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisable( GL10.GL_BLEND );
// Disable Alpha Blend
gl.glDisable( GL10.GL_TEXTURE_2D );
// Disable Texture Mapping
}
public void draw_circle_color(GL10 gl) {
336
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//create VBO from buffer with glBuffer-
Data()
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, make-
FloatBuffer(vertices_circle1));
//menempelkan tekstur ke objek
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA,
GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tures_indek[0]); //
gl.glTexCoordPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(textCoord)); //
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRA
Y);
gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, ba-
tas_sudut);
//draw circle contours
//gl.glDrawArrays(GL10.GL_LINES, 1, (int)
((int) 2*batas_sudut/step)); // membuat garis putus-
putus pada tepi lingkaran
//gl.glDrawArrays(GL10.GL_LINE_STRIP, 1,
(int) ((int) 2*batas_sudut/step));
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisable( GL10.GL_BLEND );
// Disable Alpha Blend
gl.glDisable( GL10.GL_TEXTURE_2D );
// Disable Texture Mapping
}
public void draw_kotak(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices));
// Draw the vertices as square
gl.glColorPointer(4, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices_color));
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
337
gl.glColorPointer(4, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices_color));
gl.glDrawArrays(GL10.GL_TRIANGLES, 2, 3);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}
public void draw_segitiga(GL10 gl) {
gl.glFrontFace(GL10.GL_CCW); // Front
face in counter-clockwise
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// set the colour for the triangle
//gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(new float [] {
1.0f, 1.0f, 0.0f,
// V3
0.0f, 1.0f, 0.0f,
// V2
0.5f, 0.0f, 0.0f, //
V1 - first vertex (x,y,z)
}));
// Draw the vertices as triangle
//gl.glColorPointer(4, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices_color));
//menempelkan tekstur ke objek
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA,
GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tures_indek[0]); //
gl.glTexCoordPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(textCoord_Triagle)); //
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRA
Y);
gl.glDrawArrays(GLES20.GL_TRIANGLE_STRIP,
0, 3);
//Disable the client state before leaving
338
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
//gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
gl.glDisable( GL10.GL_BLEND );
// Disable Alpha Blend
gl.glDisable( GL10.GL_TEXTURE_2D );
// Disable Texture Mapping
}
public void loadBallTexture(GL10 gl, Context con-
text,int index_Texture) {
// Bitmap bitmap = BitmapFacto-
ry.decodeResource(context.getResources(),
// resource);
/*Bitmap bitmap = BitmapFacto-
ry.decodeStream(context.getResources()
.openRawResource(R.drawable.nature));*/
Bitmap bitmap = BitmapFacto-
ry.decodeStream(context.getResources()
.openRawResource(imageFileIDs[index_Texture]));
gl.glGenTextures(1, textures_indek, 0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tures_indek[0]);
//gl.glTexParameterf(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE );
//gl.glTexParameterf(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE );
gl.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
gl.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D,
0, bitmap, 0);
bitmap.recycle();
}
}
339
Gambar 5.8 Texture Mapping Pada Segitiga
5.5 Texture Mapping Pada Lingkaran
Source Code 5.2 Code Texture Mapping Pada Lingkaran
ESRender.java
package com.texture_mapping;
import java.util.Formatter;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLU;
import android.util.Log;
import android.widget.TextView;
public class ESRender implements Renderer {
private ESText glText;
private TextView textview;
private ObjectArena objectarena; // the
primitive object to be drawn
private ObjectBall objectball;
private ObjectBall objectball_hole;
private ObjectBall objectball1;
private ObjectBall objectball2;
private ObjectBall objectball3;
340
Context context;
private int RunMode=1;
private float mAngle = 0.0f; //
Angle in degrees
private float AnimateStep = 2.0f;
// Rotation step per update
private long startTime;
private long fpsStartTime;
private long numFrames;
float radius = 50.0f; // Ball's radius
float x = radius; // Ball's center (x,y)
float y = radius;
float speedX = 5f; // Ball's speed (x,y)
float speedY = 3f;
int xMin, xMax, yMin, yMax;
private int mywidth=0;
private int myheight=0;
/** Constructor to set the handed over context */
public ESRender(Context context) {
//super();
this.context = context;
this.objectarena = new ObjectArena();
this.objectball = new ObjectBall();
this.objectball_hole = new ObjectBall();
this.objectball1 = new ObjectBall();
this.objectball2 = new ObjectBall();
this.objectball3 = new ObjectBall();
}
@Override
public void onDrawFrame(GL10 gl) {
// Draw background color
gl.glClear(GL10.GL_COLOR_BUFFER_BIT |
GL10.GL_DEPTH_BUFFER_BIT);
// menampilkan lingkaran only line with
texture
gl.glPushMatrix();
//gl.glScalef(150.0f, 150.0f,
150.0f);
gl.glTranslatef(0.0f, 100.0f,
0.0f);
gl.glLineWidth(1.0f);
gl.glEnable(GL10.GL_LINE_SMOOTH);
object-
ball_hole.draw_circle_hole(gl);
gl.glPopMatrix();
// menampilkan lingkaran dengan gradasi
warna
341
gl.glPushMatrix();
gl.glLineWidth(1.0f);
gl.glEnable(GL10.GL_LINE_SMOOTH);
//bounds.set(x - radius, y - radi-
us, x + radius, y + radius);
gl.glTranslatef(x, y, 0.0f);
//gl.glScalef(10.0f,10.0f,10.0f);
//gl.glTranslatef(0.0f, 0.0f, -
5.0f);
objectball2.draw_circle_color(gl);
gl.glPopMatrix();
// menampilkan lingkaran dengan gradasi
warna
gl.glPushMatrix();
gl.glLineWidth(1.0f);
gl.glEnable(GL10.GL_LINE_SMOOTH);
//bounds.set(x - radius, y - radi-
us, x + radius, y + radius);
gl.glTranslatef(0, 200, 0.0f);
//gl.glScalef(10.0f,10.0f,10.0f);
//gl.glTranslatef(0.0f, 0.0f, -
5.0f);
objectball3.draw_circle_color(gl);
gl.glPopMatrix();
//render text
gl.glPushMatrix();
// enable texture + alpha blending
// NOTE: this is required for text
rendering! we could incorporate it into
// the GLText class, but then it
would be called multiple times (which impacts perfor-
mance).
gl.glEnable( GL10.GL_TEXTURE_2D );
// Enable Texture Mapping
gl.glEnable( GL10.GL_BLEND );
// Enable Alpha Blend
gl.glBlendFunc( GL10.GL_SRC_ALPHA,
GL10.GL_ONE_MINUS_SRC_ALPHA ); // Set Alpha Blend
Function
//Log.d(TAG, "Frames per second:
" + fps + " (" + numFrames
// + " frames in " + fpsE-
lapsed + " ms)");
//}
glText.begin(1.0f, 1.0f, 1.0f, 1.0f);
// Begin Text Rendering (Set Color WHITE)
//glText.draw( "Posisi Bola : ("+ x +
","+y+")",150, 10); // Draw Test String
342
// Keep track of number of frames
drawn
numFrames++;
long fpsElapsed = Sys-
tem.currentTimeMillis() - fpsStartTime;
//if (fpsElapsed > 1 * 1000) { //
every 5 seconds
float fps = (numFrames *
1000.0F) / fpsElapsed;
// glText.draw( "Frames per
second : "+ fps + " (" + numFrames + " frames in " +
fpsElapsed + " ms)",150, 30); // Draw Test
String
fpsStartTime = Sys-
tem.currentTimeMillis();
numFrames = 0;
//}
glText.end();
// End Text Rendering
// disable texture + alpha
gl.glDisable( GL10.GL_BLEND );
// Disable Alpha Blend
gl.glDisable( GL10.GL_TEXTURE_2D );
// Disable Texture Mapping
gl.glPopMatrix();
// // segitiga
// gl.glPushMatrix();
// //GLU.gluLookAt(gl, 0, 0, 0.01f,
0f, 0f, 0f, 0f, 1.0f, 0.0f);
//
// gl.glTranslatef(50.0f, 60.0f,
0.0f);
// gl.glScalef(80.0f, 80.0f, 0.0f);
// gl.glRotatef(180, 1.0f, 0.0f,
0.0f);
// gl.glRotatef(mAngle, 0.0f, 1.0f,
0.0f);
// gl.glTranslatef(-0.5f, -0.5f,
0.0f);
// objectball1.draw_segitiga(gl);
// gl.glPopMatrix();
// update
moveWithCollisionDetection(this);
set((int)-radius, (int)-radius, mywidth,
myheight);
// Update the rotational angle after each
refresh
if (RunMode==1) {
// re-Calculate animation parame-
ters
mAngle += AnimateStep;
343
if (mAngle > 360.0) {
//CurrentAngle -=
360.0*Math.floor(CurrentAngle/360.0);
mAngle=0.0f;
mAngle += AnimateStep;
}
}
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig
config) {
gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f); // Set
color's clear-value to black
gl.glClearDepthf(1.0f); // Set depth's clear-
value to farthest
gl.glEnable(GL10.GL_DEPTH_TEST); // Ena-
bles depth-buffer for hidden
// surface removal
gl.glDepthFunc(GL10.GL_LEQUAL); // The
type of depth testing to do
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
GL10.GL_NICEST); // nice
// perspective
// view
gl.glShadeModel(GL10.GL_SMOOTH); // Ena-
ble smooth shading of color
gl.glDisable(GL10.GL_DITHER); // Disable
dithering for better
// performance
// Create the GLText
glText = new ESText( gl, context.getAssets()
);
// Load the font from file (set size + pad-
ding), creates the texture
// NOTE: after a successful call to this the
font is ready for rendering!
glText.load( "Roboto-Regular.ttf", 14, 2, 2
); // Create Font (Height: 14 Pixels / X+Y Padding 2
Pixels)
//gl.glDisable(GL10.GL_DITHER); // Disa-
ble dithering for better
// performance
// Setup Texture, each time the surface is
created (NEW)
objectball_hole.loadBallTexture(gl, con-
text,0);
objectball1.loadBallTexture(gl, context,1);
objectball2.loadBallTexture(gl, context,0);
objectball3.loadBallTexture(gl, context,1);
gl.glEnable(GL10.GL_TEXTURE_2D); // Ena-
344
ble texture (NEW)
}
@Override
public void onSurfaceChanged(GL10 gl, int width,
int height) {
mywidth=width;
myheight=height;
/*
if (height == 0)
height = 1; // To prevent divide
by zero
float aspect = (float) width / height;
mywidth=width;
myheight=height;
// Set the viewport (display area) to
cover the entire window
gl.glViewport(0, 0, width, height);
// Setup perspective projection, with as-
pect ratio matches viewport
gl.glMatrixMode(GL10.GL_PROJECTION); //
Select projection matrix
gl.glLoadIdentity(); // Reset projection
matrix
gl.glViewport( 0, 0, width, height );
// Setup orthographic projection
gl.glMatrixMode( GL10.GL_PROJECTION );
// Activate Projection Matrix
gl.glLoadIdentity();
// Load Identity Matrix
gl.glOrthof(
// Set Ortho Projection
(Left,Right,Bottom,Top,Front,Back)
0, width,
0, height,
1.0f, -10.0f
);
// Save width and height
//this.width = width;
// Save Current Width
//this.height = height;
// Save Current Height
gl.glMatrixMode(GL10.GL_MODELVIEW); // Se-
lect model-view matrix
gl.glLoadIdentity(); // Reset
}
345
public float getxMax() {
return xMax;
}
public void setxMax(int xmax) {
xMax = xmax;
}
public float getxMin() {
return xMin;
}
public void setxMin(int xmin) {
xMin = xmin;
}
public float getyMax() {
return yMax;
}
public void setyMax(int ymax) {
yMax = ymax;
}
public float getyMin() {
return yMin;
}
public void setyMin(int ymin) {
yMin = ymin;
}
public float getspeedX() {
return speedX;
}
public void setspeedX(float speedX_) {
speedX = speedX_;
}
public float getspeedY() {
return speedY;
}
public void setspeedY(float speedY_) {
speedY = speedY_;
}
public void moveWithCollisionDetection(ESRender
esRender) {
// Get new (x,y) position
x += speedX;
y += speedY;
// Detect collision and react
if (x + radius > esRender.getxMax()) {
speedX = -speedX;
x = esRender.getxMax() - radius;
}
else if (x - radius < esRender.getxMin())
{
speedX = -speedX;
x = esRender.getxMin() + radius;
}
if (y + radius > esRender.getyMax()) {
speedY = -speedY;
346
y = esRender.getyMax() - radius;
} else if (y - radius < esRen-
der.getyMin()) {
speedY = -speedY;
y = esRender.getyMin() + radius;
}
}
public void set(int x, int y, int width, int
height) {
xMin = x;
//xMax = x + width - 1;
xMax = x + width;
yMin = y;
//yMax = y + height - 1;
yMax = y + height;
}
}
ESSurfaceView.java
package com.texture_mapping;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
/**
* A view container where OpenGL ES graphics can be
drawn on screen.
* This view can also be used to capture touch events,
such as a user
* interacting with drawn objects.
*/
public class ESSurfaceView extends GLSurfaceView {
private final ESRender esRender;
private float previousX;
private float previousY;
public ESSurfaceView(Context context) {
super(context);
// Set the Renderer for drawing on the GLSur-
faceView
esRender = new ESRender(context);
setRenderer(esRender);
// To enable keypad
this.setFocusable(true);
this.requestFocus();
347
// To enable touch mode
this.setFocusableInTouchMode(true);
// Render the view only when there is a change
in the drawing data
// merender hanya ketika ada perubahan/ event
//setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
//private final float TOUCH_SCALE_FACTOR =
getWidth() / getHeight();
private float mPreviousX;
private float mPreviousY;
@Override
public boolean onTouchEvent(MotionEvent v) {
// MotionEvent reports input details from the
touch screen
// and other input controls. In this case, we
are only
// interested in events where the touch posi-
tion changed.
float currentX = v.getX();
float currentY = v.getY();
float deltaX, deltaY;
//float scalingFactor = 0.50f / ((esRen-
der.xMax > esRender.yMax) ? esRender.yMax
//: esRender.xMax);
switch (v.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.v("Test Action Down", "action
down working");
//break;
requestRender();
//case MotionEvent.ACTION_POINTER_UP:
//Log.v("Test Action
ACTION_POINTER_UP", "action working");
//requestRender();
//case MotionEvent.ACTION_MOVE:
//Log.v("Test Action
ACTION_POINTER_DOWN", "action working");
//requestRender();
//case MotionEvent.ACTION_UP:
//Log.v("Test Action Up", "action
up working");
//requestRender();
case MotionEvent.ACTION_MOVE:
// Modify rotational angles according to
movement
deltaX = currentX - previousX;
deltaY = currentY - previousY;
//esRender.setspeedX(esRender.getspeedX()+ (del-
348
taX/getWidth()));
//esRender.setspeedY(esRender.getspeedY()+ (del-
taY/getHeight()));
esRen-
der.setspeedX(esRender.getspeedX()+ deltaX/100);
esRen-
der.setspeedY(esRender.getspeedY()+ deltaY/100);
requestRender();
}
// Save current x, y
previousX = currentX;
previousY = currentY;
return true; // Event handled
//break;
}
// Key-up event handler
@Override
public boolean onKeyUp(int keyCode, KeyEvent
event) {
switch (keyCode) {
case KeyEvent.KEYCODE_A: // mengurangi
kecepatan object
if((esRender.getspeedX()- 0.05f
>0) ){
esRen-
der.setspeedX(esRender.getspeedX()- 0.05f);
}
if((esRender.getspeedX()- 0.05f
<0) ){
esRender.setspeedX(0.0f);
}
if((esRender.getspeedY()- 0.05f
>=0)){
esRen-
der.setspeedY(esRender.getspeedY()- 0.05f);
}
if((esRender.getspeedY()- 0.05f
<0) ){
esRender.setspeedY(0.0f);
}
Log.v("Test Action KEYCODE_A",
"action working");
break;
case KeyEvent.KEYCODE_Z:
Log.v("Test Action KEYCODE_Z",
"action working");
break;
}
return true; // Event handled
}
}
349
MainActivity.java
package com.texture_mapping;
import com.texture_mapping.R;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.Window;
import android.view.WindowManager;
public class MainActivity extends Activity {
/** The OpenGL view */
private GLSurfaceView glSurfaceView;
@Override
protected void onCreate(Bundle savedInstanceS-
tate) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
// requesting to turn the title OFF
requestWindowFeature(Window.FEATURE_NO_TITLE);
// making it full screen
getWin-
dow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCR
EEN,
WindowManag-
er.LayoutParams.FLAG_FULLSCREEN);
// Initiate the Open GL view and
// create an instance with this activity
glSurfaceView = new ESSurfaceView(this);
// set our renderer to be the main renderer
with
// the current activity context
//glSurfaceView.setRenderer(new ESRender());
setContentView(glSurfaceView);
}
/**
* Remember to resume the glSurface
*/
@Override
protected void onResume() {
super.onResume();
glSurfaceView.onResume();
}
/**
* Also pause the glSurface
*/
350
@Override
protected void onPause() {
super.onPause();
glSurfaceView.onPause();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to
the action bar if it is present.
getMenuInflater().inflate(R.menu.main,
menu);
return true;
}
}
ObjectBall.java
package com.texture_mapping;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;
import ja-
vax.microedition.khronos.opengles.GL11ExtensionPack;
import com.texture_mapping.R;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLES20;
import android.opengl.GLUtils;
import android.util.Log;
public class ObjectBall {
private float vertices[] = {
-0.5f, -0.5f, 0.0f, // V1 -
first vertex (x,y,z)
-0.5f, 0.5f, 0.0f, //
V2
0.5f, 0.5f, 0.0f, //
V3
0.5f, -0.5f, 0.0f, // V4
-0.5f, -0.5f, 0.0f //
V5
};
351
private float textCoord_Triagle[]={
1.0f, 1.0f, 0.0f, //
V3
0.0f, 1.0f, 0.0f, //
V2
0.5f, 0.0f, 0.0f, // V1 -
first vertex (x,y,z)
};
float[] texCoords = { // Texture coords for the
above face (NEW)
0.0f, 1.0f, // A. left-bottom
(NEW)
1.0f, 1.0f, // B. right-bottom
(NEW)
0.0f, 0.0f, // C. left-top (NEW)
1.0f, 0.0f // D. right-top (NEW)
};
private float vertices_color[] = {
1.0f, 0.0f, 0.0f, 1.0f, //
CV1 - first color (red,green,blue)
0.0f, 1.0f, 0.0f, 1.0f, //
CV2
0.0f, 0.0f, 1.0f, 1.0f, //
CV3
0.0f, 1.0f, 0.0f, 1.0f, //
CV4
1.0f, 0.0f, 0.0f, 1.0f
// CV5
};
private float vertices_circle[]={0.0f,0.0f,0.0f};
private float verti-
ces_circle_color[]={0.0f,0.0f,0.0f,0.5f};
private float textCoord[],textCoord_hole[];
private float verti-
ces_circle1[],vertices_circle1_hole[];
private int[] imageFileIDs = { // Image file IDs
R.drawable.nature,
R.drawable.mule};
int[] textures_indek = new int[1];
private int batas_sudut=360;
float jari_jari;
float a,b;
float x,y;
float step=3.0f,step_line=0.2f;
float x1,y1;
float x2,y2;
float teta, teta_hole;
private int loop,loop_color;
public ObjectBall() {
// ============ start to generate stetch
352
texture coordinat ==========================
//Inisialisasi
jari_jari=0.5f;
// Titik Pusat
a = 0.5f; b = 0.5f ;
//x=a+jari_jari; y=b;
teta = 0;
// generate stretch texture coordinat
teta=0; teta_hole=0;
textCoord = new float[batas_sudut * 3];
textCoord_hole = new float[batas_sudut *
3];
for (int ii = 0; ii < batas_sudut * 3; ii
+= 3) {
// membentuk textCoord untuk cir-
cle color
textCoord[ii] =
(jari_jari*((float) Math.cos(-teta)))+a;
textCoord[ii + 1] =
(jari_jari*((float) Math.sin(-teta)))+b;
textCoord[ii + 2] = 0.0f;
teta += Math.PI / 90;
// membentuk textCoord untuk cir-
cle hole
textCoord_hole[ii] =
(jari_jari*((float) Math.cos(-teta_hole)))+a;
textCoord_hole[ii + 1] =
(jari_jari*((float) Math.sin(-teta_hole)))+b;
textCoord_hole[ii + 2] = 0.0f;
teta_hole += 15;
}
// ============ start to generate verti-
ces to circle (Cara 1) ==========================
//Inisialisasi
jari_jari=50.0f;
// Titik Pusat
a = 50.0f; b = 50.0f ;
teta=0; teta_hole=0;
vertices_circle1 = new float[batas_sudut
* 3];
vertices_circle1_hole = new
float[batas_sudut * 3];
for (int ii = 0; ii < batas_sudut * 3; ii
+= 3) {
// membentuk vertices_circle1
vertices_circle1[ii] =
(jari_jari*((float) Math.cos(teta)))+a;
vertices_circle1[ii + 1] =
(jari_jari*((float) Math.sin(teta)))+b;
vertices_circle1[ii + 2] = 0.0f;
353
teta += Math.PI / 90;
// membentuk vertices_circle1
vertices_circle1_hole[ii] =
(jari_jari*((float) Math.cos(teta_hole)))+a;
vertices_circle1_hole[ii + 1] =
(jari_jari*((float) Math.sin(teta_hole)))+b;
vertices_circle1_hole[ii + 2] =
0.0f;
teta_hole += 15;
}
// ============ start to generate verti-
ces to circle (Cara 2) ==========================
//Inisialisasi
jari_jari=50.0f;
// Titik Pusat
a = 50.0f; b = 50.0f ;
x=a+jari_jari; y=b;
loop=0;
loop_color=0;
vertices_circle=new
float[(int)(3*batas_sudut/step)*3];
vertices_circle_color=new
float[(int)(3*batas_sudut/step)*4];
for(teta=0;teta<=2*batas_sudut;teta+=step){
vertices_circle[loop] = (float) ((x-
a)*Math.cos((teta/180)*(22/7)) - ((y-
b)*Math.sin((teta/180)*(22/7))) + a);
vertices_circle[loop+1] = (float) ((x-
a)*Math.sin((teta/180)*(22/7)) - ((y-
b)*Math.cos((teta/180)*(22/7))) + b);
vertices_circle[loop+2]=0;
loop+=3;
//mengenerate warna untuk setiap vertex
//vertices_circle_color[loop_color]=(float) ((x-
a)*Math.cos((teta/180)*(22/7)) - ((y-
b)*Math.sin((teta/180)*(22/7))) + a);
//vertices_circle_color[loop_color+1]=(float)
((x-a)*Math.sin((teta/180)*(22/7)) - ((y-
b)*Math.cos((teta/180)*(22/7))) + b);
vertices_circle_color[loop_color]=(float)
(Math.cos((teta/180)*(22/7)) );
verti-
ces_circle_color[loop_color+1]=(float)
(Math.sin((teta/180)*(22/7)));
vertices_circle_color[loop_color+2]=0.5f;
vertices_circle_color[loop_color+3]=0.5f;
loop_color+=4;
}
354
// ============= end for generate vertices to
circle ====================
}
// Point to our vertex buffer, return buffer
holding the vertices
public static FloatBuffer makeFloatBuffer(float[]
arr){
ByteBuffer bb = ByteBuff-
er.allocateDirect(arr.length * 4);
bb.order(ByteOrder.nativeOrder());
FloatBuffer fb = bb.asFloatBuffer();
fb.put(arr);
fb.position(0);
return fb;
}
// Setup index-array buffer. Indices in byte.
public static ByteBuffer makeByteBuffer(byte[]
arr){
ByteBuffer bb = ByteBuff-
er.allocateDirect(arr.length);
bb.put(arr);
bb.position(0);
return bb;
}
/** The draw method for the primitive object with
the GL context */
public void draw_circle(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// set the colour for the object circle
//gl.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
//create VBO from buffer with glBuffer-
Data()
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, make-
FloatBuffer(vertices_circle));
//memetakan warna untuk setiap vertex
gl.glColorPointer(4, GL10.GL_FLOAT, 0, make-
FloatBuffer(vertices_circle_color));
//draw circle as filled shape
//gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 1,
(int) ((int) 2*batas_sudut/step));
//draw circle contours
//gl.glDrawArrays(GL10.GL_LINES, 1, (int)
((int) 2*batas_sudut/step)); // membuat garis putus-
putus pada tepi lingkaran
//gl.glDrawArrays(GL10.GL_LINES, 1, (int)
((int) 2*batas_sudut/step));
355
gl.glDrawArrays(GL10.GL_LINE_STRIP, 1, (int)
((int) 2*batas_sudut/step));
//gl.glDrawArrays(GL10.GL_POINTS, 1, (int)
((int) 2*batas_sudut/step));
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}
public void draw_circle_hole(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//create VBO from buffer with glBuffer-
Data()
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, make-
FloatBuffer(vertices_circle1_hole));
//menempelkan tekstur ke objek
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA,
GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tures_indek[0]); //
gl.glTexCoordPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(textCoord_hole)); //
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRA
Y);
gl.glDrawArrays(GL10.GL_LINE_STRIP, 0, ba-
tas_sudut);
//draw circle contours
//gl.glDrawArrays(GL10.GL_LINES, 1, (int)
((int) 2*batas_sudut/step)); // membuat garis putus-
putus pada tepi lingkaran
//gl.glDrawArrays(GL10.GL_LINE_STRIP, 1,
(int) ((int) 2*batas_sudut/step));
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisable( GL10.GL_BLEND );
// Disable Alpha Blend
gl.glDisable( GL10.GL_TEXTURE_2D );
// Disable Texture Mapping
}
public void draw_circle_color(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
356
//create VBO from buffer with glBuffer-
Data()
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, make-
FloatBuffer(vertices_circle1));
//menempelkan tekstur ke objek
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA,
GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tures_indek[0]); //
gl.glTexCoordPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(textCoord)); //
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRA
Y);
gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, ba-
tas_sudut);
//draw circle contours
//gl.glDrawArrays(GL10.GL_LINES, 1, (int)
((int) 2*batas_sudut/step)); // membuat garis putus-
putus pada tepi lingkaran
//gl.glDrawArrays(GL10.GL_LINE_STRIP, 1,
(int) ((int) 2*batas_sudut/step));
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisable( GL10.GL_BLEND );
// Disable Alpha Blend
gl.glDisable( GL10.GL_TEXTURE_2D );
// Disable Texture Mapping
}
public void draw_kotak(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices));
// Draw the vertices as square
gl.glColorPointer(4, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices_color));
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
gl.glColorPointer(4, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices_color));
357
gl.glDrawArrays(GL10.GL_TRIANGLES, 2, 3);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}
public void draw_segitiga(GL10 gl) {
gl.glFrontFace(GL10.GL_CCW); // Front
face in counter-clockwise
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// set the colour for the triangle
//gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(new float [] {
1.0f, 1.0f, 0.0f,
// V3
0.0f, 1.0f, 0.0f,
// V2
0.5f, 0.0f, 0.0f, //
V1 - first vertex (x,y,z)
}));
// Draw the vertices as triangle
//gl.glColorPointer(4, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices_color));
//menempelkan tekstur ke objek
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA,
GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tures_indek[0]); //
gl.glTexCoordPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(textCoord_Triagle)); //
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRA
Y);
gl.glDrawArrays(GLES20.GL_TRIANGLE_STRIP,
0, 3);
358
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
//gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
gl.glDisable( GL10.GL_BLEND );
// Disable Alpha Blend
gl.glDisable( GL10.GL_TEXTURE_2D );
// Disable Texture Mapping
}
public void loadBallTexture(GL10 gl, Context con-
text,int index_Texture) {
// Bitmap bitmap = BitmapFacto-
ry.decodeResource(context.getResources(),
// resource);
/*Bitmap bitmap = BitmapFacto-
ry.decodeStream(context.getResources()
.openRawResource(R.drawable.nature));*/
Bitmap bitmap = BitmapFacto-
ry.decodeStream(context.getResources()
.openRawResource(imageFileIDs[index_Texture]));
gl.glGenTextures(1, textures_indek, 0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tures_indek[0]);
//gl.glTexParameterf(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE );
//gl.glTexParameterf(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE );
gl.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
gl.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D,
0, bitmap, 0);
bitmap.recycle();
}
}
359
Gambar 5.9 Texture Mapping Pada Lingkaran
5.6 Texture Mapping Pada Kubus
Source Code 5.3 Code Texture Mapping Pada Kubus
ESRender.java
package com.wordpress.androidfreecode;
import java.io.IOException;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
//import android.opengl.GLU;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLU;
public class ESRender implements Renderer {
private Context context; // Application context
needed to read image (NEW)
private TextureKubus kubus;
int RunMode=1;
float CurrentAngle = 0.0f; //
Angle in degrees
float AnimateStep = 2.0f; //
Rotation step per update
360
/** Constructor to set the handed over context */
public ESRender(Context context) {
this.context = context; // Get the ap-
plication context (NEW)
kubus = new TextureKubus();
}
@Override
public void onDrawFrame(GL10 gl) {
// clear Screen and Depth Buffer
//gl.glClearColor(1.0f, 1.0f,
1.0f, 1.0f); // set background dgn warna putih
//gl.glClearColor(0.0f, 0.0f,
0.0f, 1.0f); // set background dgn warna hitam
gl.glClear(GL10.GL_COLOR_BUFFER_BIT |
GL10.GL_DEPTH_BUFFER_BIT);
// ----- Render the Kubus -----
gl.glPushMatrix();
gl.glTranslatef(0.0f, 0.9f, -
5.0f);
//gl.glTranslatef(0.0f, 0.0f, -
6.0f); // Translate into the screen
gl.glRotatef(CurrentAngle, 0.1f,
1.0f, 0.2f); // Rotate
//gl.glRotatef(CurrentAngle, 1.0f,
1.0f, 1.0f );
gl.glTranslatef(-0.5f,-0.5f,-
0.5f);
kubus.draw(gl);
gl.glPopMatrix();
// Update the rotational angle after each
refresh
if (RunMode==1) {
// re-Calculate animation parame-
ters
CurrentAngle += AnimateStep;
if (CurrentAngle > 360.0) {
//CurrentAngle -=
360.0*Math.floor(CurrentAngle/360.0);
CurrentAngle=0.0f;
CurrentAngle += Ani-
mateStep;
}
}
}
@Override
public void onSurfaceChanged(GL10 gl, int width,
int height) {
if (height == 0)
height = 1; // To prevent divide
by zero
float aspect = (float) width / height;
361
// Set the viewport (display area) to
cover the entire window
gl.glViewport(0, 0, width, height);
// Setup perspective projection, with as-
pect ratio matches viewport
gl.glMatrixMode(GL10.GL_PROJECTION); //
Select projection matrix
gl.glLoadIdentity(); // Reset projection
matrix
// Use perspective projection
GLU.gluPerspective(gl, 45, aspect, 0.1f,
100.f);
//gl.glOrthof(-3.0f, 3.0f, -3.0f, 3.0f, -
3.0f, 3.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW); //
Select model-view matrix
gl.glLoadIdentity(); // Reset
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig
config) {
gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// Set color's clear-value to black
gl.glClearDepthf(1.0f); // Set depth's
clear-value to farthest
gl.glEnable(GL10.GL_DEPTH_TEST); // Ena-
bles depth-buffer for hidden
// surface removal
gl.glDepthFunc(GL10.GL_LEQUAL); // The
type of depth testing to do
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
GL10.GL_NICEST); // nice
// perspective
// view
gl.glShadeModel(GL10.GL_SMOOTH); // Ena-
ble smooth shading of color
gl.glDisable(GL10.GL_DITHER); // Disable
dithering for better
// performance
// Setup Texture, each time the surface
is created (NEW)
kubus.loadTexture(gl, context);
gl.glEnable(GL10.GL_TEXTURE_2D); // Ena-
ble texture (NEW)
}
public int getRunMode() {
return RunMode;
}
public void setRunMode(int mRunMode) {
362
RunMode = mRunMode;
}
public float getAnimateStep() {
return AnimateStep;
}
public void setAnimateStep(float mAnimateStep) {
AnimateStep = mAnimateStep;
}
}
MainActivity.java
package com.wordpress.androidfreecode;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
/**
* Our OpenGL program's main activity
*/
public class MainActivity extends Activity {
private GLSurfaceView glView; // Use GLSur-
faceView
// Call back when the activity is started, to in-
itialize the view
@Override
protected void onCreate(Bundle savedInstanceS-
tate) {
super.onCreate(savedInstanceState);
// requesting to turn the title OFF
requestWindowFeature(Window.FEATURE_NO_TITLE);
// making it full screen
getWin-
dow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCR
EEN,
WindowManag-
er.LayoutParams.FLAG_FULLSCREEN);
glView = new GLSurfaceView(this); // Al-
locate a GLSurfaceView
glView.setRenderer(new ESRender(this));
// Use a custom renderer
this.setContentView(glView); // This ac-
tivity sets to GLSurfaceView
}
363
// Call back when the activity is going into the
background
@Override
protected void onPause() {
super.onPause();
glView.onPause();
}
// Call back after onPause()
@Override
protected void onResume() {
super.onResume();
glView.onResume();
}
}
TextureKubus.java
package com.wordpress.androidfreecode;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
/*
* A cube with texture.
* Define the vertices for only one representative
face.
* * Render the cube by translating and rotating the
face.
*/
public class TextureKubus {
private FloatBuffer vertexBuffer; // Buffer for
vertex-array
private FloatBuffer texBuffer; // Buffer for tex-
ture-coords-array (NEW)
private float[] vertices = { // Vertices for a
face
-1.0f, -1.0f, 0.0f, // 0. left-
bottom-front
1.0f, -1.0f, 0.0f, // 1. right-
364
bottom-front
-1.0f, 1.0f, 0.0f, // 2. left-top-
front
1.0f, 1.0f, 0.0f // 3. right-top-
front
};
float[] texCoords = { // Texture coords for the
above face (NEW)
0.0f, 1.0f, // A. left-bottom
(NEW)
1.0f, 1.0f, // B. right-bottom
(NEW)
0.0f, 0.0f, // C. left-top (NEW)
1.0f, 0.0f // D. right-top (NEW)
};
int[] textureIDs = new int[1]; // Array for 1
texture-ID (NEW)
// Constructor - Set up the buffers
public TextureKubus() {
// Setup vertex-array buffer. Vertices in
float. An float has 4 bytes
ByteBuffer vbb = ByteBuff-
er.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder()); //
Use native byte order
vertexBuffer = vbb.asFloatBuffer(); //
Convert from byte to float
vertexBuffer.put(vertices); // Copy data
into buffer
vertexBuffer.position(0); // Rewind
// Setup texture-coords-array buffer, in
float. An float has 4 bytes
// (NEW)
ByteBuffer tbb = ByteBuff-
er.allocateDirect(texCoords.length * 4);
tbb.order(ByteOrder.nativeOrder());
texBuffer = tbb.asFloatBuffer();
texBuffer.put(texCoords);
texBuffer.position(0);
}
// Draw the shape
public void draw(GL10 gl) {
gl.glFrontFace(GL10.GL_CCW); // Front
face in counter-clockwise
// orientation
gl.glEnable(GL10.GL_CULL_FACE); // Enable
cull face
gl.glCullFace(GL10.GL_BACK); // Cull the
back face (don't display)
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
vertexBuffer);
365
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRA
Y); // Enable
// texture-coords-array
// (NEW)
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0,
texBuffer); // Define
// texture-coords
// buffer (NEW)
// front
gl.glPushMatrix();
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
// left
gl.glPushMatrix();
gl.glRotatef(270.0f, 0.0f, 1.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
// back
gl.glPushMatrix();
gl.glRotatef(180.0f, 0.0f, 1.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
// right
gl.glPushMatrix();
gl.glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
// top
gl.glPushMatrix();
gl.glRotatef(270.0f, 1.0f, 0.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
// bottom
gl.glPushMatrix();
gl.glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
366
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARR
AY); // Disable
// texture-coords-array
// (NEW)
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisable(GL10.GL_CULL_FACE);
}
// Load an image into GL texture
public void loadTexture(GL10 gl,Context c) {
gl.glGenTextures(1, textureIDs, 0); //
Generate texture-ID array
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[0]); // Bind to texture
// ID
// Set up texture filters
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);
// Construct an input stream to texture
image "res\drawable\nature.png"
//AssetManager assetManager =
c.getAssets();
//InputStream istream = assetManag-
er.open("nature.png");
InputStream istream =
c.getResources().openRawResource(R.drawable.nature);
Bitmap bitmap;
try {
// Read and decode input as bitmap
bitmap = BitmapFacto-
ry.decodeStream(istream);
} finally {
try {
istream.close();
} catch (IOException e) {
}
}
// Build Texture from loaded bitmap for
the currently-bind texture ID
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0,
bitmap, 0);
bitmap.recycle();
367
}
}
Gambar 5.10 Texture Mapping Pada Kubus
5.7 Texture Mapping Pada Bola
Source Code 5.4 Code Texture Mapping Pada Bola
ESRender.java
package com.texture_mapping;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLU;
public class ESRender implements Renderer {
/** Tilt the spheres a little. */
private static final int AXIAL_TILT_DEGRESS =
30;
/** Clear colour, alpha component. */
private static final float CLEAR_RED = 0.0f;
/** Clear colour, alpha component. */
private static final float CLEAR_GREEN = 0.0f;
/** Clear colour, alpha component. */
private static final float CLEAR_BLUE = 0.0f;
368
/** Clear colour, alpha component. */
private static final float CLEAR_ALPHA = 0.5f;
/** Perspective setup, field of view component.
*/
private static final float FOVY = 45.0f;
/** Perspective setup, near component. */
private static final float Z_NEAR = 0.1f;
/** Perspective setup, far component. */
private static final float Z_FAR = 100.0f;
/** Object distance on the screen. move it back
a bit so we can see it! */
private static final float OBJECT_DISTANCE = -
15.0f;
/** The earth's sphere. */
private final MySphere mEarth;
/** The context. */
private final Context mContext;
/** The rotation angle, just to give the screen
some action. */
private float mRotationAngle;
/**
* Constructor to set the handed over context.
* @param context The context.
*/
public ESRender(final Context context) {
this.mContext = context;
//this.mEarth = new MySphere(3, 2);
this.mEarth = new MySphere(5, 3);
this.mRotationAngle = 0.0f;
}
// Call back to draw the current frame.
@Override
public void onDrawFrame(GL10 gl) {
// Clear color and depth buffers
gl.glClear(GL10.GL_COLOR_BUFFER_BIT |
GL10.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
// ----- Render the Sphere -------
-------
gl.glPushMatrix();
gl.glTranslatef(0.0f, 0.0f,
OBJECT_DISTANCE);
gl.glRotatef(AXIAL_TILT_DEGRESS, 1,
0, 0);
gl.glRotatef(this.mRotationAngle++,
0, 1, 0);
this.mEarth.draw(gl);
gl.glPopMatrix();
}
369
// Call back when the surface is first created or
re-created.
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig
config) {
this.mEarth.loadGLTexture(gl,
this.mContext, R.drawable.earth);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glClearColor(CLEAR_RED, CLEAR_GREEN,
CLEAR_BLUE, CLEAR_ALPHA);
gl.glClearDepthf(1.0f);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
GL10.GL_NICEST);
}
// Call back after onSurfaceCreated() or whenever
the window's size changes.
@Override
public void onSurfaceChanged(GL10 gl, int width,
int height) {
final float aspectRatio = (float) width /
(float) (height == 0 ? 1 : height);
// gl.glViewport(0, 0, width, height);
//gl.glMatrixMode(GL10.GL_PROJECTION);
// gl.glLoadIdentity();
/*if (height == 0)
height = 1; // To prevent divide
by zero
float aspectRatio = (float) width /
height;*/
// Set the viewport (display area) to
cover the entire window
gl.glViewport(0, 0, width, height);
// Setup perspective projection, with as-
pect ratio matches viewport
gl.glMatrixMode(GL10.GL_PROJECTION); //
Select projection matrix
gl.glLoadIdentity(); // Reset projection
matrix
// Use perspective projection
//GLU.gluPerspective(gl, 45, aspect,
0.1f, 100.f);
// gl.glOrthof(-3.0f, 3.0f, -3.0f, 3.0f,
-3.0f, 3.0f);
GLU.gluPerspective(gl, FOVY, aspectRatio,
Z_NEAR, Z_FAR);
gl.glMatrixMode(GL10.GL_MODELVIEW); //
370
Select model-view matrix
gl.glLoadIdentity(); // Reset
}
}
MainActivity.java
package com.texture_mapping;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
public class MainActivity extends Activity {
/** The OpenGL view. */
private GLSurfaceView glSurfaceView;
@Override
protected void onCreate(final Bundle savedIn-
stanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.F
LAG_FULLSCREEN, WindowManag-
er.LayoutParams.FLAG_FULLSCREEN);
this.glSurfaceView = new GLSurfaceView(this);
this.glSurfaceView.setRenderer(new ESRen-
der(this));
this.setContentView(this.glSurfaceView);
}
/**
* Remember to resume the glSurface
*/
@Override
protected void onResume() {
super.onResume();
this.glSurfaceView.onResume();
}
/**
* Also pause the glSurface
*/
@Override
protected void onPause() {
371
super.onPause();
this.glSurfaceView.onPause();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to
the action bar if it is present.
getMenuInflater().inflate(R.menu.main,
menu);
return true;
}
}
Maths.java
package com.texture_mapping; /** * @author Jim Cornmell re-edit by XTech * */ public final class Maths { /** 180 in radians. */ public static final double ONE_EIGHTY_DEGREES = Math.PI; /** 360 in radians. */ public static final double THREE_SIXTY_DEGREES = ONE_EIGHTY_DEGREES * 2; /** 120 in radians. */ public static final double ONE_TWENTY_DEGREES = THREE_SIXTY_DEGREES / 3; /** 90 degrees, North pole. */ public static final double NINETY_DEGREES = Math.PI / 2; /** Used by power. */ private static final long POWER_CLAMP = 0x00000000ffffffffL; /** * Constructor, although not used at the moment. */ private Maths() { } /** * Quick integer power function. * * @param base * number to raise. * @param raise
372
* to this power. * @return base ^ raise. */ public static int power(final int base, final int raise) { int p = 1; long b = raise & POWER_CLAMP; // bits in b correspond to values of powerN // so start with p=1, and for each set bit in b, multiply corresponding // table entry long powerN = base; while (b != 0) { if ((b & 1) != 0) { p *= powerN; } b >>>= 1; powerN = powerN * powerN; } return p; } }
MySphere.java
package com.texture_mapping;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
/**
* Render a sphere.
*
* @author Jim Cornmell re-edit by XTech
* @since July 2013
*/
public class MySphere {
/** Maximum allowed depth. */
private static final int MAXIMUM_ALLOWED_DEPTH = 5;
/** Used in vertex strip calculations, related to
properties of a icosahedron. */
373
private static final int VERTEX_MAGIC_NUMBER = 5;
/** Each vertex is a 2D coordinate. */
private static final int NUM_FLOATS_PER_VERTEX = 3;
/** Each texture is a 2D coordinate. */
private static final int NUM_FLOATS_PER_TEXTURE = 2;
/** Each vertex is made up of 3 points, x, y, z. */
private static final int
AMOUNT_OF_NUMBERS_PER_VERTEX_POINT = 3;
/** Each texture point is made up of 2 points, x, y
(in reference to the texture being a 2D image). */
private static final int
AMOUNT_OF_NUMBERS_PER_TEXTURE_POINT = 2;
/** Buffer holding the vertices. */
private final List<FloatBuffer> mVertexBuffer = new
ArrayList<FloatBuffer>();
/** The vertices for the sphere. */
private final List<float[]> mVertices = new Ar-
rayList<float[]>();
/** Buffer holding the texture coordinates. */
private final List<FloatBuffer> mTextureBuffer = new
ArrayList<FloatBuffer>();
/** Mapping texture coordinates for the vertices. */
private final List<float[]> mTexture = new Ar-
rayList<float[]>();
/** The texture pointer. */
private final int[] mTextures = new int[1];
/** Total number of strips for the given depth. */
private final int mTotalNumStrips;
/**
* Sphere constructor.
* @param depth integer representing the split of
the sphere.
* @param radius The spheres radius.
*/
public MySphere(final int depth, final float radius)
{
// Clamp depth to the range 1 to
MAXIMUM_ALLOWED_DEPTH;
final int d = Math.max(1,
Math.min(MAXIMUM_ALLOWED_DEPTH, depth));
// Calculate basic values for the sphere.
this.mTotalNumStrips = Maths.power(2, d - 1) *
VERTEX_MAGIC_NUMBER;
final int numVerticesPerStrip = Maths.power(2, d)
* 3;
final double altitudeStepAngle =
Maths.ONE_TWENTY_DEGREES / Maths.power(2, d);
374
final double azimuthStepAngle =
Maths.THREE_SIXTY_DEGREES / this.mTotalNumStrips;
double x, y, z, h, altitude, azimuth;
for (int stripNum = 0; stripNum <
this.mTotalNumStrips; stripNum++) {
// Setup arrays to hold the points for this
strip.
final float[] vertices = new
float[numVerticesPerStrip * NUM_FLOATS_PER_VERTEX]; //
NOPMD
final float[] texturePoints = new
float[numVerticesPerStrip * NUM_FLOATS_PER_TEXTURE];
// NOPMD
int vertexPos = 0;
int texturePos = 0;
// Calculate position of the first vertex in
this strip.
altitude = Maths.NINETY_DEGREES;
azimuth = stripNum * azimuthStepAngle;
// Draw the rest of this strip.
for (int vertexNum = 0; vertexNum < numVertices-
PerStrip; vertexNum += 2) {
// First point - Vertex.
y = radius * Math.sin(altitude);
h = radius * Math.cos(altitude);
z = h * Math.sin(azimuth);
x = h * Math.cos(azimuth);
vertices[vertexPos++] = (float) x;
vertices[vertexPos++] = (float) y;
vertices[vertexPos++] = (float) z;
// First point - Texture.
texturePoints[texturePos++] = (float) (1 - az-
imuth / Maths.THREE_SIXTY_DEGREES);
texturePoints[texturePos++] = (float) (1 -
(altitude + Maths.NINETY_DEGREES) /
Maths.ONE_EIGHTY_DEGREES);
// Second point - Vertex.
altitude -= altitudeStepAngle;
azimuth -= azimuthStepAngle / 2.0;
y = radius * Math.sin(altitude);
h = radius * Math.cos(altitude);
z = h * Math.sin(azimuth);
x = h * Math.cos(azimuth);
vertices[vertexPos++] = (float) x;
vertices[vertexPos++] = (float) y;
vertices[vertexPos++] = (float) z;
// Second point - Texture.
texturePoints[texturePos++] = (float) (1 - az-
imuth / Maths.THREE_SIXTY_DEGREES);
texturePoints[texturePos++] = (float) (1 -
(altitude + Maths.NINETY_DEGREES) /
Maths.ONE_EIGHTY_DEGREES);
375
azimuth += azimuthStepAngle;
}
this.mVertices.add(vertices);
this.mTexture.add(texturePoints);
ByteBuffer byteBuffer = ByteBuff-
er.allocateDirect(numVerticesPerStrip *
NUM_FLOATS_PER_VERTEX * Float.SIZE);
byteBuffer.order(ByteOrder.nativeOrder());
FloatBuffer fb = byteBuffer.asFloatBuffer();
fb.put(this.mVertices.get(stripNum));
fb.position(0);
this.mVertexBuffer.add(fb);
// Setup texture.
byteBuffer = ByteBuff-
er.allocateDirect(numVerticesPerStrip *
NUM_FLOATS_PER_TEXTURE * Float.SIZE);
byteBuffer.order(ByteOrder.nativeOrder());
fb = byteBuffer.asFloatBuffer();
fb.put(this.mTexture.get(stripNum));
fb.position(0);
this.mTextureBuffer.add(fb);
}
}
/**
* Load the texture for the square.
*
* @param gl Handle.
* @param context Handle.
* @param texture Texture map for the sphere.
*/
public void loadGLTexture(final GL10 gl, final Con-
text context, final int texture) {
final Bitmap bitmap = BitmapFacto-
ry.decodeResource(context.getResources(), texture);
// Generate one texture pointer, and bind it to
the texture array.
gl.glGenTextures(1, this.mTextures, 0);
gl.glBindTexture(GL10.GL_TEXTURE_2D,
this.mTextures[0]);
// Create nearest filtered texture.
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);
// Use Android GLUtils to specify a two-
dimensional texture image from our bitmap.
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap,
0);
// Tidy up.
bitmap.recycle();
}
376
/**
* The draw method for the square with the GL con-
text.
*
* @param gl Graphics handle.
*/
public void draw(final GL10 gl) {
// bind the previously generated texture.
gl.glBindTexture(GL10.GL_TEXTURE_2D,
this.mTextures[0]);
// Point to our buffers.
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// Set the face rotation, clockwise in this case.
gl.glFrontFace(GL10.GL_CW);
// Point to our vertex buffer.
for (int i = 0; i < this.mTotalNumStrips; i++) {
gl.glVertexPointer(AMOUNT_OF_NUMBERS_PER_VERTEX_POINT,
GL10.GL_FLOAT, 0, this.mVertexBuffer.get(i));
gl.glTexCoordPointer(AMOUNT_OF_NUMBERS_PER_TEXTURE_POI
NT, GL10.GL_FLOAT, 0, this.mTextureBuffer.get(i));
// Draw the vertices as triangle strip.
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0,
this.mVertices.get(i).length /
AMOUNT_OF_NUMBERS_PER_VERTEX_POINT);
}
// Disable the client state before leaving.
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
}
377
Gambar 5.11 Texture Mapping Pada Bola
378
BAB 6 Blending
6.1 Pengertian Blending
Blending merupakan fungsi yang menggabungkan nilai warna dari sumber (source) dan tujuan (destination/object), sehingga efek akhir scene terlihat transparan. Pencampuran dapat mengontrol berapa banyak warna yang dapat dikombinasikan. Dengan demikian untuk proses membuat terang fragmen dapat menggunakan alpha pencampuran. Warna pencampuran terletak pada teknik utama, seperti transparan, digital composite dan lukisan. Operasi campuran yaitu cara yang paling alami untuk mengetahui bahwa komponen RGB adalah suatu fragmen yang mewakili warna dan komponen alfa adalah suatu fragmen yang mewakili sifat tidak tembus cahaya. Dengan demikian, transparan mempunyai permukaan lebih rendah daripada yang buram.
Dengan menggunakan glBlendFunc() untuk persediaan pada dua hal utama, yang pertama menentukan bagaimana faktor sumber dan tujuan harus dihitung dan yang kedua menunjukan bagaimana faktor sumber dan tujuan dihitung. Dan untuk proses pencampurannya harus ada faktor pengaktifannya menggunakan : glEnable (GL_BLEND). Menggunakan glDisable() dengan GL_BLEND untuk menonaktifkan Pencampuran dan menggunakan konstan GL_ONE(sumber) dan GL_ZERO(tujuan) memberikan hasil yang sama seperti ketika Pencampuran dinonaktifkan. Nilai-nilai ini bersifat default dengan void glBlendFunc(GLenum sfactor, GLenum dfactor). Teknik blending juga digunakan untuk ilusi dari cerminan sebuah objek pada Gambar 6.1.
Gambar 6.1 Teknik blending untuk mendapatkan efek pantulan
379
6.2 Source and Destination Factor Pada Blending
RGBA (Red, Green, Blue, Alpha)
Alpha digunakan untuk mengatur tingkat opacity objek.
a = 1 → tidak transparan
a = 0 → transparan
0 < a < 1 → nilai untuk mengatur tingkat opacity
Blending colors
Source color : (Rs, Gs, Bs, As)
Destination color : (Rd, Gd, Bd, Ad)
Source factor : (Sr, Sg, Sb, Sa)
Destination factor : (Dr, Dg, Db, Da)
Blended RGBA = (RsSr+RdDr, GsSg+GdDg, BsSb+BdDb, As-Sa+AdDa)
6.3 Matematika Blending
Contoh soal blending :
Biasanya, alasan mengapa seseorang menggunakan:
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
karena ingin menggunakan nilai alpha yang baru saja diberikan. Hal
Ini digunakan untuk memperbanyak warna, dan kemudian menggu-
nakan (1 - alpha) dan menggunakannya untuk memperbanyak warna
buffer saat ini dalam koordinat.
Oleh karena itu, jika melukis dengan quad glColor4f (1.0f, 1.0f, 1.0f,
0.6f) dan buffer diisi dengan glColor4f (1.0f, 0.0f, 0.0f, 1.0f), operasi
akhirnya akan menjadi:
(1.0f, 1.0f, 1.0f) * ALPHA (1.0f, 0.0f, 0.0f) * (1 - ALPHA)
(0.6f, 0.6f, 0.6f) (0.4f, 0.0f, 0.0f)
Jadi warna akhir adalah (1.0f, 0.6f, 0.6f)
380
Berikut contohnya :
Objek ke 1 (biru) dengan RGBA (10, 20, 5, 0.2)
S
Objek ke 2 (merah) dengan RGBA (30, 15, 6, 0.1)
D
Gabungan objek satu dan objek 2
(R G B A) ?
GL_ONE_MINUS_SRC_ALPHA S/D (1,1,1,1) = (As,As,As,As)
= (1, 1, 1, 1)(0.2, 0.2, 0.2, 0.2)
= (0.8, 0.8, 0.8, 0.8)
381
Blended color
Rblend = 0.8*10/S + 30*0.8/D
= 8/S + 24/D
= 32/SD
Gblend = 0.8*20/S + 15*0.8/D
= 16/S + 12/D
= 24/SD
Bblend = 0.8*5/S + 6*0.8/D
= 4/S + 4.8/D
= 8.8/SD
Alphablend = 0.8*0.2/S + 0.1*0.8/D
= 0.16/S + 0.08/D
= 0.24/SD
RGBA adalah = (32, 24, 8.8, 0.24)
6.4 Blending Dua Segitiga
Source Code 6.1 Code Blending Dua Segitiga
ESRender.java
package com.blending;
import java.util.Formatter;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLU;
import android.util.Log;
import android.widget.TextView;
public class ESRender implements Renderer {
private ESText glText;
private TextView textview;
382
private ObjectArena objectarena; // the primitive
object to be drawn
private ObjectBall objectball;
private ObjectBall objectball2;
private ObjectBall objectball3;
private PrimitivesObject primob;
Context context;
int Run_Mode=0;
float CurrentAngle = 0.0f; //
Angle in degrees
float AnimateStep = 2.0f; //
Rotation step per update
float radius = 50.0f; // Ball's radius
float x = radius; // Ball's center (x,y)
float y = radius;
float speedX = 5f; // Ball's speed (x,y)
float speedY = 3f;
int xMin, xMax, yMin, yMax;
private int mywidth = 0;
private int myheight = 0;
private int jumlah_pantulan=0;
/** Constructor to set the handed over context */
public ESRender(Context context) {
// super();
this.context = context;
this.objectarena = new ObjectArena();
this.objectball = new ObjectBall();
this.objectball2 = new ObjectBall();
this.objectball3 = new ObjectBall();
this.primob = new PrimitivesObject();
}
@Override
public void onDrawFrame(GL10 gl) {
// Draw background color
gl.glClear(GL10.GL_COLOR_BUFFER_BIT |
GL10.GL_DEPTH_BUFFER_BIT);
// segitiga merah
gl.glPushMatrix();
gl.glColor4f(1.0f, 0.0f, 0.0f,
0.5f);
gl.glTranslatef(50.0f, 60.0f,
0.0f);
gl.glScalef(80.0f, 80.0f, 0.0f);
gl.glRotatef(180, 1.0f, 0.0f,
0.0f);
gl.glTranslatef(5.0f, -3.5f,
0.0f);
objectball.draw_segitiga(gl);
gl.glPopMatrix();
383
// segitiga hijau
gl.glPushMatrix();
gl.glColor4f(0.0f, 0.0f, 1.0f,
0.5f);
gl.glTranslatef(60.0f, 60.0f,
0.0f);
gl.glScalef(80.0f, 80.0f, 0.0f);
gl.glRotatef(180, 1.0f, 0.0f,
0.0f);
gl.glTranslatef(5.0f, -3.5f,
0.0f);
objectball.draw_segitiga(gl);
gl.glPopMatrix();
// update
moveWithCollisionDetection(this);
set((int)-radius, (int)-radius, mywidth,
myheight);
// render text
gl.glPushMatrix();
// gl.glScalef(10.0f, 10.0f, 10.0f);
// enable texture + alpha blending
// NOTE: this is required for text ren-
dering! we could incorporate it
// into
// the GLText class, but then it would be
called multiple times (which
// impacts performance).
gl.glEnable(GL10.GL_TEXTURE_2D); // Ena-
ble Texture Mapping
gl.glEnable(GL10.GL_BLEND); // Enable Al-
pha Blend
gl.glBlendFunc(GL10.GL_SRC_ALPHA,
GL10.GL_ONE_MINUS_SRC_ALPHA); // Set
// Alpha
// Blend
// Function
// disable texture + alpha
gl.glDisable(GL10.GL_BLEND); // Disable
Alpha Blend
gl.glDisable(GL10.GL_TEXTURE_2D); // Dis-
able Texture Mapping
gl.glPopMatrix();
384
// Update the rotational angle after each
refresh
// re-Calculate animation parame-
ters
CurrentAngle += AnimateStep;
if (CurrentAngle > 360.0) {
//CurrentAngle -=
360.0*Math.floor(CurrentAngle/360.0);
CurrentAngle=0.0f;
CurrentAngle += Ani-
mateStep;
}
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig
config) {
gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
// Set color's clear-value to
// black
gl.glClearDepthf(1.0f); // Set depth's
clear-value to farthest
gl.glEnable(GL10.GL_DEPTH_TEST); // Ena-
bles depth-buffer for hidden
// surface removal
gl.glDepthFunc(GL10.GL_LEQUAL); // The
type of depth testing to do
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
GL10.GL_NICEST); // nice
// perspective
// view
gl.glShadeModel(GL10.GL_SMOOTH); // Ena-
ble smooth shading of color
gl.glDisable(GL10.GL_DITHER); // Disable
dithering for better
// performance
// Create the GLText
glText = new ESText(gl, con-
text.getAssets());
// Load the font from file (set size +
padding), creates the texture
// NOTE: after a successful call to this
the font is ready for
// rendering!
glText.load("Roboto-Regular.ttf", 14, 2,
2); // Create Font (Height: 14
//
Pixels / X+Y Padding
// 2
Pixels)
385
// gl.glDisable(GL10.GL_DITHER); // Disa-
ble dithering for better
// performance
// Setup Texture, each time the surface
is created (NEW)
objectball2.loadBallTexture(gl, context);
gl.glEnable(GL10.GL_TEXTURE_2D); // Ena-
ble texture (NEW)
}
@Override
public void onSurfaceChanged(GL10 gl, int width,
int height) {
mywidth = width;
myheight = height;
gl.glViewport(0, 0, width, height);
// Setup orthographic projection
gl.glMatrixMode(GL10.GL_PROJECTION); //
Activate Projection Matrix
gl.glLoadIdentity(); // Load Identity Ma-
trix
gl.glOrthof( // Set Ortho Projection
(Left,Right,Bottom,Top,Front,Back)
0, width, 0, height,
100.0f, -100.0f);
// Save width and height
// this.width = width; // Save Current
Width
// this.height = height; // Save Current
Height
gl.glMatrixMode(GL10.GL_MODELVIEW); //
Select model-view matrix
gl.glLoadIdentity(); // Reset
}
public float getxMax() {
return xMax;
}
public void setxMax(int xmax) {
xMax = xmax;
}
public float getxMin() {
return xMin;
}
public void setxMin(int xmin) {
xMin = xmin;
}
public float getyMax() {
386
return yMax;
}
public void setyMax(int ymax) {
yMax = ymax;
}
public float getyMin() {
return yMin;
}
public void setyMin(int ymin) {
yMin = ymin;
}
public float getspeedX() {
return speedX;
}
public void setspeedX(float speedX_) {
speedX = speedX_;
}
public float getspeedY() {
return speedY;
}
public void setspeedY(float speedY_) {
speedY = speedY_;
}
public void moveWithCollisionDetection(ESRender
esRender) {
// Get new (x,y) position
x += speedX;
y += speedY;
// Detect collision and react
if (x + radius > esRender.getxMax()) {
speedX = -speedX;
x = esRender.getxMax() - radius;
this.jumlah_pantulan+=1;
} else if (x - radius < esRen-
der.getxMin()) {
speedX = -speedX;
x = esRender.getxMin() + radius;
this.jumlah_pantulan+=1;
}
if (y + radius > esRender.getyMax()) {
speedY = -speedY;
y = esRender.getyMax() - radius;
this.jumlah_pantulan+=1;
} else if (y - radius < esRen-
der.getyMin()) {
speedY = -speedY;
y = esRender.getyMin() + radius;
this.jumlah_pantulan+=1;
}
// pengkondisian penghitungan pantulan
mulai dari nol
if(Run_Mode==0){
this.jumlah_pantulan-=4;
387
this.Run_Mode=1;
}
}
public void set(int x, int y, int width, int
height) {
xMin = x;
// xMax = x + width - 1;
xMax = x + width;
yMin = y;
// yMax = y + height - 1;
yMax = y + height;
}
}
ESSurfaceView.java
package com.blending;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
/**
* A view container where OpenGL ES graphics can be
drawn on screen.
* This view can also be used to capture touch events,
such as a user
* interacting with drawn objects.
*/
public class ESSurfaceView extends GLSurfaceView {
private final ESRender esRender;
private float previousX;
private float previousY;
public ESSurfaceView(Context context) {
super(context);
// Set the Renderer for drawing on the GLSur-
faceView
esRender = new ESRender(context);
setRenderer(esRender);
// To enable keypad
this.setFocusable(true);
this.requestFocus();
// To enable touch mode
this.setFocusableInTouchMode(true);
// Render the view only when there is a change
in the drawing data
// merender hanya ketika ada perubahan/ event
388
//setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
//private final float TOUCH_SCALE_FACTOR =
getWidth() / getHeight();
private float mPreviousX;
private float mPreviousY;
@Override
public boolean onTouchEvent(MotionEvent v) {
// MotionEvent reports input details from the
touch screen
// and other input controls. In this case, we
are only
// interested in events where the touch posi-
tion changed.
float currentX = v.getX();
float currentY = v.getY();
float deltaX, deltaY;
//float scalingFactor = 0.50f / ((esRen-
der.xMax > esRender.yMax) ? esRender.yMax
//: esRender.xMax);
switch (v.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.v("Test Action Down", "action
down working");
//break;
requestRender();
//case MotionEvent.ACTION_POINTER_UP:
//Log.v("Test Action
ACTION_POINTER_UP", "action working");
//requestRender();
//case MotionEvent.ACTION_MOVE:
//Log.v("Test Action
ACTION_POINTER_DOWN", "action working");
//requestRender();
//case MotionEvent.ACTION_UP:
//Log.v("Test Action Up", "action
up working");
//requestRender();
case MotionEvent.ACTION_MOVE:
// Modify rotational angles according to
movement
deltaX = currentX - previousX;
deltaY = currentY - previousY;
//esRender.setspeedX(esRender.getspeedX()+ (del-
taX/getWidth()));
//esRender.setspeedY(esRender.getspeedY()+ (del-
taY/getHeight()));
esRen-
der.setspeedX(esRender.getspeedX()+ deltaX/100);
esRen-
389
der.setspeedY(esRender.getspeedY()+ deltaY/100);
requestRender();
}
// Save current x, y
previousX = currentX;
previousY = currentY;
return true; // Event handled
//break;
}
// Key-up event handler
@Override
public boolean onKeyUp(int keyCode, KeyEvent
event) {
switch (keyCode) {
case KeyEvent.KEYCODE_A: // mengurangi
kecepatan object
if((esRender.getspeedX()- 0.05f
>0) ){
esRen-
der.setspeedX(esRender.getspeedX()- 0.05f);
}
if((esRender.getspeedX()- 0.05f
<0) ){
esRender.setspeedX(0.0f);
}
if((esRender.getspeedY()- 0.05f
>=0)){
esRen-
der.setspeedY(esRender.getspeedY()- 0.05f);
}
if((esRender.getspeedY()- 0.05f
<0) ){
esRender.setspeedY(0.0f);
}
Log.v("Test Action KEYCODE_A",
"action working");
break;
case KeyEvent.KEYCODE_Z:
Log.v("Test Action KEYCODE_Z",
"action working");
break;
}
return true; // Event handled
}
}
MainActivity.java
package com.blending;
390
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.Window;
import android.view.WindowManager;
public class MainActivity extends Activity {
/** The OpenGL view */
private GLSurfaceView glSurfaceView;
@Override
protected void onCreate(Bundle savedInstanceS-
tate) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
// requesting to turn the title OFF
requestWindowFeature(Window.FEATURE_NO_TITLE);
// making it full screen
getWin-
dow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCR
EEN,
WindowManag-
er.LayoutParams.FLAG_FULLSCREEN);
// Initiate the Open GL view and
// create an instance with this activity
glSurfaceView = new ESSurfaceView(this);
// set our renderer to be the main renderer
with
// the current activity context
//glSurfaceView.setRenderer(new ESRender());
setContentView(glSurfaceView);
}
/**
* Remember to resume the glSurface
*/
@Override
protected void onResume() {
super.onResume();
glSurfaceView.onResume();
}
/**
* Also pause the glSurface
*/
@Override
protected void onPause() {
super.onPause();
glSurfaceView.onPause();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to
391
the action bar if it is present.
getMenuInflater().inflate(R.menu.main,
menu);
return true;
}
}
PrimitivesObject.java
package com.blending;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLES20;
public class PrimitivesObject {
private float vertices[] = { -0.5f, -0.5f, 0.0f,
// V1 - first vertex
//
(x,y,z)
-0.5f, 0.5f, 0.0f, // V2
0.5f, 0.5f, 0.0f, // V3
0.5f, -0.5f, 0.0f, // V4
-0.5f, -0.5f, 0.0f // V5
};
private float[] vertices_quad = { // Vertices for
the square
-1.0f, -1.0f, 0.0f, // 0. left-bottom
1.0f, -1.0f, 0.0f, // 1. right-
bottom
-1.0f, 1.0f, 0.0f, // 2. left-top
1.0f, 1.0f, 0.0f // 3. right-top
};
private float vertices_color[] = { 1.0f, 0.0f,
0.0f, 1.0f, // CV1 - first
// color
// (red,green,blue)
0.0f, 1.0f, 0.0f, 1.0f, // CV2
0.0f, 0.0f, 1.0f, 1.0f, // CV3
0.0f, 1.0f, 0.0f, 1.0f, // CV4
1.0f, 0.0f, 0.0f, 1.0f // CV5
};
392
private float vertices_circle[] = { 0.0f, 0.0f,
0.0f };
private float vertices_circle_color[] = { 0.0f,
0.0f, 0.0f, 0.5f };
private float vertices_line[] = { 0.0f, 0.0f,
0.0f };
private float vertices_line_color[] = { 0.0f,
0.0f, 0.0f, 1.0f };
private int batas_sudut = 360;
float jari_jari;
float a, b;
float x, y;
float step = 3.0f, step_line = 0.2f;
float x1, y1;
float x2, y2;
private int loop, loop_color, loop_line,
loop_line_color;
public PrimitivesObject() {
// ============ start to generate verti-
ces to circle
// ==========================
// Inisialisasi
jari_jari = 1.0f;
// Titik Pusat
a = 0.0f;
b = 0.0f;
x = a + jari_jari;
y = b;
loop = 3;
loop_color = 4;
vertices_circle = new float[(int) (3 *
batas_sudut / step) * 3];
vertices_circle_color = new float[(int)
(3 * batas_sudut / step) * 4];
for (float teta = 0; teta <= 2 * ba-
tas_sudut; teta += step) {
vertices_circle[loop] = (float)
((x - a)
* Math.cos((teta /
180) * (22 / 7))
- ((y - b) *
Math.sin((teta / 180) * (22 / 7))) + a);
vertices_circle[loop + 1] =
(float) ((x - a)
* Math.sin((teta /
180) * (22 / 7))
- ((y - b) *
Math.cos((teta / 180) * (22 / 7))) + b);
vertices_circle[loop + 2] = 0;
loop += 3;
// mengenerate warna untuk setiap
vertex
vertices_circle_color[loop_color]
393
= (float) ((x - a)
* Math.cos((teta /
180) * (22 / 7))
- ((y - b) *
Math.sin((teta / 180) * (22 / 7))) + a);
vertices_circle_color[loop_color +
1] = (float) ((x - a)
* Math.sin((teta /
180) * (22 / 7))
- ((y - b) *
Math.cos((teta / 180) * (22 / 7))) + b);
vertices_circle_color[loop_color +
2] = 0.5f;
vertices_circle_color[loop_color +
3] = 0.5f;
loop_color += 4;
}
// ============= end for generate verti-
ces to circle
// ====================
// ============ start to generate verti-
ces to line
// ==========================
x1 = -1.0f;
y1 = -1.0f;
x2 = 1.0f;
y2 = 1.0f;
loop_line = 3;
loop_line_color = 4;
vertices_line = new float[(int) (2 * (x2
- x1) / step_line) * 3];
vertices_line_color = new float[(int) (2
* (x2 - x1) / step_line) * 4];
float m = (y2 - y1) / (x2 - x1);
for (x = x1; x <= x2; x += step_line) {
vertices_line[loop_line] = (float)
(x);
vertices_line[loop_line + 1] =
(float) (m * (x - x1) + y1);
vertices_line[loop_line + 2] = 0;
loop_line += 3;
// mengenerate warna untuk setiap
vertex
verti-
ces_line_color[loop_line_color] = (float) (0.5 * x);
verti-
ces_line_color[loop_line_color + 1] = (float) (0.5 * m
* (x - x1) + y1);
verti-
ces_line_color[loop_line_color + 2] = 1.0f;
verti-
ces_line_color[loop_line_color + 3] = 1.0f;
loop_line_color += 4;
}
// ============= end for generate verti-
394
ces to line ====================
}
// Point to our vertex buffer, return buffer
holding the vertices
public static FloatBuffer makeFloatBuffer(float[]
arr) {
ByteBuffer bb = ByteBuff-
er.allocateDirect(arr.length * 4);
bb.order(ByteOrder.nativeOrder());
FloatBuffer fb = bb.asFloatBuffer();
fb.put(arr);
fb.position(0);
return fb;
}
/** The draw method for the primitive object with
the GL context */
public void draw_points(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// set the colour for the points (pem-
berian warna untuk titik)
gl.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
// Point to our vertex buffer (mendata
nilai lokasi/posisi titik)
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(new float[] {
1.0f, 1.0f, 0.0f, // V1 -
first vertex (x,y,z)
1.0f, 0.8f, 0.0f, // V2
1.0f, 0.6f, 0.0f, // V3
1.0f, 0.4f, 0.0f, // V4
1.0f, 0.2f, 0.0f, // V5
1.0f, 0.0f, 0.0f, // V6
1.0f, -0.2f, 0.0f, // V7
1.0f, -0.4f, 0.0f, // V8
1.0f, -0.6f, 0.0f, // V9
1.0f, -0.8f, 0.0f, // V10
1.0f, -1.0f, 0.0f, // V11
0.8f, -1.0f, 0.0f, // V12
0.6f, -1.0f, 0.0f, // V13
0.4f, -1.0f, 0.0f, // V14
0.2f, -1.0f, 0.0f, // V15
0.0f, -1.0f, 0.0f, // V16
-0.2f, -1.0f, 0.0f, // V17
-0.4f, -1.0f, 0.0f, // V18
-0.6f, -1.0f, 0.0f, // V19
-0.7f, -1.0f, 0.0f, // V20
-0.8f, -1.0f, 0.0f, // V21
-1.0f, -1.0f, 0.0f, // V22
}));
395
// Draw the vertices as points (menggam-
bar titik-titik)
gl.glDrawArrays(GL10.GL_POINTS, 0, 22);
// Disable the client state before leav-
ing
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
//
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}
public void draw_line(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// set the colour for the line (pemberian
warna untuk garis)
gl.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
// Point to our vertex buffer (mendata
nilai lokasi/posisi titik yang
// menyusun garis)
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(new float[] {
1.0f, 1.0f, 0.0f, // V1 -
first vertex (x,y,z)
-1.0f, -1.0f, 0.0f, // V2
- second vertex
}));
// Draw the vertices as lines (menggambar
garis dari titik-titik)
gl.glDrawArrays(GL10.GL_LINES, 0, 2);
/*
* gl.glDrawElements(GL10.GL_LINES, 2,
GL10.GL_UNSIGNED_SHORT,
* makeFloatBuffer(new float [] { 1.0f,
1.0f, 0.0f, // V1 - first vertex
* (x,y,z) -1.0f, -1.0f, 0.0f, // V2 -
second vertex }));
*/
// Disable the client state before leav-
ing
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
//
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}
public void draw_line_color(GL10 gl) {
396
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// set the colour for the line (pemberian
warna untuk garis)
gl.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
// Point to our vertex buffer (mendata
nilai lokasi/posisi titik yang
// menyusun garis)
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices_line));
// memetakan warna untuk setiap vertex
gl.glColorPointer(4, GL10.GL_FLOAT, 0,
makeFloatBuff-
er(vertices_line_color));
// Draw the vertices as lines (menggambar
garis dari titik-titik)
gl.glDrawArrays(GL10.GL_LINE_STRIP, 0,
(int) (2 * (x2 - x1) /
step_line));
/*
* gl.glDrawElements(GL10.GL_LINES, 2,
GL10.GL_UNSIGNED_SHORT,
* makeFloatBuffer(new float [] { 1.0f,
1.0f, 0.0f, // V1 - first vertex
* (x,y,z) -1.0f, -1.0f, 0.0f, // V2 -
second vertex }));
*/
// Disable the client state before leav-
ing
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}
public void draw_circle(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// set the colour for the object circle
gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
// create VBO from buffer with glBuffer-
Data()
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuff-
er(vertices_circle));
// draw circle as filled shape
// gl.glDrawArrays(GL10.GL_TRIANGLE_FAN,
397
1, (int) ((int)
// 2*batas_sudut/step));
// draw circle contours
// gl.glDrawArrays(GL10.GL_LINES, 1,
(int) ((int) 2*batas_sudut/step));
// // membuat garis putus-putus pada tepi
lingkaran
gl.glDrawArrays(GL10.GL_LINES, 1, (int)
((int) 2 * batas_sudut / step));
// gl.glDrawArrays(GL10.GL_LINE_STRIP, 1,
(int) ((int)
// 2*batas_sudut/step));
// gl.glDrawArrays(GL10.GL_POINTS, 1,
(int) ((int) 2*batas_sudut/step));
// Disable the client state before leav-
ing
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
//
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}
public void draw_circle_color(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// set the colour edge for the object
circle
gl.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
// create VBO from buffer with glBuffer-
Data()
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuff-
er(vertices_circle));
// memetakan warna untuk setiap vertex
gl.glColorPointer(4, GL10.GL_FLOAT, 0,
makeFloatBuff-
er(vertices_circle_color));
// draw circle as filled shape
// gl.glDrawArrays(GL10.GL_TRIANGLE_FAN,
1, (int) ((int)
// 2*batas_sudut/step));
gl.glDrawArrays(GL10.GL_LINE_STRIP, 1,
(int) ((int) 2 * ba-
tas_sudut / step));
// Disable the client state before leav-
ing
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
398
}
public void draw_kotak(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices));
// Draw the vertices as square
gl.glColorPointer(4, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices_color));
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
gl.glColorPointer(4, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices_color));
gl.glDrawArrays(GL10.GL_TRIANGLES, 2, 3);
// Disable the client state before leav-
ing
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}
public void draw_segitiga(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// set the colour for the triangle
gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(new float[] {
-0.5f, -0.5f, 0.0f, // V1
- first vertex (x,y,z)
0.5f, -0.5f, 0.0f, // V2 -
second vertex
0.0f, 0.5f, 0.0f // V3 -
third vertex
}));
// Draw the vertices as triangle
gl.glColorPointer(4, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices_color));
gl.glDrawArrays(GLES20.GL_TRIANGLES, 0,
3);
// Disable the client state before leav-
ing
399
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}
// Render the shape quad
public void draw_quad(GL10 gl) {
// Enable vertex-array and define its
buffer
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices_quad));
// Draw the primitives from the vertex-
array directly
gl.glPolygonOffset(0.0f, 1.0f);
gl.glScalef(0.5f, 0.5f, 0.5f);
gl.glColor4f(0.5f, 0.5f, 1.0f, 1.0f); //
Set the current color (NEW)
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, vertices_quad.length / 3);
//gl.glDrawArrays(GL10.GL_TRIANGLES, 0,
vertices_quad.length / 3);
//gl.glDrawArrays(GL10.GL_LINES, 0, ver-
tices_quad.length / 3);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
}
Gambar 6.2 Blending Dua Segitiga
400
6.5 Blending Pada Kubus
Source Code 6.2 Code Blending Pada Kubus
ESRender.java
package com.blending;
import java.io.IOException;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
//import android.opengl.GLU;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLU;
public class ESRender implements Renderer {
private Context context; // Application context
needed to read image (NEW)
private TextureKubus kubus;
int RunMode = 1;
float CurrentAngle = 0.0f; // Angle in degrees
float AnimateStep = 2.0f; // Rotation step per
update
// Lighting
boolean lightingEnabled = false;
private float[] lightAmbient = { 0.5f, 0.5f,
0.5f, 1.0f };
private float[] lightDiffuse = { 1.0f, 1.0f,
1.0f, 1.0f };
private float[] lightPosition = { 0.0f, 0.0f,
2.0f, 1.0f };
// Blending (NEW)
boolean blendingEnabled = false; // Is blending
on? (NEW)
/** Constructor to set the handed over context */
public ESRender(Context context) {
this.context = context; // Get the appli-
cation context (NEW)
kubus = new TextureKubus();
}
@Override
public void onDrawFrame(GL10 gl) {
// clear Screen and Depth Buffer
// gl.glClearColor(1.0f, 1.0f, 1.0f,
1.0f); // set background dgn warna
// putih
401
// gl.glClearColor(0.0f, 0.0f, 0.0f,
1.0f); // set background dgn warna
// hitam
gl.glClear(GL10.GL_COLOR_BUFFER_BIT |
GL10.GL_DEPTH_BUFFER_BIT);
// Enable lighting?
if (lightingEnabled) {
gl.glEnable(GL10.GL_LIGHTING);
} else {
gl.glDisable(GL10.GL_LIGHTING);
}
// Blending Enabled? (NEW)
if (blendingEnabled) {
gl.glEnable(GL10.GL_BLEND); //
Turn blending on (NEW)
gl.glDisable(GL10.GL_DEPTH_TEST);
// Turn depth testing off (NEW)
} else {
gl.glDisable(GL10.GL_BLEND); //
Turn blending off (NEW)
gl.glEnable(GL10.GL_DEPTH_TEST);
// Turn depth testing on (NEW)
}
//gl.glLoadIdentity();
// ----- Render the Kubus -----
gl.glPushMatrix();
gl.glTranslatef(0.0f, 0.9f, -
5.0f);
// gl.glTranslatef(0.0f, 0.0f, -
6.0f); // Translate into the screen
gl.glRotatef(CurrentAngle, 0.1f,
1.0f, 0.2f); // Rotate
// gl.glRotatef(CurrentAngle,
1.0f, 1.0f, 1.0f );
gl.glTranslatef(-0.5f, -0.5f, -
0.5f);
//gl.glScalef(0.5f, 0.5f, 0.5f);
kubus.draw(gl);
gl.glPopMatrix();
// Update the rotational angle after each
refresh
if (RunMode == 1) {
// re-Calculate animation parame-
ters
CurrentAngle += AnimateStep;
if (CurrentAngle > 360.0) {
// CurrentAngle -=
360.0*Math.floor(CurrentAngle/360.0);
CurrentAngle = 0.0f;
CurrentAngle += Ani-
mateStep;
}
}
402
}
@Override
public void onSurfaceChanged(GL10 gl, int width,
int height) {
if (height == 0)
height = 1; // To prevent divide
by zero
float aspect = (float) width / height;
// Set the viewport (display area) to
cover the entire window
gl.glViewport(0, 0, width, height);
// Setup perspective projection, with as-
pect ratio matches viewport
gl.glMatrixMode(GL10.GL_PROJECTION); //
Select projection matrix
gl.glLoadIdentity(); // Reset projection
matrix
// Use perspective projection
GLU.gluPerspective(gl, 45, aspect, 0.1f,
100.f);
// gl.glOrthof(-3.0f, 3.0f, -3.0f, 3.0f,
-3.0f, 3.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW); //
Select model-view matrix
gl.glLoadIdentity(); // Reset
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig
config) {
gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// Set color's clear-value to
// black
gl.glClearDepthf(1.0f); // Set depth's
clear-value to farthest
gl.glEnable(GL10.GL_DEPTH_TEST); // Ena-
bles depth-buffer for hidden
// surface removal
gl.glDepthFunc(GL10.GL_LEQUAL); // The
type of depth testing to do
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
GL10.GL_NICEST); // nice
// perspective
// view
gl.glShadeModel(GL10.GL_SMOOTH); // Ena-
ble smooth shading of color
gl.glDisable(GL10.GL_DITHER); // Disable
dithering for better
// performance
// Setup Texture, each time the surface
403
is created (NEW)
kubus.loadTexture(gl, context);
gl.glEnable(GL10.GL_TEXTURE_2D); // Ena-
ble texture (NEW)
// Setup lighting GL_LIGHT1 with ambient
and diffuse lights
gl.glLightfv(GL10.GL_LIGHT1,
GL10.GL_AMBIENT, lightAmbient, 0);
gl.glLightfv(GL10.GL_LIGHT1,
GL10.GL_DIFFUSE, lightDiffuse, 0);
gl.glLightfv(GL10.GL_LIGHT1,
GL10.GL_POSITION, lightPosition, 0);
gl.glEnable(GL10.GL_LIGHT1); // Enable
Light 1
gl.glEnable(GL10.GL_LIGHT0); // Enable
the default Light 0
// Setup Blending (NEW)
gl.glColor4f(1.0f, 1.0f, 1.0f, 0.5f); //
Full brightness, 50% alpha (NEW)
gl.glBlendFunc(GL10.GL_SRC_ALPHA,
GL10.GL_ONE); // Select blending function (NEW)
}
public int getRunMode() {
return RunMode;
}
public void setRunMode(int mRunMode) {
RunMode = mRunMode;
}
public float getAnimateStep() {
return AnimateStep;
}
public void setAnimateStep(float mAnimateStep) {
AnimateStep = mAnimateStep;
}
}
ESSurfaceView.java
package com.blending;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
404
/**
* A view container where OpenGL ES graphics can be
drawn on screen. This view
* can also be used to capture touch events, such as a
user interacting with
* drawn objects.
*/
public class ESSurfaceView extends GLSurfaceView {
private final ESRender esRender;
public ESSurfaceView(Context context) {
super(context);
// Set the Renderer for drawing on the
GLSurfaceView
esRender = new ESRender(context);
setRenderer(esRender);
// To enable keypad
this.setFocusable(true);
this.requestFocus();
// To enable touch mode
this.setFocusableInTouchMode(true);
// Render the view only when there is a
change in the drawing data
// merender hanya ketika ada perubahan/
event
// setRender-
Mode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
private float mPreviousX;
private float mPreviousY;
@Override
public boolean onTouchEvent(MotionEvent v) {
// MotionEvent reports input details from
the touch screen
// and other input controls. In this
case, we are only
// interested in events where the touch
position changed.
float x = v.getX();
float y = v.getY();
switch (v.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.v("Test Action Down", "action
down working");
break;
// case MotionEvent.ACTION_POINTER_UP:
// Log.v("Test Action ACTION_POINTER_UP",
"action working");
// requestRender();
405
// case MotionEvent.ACTION_MOVE:
// Log.v("Test Action
ACTION_POINTER_DOWN", "action working");
// requestRender();
// case MotionEvent.ACTION_UP:
// Log.v("Test Action Up", "action up
working");
// requestRender();
case MotionEvent.ACTION_MOVE:
Log.v("Test Action move", "action
down working");
float dx = (x - mPreviousX);
float dy = (y - mPreviousY);
mPreviousX = x;
mPreviousY = y;
esRender.blendingEnabled = !esRen-
der.blendingEnabled;
requestRender();
}
return true;
}
// Key-up event handler
@Override
public boolean onKeyUp(int keyCode, KeyEvent
event) {
float x=getHeight();
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_RIGHT: // In-
crease rightward speed
Log.v("Test Action
KEYCODE_DPAD_RIGHT", "action working");
requestRender();
break;
case KeyEvent.KEYCODE_DPAD_LEFT: // In-
crease leftward speed
requestRender();
break;
case KeyEvent.KEYCODE_DPAD_UP: // In-
crease upward speed
break;
case KeyEvent.KEYCODE_DPAD_DOWN: // In-
crease downward speed
break;
case KeyEvent.KEYCODE_DPAD_CENTER: //
Stop
break;
case KeyEvent.KEYCODE_B: // enable blend-
ing
Log.v("Test Action B", "action
working");
esRender.blendingEnabled = !esRen-
der.blendingEnabled;
requestRender();
break;
406
}
return true; // Event handled
}
}
MainActivity.java
package com.blending;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.Window;
import android.view.WindowManager;
public class MainActivity extends Activity {
/** The OpenGL view */
private GLSurfaceView glSurfaceView;
@Override
protected void onCreate(Bundle savedInstanceS-
tate) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
// requesting to turn the title OFF
requestWindowFeature(Window.FEATURE_NO_TITLE);
// making it full screen
getWin-
dow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCR
EEN,
WindowManag-
er.LayoutParams.FLAG_FULLSCREEN);
// Initiate the Open GL view and
// create an instance with this activity
glSurfaceView = new ESSurfaceView(this);
// set our renderer to be the main renderer
with
// the current activity context
//glSurfaceView.setRenderer(new ESRender());
setContentView(glSurfaceView);
}
/**
* Remember to resume the glSurface
*/
@Override
protected void onResume() {
super.onResume();
407
glSurfaceView.onResume();
}
/**
* Also pause the glSurface
*/
@Override
protected void onPause() {
super.onPause();
glSurfaceView.onPause();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to
the action bar if it is present.
getMenuInflater().inflate(R.menu.main,
menu);
return true;
}
}
TextureKubus.java
package com.blending;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
/*
* A cube with texture.
* Define the vertices for only one representative
face.
* * Render the cube by translating and rotating the
face.
*/
public class TextureKubus {
private FloatBuffer vertexBuffer; // Buffer for
vertex-array
private FloatBuffer texBuffer; // Buffer for tex-
ture-coords-array (NEW)
private float[] vertices = { // Vertices for a
408
face
-1.0f, -1.0f, 0.0f, // 0. left-
bottom-front
1.0f, -1.0f, 0.0f, // 1. right-
bottom-front
-1.0f, 1.0f, 0.0f, // 2. left-top-
front
1.0f, 1.0f, 0.0f // 3. right-top-
front
};
float[] texCoords = { // Texture coords for the
above face (NEW)
0.0f, 1.0f, // A. left-bottom
(NEW)
1.0f, 1.0f, // B. right-bottom
(NEW)
0.0f, 0.0f, // C. left-top (NEW)
1.0f, 0.0f // D. right-top (NEW)
};
int[] textureIDs = new int[1]; // Array for 1
texture-ID (NEW)
// Constructor - Set up the buffers
public TextureKubus() {
// Setup vertex-array buffer. Vertices in
float. An float has 4 bytes
ByteBuffer vbb = ByteBuff-
er.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder()); //
Use native byte order
vertexBuffer = vbb.asFloatBuffer(); //
Convert from byte to float
vertexBuffer.put(vertices); // Copy data
into buffer
vertexBuffer.position(0); // Rewind
// Setup texture-coords-array buffer, in
float. An float has 4 bytes
// (NEW)
ByteBuffer tbb = ByteBuff-
er.allocateDirect(texCoords.length * 4);
tbb.order(ByteOrder.nativeOrder());
texBuffer = tbb.asFloatBuffer();
texBuffer.put(texCoords);
texBuffer.position(0);
}
// Draw the shape
public void draw(GL10 gl) {
gl.glFrontFace(GL10.GL_CCW); // Front
face in counter-clockwise
// orientation
//gl.glEnable(GL10.GL_CULL_FACE); // Ena-
ble cull face / disable transparan object
gl.glCullFace(GL10.GL_BACK); // Cull the
back face (don't display)
409
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
vertexBuffer);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRA
Y); // Enable
// texture-coords-array
// (NEW)
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0,
texBuffer); // Define
// texture-coords
// buffer (NEW)
// front
gl.glPushMatrix();
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
// left
gl.glPushMatrix();
gl.glRotatef(270.0f, 0.0f, 1.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
// back
gl.glPushMatrix();
gl.glRotatef(180.0f, 0.0f, 1.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
// right
gl.glPushMatrix();
gl.glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
// top
gl.glPushMatrix();
gl.glRotatef(270.0f, 1.0f, 0.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
// bottom
410
gl.glPushMatrix();
gl.glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARR
AY); // Disable
// texture-coords-array
// (NEW)
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
//gl.glDisable(GL10.GL_CULL_FACE);
}
// Load an image into GL texture
public void loadTexture(GL10 gl,Context c) {
gl.glGenTextures(1, textureIDs, 0); //
Generate texture-ID array
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[0]); // Bind to texture
// ID
// Set up texture filters
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);
// Construct an input stream to texture
image "res\drawable\nature.png"
//AssetManager assetManager =
c.getAssets();
//InputStream istream = assetManag-
er.open("nature.png");
InputStream istream =
c.getResources().openRawResource(R.drawable.nature);
Bitmap bitmap;
try {
// Read and decode input as bitmap
bitmap = BitmapFacto-
ry.decodeStream(istream);
} finally {
try {
istream.close();
} catch (IOException e) {
}
}
// Build Texture from loaded bitmap for
411
the currently-bind texture ID
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0,
bitmap, 0);
bitmap.recycle();
}
}
Gambar 6.3 Blending Pada Kubus (Blending tidak terlihat jika belum ada gerakan sentuhan ke sembarang arah pada layarnya)
6.6 Blending Pada Bola
Source Code 6.3 Code Blending Pada Bola
ESRender.java
package com.blending;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLU;
public class ESRender implements Renderer {
/** Tilt the spheres a little. */
private static final int AXIAL_TILT_DEGRESS =
30;
412
/** Clear colour, alpha component. */
private static final float CLEAR_RED = 0.0f;
/** Clear colour, alpha component. */
private static final float CLEAR_GREEN = 0.0f;
/** Clear colour, alpha component. */
private static final float CLEAR_BLUE = 0.0f;
/** Clear colour, alpha component. */
private static final float CLEAR_ALPHA = 0.5f;
/** Perspective setup, field of view component.
*/
private static final float FOVY = 45.0f;
/** Perspective setup, near component. */
private static final float Z_NEAR = 0.1f;
/** Perspective setup, far component. */
private static final float Z_FAR = 100.0f;
/** Object distance on the screen. move it back
a bit so we can see it! */
private static final float OBJECT_DISTANCE = -
15.0f;
/** The earth's sphere. */
private final MySphere mEarth;
/** The context. */
private final Context mContext;
/** The rotation angle, just to give the screen
some action. */
private float mRotationAngle;
/**
* Constructor to set the handed over context.
* @param context The context.
*/
public ESRender(final Context context) {
this.mContext = context;
//this.mEarth = new MySphere(3, 2);
this.mEarth = new MySphere(5, 3);
this.mRotationAngle = 0.0f;
}
// Call back to draw the current frame.
@Override
public void onDrawFrame(GL10 gl) {
// Clear color and depth buffers
gl.glClear(GL10.GL_COLOR_BUFFER_BIT |
GL10.GL_DEPTH_BUFFER_BIT);
gl.glEnable(GL10.GL_BLEND); // Turn
blending on (NEW)
gl.glDisable(GL10.GL_DEPTH_TEST); // Turn
413
depth testing off (NEW)
//gl.glLoadIdentity();
// ----- Render the Sphere -------
-------
gl.glPushMatrix();
gl.glTranslatef(0.0f, 0.0f,
OBJECT_DISTANCE);
gl.glRotatef(AXIAL_TILT_DEGRESS, 1,
0, 0);
gl.glRotatef(this.mRotationAngle++,
0, 1, 0);
this.mEarth.draw(gl);
gl.glPopMatrix();
}
// Call back when the surface is first created or
re-created.
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig
config) {
this.mEarth.loadGLTexture(gl,
this.mContext, R.drawable.earth);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glClearColor(CLEAR_RED, CLEAR_GREEN,
CLEAR_BLUE, CLEAR_ALPHA);
gl.glClearDepthf(1.0f);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
GL10.GL_NICEST);
// Setup Blending (NEW)
gl.glColor4f(1.0f, 1.0f, 1.0f, 0.5f); //
Full brightness, 50% alpha (NEW)
gl.glBlendFunc(GL10.GL_SRC_ALPHA,
GL10.GL_ONE); // Select blending function (NEW)
//gl.glBlendFunc(GL10.GL_ZERO,
GL10.GL_ZERO); // Select blending function (NEW)
}
// Call back after onSurfaceCreated() or whenever
the window's size changes.
@Override
public void onSurfaceChanged(GL10 gl, int width,
int height) {
final float aspectRatio = (float) width /
(float) (height == 0 ? 1 : height);
// gl.glViewport(0, 0, width, height);
//gl.glMatrixMode(GL10.GL_PROJECTION);
// gl.glLoadIdentity();
414
/*if (height == 0)
height = 1; // To prevent divide
by zero
float aspectRatio = (float) width /
height;*/
// Set the viewport (display area) to
cover the entire window
gl.glViewport(0, 0, width, height);
// Setup perspective projection, with as-
pect ratio matches viewport
gl.glMatrixMode(GL10.GL_PROJECTION); //
Select projection matrix
gl.glLoadIdentity(); // Reset projection
matrix
// Use perspective projection
//GLU.gluPerspective(gl, 45, aspect,
0.1f, 100.f);
// gl.glOrthof(-3.0f, 3.0f, -3.0f, 3.0f,
-3.0f, 3.0f);
GLU.gluPerspective(gl, FOVY, aspectRatio,
Z_NEAR, Z_FAR);
gl.glMatrixMode(GL10.GL_MODELVIEW); //
Select model-view matrix
gl.glLoadIdentity(); // Reset
}
}
MainActivity.java
package com.blending;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
public class MainActivity extends Activity {
/** The OpenGL view. */
private GLSurfaceView glSurfaceView;
@Override
protected void onCreate(final Bundle savedIn-
stanceState) {
super.onCreate(savedInstanceState);
415
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.F
LAG_FULLSCREEN, WindowManag-
er.LayoutParams.FLAG_FULLSCREEN);
this.glSurfaceView = new GLSurfaceView(this);
this.glSurfaceView.setRenderer(new ESRen-
der(this));
this.setContentView(this.glSurfaceView);
}
/**
* Remember to resume the glSurface
*/
@Override
protected void onResume() {
super.onResume();
this.glSurfaceView.onResume();
}
/**
* Also pause the glSurface
*/
@Override
protected void onPause() {
super.onPause();
this.glSurfaceView.onPause();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to
the action bar if it is present.
getMenuInflater().inflate(R.menu.main,
menu);
return true;
}
}
Maths.java
package com.blending; /** * @author Jim Cornmell re-edit by XTech * */ public final class Maths { /** 180 in radians. */ public static final double ONE_EIGHTY_DEGREES = Math.PI; /** 360 in radians. */ public static final double THREE_SIXTY_DEGREES = ONE_EIGHTY_DEGREES * 2;
416
/** 120 in radians. */ public static final double ONE_TWENTY_DEGREES = THREE_SIXTY_DEGREES / 3; /** 90 degrees, North pole. */ public static final double NINETY_DEGREES = Math.PI / 2; /** Used by power. */ private static final long POWER_CLAMP = 0x00000000ffffffffL; /** * Constructor, although not used at the moment. */ private Maths() { } /** * Quick integer power function. * * @param base * number to raise. * @param raise * to this power. * @return base ^ raise. */ public static int power(final int base, final int raise) { int p = 1; long b = raise & POWER_CLAMP; // bits in b correspond to values of powerN // so start with p=1, and for each set bit in b, multiply corresponding // table entry long powerN = base; while (b != 0) { if ((b & 1) != 0) { p *= powerN; } b >>>= 1; powerN = powerN * powerN; } return p; } }
MySphere.java
package com.blending;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
417
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
/**
* Render a sphere.
*
* @author Jim Cornmell re-edit by XTech
* @since July 2013
*/
public class MySphere {
/** Maximum allowed depth. */
private static final int MAXIMUM_ALLOWED_DEPTH = 5;
/** Used in vertex strip calculations, related to
properties of a icosahedron. */
private static final int VERTEX_MAGIC_NUMBER = 5;
/** Each vertex is a 2D coordinate. */
private static final int NUM_FLOATS_PER_VERTEX = 3;
/** Each texture is a 2D coordinate. */
private static final int NUM_FLOATS_PER_TEXTURE = 2;
/** Each vertex is made up of 3 points, x, y, z. */
private static final int
AMOUNT_OF_NUMBERS_PER_VERTEX_POINT = 3;
/** Each texture point is made up of 2 points, x, y
(in reference to the texture being a 2D image). */
private static final int
AMOUNT_OF_NUMBERS_PER_TEXTURE_POINT = 2;
/** Buffer holding the vertices. */
private final List<FloatBuffer> mVertexBuffer = new
ArrayList<FloatBuffer>();
/** The vertices for the sphere. */
private final List<float[]> mVertices = new Ar-
rayList<float[]>();
/** Buffer holding the texture coordinates. */
private final List<FloatBuffer> mTextureBuffer = new
ArrayList<FloatBuffer>();
/** Mapping texture coordinates for the vertices. */
private final List<float[]> mTexture = new Ar-
rayList<float[]>();
/** The texture pointer. */
private final int[] mTextures = new int[1];
418
/** Total number of strips for the given depth. */
private final int mTotalNumStrips;
/**
* Sphere constructor.
* @param depth integer representing the split of
the sphere.
* @param radius The spheres radius.
*/
public MySphere(final int depth, final float radius)
{
// Clamp depth to the range 1 to
MAXIMUM_ALLOWED_DEPTH;
final int d = Math.max(1,
Math.min(MAXIMUM_ALLOWED_DEPTH, depth));
// Calculate basic values for the sphere.
this.mTotalNumStrips = Maths.power(2, d - 1) *
VERTEX_MAGIC_NUMBER;
final int numVerticesPerStrip = Maths.power(2, d)
* 3;
final double altitudeStepAngle =
Maths.ONE_TWENTY_DEGREES / Maths.power(2, d);
final double azimuthStepAngle =
Maths.THREE_SIXTY_DEGREES / this.mTotalNumStrips;
double x, y, z, h, altitude, azimuth;
for (int stripNum = 0; stripNum <
this.mTotalNumStrips; stripNum++) {
// Setup arrays to hold the points for this
strip.
final float[] vertices = new
float[numVerticesPerStrip * NUM_FLOATS_PER_VERTEX]; //
NOPMD
final float[] texturePoints = new
float[numVerticesPerStrip * NUM_FLOATS_PER_TEXTURE];
// NOPMD
int vertexPos = 0;
int texturePos = 0;
// Calculate position of the first vertex in
this strip.
altitude = Maths.NINETY_DEGREES;
azimuth = stripNum * azimuthStepAngle;
// Draw the rest of this strip.
for (int vertexNum = 0; vertexNum < numVertices-
PerStrip; vertexNum += 2) {
// First point - Vertex.
y = radius * Math.sin(altitude);
h = radius * Math.cos(altitude);
z = h * Math.sin(azimuth);
x = h * Math.cos(azimuth);
vertices[vertexPos++] = (float) x;
vertices[vertexPos++] = (float) y;
vertices[vertexPos++] = (float) z;
// First point - Texture.
texturePoints[texturePos++] = (float) (1 - az-
419
imuth / Maths.THREE_SIXTY_DEGREES);
texturePoints[texturePos++] = (float) (1 -
(altitude + Maths.NINETY_DEGREES) /
Maths.ONE_EIGHTY_DEGREES);
// Second point - Vertex.
altitude -= altitudeStepAngle;
azimuth -= azimuthStepAngle / 2.0;
y = radius * Math.sin(altitude);
h = radius * Math.cos(altitude);
z = h * Math.sin(azimuth);
x = h * Math.cos(azimuth);
vertices[vertexPos++] = (float) x;
vertices[vertexPos++] = (float) y;
vertices[vertexPos++] = (float) z;
// Second point - Texture.
texturePoints[texturePos++] = (float) (1 - az-
imuth / Maths.THREE_SIXTY_DEGREES);
texturePoints[texturePos++] = (float) (1 -
(altitude + Maths.NINETY_DEGREES) /
Maths.ONE_EIGHTY_DEGREES);
azimuth += azimuthStepAngle;
}
this.mVertices.add(vertices);
this.mTexture.add(texturePoints);
ByteBuffer byteBuffer = ByteBuff-
er.allocateDirect(numVerticesPerStrip *
NUM_FLOATS_PER_VERTEX * Float.SIZE);
byteBuffer.order(ByteOrder.nativeOrder());
FloatBuffer fb = byteBuffer.asFloatBuffer();
fb.put(this.mVertices.get(stripNum));
fb.position(0);
this.mVertexBuffer.add(fb);
// Setup texture.
byteBuffer = ByteBuff-
er.allocateDirect(numVerticesPerStrip *
NUM_FLOATS_PER_TEXTURE * Float.SIZE);
byteBuffer.order(ByteOrder.nativeOrder());
fb = byteBuffer.asFloatBuffer();
fb.put(this.mTexture.get(stripNum));
fb.position(0);
this.mTextureBuffer.add(fb);
}
}
/**
* Load the texture for the square.
*
* @param gl Handle.
* @param context Handle.
* @param texture Texture map for the sphere.
*/
public void loadGLTexture(final GL10 gl, final Con-
text context, final int texture) {
420
final Bitmap bitmap = BitmapFacto-
ry.decodeResource(context.getResources(), texture);
// Generate one texture pointer, and bind it to
the texture array.
gl.glGenTextures(1, this.mTextures, 0);
gl.glBindTexture(GL10.GL_TEXTURE_2D,
this.mTextures[0]);
// Create nearest filtered texture.
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);
// Use Android GLUtils to specify a two-
dimensional texture image from our bitmap.
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap,
0);
// Tidy up.
bitmap.recycle();
}
/**
* The draw method for the square with the GL con-
text.
*
* @param gl Graphics handle.
*/
public void draw(final GL10 gl) {
// bind the previously generated texture.
gl.glBindTexture(GL10.GL_TEXTURE_2D,
this.mTextures[0]);
// Point to our buffers.
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// Set the face rotation, clockwise in this case.
gl.glFrontFace(GL10.GL_CW);
// Point to our vertex buffer.
for (int i = 0; i < this.mTotalNumStrips; i++) {
gl.glVertexPointer(AMOUNT_OF_NUMBERS_PER_VERTEX_POINT,
GL10.GL_FLOAT, 0, this.mVertexBuffer.get(i));
gl.glTexCoordPointer(AMOUNT_OF_NUMBERS_PER_TEXTURE_POI
NT, GL10.GL_FLOAT, 0, this.mTextureBuffer.get(i));
// Draw the vertices as triangle strip.
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0,
this.mVertices.get(i).length /
AMOUNT_OF_NUMBERS_PER_VERTEX_POINT);
}
// Disable the client state before leaving.
421
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
}
Gambar 6.4 Blending Pada Bola
422
BAB 7 Lighting & Shading
7.1 Pengertian Lighting & Shading
Salah satu tujuan dari grafika komputer adalah menghasilkan
tampilan yang senyata mungkin, dan karena pengaruh cahaya sangat
besar terhadap hasil nyata maka dalam membuat tampilan akhir fac-
tor pencahayaan harus diperhitungkan pula. Tetapi mengingat bahwa
grafika computer adalah model matematika dari kehidupan nyata
maka pencahayaan juga harus diubah menjadi model matematika.
Model matematika itu harus memenuhi persyaratan sebagai berikut:
Menghasilkan efek seperti cahaya sungguhan
Dapat dihitung dengan cepat
Model pencahayaan tiga dimensi yang realistik menyangkut
dua elemen penting yang sangat berkaitan erat dengan shading
model, yaitu:
Keakuratan dalam menggambarkan objek.
Teknik pencahayaan yang baik.
Saat cahaya menimpa permukaan benda maka sebagian ca-
haya akan dipantulkan dan sebagian lain diserap. Bergantung kepada
frekuensi atau panjang gelombang yang dipantulkan dan diserap
maka kita akan melihat warna. Mata kita selain sensitive terhadap
warna juga sensitive terhadap intensitas cahaya (brightness). Secara
awam kita menyebut intensitas cahaya sebagai kecerahan.
Gambar 7.1 Pencahayaan
Sifat materi penyusun benda menentukan bagaimana cahaya
bereaksi terhadap materi penyusun benda. Secara umum, cahaya
yang menimpa sebuah permukaan akan dipantulkan oleh permukaan.
423
7.2 Proses dan Fungsi Pada Lighting
float lightAmbient[] = new float[] { 0.2f, 0.3f,
0.6f, 1.0f };
float light_position[] = { 0.0f, 0.0f, 1.0f, 0.0f
};
float white[] = new float[] { 1.0f, 1.0f, 1.0f,
1.0f };
1. gl.glPushMatrix();
2. gl.glTranslatef(0.0f, 0.9f, -5.0f);
3. gl.glRotatef(CurrentAngle, 0.0f, 1.0f, 0.0f );
4. gl.glMaterialf(GL10.GL_FRONT,
GL10.GL_SHININESS, 256.0f);
5. gl.glLightfv(GL10.GL_LIGHT0,GL10.GL_POSITION,l
ight_position,0);
6. gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE,
white, 0);
7. gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT,
lightAmbient, 0);
8. gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_SPECULAR,
white, 0);
9. gl.glScalef(0.1f, 0.1f, 0.1f);
10. lampu.draw(gl);
11. gl.glPopMatrix();
Penjelasan :
1. Untuk membuka atau awalan dalam pembuatan desain dalam
opengl
2. Untuk pengaturan posisi object yang kita inginkan
3. Untuk memutar object dengan sudut yang kita inginkan
4. Cahaya hanya berada dibagian depan , area yang
mendapatkan cahaya sebesar “256.0f”.
5. Untuk pengaturan cahaya pada object dengan memanggil
“light_position” (posisi cahaya)
6. Untuk pengaturan cahaya pada object dengan memanggil
“white” (cahaya warna putih atau terang).
7. Untuk pengaturan cahaya pada object dengan memanggil
“lightAmbient”(cahaya berasal dari segala arah).
424
8. Untuk pengaturan cahaya pada object dengan memanggil
“white” (cahaya warna putih atau terang).
9. Untuk ukuran object ,misal kecil ,besar atau sedang.
10. Memanggil object yang akan kita gunakan.
11. Menutup pembuatan object pada opengl.
7.3 Normal Vektor Pada Lighting
Normal Vector adalah vector yang arahnya tegak lurus pada
luasan (face). Normal Vector dapat diperoleh dari perkalian silang
(cross-product) dari dua vector yang berada pada face. Besar dari
Normal Vector tegantung pada hasil perkalian silangnya. Cara yang
digunakan untuk menghitung vektor normal dari 3 vertex adalah :
|axb|=|a||b|sin Ө
Gambar 7.2 Normal Vector
Untuk mndefinisikan vektor normal, dapat menggunakan perintah sebagai berikut :
glNormal3f(fNormalX, fNormalY, fNormalZ) : glVertex3f(fVert1, fVert2, fVert3) :
a
b
a x b
)()(
)()(
)()(
b x a
yxyx
zxzx
zyzy
zyx
zyx
abba
baab
abba
bbb
aaa
kji
425
7.4 Lighting Pada Interior
Source Code 7.1 Code Lighting Pada Interior
ESRender.java
package com.ligthing;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.Formatter;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLU;
import android.util.Log;
import android.widget.TextView;
public class ESRender implements Renderer {
private ESText glText;
private TextView textview;
private ObjectArena objectarena; // the primitive
object to be drawn
private ObjectBall objectball;
private ObjectBall objectball2;
private ObjectBall objectball3;
private PrimitivesObject primob;
private TransObject transobject;
private final MySphere mEarth, mEarth2, mEarth3;
private boolean isOn=true;
private PhotoKubus kotak; // (NEW)
// private PhotoKubus tembok_blkng;
private TextureKubus tembok;
private Context context;
private kubus kubus;
private lukisan lukisan;
private lukisan lukisan1;
private pintu pintu;
private kubus_kecil kubus_kecil;
private kaki_meja kaki_meja;
private lampu lampu;
// Context context;
int Run_Mode = 0;
float CurrentAngle = 0.0f; // Angle in degrees
426
float AnimateStep = -2.0f; // Rotation step per
update
float CurrentAngle1 = 0.0f; // Angle in degrees
float AnimateStep1 = 2.0f; // Rotation step per
update
float radius = 50.0f; // Ball's radius
float x = radius; // Ball's center (x,y)
float y = radius;
float speedX = 5f; // Ball's speed (x,y)
float speedY = 3f;
int xMin, xMax, yMin, yMax;
private int mywidth = 0;
private int myheight = 0;
private int jumlah_pantulan = 0;
// posisi cahaya
// base transformasi yang ada pada objek
// gl.glTranslatef(600.0f, 200.0f, 0.0f);
// gl.glScalef(25.0f, 25.0f, 25.0f);
// gl.glTranslatef (0.0f, 0.0f, -5.0f);
// float[] position = { 0.0f, 0.0f, 1.5f, 1.0f };
// original
float[] position = { ((0.0f) * 25.0f) + 600.0f,
((0.0f) * 25.0f) + 200.0f,
((1.5f - 5.0f) * 25.0f) + 0.0f,
1.0f };
float[] position41 = { ((0.0f) * 25.0f) + 800.0f,
((0.0f) * 25.0f) + 400.0f, ((1.5f
- 5.0f) * 25.0f) + 0.0f, 1.0f };
float[] position42 = { ((0.0f) * 25.0f) + 800.0f,
((0.0f) * 25.0f) + 400.0f, ((-1.5f
- 5.0f) * 25.0f) + 0.0f, 1.0f };
float[] position1 = { ((0.0f) * 25.0f) + 800.0f,
((0.0f) * 25.0f) + 200.0f,
((1.5f - 5.0f) * 25.0f) + 0.0f,
1.0f };
// float[] position2 = { 0.0f, 0.0f, -1.5f,
0.0f}; //{x,y,z,w}
float[] position2 = { ((0.0f) * 25.0f) + 800.0f,
((0.0f) * 25.0f) + 200.0f,
((-1.5f - 5.0f) * 25.0f) + 0.0f,
1.0f };
float[] position3 = { ((0.0f) * 25.0f) + 800.0f,
((0.0f) * 25.0f) + 200.0f,
((-1.5f - 5.0f) * 25.0f) + 0.0f,
1.0f };
float black[] = new float[] { 0.0f, 0.0f, 0.0f,
1.0f };
float yellow[] = new float[] { 1.0f, 1.0f, 0.0f,
1.0f };
float cyan[] = new float[] { 0.0f, 1.0f, 1.0f,
427
1.0f };
float white[] = new float[] { 1.0f, 1.0f, 1.0f,
1.0f };
float orange[] = new float[] { 1.0f, 0.5f, 0.0f,
0.0f };
float diffuseMaterial[] = new float[] { 0.73f,
0.13f, 0.86f, 1.0f }; // set cahaya warna ungu
float diffuseMaterial2[] = new float[] { 0.5f,
0.5f, 0.5f, 1.0f }; // set cahaya warna ungu
float lightAmbient[] = new float[] { 0.2f, 0.3f,
0.6f, 1.0f };
float mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f
};
float light_position[] = { -1.5f, 0.0f, 0.0f,
0.0f };
/** Constructor to set the handed over context */
public ESRender(Context context) {
// super();
this.context = context;
this.objectarena = new ObjectArena();
this.objectball = new ObjectBall();
this.objectball2 = new ObjectBall();
this.objectball3 = new ObjectBall();
this.primob = new PrimitivesObject();
this.mEarth = new MySphere(5, 3);
this.mEarth2 = new MySphere(5, 3);
this.mEarth3 = new MySphere(5, 3);
this.transobject = new TransObject();
kotak = new PhotoKubus(context); // (NEW)
// tembok_blkng = new PhotoKu-
bus(context);
tembok = new TextureKubus(context);
lukisan = new lukisan(context);//
lukisan1 = new lukisan(context);//
// this.context = context; // Get the ap-
plication context (NEW)
kubus = new kubus();
pintu = new pintu(context);
kubus_kecil = new kubus_kecil(context);
kaki_meja = new kaki_meja(context);
lampu = new lampu(context);
}
@Override
public void onDrawFrame(GL10 gl) {
// Draw background color
gl.glClear(GL10.GL_COLOR_BUFFER_BIT |
GL10.GL_DEPTH_BUFFER_BIT);
// gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glEnable(GL10.GL_NORMALIZE);
// gl.glMaterialfv(GL10.GL_FRONT,
GL10.GL_AMBIENT_AND_DIFFUSE,
428
// makeFloatBuffer(cyan));
gl.glMaterialfv(GL10.GL_FRONT,
GL10.GL_SPECULAR, white, 0);
gl.glMaterialfv(GL10.GL_FRONT,
GL10.GL_SHININESS, white, 0);
gl.glMaterialfv(GL10.GL_FRONT,
GL10.GL_DIFFUSE, white, 0);
// gl.glMatrixMode( GL10.GL_MODELVIEW );
// Activate Model View Matrix
// gl.glLoadIdentity(); // Load Identity
Matrix
if(isOn){
gl.glDisable(GL10.GL_LIGHTING);
}
// bawah lantai
gl.glPushMatrix();
// gl.glDisable(GL10.GL_LIGHTING);
gl.glTranslatef(0.0f, 0.0f, -5.0f);
// gl.glScalef(50.0f, 50.0f, 50.0f);
gl.glRotatef(90, 1, 0, 0);
kotak.draw(gl);
// gl.glEnable(GL10.GL_LIGHTING);
gl.glPopMatrix();
// atap
gl.glPushMatrix();
// gl.glDisable(GL10.GL_LIGHTING);
gl.glTranslatef(0.0f, 0.0f, -5.0f);
gl.glRotatef(180, 1.0f, 0.0f, 0.0f);
gl.glRotatef(90, 1.0f, 0.0f, 0.0f);
// gl.glTranslatef(0.0f, 0.0f, -6.0f); //
Translate into the screen
// gl.glRotatef(CurrentAngle, 0.1f, 1.0f,
0.2f); // Rotate
// gl.glRotatef(CurrentAngle, 1.0f, 1.0f,
1.0f );
// gl.glTranslatef(-0.5f,-0.5f,-0.5f);
// gl.glScalef(2.0f, 2.0f, 2.0f);
kotak.draw_atap(gl);
// gl.glEnable(GL10.GL_LIGHTING);
gl.glPopMatrix();
// tembok belakang
gl.glPushMatrix();
// gl.glDisable(GL10.GL_LIGHTING);
gl.glTranslatef(0.0f, 0.0f, -5.0f);
gl.glRotatef(90, 1.0f, 0.0f, 0.0f);
gl.glRotatef(90, 1.0f, 0.0f, 0.0f);
kotak.draw_tembok_blk(gl);
// gl.glEnable(GL10.GL_LIGHTING);
gl.glPopMatrix();
// tembok samping kanan
gl.glPushMatrix();
// gl.glDisable(GL10.GL_LIGHTING);
gl.glTranslatef(1.0f, 0.0f, 0.0f);
429
gl.glTranslatef(0.0f, 0.0f, -5.0f);
gl.glRotatef(180, 1.0f, 0.0f, 1.0f);
tembok.draw_tembok_smp(gl);
// gl.glEnable(GL10.GL_LIGHTING);
gl.glPopMatrix();
// tembok samping kiri
gl.glPushMatrix();
// gl.glDisable(GL10.GL_LIGHTING);
gl.glTranslatef(-1.0f, 0.0f, -5.0f);
// gl.glTranslatef(0.0f, 0.0f, -6.0f); //
Translate into the screen
// gl.glRotatef(CurrentAngle, 0.1f, 1.0f,
0.2f); // Rotate
// gl.glRotatef(270, 0.0f, 0.0f, 1.0f);
gl.glRotatef(90, 0.0f, 1.0f, 0.0f);
gl.glRotatef(180, 1.0f, 0.0f, 0.0f);
// gl.glTranslatef(-0.5f,-0.5f,-0.5f);
// gl.glScalef(2.0f, 2.0f, 2.0f);
tembok.draw_tembok_smp(gl);
// gl.glEnable(GL10.GL_LIGHTING);
gl.glPopMatrix();
// lukisan
gl.glPushMatrix();
// gl.glDisable(GL10.GL_LIGHTING);
gl.glTranslatef(1.5f, 0.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, -5.0f);
gl.glRotatef(90, 0.0f, 1.0f, 0.0f);
gl.glScalef(0.5f, 0.5f, 0.5f);
// gl.glRotatef(CurrentAngle, 0.0f, 1.0f,
0.0f);
lukisan.draw_lukisan(gl);
// gl.glEnable(GL10.GL_LIGHTING);
gl.glPopMatrix();
// lukisan2
gl.glPushMatrix();
// gl.glDisable(GL10.GL_LIGHTING);
gl.glTranslatef(0.5f, 0.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, -5.5f);
gl.glRotatef(180, 0.0f, 1.0f, 0.0f);
gl.glScalef(0.3f, 0.5f, 0.1f);
// gl.glRotatef(CurrentAngle, 0.0f, 1.0f,
0.0f);
lukisan.draw_lukisan1(gl);
// gl.glEnable(GL10.GL_LIGHTING);
gl.glPopMatrix();
// PINTU
gl.glPushMatrix();
// gl.glDisable(GL10.GL_LIGHTING);
gl.glTranslatef(-1.3f, -0.2f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, -5.5f);
gl.glRotatef(180, 0.0f, 1.0f, 0.0f);
gl.glScalef(0.5f, 0.8f, 0.5f);
// gl.glRotatef(CurrentAngle, 0.0f, 1.0f,
430
0.0f);
pintu.draw_pintu(gl);
// gl.glEnable(GL10.GL_LIGHTING);
gl.glPopMatrix();
// // buat meja
// gl.glPushMatrix();
//
// gl.glTranslatef(0.0f, 0.0f, -5.0f);
// gl.glScalef(0.5f, 0.5f, 0.5f);
// gl.glRotatef(90, 1.0f, 0.0f, 0.0f);
// kotak.draw_meja(gl);
// gl.glPopMatrix();
// MEJA
gl.glPushMatrix();
// gl.glDisable(GL10.GL_LIGHTING);
gl.glTranslatef(1.5f, -0.6f, -5.0f);
//
gl.glScalef(0.4f, 0.05f, 1.0f);
// gl.glTranslatef(0.0f, 0.0f, -6.0f); //
Translate into the screen
// gl.glRotatef(CurrentAngle, 0.0f, 1.0f,
0.0f); // Rotate
gl.glRotatef(90, 1.0f, 0.0f, 0.0f);
// gl.glRotatef(CurrentAngle, 1.0f, 1.0f,
1.0f );
// gl.glTranslatef(-0.5f,-0.5f,-0.5f);
kaki_meja.draw(gl);
// gl.glEnable(GL10.GL_LIGHTING);
gl.glPopMatrix();
// KAKI MEJA
gl.glPushMatrix();
// gl.glDisable(GL10.GL_LIGHTING);
gl.glTranslatef(1.6f, -0.8f, -5.0f);
gl.glScalef(0.05f, 0.17f, 0.05f);
// gl.glTranslatef(0.0f, 0.0f, -6.0f); //
Translate into the screen
gl.glRotatef(90, 0.0f, 1.0f, 0.0f); //
Rotate
// gl.glRotatef(CurrentAngle, 1.0f, 1.0f,
1.0f );
// gl.glTranslatef(-0.5f,-0.5f,-0.5f);
kaki_meja.draw(gl);
// gl.glEnable(GL10.GL_LIGHTING);
gl.glPopMatrix();
// Meja 2
gl.glPushMatrix();
// gl.glDisable(GL10.GL_LIGHTING);
gl.glTranslatef(0.0f, -0.6f, -5.0f);
//
gl.glScalef(0.4f, 0.05f, 1.0f);
// gl.glTranslatef(0.0f, 0.0f, -6.0f); //
Translate into the screen
// gl.glRotatef(CurrentAngle, 0.0f, 1.0f,
0.0f); // Rotate
431
gl.glRotatef(90, 1.0f, 0.0f, 0.0f);
// gl.glRotatef(CurrentAngle, 1.0f, 1.0f,
1.0f );
// gl.glTranslatef(-0.5f,-0.5f,-0.5f);
kaki_meja.draw(gl);
// gl.glEnable(GL10.GL_LIGHTING);
gl.glPopMatrix();
// KAKI MEJA
gl.glPushMatrix();
// gl.glDisable(GL10.GL_LIGHTING);
gl.glTranslatef(0.0f, -0.8f, -5.0f);
gl.glScalef(0.05f, 0.17f, 0.05f);
// gl.glTranslatef(0.0f, 0.0f, -6.0f); //
Translate into the screen
gl.glRotatef(90, 0.0f, 1.0f, 0.0f); //
Rotate
// gl.glRotatef(CurrentAngle, 1.0f, 1.0f,
1.0f );
// gl.glTranslatef(-0.5f,-0.5f,-0.5f);
kaki_meja.draw(gl);
// gl.glEnable(GL10.GL_LIGHTING);
gl.glPopMatrix();
// kubus di atas meja
gl.glPushMatrix();
// gl.glDisable(GL10.GL_LIGHTING);
gl.glTranslatef(0.0f, -0.4f, -5.0f);
gl.glScalef(0.1f, 0.1f, 0.1f);
// gl.glTranslatef(0.0f, 0.0f, -6.0f); //
Translate into the screen
gl.glRotatef(CurrentAngle, 0.0f, 1.0f,
0.0f); // Rotate
// gl.glRotatef(CurrentAngle, 1.0f, 1.0f,
1.0f );
// gl.glTranslatef(-0.5f,-0.5f,-0.5f);
kubus_kecil.draw(gl);
// gl.glEnable(GL10.GL_LIGHTING);
gl.glPopMatrix();
// kubus di atas meja 2
gl.glPushMatrix();
//
gl.glDisable(GL10.GL_LIGHTING);
gl.glTranslatef(-0.1f, -
0.4f, -4.5f);
gl.glScalef(0.1f, 0.1f,
0.1f);
// gl.glTranslatef(0.0f,
0.0f, -6.0f); // Translate into the screen
gl.glRotatef(45, 0.0f,
1.0f, 0.0f); // Rotate
//
gl.glRotatef(CurrentAngle, 1.0f, 1.0f, 1.0f );
// gl.glTranslatef(-0.5f,-
0.5f,-0.5f);
kubus_kecil.draw(gl);
//
gl.glEnable(GL10.GL_LIGHTING);
432
gl.glPopMatrix();
// bola 1
gl.glPushMatrix();
// gl.glDisable(GL10.GL_LIGHTING);
gl.glTranslatef(1.6f, -0.4f, -5.0f);
gl.glScalef(0.05f, 0.05f, 0.05f);
//gl.glRotatef(CurrentAngle, 0, 1, 0);
mEarth.draw(gl);
// gl.glEnable(GL10.GL_LIGHTING);
gl.glPopMatrix();
// bola 1
gl.glPushMatrix();
//
gl.glDisable(GL10.GL_LIGHTING);
gl.glTranslatef(1.0f, -
0.4f, -5.0f);
gl.glScalef(0.05f, 0.05f,
0.05f);
gl.glRotatef(CurrentAngle,
1.0f, 0.0f, 0.0f);
mEarth.draw(gl);
//
gl.glEnable(GL10.GL_LIGHTING);
gl.glPopMatrix();
// LAMPU
gl.glPushMatrix();
// gl.glDisable(GL10.GL_LIGHTING);
gl.glTranslatef(0.0f, 0.7f, -5.0f);
// gl.glRotatef(180, 0.0f, 0.0f, 1.0f); //
Rotate
// gl.glTranslatef(0.0f, 0.0f, -6.0f); //
Translate into the screen
// gl.glRotatef(0, 0.0f, 1.0f, 0.0f); // Ro-
tate
gl.glRotatef(CurrentAngle, 0.0f, 1.0f,
0.0f );
// gl.glTranslatef(-0.5f,-0.5f,-0.5f);
// gl.glPushMatrix();
// gl.glRotatef(180, 1.0f, 0.0f, 0.0f);
gl.glMaterialf(GL10.GL_BACK,
GL10.GL_SHININESS, 256.0f);
gl.glLightfv(GL10.GL_LIGHT0,
GL10.GL_POSITION, light_position, 0);
gl.glLightfv(GL10.GL_LIGHT0,
GL10.GL_DIFFUSE, white, 0);
gl.glLightfv(GL10.GL_LIGHT0,
GL10.GL_AMBIENT, lightAmbient, 0);
gl.glLightfv(GL10.GL_LIGHT0,
GL10.GL_SPECULAR, white, 0);
// gl.glTranslatef (0.0f, 0.0f, -0.5f);
433
// gl.glDisable (GL10.GL_LIGHTING);
// gl.glScalef(0.01f, 0.01f,
0.01f);
// transob-
ject.draw_kubus(gl);
// gl.glEnable (GL10.GL_LIGHTING);
// gl.glPopMatrix();
gl.glScalef(0.04f, 0.04f, 0.04f);
mEarth3.draw(gl);
// gl.glEnable(GL10.GL_LIGHTING);
gl.glPopMatrix();
// penyangga lampu
gl.glPushMatrix();
//
gl.glDisable(GL10.GL_LIGHTING);
gl.glTranslatef(0.0f,
0.8f, -5.0f);
gl.glScalef(0.03f, 0.2f,
0.05f);
// gl.glTranslatef(0.0f,
0.0f, -6.0f); // Translate into the screen
gl.glRotatef(90, 0.0f,
1.0f, 0.0f); // Rotate
//
gl.glRotatef(CurrentAngle, 1.0f, 1.0f, 1.0f );
// gl.glTranslatef(-0.5f,-
0.5f,-0.5f);
kaki_meja.draw(gl);
//
gl.glEnable(GL10.GL_LIGHTING);
gl.glPopMatrix();
if(isOn){
gl.glEnable(GL10.GL_LIGHTING);
}
// Update the rotational angle after each
refresh
// re-Calculate animation parameters
CurrentAngle1 += AnimateStep1;
if (CurrentAngle1 < -360.0) {
// CurrentAngle -=
360.0*Math.floor(CurrentAngle/360.0);
CurrentAngle1 = 0.0f;
CurrentAngle1 += AnimateStep1;
}
CurrentAngle += AnimateStep;
if (CurrentAngle > 360.0) {
// CurrentAngle -=
360.0*Math.floor(CurrentAngle/360.0);
CurrentAngle = 0.0f;
CurrentAngle += AnimateStep;
}
}
434
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig
config) {
gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
// Set color's clear-value to
// black
gl.glClearDepthf(1.0f); // Set depth's
clear-value to farthest
gl.glEnable(GL10.GL_DEPTH_TEST); // Ena-
bles depth-buffer for hidden
// surface removal
gl.glDepthFunc(GL10.GL_LEQUAL); // The
type of depth testing to do
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
GL10.GL_NICEST); // nice
// perspective
// view
gl.glShadeModel(GL10.GL_SMOOTH); // Ena-
ble smooth shading of color
gl.glDisable(GL10.GL_DITHER); // Disable
dithering for better
// performance
gl.glEnable(GL10.GL_LIGHTING);
gl.glEnable(GL10.GL_LIGHT0);
gl.glEnable(GL10.GL_LIGHT1);
// Create the GLText
glText = new ESText(gl, con-
text.getAssets());
// Load the font from file (set size +
padding), creates the texture
// NOTE: after a successful call to this
the font is ready for
// rendering!
glText.load("Roboto-Regular.ttf", 14, 2,
2); // Create Font (Height: 14
//
Pixels / X+Y Padding
// 2
Pixels)
// gl.glDisable(GL10.GL_DITHER); // Disa-
ble dithering for better
// performance
// Setup Blending (NEW)
gl.glColor4f(1.0f, 1.0f, 1.0f, 0.5f); //
Full brightness, 50% alpha
// (NEW)
gl.glBlendFunc(GL10.GL_SRC_ALPHA,
GL10.GL_ONE); // Select blending
435
//
function (NEW)
// Setup Texture, each time the surface
is created (NEW)
objectball2.loadBallTexture(gl, context);
mEarth.loadGLTexture(gl, context, 2);
// mEarth2.loadGLTexture(gl, context,6);
mEarth3.loadGLTexture(gl, context, 5);
kotak.loadTexture(gl, context); // Load
images into textures (NEW)
tembok.loadTexture(gl, context);
//
kubus.loadTexture(gl, context);
lukisan.loadTexture(gl, context);
pintu.loadTexture(gl, context);
kubus_kecil.loadTexture(gl, context);
kaki_meja.loadTexture(gl, context);
lampu.loadTexture(gl, context);
gl.glEnable(GL10.GL_TEXTURE_2D); // Ena-
ble texture (NEW)
}
@Override
public void onSurfaceChanged(GL10 gl, int width,
int height) {
// mywidth = width;
// myheight = height;
if (height == 0)
height = 1; // To prevent divide
by zero
float aspect = (float) width / height;
gl.glViewport(0, 0, width, height);
// Setup orthographic projection
gl.glMatrixMode(GL10.GL_PROJECTION); //
Activate Projection Matrix
gl.glLoadIdentity(); // Load Identity Ma-
trix
// gl.glOrthof( // Set Ortho Projection
// (Left,Right,Bottom,Top,Front,Back)
// 0, width, 0, height, 500.0f, -500.0f);
// gl.glOrthof(arg0, arg1, arg2, arg3,
arg4, arg5);
// GLU.gluPerspective(gl, fovy, aspect,
zNear, zFar);
// Use perspective projection
GLU.gluPerspective(gl, 45, aspect, 0.1f,
100.f);
// GLU.gluPerspective(gl, 45, aspect,
500.0f, -500.f);
// Save width and height
// this.width = width; // Save Current
436
Width
// this.height = height; // Save Current
Height
gl.glMatrixMode(GL10.GL_MODELVIEW); //
Select model-view matrix
gl.glLoadIdentity(); // Reset
}
public float getxMax() {
return xMax;
}
public void setxMax(int xmax) {
xMax = xmax;
}
public float getxMin() {
return xMin;
}
public void setxMin(int xmin) {
xMin = xmin;
}
public float getyMax() {
return yMax;
}
public void setyMax(int ymax) {
yMax = ymax;
}
public float getyMin() {
return yMin;
}
public void setyMin(int ymin) {
yMin = ymin;
}
public float getspeedX() {
return speedX;
}
public void setspeedX(float speedX_) {
speedX = speedX_;
}
public float getspeedY() {
return speedY;
}
public void setspeedY(float speedY_) {
speedY = speedY_;
}
public boolean getLamp(){
437
return isOn;
}
public boolean setOff(){
return isOn =false;
}
public boolean setOn(){
return isOn = true;
}
public void moveWithCollisionDetection(ESRender
esRender) {
// Get new (x,y) position
x += speedX;
y += speedY;
// Detect collision and react
if (x + radius > esRender.getxMax()) {
speedX = -speedX;
x = esRender.getxMax() - radius;
this.jumlah_pantulan += 1;
} else if (x - radius < esRen-
der.getxMin()) {
speedX = -speedX;
x = esRender.getxMin() + radius;
this.jumlah_pantulan += 1;
}
if (y + radius > esRender.getyMax()) {
speedY = -speedY;
y = esRender.getyMax() - radius;
this.jumlah_pantulan += 1;
} else if (y - radius < esRen-
der.getyMin()) {
speedY = -speedY;
y = esRender.getyMin() + radius;
this.jumlah_pantulan += 1;
}
// pengkondisian penghitungan pantulan
mulai dari nol
if (Run_Mode == 0) {
this.jumlah_pantulan -= 4;
this.Run_Mode = 1;
}
}
public void set(int x, int y, int width, int
height) {
xMin = x;
// xMax = x + width - 1;
xMax = x + width;
yMin = y;
// yMax = y + height - 1;
yMax = y + height;
}
}
438
ESSurfaceView.java
package com.ligthing;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
/**
* A view container where OpenGL ES graphics can be
drawn on screen.
* This view can also be used to capture touch events,
such as a user
* interacting with drawn objects.
*/
public class ESSurfaceView extends GLSurfaceView {
private final ESRender esRender;
private float previousX;
private float previousY;
private float saklar;
public ESSurfaceView(Context context) {
super(context);
// Set the Renderer for drawing on the GLSur-
faceView
esRender = new ESRender(context);
setRenderer(esRender);
// To enable keypad
this.setFocusable(true);
this.requestFocus();
// To enable touch mode
this.setFocusableInTouchMode(true);
// Render the view only when there is a change
in the drawing data
// merender hanya ketika ada perubahan/ event
//setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
//private final float TOUCH_SCALE_FACTOR =
getWidth() / getHeight();
private float mPreviousX;
private float mPreviousY;
@Override
public boolean onTouchEvent(MotionEvent v) {
// MotionEvent reports input details from the
touch screen
// and other input controls. In this case, we
are only
// interested in events where the touch position
439
changed.
float currentX = v.getX();
float currentY = v.getY();
float deltaX, deltaY;
//float scalingFactor = 0.50f / ((esRen-
der.xMax > esRender.yMax) ? esRender.yMax
//: esRender.xMax);
switch (v.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.v("Test Action Down", "action
down working");
if(esRender.getLamp()){
esRender.setOff();
}else{
esRender.setOn();
}
break;
// requestRender();
//case MotionEvent.ACTION_POINTER_UP:
//Log.v("Test Action
ACTION_POINTER_UP", "action working");
//requestRender();
//case MotionEvent.ACTION_MOVE:
//Log.v("Test Action
ACTION_POINTER_DOWN", "action working");
//requestRender();
//case MotionEvent.ACTION_UP:
//Log.v("Test Action Up", "action
up working");
//requestRender();
case MotionEvent.ACTION_MOVE:
// Modify rotational angles according to
movement
deltaX = currentX - previousX;
deltaY = currentY - previousY;
//esRender.setspeedX(esRender.getspeedX()+ (del-
taX/getWidth()));
//esRender.setspeedY(esRender.getspeedY()+ (del-
taY/getHeight()));
esRen-
der.setspeedX(esRender.getspeedX()+ deltaX/100);
esRen-
der.setspeedY(esRender.getspeedY()+ deltaY/100);
requestRender();
}
// Save current x, y
440
previousX = currentX;
previousY = currentY;
return true; // Event handled
//break;
}
// Key-up event handler
@Override
public boolean onKeyUp(int keyCode, KeyEvent
event) {
switch (keyCode) {
case KeyEvent.KEYCODE_A: // mengurangi
kecepatan object
if((esRender.getspeedX()- 0.05f
>0) ){
esRen-
der.setspeedX(esRender.getspeedX()- 0.05f);
}
if((esRender.getspeedX()- 0.05f
<0) ){
esRender.setspeedX(0.0f);
}
if((esRender.getspeedY()- 0.05f
>=0)){
esRen-
der.setspeedY(esRender.getspeedY()- 0.05f);
}
if((esRender.getspeedY()- 0.05f
<0) ){
esRender.setspeedY(0.0f);
}
Log.v("Test Action KEYCODE_A",
"action working");
break;
case KeyEvent.KEYCODE_Z:
Log.v("Test Action KEYCODE_Z",
"action working");
break;
}
return true; // Event handled
}
}
ESText.java
// This is a OpenGL ES 1.0 dynamic font rendering sys-
tem. It loads actual font
// files, generates a font map (texture) from them, and
allows rendering of
// text strings.
//
// NOTE: the rendering portions of this class uses a
sprite batcher in order
// provide decent speed rendering. Also, rendering as-
sumes a BOTTOM-LEFT
// origin, and the (x,y) positions are relative to that,
441
as well as the
// bottom-left of the string to render.
package com.ligthing;
import javax.microedition.khronos.opengles.GL10;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.opengl.GLUtils;
public class ESText {
//--Constants--//
public final static int CHAR_START = 32; //
First Character (ASCII Code)
public final static int CHAR_END = 126; //
Last Character (ASCII Code)
public final static int CHAR_CNT = ( ( ( CHAR_END -
CHAR_START ) + 1 ) + 1 ); // Character Count (Including
Character to use for Unknown)
public final static int CHAR_NONE = 32; //
Character to Use for Unknown (ASCII Code)
public final static int CHAR_UNKNOWN = ( CHAR_CNT - 1
); // Index of the Unknown Character
public final static int FONT_SIZE_MIN = 6; //
Minumum Font Size (Pixels)
public final static int FONT_SIZE_MAX = 180; //
Maximum Font Size (Pixels)
public final static int CHAR_BATCH_SIZE = 100; //
Number of Characters to Render Per Batch
//--Members--//
GL10 gl; //
GL10 Instance
AssetManager assets; //
Asset Manager
SpriteBatch batch; //
Batch Renderer
int fontPadX, fontPadY; //
Font Padding (Pixels; On Each Side, ie. Doubled on Both
X+Y Axis)
float fontHeight; //
Font Height (Actual; Pixels)
float fontAscent; //
Font Ascent (Above Baseline; Pixels)
float fontDescent; //
Font Descent (Below Baseline; Pixels)
int textureId; //
Font Texture ID [NOTE: Public for Testing Purposes On-
442
ly!]
int textureSize; //
Texture Size for Font (Square) [NOTE: Public for Testing
Purposes Only!]
TextureRegion textureRgn; //
Full Texture Region
float charWidthMax; //
Character Width (Maximum; Pixels)
float charHeight; //
Character Height (Maximum; Pixels)
final float[] charWidths; //
Width of Each Character (Actual; Pixels)
TextureRegion[] charRgn; //
Region of Each Character (Texture Coordinates)
int cellWidth, cellHeight; //
Character Cell Width/Height
int rowCnt, colCnt; //
Number of Rows/Columns
float scaleX, scaleY; //
Font Scale (X,Y Axis)
float spaceX; //
Additional (X,Y Axis) Spacing (Unscaled)
//--Constructor--//
// D: save GL instance + asset manager, create ar-
rays, and initialize the members
// A: gl - OpenGL ES 10 Instance
public ESText(GL10 gl, AssetManager assets) {
this.gl = gl; //
Save the GL10 Instance
this.assets = assets; //
Save the Asset Manager Instance
batch = new SpriteBatch( gl, CHAR_BATCH_SIZE );
// Create Sprite Batch (with Defined Size)
charWidths = new float[CHAR_CNT]; //
Create the Array of Character Widths
charRgn = new TextureRegion[CHAR_CNT]; //
Create the Array of Character Regions
// initialize remaining members
fontPadX = 0;
fontPadY = 0;
fontHeight = 0.0f;
fontAscent = 0.0f;
fontDescent = 0.0f;
textureId = -1;
textureSize = 0;
charWidthMax = 0;
charHeight = 0;
cellWidth = 0;
443
cellHeight = 0;
rowCnt = 0;
colCnt = 0;
scaleX = 1.0f; //
Default Scale = 1 (Unscaled)
scaleY = 1.0f; //
Default Scale = 1 (Unscaled)
spaceX = 0.0f;
}
//--Load Font--//
// description
// this will load the specified font file, create
a texture for the defined
// character range, and setup all required values
used to render with it.
// arguments:
// file - Filename of the font (.ttf, .otf) to
use. In 'Assets' folder.
// size - Requested pixel size of font (height)
// padX, padY - Extra padding per character (X+Y
Axis); to prevent overlapping characters.
public boolean load(String file, int size, int padX,
int padY) {
// setup requested values
fontPadX = padX; //
Set Requested X Axis Padding
fontPadY = padY; //
Set Requested Y Axis Padding
// load the font and setup paint instance for
drawing
Typeface tf = Typeface.createFromAsset( assets,
file ); // Create the Typeface from Font File
Paint paint = new Paint(); //
Create Android Paint Instance
paint.setAntiAlias( true ); //
Enable Anti Alias
paint.setTextSize( size ); //
Set Text Size
paint.setColor( 0xffffffff ); //
Set ARGB (White, Opaque)
paint.setTypeface( tf ); //
Set Typeface
// get font metrics
Paint.FontMetrics fm = paint.getFontMetrics(); //
Get Font Metrics
fontHeight = (float)Math.ceil( Math.abs( fm.bottom
) + Math.abs( fm.top ) ); // Calculate Font Height
fontAscent = (float)Math.ceil( Math.abs( fm.ascent
) ); // Save Font Ascent
fontDescent = (float)Math.ceil( Math.abs(
fm.descent ) ); // Save Font Descent
// determine the width of each character (includ-
ing unknown character)
444
// also determine the maximum character width
char[] s = new char[2]; //
Create Character Array
charWidthMax = charHeight = 0; //
Reset Character Width/Height Maximums
float[] w = new float[2]; //
Working Width Value
int cnt = 0; //
Array Counter
for ( char c = CHAR_START; c <= CHAR_END; c++ ) {
// FOR Each Character
s[0] = c; //
Set Character
paint.getTextWidths( s, 0, 1, w ); //
Get Character Bounds
charWidths[cnt] = w[0]; //
Get Width
if ( charWidths[cnt] > charWidthMax ) //
IF Width Larger Than Max Width
charWidthMax = charWidths[cnt]; //
Save New Max Width
cnt++; //
Advance Array Counter
}
s[0] = CHAR_NONE; //
Set Unknown Character
paint.getTextWidths( s, 0, 1, w ); //
Get Character Bounds
charWidths[cnt] = w[0]; //
Get Width
if ( charWidths[cnt] > charWidthMax ) //
IF Width Larger Than Max Width
charWidthMax = charWidths[cnt]; //
Save New Max Width
cnt++; //
Advance Array Counter
// set character height to font height
charHeight = fontHeight; //
Set Character Height
// find the maximum size, validate, and setup cell
sizes
cellWidth = (int)charWidthMax + ( 2 * fontPadX );
// Set Cell Width
cellHeight = (int)charHeight + ( 2 * fontPadY );
// Set Cell Height
int maxSize = cellWidth > cellHeight ? cellWidth :
cellHeight; // Save Max Size (Width/Height)
if ( maxSize < FONT_SIZE_MIN || maxSize >
FONT_SIZE_MAX ) // IF Maximum Size Outside Valid Bounds
return false; //
Return Error
// set texture size based on max font size (width
or height)
// NOTE: these values are fixed, based on the de-
fined characters. when
// changing start/end characters
445
(CHAR_START/CHAR_END) this will need adjustment too!
if ( maxSize <= 24 ) //
IF Max Size is 18 or Less
textureSize = 256; //
Set 256 Texture Size
else if ( maxSize <= 40 ) //
ELSE IF Max Size is 40 or Less
textureSize = 512; //
Set 512 Texture Size
else if ( maxSize <= 80 ) //
ELSE IF Max Size is 80 or Less
textureSize = 1024; //
Set 1024 Texture Size
else //
ELSE IF Max Size is Larger Than 80 (and Less than
FONT_SIZE_MAX)
textureSize = 2048; //
Set 2048 Texture Size
// create an empty bitmap (alpha only)
Bitmap bitmap = Bitmap.createBitmap( textureSize,
textureSize, Bitmap.Config.ALPHA_8 ); // Create Bitmap
Canvas canvas = new Canvas( bitmap ); //
Create Canvas for Rendering to Bitmap
bitmap.eraseColor( 0x00000000 ); //
Set Transparent Background (ARGB)
// calculate rows/columns
// NOTE: while not required for anything, these
may be useful to have :)
colCnt = textureSize / cellWidth; //
Calculate Number of Columns
rowCnt = (int)Math.ceil( (float)CHAR_CNT /
(float)colCnt ); // Calculate Number of Rows
// render each of the characters to the canvas
(ie. build the font map)
float x = fontPadX; //
Set Start Position (X)
float y = ( cellHeight - 1 ) - fontDescent -
fontPadY; // Set Start Position (Y)
for ( char c = CHAR_START; c <= CHAR_END; c++ ) {
// FOR Each Character
s[0] = c; //
Set Character to Draw
canvas.drawText( s, 0, 1, x, y, paint ); //
Draw Character
x += cellWidth; //
Move to Next Character
if ( ( x + cellWidth - fontPadX ) > textureSize
) { // IF End of Line Reached
x = fontPadX; //
Set X for New Row
y += cellHeight; //
Move Down a Row
}
}
s[0] = CHAR_NONE; //
Set Character to Use for NONE
446
canvas.drawText( s, 0, 1, x, y, paint ); //
Draw Character
// generate a new texture
int[] textureIds = new int[1]; //
Array to Get Texture Id
gl.glGenTextures( 1, textureIds, 0 ); //
Generate New Texture
textureId = textureIds[0]; //
Save Texture Id
// setup filters for texture
gl.glBindTexture( GL10.GL_TEXTURE_2D, textureId );
// Bind Texture
gl.glTexParameterf( GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST ); // Set
Minification Filter
gl.glTexParameterf( GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR ); // Set
Magnification Filter
gl.glTexParameterf( GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE ); // Set
U Wrapping
gl.glTexParameterf( GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE ); // Set
V Wrapping
// load the generated bitmap onto the texture
GLUtils.texImage2D( GL10.GL_TEXTURE_2D, 0, bitmap,
0 ); // Load Bitmap to Texture
gl.glBindTexture( GL10.GL_TEXTURE_2D, 0 ); //
Unbind Texture
// release the bitmap
bitmap.recycle(); //
Release the Bitmap
// setup the array of character texture regions
x = 0; //
Initialize X
y = 0; //
Initialize Y
for ( int c = 0; c < CHAR_CNT; c++ ) { //
FOR Each Character (On Texture)
charRgn[c] = new TextureRegion( textureSize,
textureSize, x, y, cellWidth-1, cellHeight-1 ); // Cre-
ate Region for Character
x += cellWidth; //
Move to Next Char (Cell)
if ( x + cellWidth > textureSize ) {
x = 0; //
Reset X Position to Start
y += cellHeight; //
Move to Next Row (Cell)
}
}
// create full texture region
textureRgn = new TextureRegion( textureSize, tex-
447
tureSize, 0, 0, textureSize, textureSize ); // Create
Full Texture Region
// return success
return true; //
Return Success
}
//--Begin/End Text Drawing--//
// D: call these methods before/after (respectively
all draw() calls using a text instance
// NOTE: color is set on a per-batch basis, and
fonts should be 8-bit alpha only!!!
// A: red, green, blue - RGB values for font (default
= 1.0)
// alpha - optional alpha value for font (default
= 1.0)
// R: [none]
public void begin() {
begin( 1.0f, 1.0f, 1.0f, 1.0f ); //
Begin with White Opaque
}
public void begin(float alpha) {
begin( 1.0f, 1.0f, 1.0f, alpha ); //
Begin with White (Explicit Alpha)
}
public void begin(float red, float green, float blue,
float alpha) {
gl.glColor4f( red, green, blue, alpha ); //
Set Color+Alpha
gl.glBindTexture( GL10.GL_TEXTURE_2D, textureId );
// Bind the Texture
batch.beginBatch(); //
Begin Batch
}
public void end() {
batch.endBatch(); //
End Batch
gl.glColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); //
Restore Default Color/Alpha
}
//--Draw Text--//
// D: draw text at the specified x,y position
// A: text - the string to draw
// x, y - the x,y position to draw text at (bottom
left of text; including descent)
// R: [none]
public void draw(String text, float x, float y) {
float chrHeight = cellHeight * scaleY; //
Calculate Scaled Character Height
float chrWidth = cellWidth * scaleX; //
Calculate Scaled Character Width
int len = text.length(); //
Get String Length
x += ( chrWidth / 2.0f ) - ( fontPadX * scaleX );
// Adjust Start X
y += ( chrHeight / 2.0f ) - ( fontPadY * scaleY );
// Adjust Start Y
448
for ( int i = 0; i < len; i++ ) { //
FOR Each Character in String
int c = (int)text.charAt( i ) - CHAR_START; //
Calculate Character Index (Offset by First Char in Font)
if ( c < 0 || c >= CHAR_CNT ) //
IF Character Not In Font
c = CHAR_UNKNOWN; //
Set to Unknown Character Index
batch.drawSprite( x, y, chrWidth, chrHeight,
charRgn[c] ); // Draw the Character
x += ( charWidths[c] + spaceX ) * scaleX; //
Advance X Position by Scaled Character Width
}
}
//--Draw Text Centered--//
// D: draw text CENTERED at the specified x,y posi-
tion
// A: text - the string to draw
// x, y - the x,y position to draw text at (bottom
left of text)
// R: the total width of the text that was drawn
public float drawC(String text, float x, float y) {
float len = getLength( text ); //
Get Text Length
draw( text, x - ( len / 2.0f ), y - ( getChar-
Height() / 2.0f ) ); // Draw Text Centered
return len; //
Return Length
}
public float drawCX(String text, float x, float y) {
float len = getLength( text ); //
Get Text Length
draw( text, x - ( len / 2.0f ), y ); //
Draw Text Centered (X-Axis Only)
return len; //
Return Length
}
public void drawCY(String text, float x, float y) {
draw( text, x, y - ( getCharHeight() / 2.0f ) );
// Draw Text Centered (Y-Axis Only)
}
//--Set Scale--//
// D: set the scaling to use for the font
// A: scale - uniform scale for both x and y axis
scaling
// sx, sy - separate x and y axis scaling factors
// R: [none]
public void setScale(float scale) {
scaleX = scaleY = scale; //
Set Uniform Scale
}
public void setScale(float sx, float sy) {
scaleX = sx; //
Set X Scale
scaleY = sy; //
Set Y Scale
}
449
//--Get Scale--//
// D: get the current scaling used for the font
// A: [none]
// R: the x/y scale currently used for scale
public float getScaleX() {
return scaleX; //
Return X Scale
}
public float getScaleY() {
return scaleY; //
Return Y Scale
}
//--Set Space--//
// D: set the spacing (unscaled; ie. pixel size) to
use for the font
// A: space - space for x axis spacing
// R: [none]
public void setSpace(float space) {
spaceX = space; //
Set Space
}
//--Get Space--//
// D: get the current spacing used for the font
// A: [none]
// R: the x/y space currently used for scale
public float getSpace() {
return spaceX; //
Return X Space
}
//--Get Length of a String--//
// D: return the length of the specified string if
rendered using current settings
// A: text - the string to get length for
// R: the length of the specified string (pixels)
public float getLength(String text) {
float len = 0.0f; //
Working Length
int strLen = text.length(); //
Get String Length (Characters)
for ( int i = 0; i < strLen; i++ ) { //
For Each Character in String (Except Last
int c = (int)text.charAt( i ) - CHAR_START; //
Calculate Character Index (Offset by First Char in Font)
len += ( charWidths[c] * scaleX ); //
Add Scaled Character Width to Total Length
}
len += ( strLen > 1 ? ( ( strLen - 1 ) * spaceX )
* scaleX : 0 ); // Add Space Length
return len; //
Return Total Length
}
//--Get Width/Height of Character--//
// D: return the scaled width/height of a character,
or max character width
450
// NOTE: since all characters are the same height,
no character index is required!
// NOTE: excludes spacing!!
// A: chr - the character to get width for
// R: the requested character size (scaled)
public float getCharWidth(char chr) {
int c = chr - CHAR_START; //
Calculate Character Index (Offset by First Char in Font)
return ( charWidths[c] * scaleX ); //
Return Scaled Character Width
}
public float getCharWidthMax() {
return ( charWidthMax * scaleX ); //
Return Scaled Max Character Width
}
public float getCharHeight() {
return ( charHeight * scaleY ); //
Return Scaled Character Height
}
//--Get Font Metrics--//
// D: return the specified (scaled) font metric
// A: [none]
// R: the requested font metric (scaled)
public float getAscent() {
return ( fontAscent * scaleY ); //
Return Font Ascent
}
public float getDescent() {
return ( fontDescent * scaleY ); //
Return Font Descent
}
public float getHeight() {
return ( fontHeight * scaleY ); //
Return Font Height (Actual)
}
//--Draw Font Texture--//
// D: draw the entire font texture (NOTE: for testing
purposes only)
// A: width, height - the width and height of the ar-
ea to draw to. this is used
// to draw the texture to the top-left corner.
public void drawTexture(int width, int height) {
batch.beginBatch( textureId ); //
Begin Batch (Bind Texture)
batch.drawSprite( textureSize / 2, height - ( tex-
tureSize / 2 ), textureSize, textureSize, textureRgn );
// Draw
batch.endBatch(); //
End Batch
}
}
451
FitObject.java
package com.ligthing;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
public class FitObject {
// Point to our vertex buffer, return buffer
holding the vertices
public static FloatBuffer makeFloatBuffer(float[]
arr){
ByteBuffer bb = ByteBuff-
er.allocateDirect(arr.length * 4);
bb.order(ByteOrder.nativeOrder());
FloatBuffer fb = bb.asFloatBuffer();
fb.put(arr);
fb.position(0);
return fb;
}
public void draw_bola(GL10 gl, float[] mat_diff,
int shiness) {
// mengaktifkan pencahayaan
//float[] mat_amb = {0.2f * 1.0f, 0.2f *
0.4f, 0.2f * 0.4f, 1.0f,};
float[] mat_amb = {0.0f * 1.0f, 0.0f *
0.4f, 0.0f * 0.4f, 1.0f,};
//float[] mat_diff = {1.0f, 0.4f, 0.4f,
0.5f,};
//float[] mat_diff = {1.0f, 0.8f, 0.04f,
1.0f};
float[] mat_spec = {1.0f, 1.0f, 1.0f,
1.0f};
/*gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glEnable(GL10.GL_CULL_FACE);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glEnable(GL10.GL_LIGHTING);
gl.glEnable(GL10.GL_LIGHT0); */
gl.glEnable(GL10.GL_LIGHTING);
gl.glEnable(GL10.GL_LIGHT0);
// set the colour edge for the object circle
//gl.glColor4f(1.0f, 0.8f, 0.04f, 1.0f);
gl.glMaterialfv(GL10.GL_FRONT_AND_BACK,
GL10.GL_AMBIENT, makeFloatBuffer(mat_amb));
gl.glMaterialfv(GL10.GL_FRONT_AND_BACK,
GL10.GL_DIFFUSE, makeFloatBuffer(mat_diff));
452
gl.glMaterialfv(GL10.GL_FRONT_AND_BACK,
GL10.GL_SPECULAR, makeFloatBuffer(mat_spec));
gl.glMaterialf(GL10.GL_FRONT_AND_BACK,
GL10.GL_SHININESS, shiness);
//gl.glMaterialf(GL10.GL_FRONT_AND_BACK,
GL10.GL_SHININESS, 128.0f);
float theta, pai;
float co, si;
float r1, r2;
float h1, h2;
float step = 2.0f;
float[][] v = new float[32][3];
ByteBuffer vbb;
FloatBuffer vBuf;
vbb = ByteBuffer.allocateDirect(v.length
* v[0].length * 4);
vbb.order(ByteOrder.nativeOrder());
vBuf = vbb.asFloatBuffer();
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
for (pai = -90.0f; pai < 90.0f; pai += step) {
int n = 0;
r1 = (float)Math.cos(pai * Math.PI / 180.0);
r2 = (float)Math.cos((pai + step) *
Math.PI / 180.0);
h1 = (float)Math.sin(pai * Math.PI /
180.0);
h2 = (float)Math.sin((pai + step) *
Math.PI / 180.0);
for (theta = 0.0f; theta <= 360.0f; theta
+= step) {
co = (float)Math.cos(theta *
Math.PI / 180.0);
si = -(float)Math.sin(theta *
Math.PI / 180.0);
v[n][0] = (r2 * co);
v[n][1] = (h2);
v[n][2] = (r2 * si);
v[n + 1][0] = (r1 * co);
v[n + 1][1] = (h1);
v[n + 1][2] = (r1 * si);
vBuf.put(v[n]);
vBuf.put(v[n + 1]);
n += 2;
if(n>31){
vBuf.position(0);
gl.glVertexPointer(3,
GL10.GL_FLOAT, 0, vBuf);
453
gl.glNormalPointer(GL10.GL_FLOAT,
0, vBuf);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, n);
n = 0;
theta -= step;
}
}
vBuf.position(0);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
vBuf);
gl.glNormalPointer(GL10.GL_FLOAT, 0,
vBuf);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, n);
}
gl.glDisable(GL10.GL_LIGHTING);
gl.glDisable(GL10.GL_LIGHT0);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
}
}
item.java
package com.ligthing;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
/*
* A photo cube with 6 pictures (textures) on its 6 fac-
es.
*/
public class item {
private FloatBuffer vertexBuffer; // Vertex Buff-
er
private FloatBuffer texBuffer; // Texture Coords
Buffer
private int numFaces = 14;
private int[] imageFileIDs = { // Image file IDs
R.drawable.caldera, // index 0
R.drawable.candice, // index 1
R.drawable.mule, // index 2
R.drawable.glass, // index 3
R.drawable.leonardo, // index 4
454
R.drawable.tmsk, // index 5
R.drawable.lantai, // index 6
R.drawable.tembok, // index 7
R.drawable.tembokx, // index 8
R.drawable.atap, // index 9
R.drawable.meja,// index 10
R.drawable.imam, // index 11
R.drawable.pintux, // index 12
R.drawable.wallpaper // index 13
};
private int[] textureIDs = new int[numFaces];
private Bitmap[] bitmap = new Bitmap[numFaces];
private float cubeHalfSize = 1.0f;
// Constructor - Set up the vertex buffer
public item(Context context) {
// Allocate vertex buffer. An float has 4
bytes
ByteBuffer vbb = ByteBuff-
er.allocateDirect(12 * 4 * numFaces);
vbb.order(ByteOrder.nativeOrder());
vertexBuffer = vbb.asFloatBuffer();
// Read images. Find the aspect ratio and
adjust the vertices
// accordingly.
for (int face = 0; face < numFaces;
face++) {
bitmap[face] = BitmapFacto-
ry.decodeStream(context.getResources()
.openRawResource(imageFileIDs[face]));
int imgWidth = bit-
map[face].getWidth();
int imgHeight = bit-
map[face].getHeight();
float faceWidth = 2.0f;
float faceHeight = 2.0f;
// Adjust for aspect ratio
if (imgWidth > imgHeight) {
faceHeight = faceHeight *
imgHeight / imgWidth;
} else {
faceWidth = faceWidth *
imgWidth / imgHeight;
}
float faceLeft = -faceWidth / 2;
float faceRight = -faceLeft;
float faceTop = faceHeight / 2;
float faceBottom = -faceTop;
// Define the vertices for this
face
// float[] vertices = { faceLeft,
faceBottom, 0.0f, // 0.
// // left-bottom-front
// faceRight, faceBottom, 0.0f, //
1. right-bottom-front
455
// faceLeft, faceTop, 0.0f, // 2.
left-top-front
// faceRight, faceTop, 0.0f, // 3.
right-top-front
// };
float[] vertices = { // Vertices
for a face
-1.0f, -1.0f, 0.0f, // 0. left-
bottom-front
1.0f, -1.0f, 0.0f,
// 1. right-bottom-front
-1.0f, 1.0f, 0.0f,
// 2. left-top-front
1.0f, 1.0f, 0.0f //
3. right-top-front
};
vertexBuffer.put(vertices); //
Populate
}
vertexBuffer.position(0); // Rewind
// Allocate texture buffer. An float has
4 bytes. Repeat for 6 faces.
float[] texCoords = { 0.0f, 1.0f, // A.
left-bottom
1.0f, 1.0f, // B. right-
bottom
0.0f, 0.0f, // C. left-top
1.0f, 0.0f // D. right-top
};
ByteBuffer tbb = ByteBuff-
er.allocateDirect(texCoords.length * 4
* numFaces);
tbb.order(ByteOrder.nativeOrder());
texBuffer = tbb.asFloatBuffer();
for (int face = 0; face < numFaces;
face++) {
texBuffer.put(texCoords);
}
texBuffer.position(0); // Rewind
}
// Render the shape (Buat lantai)
public void draw(GL10 gl) {
gl.glFrontFace(GL10.GL_CCW);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRA
Y);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0,
texBuffer);
// lantai
gl.glPushMatrix();
gl.glRotatef(90, 1.0f, 0.0f, 0.0f);
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
456
tureIDs[6]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARR
AY);
}
// Render the shape (Buat tembok belakang)
public void draw_tembok_blk(GL10 gl) {
gl.glFrontFace(GL10.GL_CCW);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRA
Y);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0,
texBuffer);
// tembok
gl.glPushMatrix();
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[7]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARR
AY);
}
// Render the shape (Buat tembok samping)
public void draw_tembok_smp(GL10 gl) {
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glFrontFace(GL10.GL_CCW);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRA
Y);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0,
texBuffer);
// tembok
457
gl.glPushMatrix();
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[13]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARR
AY);
gl.glDisable(GL10.GL_TEXTURE_2D);
}
// Render the shape (Buat atap)
public void draw_atap(GL10 gl) {
gl.glFrontFace(GL10.GL_CCW);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRA
Y);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0,
texBuffer);
// tembok
gl.glPushMatrix();
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[9]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARR
AY);
}
// Load images into 6 GL textures
public void loadTexture(GL10 gl, Context c) {
gl.glGenTextures(14, textureIDs, 0); //
Generate texture-ID array for 6
// IDs
// Generate OpenGL texture images
for (int face = 0; face < numFaces;
face++) {
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[face]);
458
// Build Texture from loaded bit-
map for the currently-bind texture
// ID
gl.glTexParameterf(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MIN_FILTER,
GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MAG_FILTER,
GL10.GL_LINEAR);
GLU-
tils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap[face], 0);
bitmap[face].recycle();
}
}
}
kaki_meja.java
package com.ligthing;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
/*
* A photo cube with 6 pictures (textures) on its 6 fac-
es.
*/
public class kaki_meja {
private FloatBuffer vertexBuffer; // Vertex Buff-
er
private FloatBuffer texBuffer; // Texture Coords
Buffer
private int numFaces = 14;
private int[] imageFileIDs = { // Image file IDs
R.drawable.caldera, //index 0
R.drawable.candice, //index 1
R.drawable.mule, //index 2
R.drawable.glass, //index 3
R.drawable.leonardo, //index 4
R.drawable.tmsk, //index 5
R.drawable.lantai, //index 6
R.drawable.tembok, //index 7
R.drawable.tembokx, //index 8
R.drawable.atap, //index 9
R.drawable.meja,// index 10
459
R.drawable.imam, //index 11
R.drawable.pintux, // index 12
R.drawable.wallpaper // index 13
};
private int[] textureIDs = new int[numFaces];
private Bitmap[] bitmap = new Bitmap[numFaces];
private float cubeHalfSize = 1.0f;
// Constructor - Set up the vertex buffer
public kaki_meja(Context context) {
// Allocate vertex buffer. An float has 4
bytes
ByteBuffer vbb = ByteBuff-
er.allocateDirect(12 * 4 * numFaces);
vbb.order(ByteOrder.nativeOrder());
vertexBuffer = vbb.asFloatBuffer();
// Read images. Find the aspect ratio and
adjust the vertices
// accordingly.
for (int face = 0; face < numFaces;
face++) {
bitmap[face] = BitmapFacto-
ry.decodeStream(context.getResources()
.openRawResource(imageFileIDs[face]));
int imgWidth = bit-
map[face].getWidth();
int imgHeight = bit-
map[face].getHeight();
float faceWidth = 2.0f;
float faceHeight = 2.0f;
// Adjust for aspect ratio
if (imgWidth > imgHeight) {
faceHeight = faceHeight *
imgHeight / imgWidth;
} else {
faceWidth = faceWidth *
imgWidth / imgHeight;
}
float faceLeft = -faceWidth / 2;
float faceRight = -faceLeft;
float faceTop = faceHeight / 2;
float faceBottom = -faceTop;
// Define the vertices for this
face
// float[] vertices = { faceLeft, fa-
ceBottom, 0.0f, // 0.
//
// left-bottom-front
// faceRight, faceBot-
tom, 0.0f, // 1. right-bottom-front
// faceLeft, faceTop,
0.0f, // 2. left-top-front
460
// faceRight, faceTop,
0.0f, // 3. right-top-front
// };
float[] vertices = { // Vertices
for a face
-1.0f, -1.0f, 0.0f,
// 0. left-bottom-front
1.0f, -1.0f, 0.0f, // 1. right-bottom-front
-
1.0f, 1.0f, 0.0f, // 2. left-top-front
1.0f, 1.0f, 0.0f // 3. right-top-front
};
vertexBuffer.put(vertices); //
Populate
}
vertexBuffer.position(0); // Rewind
// Allocate texture buffer. An float has
4 bytes. Repeat for 6 faces.
float[] texCoords = {
0.0f, 1.0f, // A. left-
bottom
1.0f, 1.0f, // B. right-
bottom
0.0f, 0.0f, // C. left-top
1.0f, 0.0f // D. right-top
};
ByteBuffer tbb = ByteBuff-
er.allocateDirect(texCoords.length * 4
* numFaces);
tbb.order(ByteOrder.nativeOrder());
texBuffer = tbb.asFloatBuffer();
for (int face = 0; face < numFaces;
face++) {
texBuffer.put(texCoords);
}
texBuffer.position(0); // Rewind
}
// Render the shape
public void draw(GL10 gl) {
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glFrontFace(GL10.GL_CCW);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRA
Y);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0,
texBuffer);
// front
gl.glPushMatrix();
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[10]);
461
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
// left
gl.glPushMatrix();
gl.glRotatef(270.0f, 0f, 1f, 0f);
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[10]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
4, 4);
gl.glPopMatrix();
// back
gl.glPushMatrix();
gl.glRotatef(180.0f, 0f, 1f, 0f);
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[10]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
8, 4);
gl.glPopMatrix();
// right
gl.glPushMatrix();
gl.glRotatef(90.0f, 0f, 1f, 0f);
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[10]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
12, 4);
gl.glPopMatrix();
// top
gl.glPushMatrix();
gl.glRotatef(270.0f, 1f, 0f, 0f);
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[10]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
16, 4);
gl.glPopMatrix();
// bottom
gl.glPushMatrix();
gl.glRotatef(90.0f, 1f, 0f, 0f);
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[10]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
20, 4);
gl.glPopMatrix();
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARR
AY);
462
gl.glDisable(GL10.GL_TEXTURE_2D);
}
// Load images into 6 GL textures
public void loadTexture(GL10 gl, Context c) {
gl.glGenTextures(14, textureIDs, 0); //
Generate texture-ID array for 6
// IDs
// Generate OpenGL texture images
for (int face = 0; face < numFaces;
face++) {
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[face]);
// Build Texture from loaded bit-
map for the currently-bind texture
// ID
gl.glTexParameterf(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MIN_FILTER,
GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MAG_FILTER,
GL10.GL_LINEAR);
GLU-
tils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap[face], 0);
bitmap[face].recycle();
}
}
}
kubus_kecil.java
package com.ligthing;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
/*
* A photo cube with 6 pictures (textures) on its 6 fac-
es.
*/
public class kubus_kecil {
private FloatBuffer vertexBuffer; // Vertex Buff-
er
463
private FloatBuffer texBuffer; // Texture Coords
Buffer
private int numFaces = 14;
private int[] imageFileIDs = { // Image file IDs
R.drawable.caldera, //index 0
R.drawable.candice, //index 1
R.drawable.mule, //index 2
R.drawable.glass, //index 3
R.drawable.leonardo, //index 4
R.drawable.tmsk, //index 5
R.drawable.lantai, //index 6
R.drawable.tembok, //index 7
R.drawable.tembokx, //index 8
R.drawable.atap, //index 9
R.drawable.meja,// index 10
R.drawable.imam, //index 11
R.drawable.pintux, // index 12
R.drawable.wallpaper // index 13
};
private int[] textureIDs = new int[numFaces];
private Bitmap[] bitmap = new Bitmap[numFaces];
private float cubeHalfSize = 1.0f;
// Constructor - Set up the vertex buffer
public kubus_kecil(Context context) {
// Allocate vertex buffer. An float has 4
bytes
ByteBuffer vbb = ByteBuff-
er.allocateDirect(12 * 4 * numFaces);
vbb.order(ByteOrder.nativeOrder());
vertexBuffer = vbb.asFloatBuffer();
// Read images. Find the aspect ratio and
adjust the vertices
// accordingly.
for (int face = 0; face < numFaces;
face++) {
bitmap[face] = BitmapFacto-
ry.decodeStream(context.getResources()
.openRawResource(imageFileIDs[face]));
int imgWidth = bit-
map[face].getWidth();
int imgHeight = bit-
map[face].getHeight();
float faceWidth = 2.0f;
float faceHeight = 2.0f;
// Adjust for aspect ratio
if (imgWidth > imgHeight) {
faceHeight = faceHeight *
imgHeight / imgWidth;
} else {
faceWidth = faceWidth *
imgWidth / imgHeight;
}
float faceLeft = -faceWidth / 2;
464
float faceRight = -faceLeft;
float faceTop = faceHeight / 2;
float faceBottom = -faceTop;
// Define the vertices for this
face
// float[] vertices = { faceLeft, fa-
ceBottom, 0.0f, // 0.
//
// left-bottom-front
// faceRight, faceBot-
tom, 0.0f, // 1. right-bottom-front
// faceLeft, faceTop,
0.0f, // 2. left-top-front
// faceRight, faceTop,
0.0f, // 3. right-top-front
// };
float[] vertices = { // Vertices
for a face
-1.0f, -1.0f, 0.0f,
// 0. left-bottom-front
1.0f, -1.0f, 0.0f, // 1. right-bottom-front
-
1.0f, 1.0f, 0.0f, // 2. left-top-front
1.0f, 1.0f, 0.0f // 3. right-top-front
};
vertexBuffer.put(vertices); //
Populate
}
vertexBuffer.position(0); // Rewind
// Allocate texture buffer. An float has
4 bytes. Repeat for 6 faces.
float[] texCoords = {
0.0f, 1.0f, // A. left-
bottom
1.0f, 1.0f, // B. right-
bottom
0.0f, 0.0f, // C. left-top
1.0f, 0.0f // D. right-top
};
ByteBuffer tbb = ByteBuff-
er.allocateDirect(texCoords.length * 4
* numFaces);
tbb.order(ByteOrder.nativeOrder());
texBuffer = tbb.asFloatBuffer();
for (int face = 0; face < numFaces;
face++) {
texBuffer.put(texCoords);
}
texBuffer.position(0); // Rewind
}
// Render the shape
public void draw(GL10 gl) {
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glFrontFace(GL10.GL_CCW);
465
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRA
Y);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0,
texBuffer);
// front
gl.glPushMatrix();
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[0]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
// left
gl.glPushMatrix();
gl.glRotatef(270.0f, 0f, 1f, 0f);
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[1]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
4, 4);
gl.glPopMatrix();
// back
gl.glPushMatrix();
gl.glRotatef(180.0f, 0f, 1f, 0f);
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[2]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
8, 4);
gl.glPopMatrix();
// right
gl.glPushMatrix();
gl.glRotatef(90.0f, 0f, 1f, 0f);
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[3]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
12, 4);
gl.glPopMatrix();
// top
gl.glPushMatrix();
gl.glRotatef(270.0f, 1f, 0f, 0f);
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[4]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
16, 4);
gl.glPopMatrix();
466
// bottom
gl.glPushMatrix();
gl.glRotatef(90.0f, 1f, 0f, 0f);
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[5]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
20, 4);
gl.glPopMatrix();
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARR
AY);
gl.glDisable(GL10.GL_TEXTURE_2D);
}
// Load images into 6 GL textures
public void loadTexture(GL10 gl, Context c) {
gl.glGenTextures(14, textureIDs, 0); //
Generate texture-ID array for 6
// IDs
// Generate OpenGL texture images
for (int face = 0; face < numFaces;
face++) {
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[face]);
// Build Texture from loaded bit-
map for the currently-bind texture
// ID
gl.glTexParameterf(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MIN_FILTER,
GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MAG_FILTER,
GL10.GL_LINEAR);
GLU-
tils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap[face], 0);
bitmap[face].recycle();
}
}
}
kubus.java
package com.ligthing;
467
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
/*
* A cube with texture.
* Define the vertices for only one representative face.
* * Render the cube by translating and rotating the
face.
*/
public class kubus {
private FloatBuffer vertexBuffer; // Buffer for
vertex-array
private FloatBuffer texBuffer; // Buffer for tex-
ture-coords-array (NEW)
private float[] vertices = { // Vertices for a
face
-1.0f, -1.0f, 0.0f, // 0. left-
bottom-front
1.0f, -1.0f, 0.0f, // 1. right-
bottom-front
-1.0f, 1.0f, 0.0f, // 2. left-top-
front
1.0f, 1.0f, 0.0f // 3. right-top-
front
};
float[] texCoords = { // Texture coords for the
above face (NEW)
0.0f, 1.0f, // A. left-bottom
(NEW)
1.0f, 1.0f, // B. right-bottom
(NEW)
0.0f, 0.0f, // C. left-top (NEW)
1.0f, 0.0f // D. right-top (NEW)
};
int[] textureIDs = new int[1]; // Array for 1
texture-ID (NEW)
// Constructor - Set up the buffers
public kubus() {
// Setup vertex-array buffer. Vertices in
float. An float has 4 bytes
ByteBuffer vbb = ByteBuff-
er.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder()); //
Use native byte order
vertexBuffer = vbb.asFloatBuffer(); //
Convert from byte to float
vertexBuffer.put(vertices); // Copy data
into buffer
468
vertexBuffer.position(0); // Rewind
// Setup texture-coords-array buffer, in
float. An float has 4 bytes
// (NEW)
ByteBuffer tbb = ByteBuff-
er.allocateDirect(texCoords.length * 4);
tbb.order(ByteOrder.nativeOrder());
texBuffer = tbb.asFloatBuffer();
texBuffer.put(texCoords);
texBuffer.position(0);
}
// Draw the shape
public void draw(GL10 gl) {
gl.glFrontFace(GL10.GL_CCW); // Front
face in counter-clockwise
// orientation
gl.glEnable(GL10.GL_CULL_FACE); // Enable
cull face
gl.glCullFace(GL10.GL_BACK); // Cull the
back face (don't display)
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
vertexBuffer);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRA
Y); // Enable
// texture-coords-array
// (NEW)
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0,
texBuffer); // Define
// texture-coords
// buffer (NEW)
// front
gl.glPushMatrix();
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
// left
gl.glPushMatrix();
gl.glRotatef(270.0f, 0.0f, 1.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
469
// back
gl.glPushMatrix();
gl.glRotatef(180.0f, 0.0f, 1.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
// right
gl.glPushMatrix();
gl.glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
// top
gl.glPushMatrix();
gl.glRotatef(270.0f, 1.0f, 0.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
// bottom
gl.glPushMatrix();
gl.glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARR
AY); // Disable
// texture-coords-array
// (NEW)
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisable(GL10.GL_CULL_FACE);
}
// Load an image into GL texture
public void loadTexture(GL10 gl,Context c) {
gl.glGenTextures(1, textureIDs, 0); //
Generate texture-ID array
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[0]); // Bind to texture
// ID
// Set up texture filters
gl.glTexParameterf(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MIN_FILTER,
470
GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MAG_FILTER,
GL10.GL_LINEAR);
// Construct an input stream to texture
image "res\drawable\nature.png"
//AssetManager assetManager =
c.getAssets();
//InputStream istream = assetManag-
er.open("nature.png");
InputStream istream =
c.getResources().openRawResource(R.drawable.atap);
Bitmap bitmap;
try {
// Read and decode input as bitmap
bitmap = BitmapFacto-
ry.decodeStream(istream);
} finally {
try {
istream.close();
} catch (IOException e) {
}
}
// Build Texture from loaded bitmap for
the currently-bind texture ID
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0,
bitmap, 0);
bitmap.recycle();
}
}
lampu.java
package com.ligthing;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
/*
* A photo cube with 6 pictures (textures) on its 6 fac-
es.
*/
public class lampu {
private FloatBuffer vertexBuffer; // Vertex Buff-
er
private FloatBuffer texBuffer; // Texture Coords
Buffer
471
private int numFaces = 15;
private int[] imageFileIDs = { // Image file IDs
R.drawable.caldera, //index 0
R.drawable.candice, //index 1
R.drawable.mule, //index 2
R.drawable.glass, //index 3
R.drawable.leonardo, //index 4
R.drawable.tmsk, //index 5
R.drawable.lantai, //index 6
R.drawable.tembok, //index 7
R.drawable.tembokx, //index 8
R.drawable.atap, //index 9
R.drawable.meja,// index 10
R.drawable.imam, //index 11
R.drawable.pintux, // index 12
R.drawable.wallpaper, // index 13
R.drawable.lampux // index 14
};
private int[] textureIDs = new int[numFaces];
private Bitmap[] bitmap = new Bitmap[numFaces];
private float cubeHalfSize = 1.0f;
// Constructor - Set up the vertex buffer
public lampu(Context context) {
// Allocate vertex buffer. An float has 4
bytes
ByteBuffer vbb = ByteBuff-
er.allocateDirect(12 * 4 * numFaces);
vbb.order(ByteOrder.nativeOrder());
vertexBuffer = vbb.asFloatBuffer();
// Read images. Find the aspect ratio and
adjust the vertices
// accordingly.
for (int face = 0; face < numFaces;
face++) {
bitmap[face] = BitmapFacto-
ry.decodeStream(context.getResources()
.openRawResource(imageFileIDs[face]));
int imgWidth = bit-
map[face].getWidth();
int imgHeight = bit-
map[face].getHeight();
float faceWidth = 2.0f;
float faceHeight = 2.0f;
// Adjust for aspect ratio
if (imgWidth > imgHeight) {
faceHeight = faceHeight *
imgHeight / imgWidth;
} else {
faceWidth = faceWidth *
imgWidth / imgHeight;
}
float faceLeft = -faceWidth / 2;
float faceRight = -faceLeft;
472
float faceTop = faceHeight / 2;
float faceBottom = -faceTop;
// Define the vertices for this
face
// float[] vertices = { faceLeft, fa-
ceBottom, 0.0f, // 0.
//
// left-bottom-front
// faceRight, faceBot-
tom, 0.0f, // 1. right-bottom-front
// faceLeft, faceTop,
0.0f, // 2. left-top-front
// faceRight, faceTop,
0.0f, // 3. right-top-front
// };
float[] vertices = { // Vertices
for a face
-1.0f, -1.0f, 0.0f,
// 0. left-bottom-front
1.0f, -1.0f, 0.0f, // 1. right-bottom-front
-
1.0f, 1.0f, 0.0f, // 2. left-top-front
1.0f, 1.0f, 0.0f // 3. right-top-front
};
vertexBuffer.put(vertices); //
Populate
}
vertexBuffer.position(0); // Rewind
// Allocate texture buffer. An float has
4 bytes. Repeat for 6 faces.
float[] texCoords = {
0.0f, 1.0f, // A. left-
bottom
1.0f, 1.0f, // B. right-
bottom
0.0f, 0.0f, // C. left-top
1.0f, 0.0f // D. right-top
};
ByteBuffer tbb = ByteBuff-
er.allocateDirect(texCoords.length * 4
* numFaces);
tbb.order(ByteOrder.nativeOrder());
texBuffer = tbb.asFloatBuffer();
for (int face = 0; face < numFaces;
face++) {
texBuffer.put(texCoords);
}
texBuffer.position(0); // Rewind
}
// Render the shape
public void draw(GL10 gl) {
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glFrontFace(GL10.GL_CCW);
473
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRA
Y);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0,
texBuffer);
// front
gl.glPushMatrix();
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[14]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
// left
gl.glPushMatrix();
gl.glRotatef(270.0f, 0f, 1f, 0f);
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[14]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
4, 4);
gl.glPopMatrix();
// back
gl.glPushMatrix();
gl.glRotatef(180.0f, 0f, 1f, 0f);
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[14]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
8, 4);
gl.glPopMatrix();
// right
gl.glPushMatrix();
gl.glRotatef(90.0f, 0f, 1f, 0f);
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[14]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
12, 4);
gl.glPopMatrix();
// top
gl.glPushMatrix();
gl.glRotatef(270.0f, 1f, 0f, 0f);
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[14]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
16, 4);
gl.glPopMatrix();
474
// bottom
gl.glPushMatrix();
gl.glRotatef(90.0f, 1f, 0f, 0f);
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[14]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
20, 4);
gl.glPopMatrix();
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARR
AY);
gl.glDisable(GL10.GL_TEXTURE_2D);
}
// Load images into 6 GL textures
public void loadTexture(GL10 gl, Context c) {
gl.glGenTextures(15, textureIDs, 0); //
Generate texture-ID array for 6
// IDs
// Generate OpenGL texture images
for (int face = 0; face < numFaces;
face++) {
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[face]);
// Build Texture from loaded bit-
map for the currently-bind texture
// ID
gl.glTexParameterf(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MIN_FILTER,
GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MAG_FILTER,
GL10.GL_LINEAR);
GLU-
tils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap[face], 0);
bitmap[face].recycle();
}
}
}
lukisan.java
package com.ligthing;
import java.nio.ByteBuffer;
475
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
/*
* A photo cube with 6 pictures (textures) on its 6 fac-
es.
*/
public class lampu {
private FloatBuffer vertexBuffer; // Vertex Buff-
er
private FloatBuffer texBuffer; // Texture Coords
Buffer
private int numFaces = 15;
private int[] imageFileIDs = { // Image file IDs
R.drawable.caldera, //index 0
R.drawable.candice, //index 1
R.drawable.mule, //index 2
R.drawable.glass, //index 3
R.drawable.leonardo, //index 4
R.drawable.tmsk, //index 5
R.drawable.lantai, //index 6
R.drawable.tembok, //index 7
R.drawable.tembokx, //index 8
R.drawable.atap, //index 9
R.drawable.meja,// index 10
R.drawable.imam, //index 11
R.drawable.pintux, // index 12
R.drawable.wallpaper, // index 13
R.drawable.lampux // index 14
};
private int[] textureIDs = new int[numFaces];
private Bitmap[] bitmap = new Bitmap[numFaces];
private float cubeHalfSize = 1.0f;
// Constructor - Set up the vertex buffer
public lampu(Context context) {
// Allocate vertex buffer. An float has 4
bytes
ByteBuffer vbb = ByteBuff-
er.allocateDirect(12 * 4 * numFaces);
vbb.order(ByteOrder.nativeOrder());
vertexBuffer = vbb.asFloatBuffer();
// Read images. Find the aspect ratio and
adjust the vertices
// accordingly.
for (int face = 0; face < numFaces;
face++) {
bitmap[face] = BitmapFacto-
ry.decodeStream(context.getResources()
.openRawResource(imageFileIDs[face]));
476
int imgWidth = bit-
map[face].getWidth();
int imgHeight = bit-
map[face].getHeight();
float faceWidth = 2.0f;
float faceHeight = 2.0f;
// Adjust for aspect ratio
if (imgWidth > imgHeight) {
faceHeight = faceHeight *
imgHeight / imgWidth;
} else {
faceWidth = faceWidth *
imgWidth / imgHeight;
}
float faceLeft = -faceWidth / 2;
float faceRight = -faceLeft;
float faceTop = faceHeight / 2;
float faceBottom = -faceTop;
// Define the vertices for this
face
// float[] vertices = { faceLeft, fa-
ceBottom, 0.0f, // 0.
//
// left-bottom-front
// faceRight, faceBot-
tom, 0.0f, // 1. right-bottom-front
// faceLeft, faceTop,
0.0f, // 2. left-top-front
// faceRight, faceTop,
0.0f, // 3. right-top-front
// };
float[] vertices = { // Vertices
for a face
-1.0f, -1.0f, 0.0f,
// 0. left-bottom-front
1.0f, -1.0f, 0.0f, // 1. right-bottom-front
-
1.0f, 1.0f, 0.0f, // 2. left-top-front
1.0f, 1.0f, 0.0f // 3. right-top-front
};
vertexBuffer.put(vertices); //
Populate
}
vertexBuffer.position(0); // Rewind
// Allocate texture buffer. An float has
4 bytes. Repeat for 6 faces.
float[] texCoords = {
0.0f, 1.0f, // A. left-
bottom
1.0f, 1.0f, // B. right-
bottom
0.0f, 0.0f, // C. left-top
1.0f, 0.0f // D. right-top
};
477
ByteBuffer tbb = ByteBuff-
er.allocateDirect(texCoords.length * 4
* numFaces);
tbb.order(ByteOrder.nativeOrder());
texBuffer = tbb.asFloatBuffer();
for (int face = 0; face < numFaces;
face++) {
texBuffer.put(texCoords);
}
texBuffer.position(0); // Rewind
}
// Render the shape
public void draw(GL10 gl) {
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glFrontFace(GL10.GL_CCW);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRA
Y);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0,
texBuffer);
// front
gl.glPushMatrix();
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[14]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
// left
gl.glPushMatrix();
gl.glRotatef(270.0f, 0f, 1f, 0f);
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[14]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
4, 4);
gl.glPopMatrix();
// back
gl.glPushMatrix();
gl.glRotatef(180.0f, 0f, 1f, 0f);
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[14]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
8, 4);
gl.glPopMatrix();
// right
gl.glPushMatrix();
gl.glRotatef(90.0f, 0f, 1f, 0f);
478
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[14]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
12, 4);
gl.glPopMatrix();
// top
gl.glPushMatrix();
gl.glRotatef(270.0f, 1f, 0f, 0f);
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[14]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
16, 4);
gl.glPopMatrix();
// bottom
gl.glPushMatrix();
gl.glRotatef(90.0f, 1f, 0f, 0f);
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[14]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
20, 4);
gl.glPopMatrix();
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARR
AY);
gl.glDisable(GL10.GL_TEXTURE_2D);
}
// Load images into 6 GL textures
public void loadTexture(GL10 gl, Context c) {
gl.glGenTextures(15, textureIDs, 0); //
Generate texture-ID array for 6
// IDs
// Generate OpenGL texture images
for (int face = 0; face < numFaces;
face++) {
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[face]);
// Build Texture from loaded bit-
map for the currently-bind texture
// ID
gl.glTexParameterf(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MIN_FILTER,
GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MAG_FILTER,
479
GL10.GL_LINEAR);
GLU-
tils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap[face], 0);
bitmap[face].recycle();
}
}
}
MainActivity.java
package com.ligthing;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.Window;
import android.view.WindowManager;
public class MainActivity extends Activity {
/** The OpenGL view */
private GLSurfaceView glSurfaceView;
@Override
protected void onCreate(Bundle savedInstanceS-
tate) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
// requesting to turn the title OFF
requestWindowFeature(Window.FEATURE_NO_TITLE);
// making it full screen
getWin-
dow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREE
N,
WindowManag-
er.LayoutParams.FLAG_FULLSCREEN);
// Initiate the Open GL view and
// create an instance with this activity
glSurfaceView = new ESSurfaceView(this);
// set our renderer to be the main renderer with
// the current activity context
//glSurfaceView.setRenderer(new ESRender());
setContentView(glSurfaceView);
}
/**
* Remember to resume the glSurface
*/
@Override
protected void onResume() {
super.onResume();
480
glSurfaceView.onResume();
}
/**
* Also pause the glSurface
*/
@Override
protected void onPause() {
super.onPause();
glSurfaceView.onPause();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to
the action bar if it is present.
getMenuInflater().inflate(R.menu.main,
menu);
return true;
}
}
Maths.java
package com.ligthing; /** * @author Jim Cornmell re-edit by XTech * */ public final class Maths { /** 180 in radians. */ public static final double ONE_EIGHTY_DEGREES = Math.PI; /** 360 in radians. */ public static final double THREE_SIXTY_DEGREES = ONE_EIGHTY_DEGREES * 2; /** 120 in radians. */ public static final double ONE_TWENTY_DEGREES = THREE_SIXTY_DEGREES / 3; /** 90 degrees, North pole. */ public static final double NINETY_DEGREES = Math.PI / 2;
481
/** Used by power. */ private static final long POWER_CLAMP = 0x00000000ffffffffL; /** * Constructor, although not used at the moment. */ private Maths() { } /** * Quick integer power function. * * @param base * number to raise. * @param raise * to this power. * @return base ^ raise. */ public static int power(final int base, final int raise) { int p = 1; long b = raise & POWER_CLAMP; // bits in b correspond to values of powerN // so start with p=1, and for each set bit in b, multiply corresponding // table entry long powerN = base; while (b != 0) { if ((b & 1) != 0) { p *= powerN; } b >>>= 1; powerN = powerN * powerN; } return p; } }
482
MySphere.java
package com.ligthing;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.opengl.GLUtils;
/**
* Render a sphere.
*
* @author Jim Cornmell re-edit by XTech
* @since July 2013
*/
public class MySphere {
/** Maximum allowed depth. */
private static final int MAXIMUM_ALLOWED_DEPTH = 5;
/** Used in vertex strip calculations, related to
properties of a icosahedron. */
private static final int VERTEX_MAGIC_NUMBER = 5;
/** Each vertex is a 2D coordinate. */
private static final int NUM_FLOATS_PER_VERTEX = 3;
/** Each texture is a 2D coordinate. */
private static final int NUM_FLOATS_PER_TEXTURE = 2;
/** Each vertex is made up of 3 points, x, y, z. */
private static final int
AMOUNT_OF_NUMBERS_PER_VERTEX_POINT = 3;
/** Each texture point is made up of 2 points, x, y
(in reference to the texture being a 2D image). */
private static final int
AMOUNT_OF_NUMBERS_PER_TEXTURE_POINT = 2;
/** Buffer holding the vertices. */
private final List<FloatBuffer> mVertexBuffer = new
ArrayList<FloatBuffer>();
/** The vertices for the sphere. */
private final List<float[]> mVertices = new Ar-
rayList<float[]>();
/** Buffer holding the texture coordinates. */
private final List<FloatBuffer> mTextureBuffer = new
ArrayList<FloatBuffer>();
483
/** Mapping texture coordinates for the vertices. */
private final List<float[]> mTexture = new Ar-
rayList<float[]>();
/** The texture pointer. */
private final int[] mTextures = new int[1];
/** Total number of strips for the given depth. */
private final int mTotalNumStrips;
private int[] imageFileIDs = { // Image file IDs
R.drawable.nature,
R.drawable.mule, R.drawable.earth,
R.drawable.basketballcolor,
R.drawable.soccerballadidas,
R.drawable.ball1,R.drawable.ball2,
R.drawable.ball3,R.drawable.ball4,R.drawable.ball
5,
R.drawable.ball6,R.drawable.ball7,R.drawable.ball
8,
R.drawable.ball9,R.drawable.ballcue
};
/**
* Sphere constructor.
* @param depth integer representing the split of the
sphere.
* @param radius The spheres radius.
*/
public MySphere(final int depth, final float radius) {
// Clamp depth to the range 1 to
MAXIMUM_ALLOWED_DEPTH;
final int d = Math.max(1,
Math.min(MAXIMUM_ALLOWED_DEPTH, depth));
// Calculate basic values for the sphere.
this.mTotalNumStrips = Maths.power(2, d - 1) *
VERTEX_MAGIC_NUMBER;
final int numVerticesPerStrip = Maths.power(2, d) *
3;
final double altitudeStepAngle =
Maths.ONE_TWENTY_DEGREES / Maths.power(2, d);
final double azimuthStepAngle =
Maths.THREE_SIXTY_DEGREES / this.mTotalNumStrips;
double x, y, z, h, altitude, azimuth;
for (int stripNum = 0; stripNum <
this.mTotalNumStrips; stripNum++) {
// Setup arrays to hold the points for this strip.
final float[] vertices = new
float[numVerticesPerStrip * NUM_FLOATS_PER_VERTEX]; //
NOPMD
final float[] texturePoints = new
float[numVerticesPerStrip * NUM_FLOATS_PER_TEXTURE]; //
NOPMD
484
int vertexPos = 0;
int texturePos = 0;
// Calculate position of the first vertex in this
strip.
altitude = Maths.NINETY_DEGREES;
azimuth = stripNum * azimuthStepAngle;
// Draw the rest of this strip.
for (int vertexNum = 0; vertexNum < numVertices-
PerStrip; vertexNum += 2) {
// First point - Vertex.
y = radius * Math.sin(altitude);
h = radius * Math.cos(altitude);
z = h * Math.sin(azimuth);
x = h * Math.cos(azimuth);
vertices[vertexPos++] = (float) x;
vertices[vertexPos++] = (float) y;
vertices[vertexPos++] = (float) z;
// First point - Texture.
texturePoints[texturePos++] = (float) (1 - azi-
muth / Maths.THREE_SIXTY_DEGREES);
texturePoints[texturePos++] = (float) (1 - (al-
titude + Maths.NINETY_DEGREES) /
Maths.ONE_EIGHTY_DEGREES);
// Second point - Vertex.
altitude -= altitudeStepAngle;
azimuth -= azimuthStepAngle / 2.0;
y = radius * Math.sin(altitude);
h = radius * Math.cos(altitude);
z = h * Math.sin(azimuth);
x = h * Math.cos(azimuth);
vertices[vertexPos++] = (float) x;
vertices[vertexPos++] = (float) y;
vertices[vertexPos++] = (float) z;
// Second point - Texture.
texturePoints[texturePos++] = (float) (1 - azi-
muth / Maths.THREE_SIXTY_DEGREES);
texturePoints[texturePos++] = (float) (1 - (al-
titude + Maths.NINETY_DEGREES) /
Maths.ONE_EIGHTY_DEGREES);
azimuth += azimuthStepAngle;
}
this.mVertices.add(vertices);
this.mTexture.add(texturePoints);
ByteBuffer byteBuffer = ByteBuff-
er.allocateDirect(numVerticesPerStrip *
NUM_FLOATS_PER_VERTEX * Float.SIZE);
byteBuffer.order(ByteOrder.nativeOrder());
FloatBuffer fb = byteBuffer.asFloatBuffer();
fb.put(this.mVertices.get(stripNum));
fb.position(0);
this.mVertexBuffer.add(fb);
485
// Setup texture.
byteBuffer = ByteBuff-
er.allocateDirect(numVerticesPerStrip *
NUM_FLOATS_PER_TEXTURE * Float.SIZE);
byteBuffer.order(ByteOrder.nativeOrder());
fb = byteBuffer.asFloatBuffer();
fb.put(this.mTexture.get(stripNum));
fb.position(0);
this.mTextureBuffer.add(fb);
}
}
/**
* Load the texture for the square.
*
* @param gl Handle.
* @param context Handle.
* @param texture Texture map for the sphere.
*/
public void loadGLTexture(final GL10 gl, final Context
context, final int index_Texture) {
//public void loadGLTexture(final GL10 gl, final Con-
text context, final int texture) {
// final Bitmap bitmap = BitmapFacto-
ry.decodeResource(context.getResources(), texture);
final Bitmap bitmap = BitmapFacto-
ry.decodeStream(context.getResources()
.openRawResource(imageFileIDs[index_Texture]));
// flip method, untuk membalik texture yang kurang
sesuai
Matrix flip = new Matrix();
flip.postScale(-1f, 1f);
final Bitmap bmp = Bitmap.createBitmap(bitmap, 0, 0,
bitmap.getWidth(), bitmap.getHeight(), flip, true);
// Generate one texture pointer, and bind it to the
texture array.
gl.glGenTextures(1, this.mTextures, 0);
gl.glBindTexture(GL10.GL_TEXTURE_2D,
this.mTextures[0]);
// Create nearest filtered texture.
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);
// Use Android GLUtils to specify a two-dimensional
texture image from our bitmap.
//GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap,
0);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);
// Tidy up.
486
//bitmap.recycle();
bmp.recycle();
}
/**
* The draw method for the square with the GL context.
*
* @param gl Graphics handle.
*/
public void draw(final GL10 gl) {
//menempelkan tekstur ke objek
gl.glEnable(GL10.GL_TEXTURE_2D);
// bind the previously generated texture.
gl.glBindTexture(GL10.GL_TEXTURE_2D,
this.mTextures[0]);
// Point to our buffers.
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// Set the face rotation, clockwise in this case.
gl.glFrontFace(GL10.GL_CCW);
// Point to our vertex buffer.
for (int i = 0; i < this.mTotalNumStrips; i++) {
gl.glVertexPointer(AMOUNT_OF_NUMBERS_PER_VERTEX_POINT,
GL10.GL_FLOAT, 0, this.mVertexBuffer.get(i));
gl.glNormalPointer(GL10.GL_FLOAT, 0,
this.mVertexBuffer.get(i));
gl.glTexCoordPointer(AMOUNT_OF_NUMBERS_PER_TEXTURE_POINT
, GL10.GL_FLOAT, 0, this.mTextureBuffer.get(i));
// Draw the vertices as triangle strip.
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0,
this.mVertices.get(i).length /
AMOUNT_OF_NUMBERS_PER_VERTEX_POINT);
}
// Disable the client state before leaving.
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
gl.glDisable( GL10.GL_TEXTURE_2D ); //
Disable Texture Mapping
}
}
ObjectArena.java
package com.ligthing;
487
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLES20;
public class ObjectArena {
private float vertices[] = {
-0.5f, -0.5f, 0.0f, // V1 -
first vertex (x,y,z)
-0.5f, 0.5f, 0.0f, //
V2
0.5f, 0.5f, 0.0f, //
V3
0.5f, -0.5f, 0.0f, // V4
-0.5f, -0.5f, 0.0f //
V5
};
private float vertices_color[] = {
1.0f, 0.0f, 0.0f, 1.0f, //
CV1 - first color (red,green,blue)
0.0f, 1.0f, 0.0f, 1.0f, //
CV2
0.0f, 0.0f, 1.0f, 1.0f, //
CV3
0.0f, 1.0f, 0.0f, 1.0f, //
CV4
1.0f, 0.0f, 0.0f, 1.0f
// CV5
};
public ObjectArena() {
}
// Point to our vertex buffer, return buffer
holding the vertices
public static FloatBuffer makeFloatBuffer(float[]
arr){
ByteBuffer bb = ByteBuff-
er.allocateDirect(arr.length * 4);
bb.order(ByteOrder.nativeOrder());
FloatBuffer fb = bb.asFloatBuffer();
fb.put(arr);
fb.position(0);
return fb;
}
/** The draw method for the primitive object with
the GL context */
public void draw_kotak(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
488
// Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices));
// Draw the vertices as square
gl.glColorPointer(4, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices_color));
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
gl.glColorPointer(4, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices_color));
gl.glDrawArrays(GL10.GL_TRIANGLES, 2, 3);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}
}
ObjectBall.java
package com.ligthing;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;
import ja-
vax.microedition.khronos.opengles.GL11ExtensionPack;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLES20;
import android.opengl.GLUtils;
import android.util.Log;
public class ObjectBall {
private float vertices_circle[]={0.0f,0.0f,0.0f};
private float verti-
ces_circle_color[]={0.0f,0.0f,0.0f,0.5f};
private float textCoord[];
private float vertices_circle1[];
int[] textures_indek = new int[1];
private int batas_sudut=360;
489
float jari_jari;
float a,b;
float x,y;
float step=3.0f,step_line=0.2f;
float x1,y1;
float x2,y2;
float teta;
private int loop,loop_color;
public ObjectBall() {
// ============ start to generate stetch
texture coordinat ==========================
//Inisialisasi
jari_jari=0.5f;
// Titik Pusat
a = 0.5f; b = 0.5f ;
//x=a+jari_jari; y=b;
teta = 0;
// generate stretch texture coordinat
teta=0;
textCoord = new float[batas_sudut * 3];
for (int ii = 0; ii < batas_sudut * 3; ii
+= 3) {
// membentuk textCoord
textCoord[ii] =
(jari_jari*((float) Math.cos(-teta)))+a;
textCoord[ii + 1] =
(jari_jari*((float) Math.sin(-teta)))+b;
textCoord[ii + 2] = 0.0f;
teta += Math.PI / 90;
}
// ============ start to generate verti-
ces to circle (Cara 1) ==========================
//Inisialisasi
jari_jari=50.0f;
// Titik Pusat
a = 50.0f; b = 50.0f ;
vertices_circle1 = new float[batas_sudut
* 3];
for (int ii = 0; ii < batas_sudut * 3; ii
+= 3) {
// membentuk vertices_circle1
vertices_circle1[ii] =
(jari_jari*((float) Math.cos(teta)))+a;
vertices_circle1[ii + 1] =
(jari_jari*((float) Math.sin(teta)))+b;
vertices_circle1[ii + 2] = 0.0f;
teta += Math.PI / 90;
}
490
// ============ start to generate verti-
ces to circle (Cara 2) ==========================
//Inisialisasi
jari_jari=50.0f;
// Titik Pusat
a = 50.0f; b = 50.0f ;
x=a+jari_jari; y=b;
loop=0;
loop_color=0;
vertices_circle=new
float[(int)(3*batas_sudut/step)*3];
vertices_circle_color=new
float[(int)(3*batas_sudut/step)*4];
for(teta=0;teta<=2*batas_sudut;teta+=step){
vertices_circle[loop] = (float) ((x-
a)*Math.cos((teta/180)*(22/7)) - ((y-
b)*Math.sin((teta/180)*(22/7))) + a);
vertices_circle[loop+1] = (float) ((x-
a)*Math.sin((teta/180)*(22/7)) - ((y-
b)*Math.cos((teta/180)*(22/7))) + b);
vertices_circle[loop+2]=0;
loop+=3;
//mengenerate warna untuk setiap vertex
//vertices_circle_color[loop_color]=(float) ((x-
a)*Math.cos((teta/180)*(22/7)) - ((y-
b)*Math.sin((teta/180)*(22/7))) + a);
//vertices_circle_color[loop_color+1]=(float)
((x-a)*Math.sin((teta/180)*(22/7)) - ((y-
b)*Math.cos((teta/180)*(22/7))) + b);
vertices_circle_color[loop_color]=(float)
(Math.cos((teta/180)*(22/7)) );
verti-
ces_circle_color[loop_color+1]=(float)
(Math.sin((teta/180)*(22/7)));
vertices_circle_color[loop_color+2]=0.5f;
vertices_circle_color[loop_color+3]=0.5f;
loop_color+=4;
}
// ============= end for generate vertices to
circle ====================
}
// Point to our vertex buffer, return buffer
holding the vertices
public static FloatBuffer makeFloatBuffer(float[]
arr){
ByteBuffer bb = ByteBuff-
er.allocateDirect(arr.length * 4);
bb.order(ByteOrder.nativeOrder());
491
FloatBuffer fb = bb.asFloatBuffer();
fb.put(arr);
fb.position(0);
return fb;
}
// Setup index-array buffer. Indices in byte.
public static ByteBuffer makeByteBuffer(byte[]
arr){
ByteBuffer bb = ByteBuff-
er.allocateDirect(arr.length);
bb.put(arr);
bb.position(0);
return bb;
}
/** The draw method for the primitive object with
the GL context */
public void draw_circle(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// set the colour for the object circle
//gl.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
//create VBO from buffer with glBuffer-
Data()
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, make-
FloatBuffer(vertices_circle));
//memetakan warna untuk setiap vertex
gl.glColorPointer(4, GL10.GL_FLOAT, 0, make-
FloatBuffer(vertices_circle_color));
//draw circle as filled shape
//gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 1,
(int) ((int) 2*batas_sudut/step));
//draw circle contours
//gl.glDrawArrays(GL10.GL_LINES, 1, (int)
((int) 2*batas_sudut/step)); // membuat garis putus-
putus pada tepi lingkaran
//gl.glDrawArrays(GL10.GL_LINES, 1, (int)
((int) 2*batas_sudut/step));
gl.glDrawArrays(GL10.GL_LINE_STRIP, 1, (int)
((int) 2*batas_sudut/step));
//gl.glDrawArrays(GL10.GL_POINTS, 1, (int)
((int) 2*batas_sudut/step));
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}
492
public void draw_circle_color(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// set the colour edge for the object
circle
//gl.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
//create VBO from buffer with glBuffer-
Data()
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, make-
FloatBuffer(vertices_circle1));
//memetakan warna untuk setiap vertex
//gl.glColorPointer(4, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices_circle_color));
//menempelkan tekstur ke objek
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA,
GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tures_indek[0]); // 4
//gl.glTexCoordPointer(3, GL10.GL_FLOAT,
1, makeFloatBuffer(vertices_circle)); // 5
gl.glTexCoordPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(textCoord)); // 5
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRA
Y);
//GL11ExtensionPack gl_ = (GL11ExtensionPack)
gl;
//GL11 gl11 = (GL11) gl;
//gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tures_indek[0]);
// Set the face rotation
//gl.glFrontFace(GL10.GL_CW);
//draw circle as filled shape
//gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0,
(int) ((int) 2*batas_sudut/step));
//gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0,
(int) ((int) 2*batas_sudut/step));
gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, ba-
tas_sudut);
//gl.glDrawArrays(GL10.GL_LINE_STRIP, 0,
(int) ((int) 2*batas_sudut/step));
//gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 1,
120);
493
//Log.i("Nilai 2*batas_sudut/step : ",
""+2*batas_sudut/step);
//gl.glDrawArrays(GL10.GL_LINE_STRIP, 1,
(int) ((int) 2*batas_sudut/step));
//gl.glDrawElements(GL10.GL_TRIANGLES, (int)
((int) 2*batas_sudut/step),
// GL10.GL_UNSIGNED_SHORT, makeFloatBuff-
er(vertices_circle));
//draw circle contours
//gl.glDrawArrays(GL10.GL_LINES, 1, (int)
((int) 2*batas_sudut/step)); // membuat garis putus-
putus pada tepi lingkaran
//gl.glDrawArrays(GL10.GL_LINE_STRIP, 1,
(int) ((int) 2*batas_sudut/step));
//gl.glDrawArrays(GL10.GL_POINTS, 1, (int)
((int) 2*batas_sudut/step));
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
//gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
gl.glDisable( GL10.GL_BLEND );
// Disable Alpha Blend
gl.glDisable( GL10.GL_TEXTURE_2D );
// Disable Texture Mapping
}
public void draw_circle_color(GL10 gl,float
red_in, float green_in,float blue_in, float alpha_in) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// set the colour edge for the object
circle
gl.glColor4f(red_in, green_in, blue_in,
0.33f);
//gl.glColor4f(red_in, green_in, blue_in,
alpha_in);
//create VBO from buffer with glBuffer-
Data()
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, make-
FloatBuffer(vertices_circle1));
//memetakan warna untuk setiap vertex
//gl.glColorPointer(4, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices_circle_color));
//menempelkan tekstur ke objek
//gl.glEnable(GL10.GL_TEXTURE_2D);
//gl.glEnable(GL10.GL_BLEND);
494
//gl.glBlendFunc(GL10.GL_SRC_ALPHA,
GL10.GL_ONE_MINUS_SRC_ALPHA);
//gl.glBindTexture(GL10.GL_TEXTURE_2D,
textures_indek[0]); // 4
//gl.glTexCoordPointer(3, GL10.GL_FLOAT,
1, makeFloatBuffer(vertices_circle)); // 5
//gl.glTexCoordPointer(3, GL10.GL_FLOAT,
0, makeFloatBuffer(textCoord)); // 5
//gl.glEnableClientState(GL10.GL_TEXTURE_COORD_AR
RAY);
//GL11ExtensionPack gl_ = (GL11ExtensionPack)
gl;
//GL11 gl11 = (GL11) gl;
//gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tures_indek[0]);
// Set the face rotation
//gl.glFrontFace(GL10.GL_CW);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA,
GL10.GL_ONE_MINUS_SRC_ALPHA);
//draw circle as filled shape
//gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0,
(int) ((int) 2*batas_sudut/step));
gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0,
batas_sudut);
//gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0,
(int) ((int) 2*batas_sudut/step));
//gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0,
batas_sudut);
//gl.glDrawArrays(GL10.GL_LINE_STRIP, 0,
(int) ((int) 2*batas_sudut/step));
//gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 1,
120);
//Log.i("Nilai 2*batas_sudut/step : ",
""+2*batas_sudut/step);
//gl.glDrawArrays(GL10.GL_LINE_STRIP, 1,
(int) ((int) 2*batas_sudut/step));
//gl.glDrawElements(GL10.GL_TRIANGLES, (int)
((int) 2*batas_sudut/step),
// GL10.GL_UNSIGNED_SHORT, makeFloatBuff-
er(vertices_circle));
//draw circle contours
//gl.glDrawArrays(GL10.GL_LINES, 1, (int)
((int) 2*batas_sudut/step)); // membuat garis putus-
putus pada tepi lingkaran
//gl.glDrawArrays(GL10.GL_LINE_STRIP, 1,
495
(int) ((int) 2*batas_sudut/step));
//gl.glDrawArrays(GL10.GL_POINTS, 1, (int)
((int) 2*batas_sudut/step));
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
//gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
gl.glDisable( GL10.GL_BLEND );
// Disable Alpha Blend
//gl.glDisable( GL10.GL_TEXTURE_2D );
// Disable Texture Mapping
}
public void draw_segitiga(GL10 gl) {
gl.glFrontFace(GL10.GL_CCW); // Front
face in counter-clockwise
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// set the colour for the triangle
//gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(new float [] {
1.0f, 1.0f, 0.0f,
// V3
0.0f, 1.0f, 0.0f,
// V2
0.5f, 0.0f, 0.0f, //
V1 - first vertex (x,y,z)
}));
// Draw the vertices as triangle
//gl.glColorPointer(4, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices_color));
//menempelkan tekstur ke objek
//gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA,
GL10.GL_ONE_MINUS_SRC_ALPHA);
//gl.glEnableClientState(GL10.GL_TEXTURE_COORD_AR
RAY);
gl.glDrawArrays(GLES20.GL_TRIANGLE_STRIP,
0, 3);
//Disable the client state before leaving
496
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
//gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
gl.glDisable( GL10.GL_BLEND );
// Disable Alpha Blend
}
public void loadBallTexture(GL10 gl, Context con-
text) {
// Bitmap bitmap = BitmapFacto-
ry.decodeResource(context.getResources(),
// resource);
Bitmap bitmap = BitmapFacto-
ry.decodeStream(context.getResources()
.openRawResource(R.drawable.nature));
gl.glGenTextures(1, textures_indek, 0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tures_indek[0]);
/*gl.glTexParameterf(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MIN_FILTER,
GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MAG_FILTER,
GL10.GL_LINEAR);
*/
//gl.glTexParameterf(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE );
//gl.glTexParameterf(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE );
gl.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
gl.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
//gl.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT );
//gl.glTexParameterf(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT );
///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(GLES20.GL_TEXTURE_2D,
0, bitmap, 0);
497
bitmap.recycle();
}
}
PhotoKubus.java
package com.ligthing;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
/*
* A photo cube with 6 pictures (textures) on its 6 fac-
es.
*/
public class PhotoKubus {
private FloatBuffer vertexBuffer; // Vertex Buff-
er
private FloatBuffer texBuffer; // Texture Coords
Buffer
private int numFaces = 18;
private int[] imageFileIDs = { // Image file IDs
R.drawable.caldera, //index 0
R.drawable.candice, //index 1
R.drawable.mule, //index 2
R.drawable.glass, //index 3
R.drawable.leonardo, //index 4
R.drawable.tmsk, //index 5
R.drawable.lantai, //index 6
R.drawable.tembok, //index 7
R.drawable.tembokx, //index 8
R.drawable.atap, //index 9
R.drawable.meja,// index 10
R.drawable.imam, //index 11
R.drawable.pintux, // index 12
R.drawable.wallpaper, // index 13
R.drawable.lantai1,
R.drawable.lumut,
R.drawable.plapon,
R.drawable.anyar
};
private int[] textureIDs = new int[numFaces];
private Bitmap[] bitmap = new Bitmap[numFaces];
private float cubeHalfSize = 1.0f;
// Constructor - Set up the vertex buffer
public PhotoKubus(Context context) {
// Allocate vertex buffer. An float has 4
bytes
498
ByteBuffer vbb = ByteBuff-
er.allocateDirect(12 * 4 * numFaces);
vbb.order(ByteOrder.nativeOrder());
vertexBuffer = vbb.asFloatBuffer();
// Read images. Find the aspect ratio and
adjust the vertices
// accordingly.
for (int face = 0; face < numFaces;
face++) {
bitmap[face] = BitmapFacto-
ry.decodeStream(context.getResources()
.openRawResource(imageFileIDs[face]));
int imgWidth = bit-
map[face].getWidth();
int imgHeight = bit-
map[face].getHeight();
float faceWidth = 2.0f;
float faceHeight = 2.0f;
// Adjust for aspect ratio
if (imgWidth > imgHeight) {
faceHeight = faceHeight *
imgHeight / imgWidth;
} else {
faceWidth = faceWidth *
imgWidth / imgHeight;
}
float faceLeft = -faceWidth / 2;
float faceRight = -faceLeft;
float faceTop = faceHeight / 2;
float faceBottom = -faceTop;
// Define the vertices for this
face
// float[] vertices = { faceLeft, fa-
ceBottom, 0.0f, // 0.
//
// left-bottom-front
// faceRight, faceBot-
tom, 0.0f, // 1. right-bottom-front
// faceLeft, faceTop,
0.0f, // 2. left-top-front
// faceRight, faceTop,
0.0f, // 3. right-top-front
// };
float[] vertices = { // Vertices
for a face
-2.0f, -1.0f, 0.0f,
// 0. left-bottom-front
2.0f, -1.0f, 0.0f, // 1. right-bottom-front
-
2.0f, 1.0f, 0.0f, // 2. left-top-front
499
2.0f, 1.0f, 0.0f // 3. right-top-front
};
vertexBuffer.put(vertices); //
Populate
}
vertexBuffer.position(0); // Rewind
// Allocate texture buffer. An float has
4 bytes. Repeat for 6 faces.
float[] texCoords = {
0.0f, 1.0f, // A. left-
bottom
1.0f, 1.0f, // B. right-
bottom
0.0f, 0.0f, // C. left-top
1.0f, 0.0f // D. right-top
};
ByteBuffer tbb = ByteBuff-
er.allocateDirect(texCoords.length * 4
* numFaces);
tbb.order(ByteOrder.nativeOrder());
texBuffer = tbb.asFloatBuffer();
for (int face = 0; face < numFaces;
face++) {
texBuffer.put(texCoords);
}
texBuffer.position(0); // Rewind
}
// Render the shape (Buat lantai)
public void draw(GL10 gl) {
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glFrontFace(GL10.GL_CCW);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRA
Y);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0,
texBuffer);
// lantai
gl.glPushMatrix();
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[14]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARR
AY);
gl.glDisable(GL10.GL_TEXTURE_2D);
}
500
// Render the shape (Buat tembok belakang)
public void draw_tembok_blk(GL10 gl) {
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glFrontFace(GL10.GL_CCW);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRA
Y);
gl.glVertexPointer(3,
GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2,
GL10.GL_FLOAT, 0, texBuffer);
// tembok
gl.glPushMatrix();
gl.glTranslatef(0f, 0f,
cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[17]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glPopMatrix();
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARR
AY);
gl.glDisable(GL10.GL_TEXTURE_2D);
}
// Render the shape (Buat tembok samping)
public void draw_tembok_smp(GL10 gl) {
gl.glFrontFace(GL10.GL_CCW);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRA
Y);
gl.glVertexPointer(3,
GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2,
GL10.GL_FLOAT, 0, texBuffer);
// tembok
gl.glPushMatrix();
gl.glTranslatef(0f, 0f,
cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[17]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glPopMatrix();
501
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARR
AY);
}
// Render the shape (Buat atap)
public void draw_atap(GL10 gl) {
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glFrontFace(GL10.GL_CCW);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRA
Y);
gl.glVertexPointer(3,
GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2,
GL10.GL_FLOAT, 0, texBuffer);
// atap
gl.glPushMatrix();
gl.glTranslatef(0f, 0f,
cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[16]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glPopMatrix();
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARR
AY);
gl.glDisable(GL10.GL_TEXTURE_2D);
}
public void draw_meja(GL10 gl) {
gl.glFrontFace(GL10.GL_CCW);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRA
Y);
gl.glVertexPointer(3,
GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2,
GL10.GL_FLOAT, 0, texBuffer);
// meja
gl.glPushMatrix();
502
gl.glTranslatef(0f, 0f,
cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[10]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glPopMatrix();
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARR
AY);
}
// buat kaki meja
public void draw_kaki_meja(GL10 gl) {
gl.glFrontFace(GL10.GL_CCW);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRA
Y);
gl.glVertexPointer(3,
GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2,
GL10.GL_FLOAT, 0, texBuffer);
// kaki meja meja
gl.glPushMatrix();
gl.glTranslatef(0f, 0f,
cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[10]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glPopMatrix();
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARR
AY);
}
// Load images into 6 GL textures
public void loadTexture(GL10 gl, Context c) {
gl.glGenTextures(18, textureIDs, 0); //
Generate texture-ID array for 6
// IDs
// Generate OpenGL texture images
for (int face = 0; face < numFaces;
face++) {
503
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[face]);
// Build Texture from loaded bit-
map for the currently-bind texture
// ID
gl.glTexParameterf(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MIN_FILTER,
GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MAG_FILTER,
GL10.GL_LINEAR);
GLU-
tils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap[face], 0);
bitmap[face].recycle();
}
}
}
pintu.java
package com.ligthing;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
/*
* A photo cube with 6 pictures (textures) on its 6 fac-
es.
*/
public class pintu {
private FloatBuffer vertexBuffer; // Vertex Buff-
er
private FloatBuffer texBuffer; // Texture Coords
Buffer
private int numFaces = 14;
private int[] imageFileIDs = { // Image file IDs
R.drawable.caldera, //index 0
R.drawable.pintuku, //index 1
R.drawable.mule, //index 2
R.drawable.glass, //index 3
R.drawable.leonardo, //index 4
R.drawable.tmsk, //index 5
R.drawable.lantai, //index 6
R.drawable.tembok, //index 7
R.drawable.tembokx, //index 8
R.drawable.atap, //index 9
504
R.drawable.meja,// index 10
R.drawable.imam, //index 11
R.drawable.pintux, // index 12
R.drawable.wallpaper // index 13
};
private int[] textureIDs = new int[numFaces];
private Bitmap[] bitmap = new Bitmap[numFaces];
private float cubeHalfSize = 1.0f;
// Constructor - Set up the vertex buffer
public pintu(Context context) {
// Allocate vertex buffer. An float has 4
bytes
ByteBuffer vbb = ByteBuff-
er.allocateDirect(12 * 4 * numFaces);
vbb.order(ByteOrder.nativeOrder());
vertexBuffer = vbb.asFloatBuffer();
// Read images. Find the aspect ratio and
adjust the vertices
// accordingly.
for (int face = 0; face < numFaces;
face++) {
bitmap[face] = BitmapFacto-
ry.decodeStream(context.getResources()
.openRawResource(imageFileIDs[face]));
int imgWidth = bit-
map[face].getWidth();
int imgHeight = bit-
map[face].getHeight();
float faceWidth = 2.0f;
float faceHeight = 2.0f;
// Adjust for aspect ratio
if (imgWidth > imgHeight) {
faceHeight = faceHeight *
imgHeight / imgWidth;
} else {
faceWidth = faceWidth *
imgWidth / imgHeight;
}
float faceLeft = -faceWidth / 2;
float faceRight = -faceLeft;
float faceTop = faceHeight / 2;
float faceBottom = -faceTop;
float[] vertices = { // Vertices
for a face
-1.0f, -1.0f, 0.0f,
// 0. left-bottom-front
1.0f, -1.0f, 0.0f, // 1. right-bottom-front
-
1.0f, 1.0f, 0.0f, // 2. left-top-front
505
1.0f, 1.0f, 0.0f // 3. right-top-front
};
vertexBuffer.put(vertices); //
Populate
}
vertexBuffer.position(0); // Rewind
// Allocate texture buffer. An float has
4 bytes. Repeat for 6 faces.
float[] texCoords = {
0.0f, 1.0f, // A. left-
bottom
1.0f, 1.0f, // B. right-
bottom
0.0f, 0.0f, // C. left-top
1.0f, 0.0f // D. right-top
};
ByteBuffer tbb = ByteBuff-
er.allocateDirect(texCoords.length * 4
* numFaces);
tbb.order(ByteOrder.nativeOrder());
texBuffer = tbb.asFloatBuffer();
for (int face = 0; face < numFaces;
face++) {
texBuffer.put(texCoords);
}
texBuffer.position(0); // Rewind
}
// Render the shape (Buat PINTU)
public void draw_pintu(GL10 gl) {
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glFrontFace(GL10.GL_CCW);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRA
Y);
gl.glVertexPointer(3,
GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2,
GL10.GL_FLOAT, 0, texBuffer);
// tembok
gl.glPushMatrix();
gl.glTranslatef(0f, 0f,
cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[1]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glPopMatrix();
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARR
AY);
506
gl.glDisable(GL10.GL_TEXTURE_2D);
}
// Load images into 6 GL textures
public void loadTexture(GL10 gl, Context c) {
gl.glGenTextures(14, textureIDs, 0); //
Generate texture-ID array for 6
// IDs
// Generate OpenGL texture images
for (int face = 0; face < numFaces;
face++) {
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[face]);
// Build Texture from loaded bit-
map for the currently-bind texture
// ID
gl.glTexParameterf(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MIN_FILTER,
GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MAG_FILTER,
GL10.GL_LINEAR);
GLU-
tils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap[face], 0);
bitmap[face].recycle();
}
}
}
PrimitivesObject.java
package com.ligthing;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLES20;
public class PrimitivesObject {
private float vertices[] = { -0.5f, -0.5f, 0.0f,
// V1 - first vertex
//
(x,y,z)
-0.5f, 0.5f, 0.0f, // V2
0.5f, 0.5f, 0.0f, // V3
0.5f, -0.5f, 0.0f, // V4
507
-0.5f, -0.5f, 0.0f // V5
};
private float[] vertices_quad = { // Vertices for
the square
-1.0f, -1.0f, 0.0f, // 0. left-bottom
1.0f, -1.0f, 0.0f, // 1. right-
bottom
-1.0f, 1.0f, 0.0f, // 2. left-top
1.0f, 1.0f, 0.0f // 3. right-top
};
private float vertices_color[] = { 1.0f, 0.0f,
0.0f, 1.0f, // CV1 - first
// color
// (red,green,blue)
0.0f, 1.0f, 0.0f, 1.0f, // CV2
0.0f, 0.0f, 1.0f, 1.0f, // CV3
0.0f, 1.0f, 0.0f, 1.0f, // CV4
1.0f, 0.0f, 0.0f, 1.0f // CV5
};
private float vertices_circle[] = { 0.0f, 0.0f,
0.0f };
private float vertices_circle_color[] = { 0.0f,
0.0f, 0.0f, 0.5f };
private float vertices_line[] = { 0.0f, 0.0f,
0.0f };
private float vertices_line_color[] = { 0.0f,
0.0f, 0.0f, 1.0f };
private int batas_sudut = 360;
float jari_jari;
float a, b;
float x, y;
float step = 3.0f, step_line = 0.2f;
float x1, y1;
float x2, y2;
private int loop, loop_color, loop_line,
loop_line_color;
public PrimitivesObject() {
// ============ start to generate verti-
ces to circle
// ==========================
// Inisialisasi
jari_jari = 1.0f;
// Titik Pusat
a = 0.0f;
b = 0.0f;
x = a + jari_jari;
y = b;
loop = 3;
508
loop_color = 4;
vertices_circle = new float[(int) (3 *
batas_sudut / step) * 3];
vertices_circle_color = new float[(int)
(3 * batas_sudut / step) * 4];
for (float teta = 0; teta <= 2 * ba-
tas_sudut; teta += step) {
vertices_circle[loop] = (float)
((x - a)
* Math.cos((teta /
180) * (22 / 7))
- ((y - b) *
Math.sin((teta / 180) * (22 / 7))) + a);
vertices_circle[loop + 1] =
(float) ((x - a)
* Math.sin((teta /
180) * (22 / 7))
- ((y - b) *
Math.cos((teta / 180) * (22 / 7))) + b);
vertices_circle[loop + 2] = 0;
loop += 3;
// mengenerate warna untuk setiap
vertex
vertices_circle_color[loop_color]
= (float) ((x - a)
* Math.cos((teta /
180) * (22 / 7))
- ((y - b) *
Math.sin((teta / 180) * (22 / 7))) + a);
vertices_circle_color[loop_color +
1] = (float) ((x - a)
* Math.sin((teta /
180) * (22 / 7))
- ((y - b) *
Math.cos((teta / 180) * (22 / 7))) + b);
vertices_circle_color[loop_color +
2] = 0.5f;
vertices_circle_color[loop_color +
3] = 0.5f;
loop_color += 4;
}
// ============= end for generate verti-
ces to circle
// ====================
// ============ start to generate verti-
ces to line
// ==========================
x1 = -1.0f;
y1 = -1.0f;
x2 = 1.0f;
y2 = 1.0f;
loop_line = 3;
loop_line_color = 4;
vertices_line = new float[(int) (2 * (x2
- x1) / step_line) * 3];
vertices_line_color = new float[(int) (2
509
* (x2 - x1) / step_line) * 4];
float m = (y2 - y1) / (x2 - x1);
for (x = x1; x <= x2; x += step_line) {
vertices_line[loop_line] = (float)
(x);
vertices_line[loop_line + 1] =
(float) (m * (x - x1) + y1);
vertices_line[loop_line + 2] = 0;
loop_line += 3;
// mengenerate warna untuk setiap
vertex
verti-
ces_line_color[loop_line_color] = (float) (0.5 * x);
verti-
ces_line_color[loop_line_color + 1] = (float) (0.5 * m
* (x - x1) + y1);
verti-
ces_line_color[loop_line_color + 2] = 1.0f;
verti-
ces_line_color[loop_line_color + 3] = 1.0f;
loop_line_color += 4;
}
// ============= end for generate verti-
ces to line ====================
}
// Point to our vertex buffer, return buffer
holding the vertices
public static FloatBuffer makeFloatBuffer(float[]
arr) {
ByteBuffer bb = ByteBuff-
er.allocateDirect(arr.length * 4);
bb.order(ByteOrder.nativeOrder());
FloatBuffer fb = bb.asFloatBuffer();
fb.put(arr);
fb.position(0);
return fb;
}
/** The draw method for the primitive object with
the GL context */
public void draw_points(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// set the colour for the points (pem-
berian warna untuk titik)
gl.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
// Point to our vertex buffer (mendata
nilai lokasi/posisi titik)
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(new float[] {
1.0f, 1.0f, 0.0f, // V1 -
510
first vertex (x,y,z)
1.0f, 0.8f, 0.0f, // V2
1.0f, 0.6f, 0.0f, // V3
1.0f, 0.4f, 0.0f, // V4
1.0f, 0.2f, 0.0f, // V5
1.0f, 0.0f, 0.0f, // V6
1.0f, -0.2f, 0.0f, // V7
1.0f, -0.4f, 0.0f, // V8
1.0f, -0.6f, 0.0f, // V9
1.0f, -0.8f, 0.0f, // V10
1.0f, -1.0f, 0.0f, // V11
0.8f, -1.0f, 0.0f, // V12
0.6f, -1.0f, 0.0f, // V13
0.4f, -1.0f, 0.0f, // V14
0.2f, -1.0f, 0.0f, // V15
0.0f, -1.0f, 0.0f, // V16
-0.2f, -1.0f, 0.0f, // V17
-0.4f, -1.0f, 0.0f, // V18
-0.6f, -1.0f, 0.0f, // V19
-0.7f, -1.0f, 0.0f, // V20
-0.8f, -1.0f, 0.0f, // V21
-1.0f, -1.0f, 0.0f, // V22
}));
// Draw the vertices as points (menggam-
bar titik-titik)
gl.glDrawArrays(GL10.GL_POINTS, 0, 22);
// Disable the client state before leav-
ing
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
//
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}
public void draw_line(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// set the colour for the line (pemberian
warna untuk garis)
gl.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
// Point to our vertex buffer (mendata
nilai lokasi/posisi titik yang
// menyusun garis)
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(new float[] {
1.0f, 1.0f, 0.0f, // V1 -
first vertex (x,y,z)
-1.0f, -1.0f, 0.0f, // V2
- second vertex
}));
511
// Draw the vertices as lines (menggambar
garis dari titik-titik)
gl.glDrawArrays(GL10.GL_LINES, 0, 2);
/*
* gl.glDrawElements(GL10.GL_LINES, 2,
GL10.GL_UNSIGNED_SHORT,
* makeFloatBuffer(new float [] { 1.0f,
1.0f, 0.0f, // V1 - first vertex
* (x,y,z) -1.0f, -1.0f, 0.0f, // V2 -
second vertex }));
*/
// Disable the client state before leav-
ing
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
//
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}
public void draw_line_color(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// set the colour for the line (pemberian
warna untuk garis)
gl.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
// Point to our vertex buffer (mendata
nilai lokasi/posisi titik yang
// menyusun garis)
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices_line));
// memetakan warna untuk setiap vertex
gl.glColorPointer(4, GL10.GL_FLOAT, 0,
makeFloatBuff-
er(vertices_line_color));
// Draw the vertices as lines (menggambar
garis dari titik-titik)
gl.glDrawArrays(GL10.GL_LINE_STRIP, 0,
(int) (2 * (x2 - x1) /
step_line));
/*
* gl.glDrawElements(GL10.GL_LINES, 2,
GL10.GL_UNSIGNED_SHORT,
* makeFloatBuffer(new float [] { 1.0f,
1.0f, 0.0f, // V1 - first vertex
* (x,y,z) -1.0f, -1.0f, 0.0f, // V2 -
second vertex }));
*/
// Disable the client state before leav-
512
ing
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}
public void draw_circle(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// set the colour for the object circle
gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
// create VBO from buffer with glBuffer-
Data()
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuff-
er(vertices_circle));
// draw circle as filled shape
// gl.glDrawArrays(GL10.GL_TRIANGLE_FAN,
1, (int) ((int)
// 2*batas_sudut/step));
// draw circle contours
// gl.glDrawArrays(GL10.GL_LINES, 1,
(int) ((int) 2*batas_sudut/step));
// // membuat garis putus-putus pada tepi
lingkaran
gl.glDrawArrays(GL10.GL_LINES, 1, (int)
((int) 2 * batas_sudut / step));
// gl.glDrawArrays(GL10.GL_LINE_STRIP, 1,
(int) ((int)
// 2*batas_sudut/step));
// gl.glDrawArrays(GL10.GL_POINTS, 1,
(int) ((int) 2*batas_sudut/step));
// Disable the client state before leav-
ing
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
//
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}
public void draw_circle_color(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// set the colour edge for the object
circle
gl.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
513
// create VBO from buffer with glBuffer-
Data()
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuff-
er(vertices_circle));
// memetakan warna untuk setiap vertex
gl.glColorPointer(4, GL10.GL_FLOAT, 0,
makeFloatBuff-
er(vertices_circle_color));
// draw circle as filled shape
// gl.glDrawArrays(GL10.GL_TRIANGLE_FAN,
1, (int) ((int)
// 2*batas_sudut/step));
gl.glDrawArrays(GL10.GL_LINE_STRIP, 1,
(int) ((int) 2 * ba-
tas_sudut / step));
// Disable the client state before leav-
ing
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}
public void draw_kotak(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices));
// Draw the vertices as square
gl.glColorPointer(4, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices_color));
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
gl.glColorPointer(4, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices_color));
gl.glDrawArrays(GL10.GL_TRIANGLES, 2, 3);
// Disable the client state before leav-
ing
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}
public void draw_segitiga(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
514
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// set the colour for the triangle
gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(new float[] {
-0.5f, -0.5f, 0.0f, // V1
- first vertex (x,y,z)
0.5f, -0.5f, 0.0f, // V2 -
second vertex
0.0f, 0.5f, 0.0f // V3 -
third vertex
}));
// Draw the vertices as triangle
gl.glColorPointer(4, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices_color));
gl.glDrawArrays(GLES20.GL_TRIANGLES, 0,
3);
// Disable the client state before leav-
ing
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}
// Render the shape quad
public void draw_quad(GL10 gl) {
// Enable vertex-array and define its
buffer
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices_quad));
// Draw the primitives from the vertex-
array directly
gl.glPolygonOffset(0.0f, 1.0f);
gl.glScalef(0.5f, 0.5f, 0.5f);
gl.glColor4f(0.5f, 0.5f, 1.0f, 1.0f); //
Set the current color (NEW)
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, vertices_quad.length / 3);
//gl.glDrawArrays(GL10.GL_TRIANGLES, 0,
vertices_quad.length / 3);
//gl.glDrawArrays(GL10.GL_LINES, 0, ver-
tices_quad.length / 3);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
}
515
SpriteBatch.java
package com.ligthing;
import android.util.FloatMath;
import javax.microedition.khronos.opengles.GL10;
public class SpriteBatch {
//--Constants--//
final static int VERTEX_SIZE = 4; //
Vertex Size (in Components) ie. (X,Y,U,V)
final static int VERTICES_PER_SPRITE = 4; //
Vertices Per Sprite
final static int INDICES_PER_SPRITE = 6; //
Indices Per Sprite
//--Members--//
GL10 gl; //
GL Instance
Vertices vertices; //
Vertices Instance Used for Rendering
float[] vertexBuffer; //
Vertex Buffer
int bufferIndex; //
Vertex Buffer Start Index
int maxSprites; //
Maximum Sprites Allowed in Buffer
int numSprites; //
Number of Sprites Currently in Buffer
//--Constructor--//
// D: prepare the sprite batcher for specified maxi-
mum number of sprites
// A: gl - the gl instance to use for rendering
// maxSprites - the maximum allowed sprites per
batch
public SpriteBatch(GL10 gl, int maxSprites) {
this.gl = gl; //
Save GL Instance
this.vertexBuffer = new float[maxSprites *
VERTICES_PER_SPRITE * VERTEX_SIZE]; // Create Vertex
Buffer
this.vertices = new Vertices( gl, maxSprites *
VERTICES_PER_SPRITE, maxSprites * INDICES_PER_SPRITE,
false, true, false ); // Create Rendering Vertices
this.bufferIndex = 0; //
Reset Buffer Index
this.maxSprites = maxSprites; //
Save Maximum Sprites
this.numSprites = 0; //
Clear Sprite Counter
short[] indices = new short[maxSprites *
INDICES_PER_SPRITE]; // Create Temp Index Buffer
int len = indices.length; //
Get Index Buffer Length
516
short j = 0; //
Counter
for ( int i = 0; i < len; i+= INDICES_PER_SPRITE,
j += VERTICES_PER_SPRITE ) { // FOR Each Index Set
(Per Sprite)
indices[i + 0] = (short)( j + 0 ); //
Calculate Index 0
indices[i + 1] = (short)( j + 1 ); //
Calculate Index 1
indices[i + 2] = (short)( j + 2 ); //
Calculate Index 2
indices[i + 3] = (short)( j + 2 ); //
Calculate Index 3
indices[i + 4] = (short)( j + 3 ); //
Calculate Index 4
indices[i + 5] = (short)( j + 0 ); //
Calculate Index 5
}
vertices.setIndices( indices, 0, len ); //
Set Index Buffer for Rendering
}
//--Begin Batch--//
// D: signal the start of a batch. set the texture
and clear buffer
// NOTE: the overloaded (non-texture) version as-
sumes that the texture is already bound!
// A: textureId - the ID of the texture to use for
the batch
// R: [none]
public void beginBatch(int textureId) {
gl.glBindTexture( GL10.GL_TEXTURE_2D, textureId );
// Bind the Texture
numSprites = 0; //
Empty Sprite Counter
bufferIndex = 0; //
Reset Buffer Index (Empty)
}
public void beginBatch() {
numSprites = 0; //
Empty Sprite Counter
bufferIndex = 0; //
Reset Buffer Index (Empty)
}
//--End Batch--//
// D: signal the end of a batch. render the batched
sprites
// A: [none]
// R: [none]
public void endBatch() {
if ( numSprites > 0 ) { //
IF Any Sprites to Render
vertices.setVertices( vertexBuffer, 0, buffer-
Index ); // Set Vertices from Buffer
vertices.bind(); //
Bind Vertices
vertices.draw( GL10.GL_TRIANGLES, 0, numSprites
* INDICES_PER_SPRITE ); // Render Batched Sprites
517
vertices.unbind(); //
Unbind Vertices
}
}
//--Draw Sprite to Batch--//
// D: batch specified sprite to batch. adds vertices
for sprite to vertex buffer
// NOTE: MUST be called after beginBatch(), and
before endBatch()!
// NOTE: if the batch overflows, this will render
the current batch, restart it,
// and then batch this sprite.
// A: x, y - the x,y position of the sprite (center)
// width, height - the width and height of the
sprite
// region - the texture region to use for sprite
// R: [none]
public void drawSprite(float x, float y, float width,
float height, TextureRegion region) {
if ( numSprites == maxSprites ) { //
IF Sprite Buffer is Full
endBatch(); //
End Batch
// NOTE: leave current texture bound!!
numSprites = 0; //
Empty Sprite Counter
bufferIndex = 0; //
Reset Buffer Index (Empty)
}
float halfWidth = width / 2.0f; //
Calculate Half Width
float halfHeight = height / 2.0f; //
Calculate Half Height
float x1 = x - halfWidth; //
Calculate Left X
float y1 = y - halfHeight; //
Calculate Bottom Y
float x2 = x + halfWidth; //
Calculate Right X
float y2 = y + halfHeight; //
Calculate Top Y
vertexBuffer[bufferIndex++] = x1; //
Add X for Vertex 0
vertexBuffer[bufferIndex++] = y1; //
Add Y for Vertex 0
vertexBuffer[bufferIndex++] = region.u1; //
Add U for Vertex 0
vertexBuffer[bufferIndex++] = region.v2; //
Add V for Vertex 0
vertexBuffer[bufferIndex++] = x2; //
Add X for Vertex 1
vertexBuffer[bufferIndex++] = y1; //
Add Y for Vertex 1
vertexBuffer[bufferIndex++] = region.u2; //
Add U for Vertex 1
518
vertexBuffer[bufferIndex++] = region.v2; //
Add V for Vertex 1
vertexBuffer[bufferIndex++] = x2; //
Add X for Vertex 2
vertexBuffer[bufferIndex++] = y2; //
Add Y for Vertex 2
vertexBuffer[bufferIndex++] = region.u2; //
Add U for Vertex 2
vertexBuffer[bufferIndex++] = region.v1; //
Add V for Vertex 2
vertexBuffer[bufferIndex++] = x1; //
Add X for Vertex 3
vertexBuffer[bufferIndex++] = y2; //
Add Y for Vertex 3
vertexBuffer[bufferIndex++] = region.u1; //
Add U for Vertex 3
vertexBuffer[bufferIndex++] = region.v1; //
Add V for Vertex 3
numSprites++; //
Increment Sprite Count
}
}
TextureKubus.java
package com.ligthing;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
/*
* A photo cube with 6 pictures (textures) on its 6 fac-
es.
*/
public class TextureKubus {
private FloatBuffer vertexBuffer; // Vertex Buff-
er
private FloatBuffer texBuffer; // Texture Coords
Buffer
private int numFaces = 15;
private int[] imageFileIDs = { // Image file IDs
R.drawable.caldera, // index 0
R.drawable.candice, // index 1
R.drawable.mule, // index 2
R.drawable.glass, // index 3
R.drawable.leonardo, // index 4
R.drawable.tmsk, // index 5
519
R.drawable.lantai, // index 6
R.drawable.tembok, // index 7
R.drawable.anyar, // index 8
R.drawable.atap, // index 9
R.drawable.meja,// index 10
R.drawable.imam, // index 11
R.drawable.pintux, // index 12
R.drawable.wallpaper, // index 13
R.drawable.lumut
};
private int[] textureIDs = new int[numFaces];
private Bitmap[] bitmap = new Bitmap[numFaces];
private float cubeHalfSize = 1.0f;
// Constructor - Set up the vertex buffer
public TextureKubus(Context context) {
// Allocate vertex buffer. An float has 4
bytes
ByteBuffer vbb = ByteBuff-
er.allocateDirect(12 * 4 * numFaces);
vbb.order(ByteOrder.nativeOrder());
vertexBuffer = vbb.asFloatBuffer();
// Read images. Find the aspect ratio and
adjust the vertices
// accordingly.
for (int face = 0; face < numFaces;
face++) {
bitmap[face] = BitmapFacto-
ry.decodeStream(context.getResources()
.openRawResource(imageFileIDs[face]));
int imgWidth = bit-
map[face].getWidth();
int imgHeight = bit-
map[face].getHeight();
float faceWidth = 2.0f;
float faceHeight = 2.0f;
// Adjust for aspect ratio
if (imgWidth > imgHeight) {
faceHeight = faceHeight *
imgHeight / imgWidth;
} else {
faceWidth = faceWidth *
imgWidth / imgHeight;
}
float faceLeft = -faceWidth / 2;
float faceRight = -faceLeft;
float faceTop = faceHeight / 2;
float faceBottom = -faceTop;
// Define the vertices for this
face
// float[] vertices = { faceLeft,
faceBottom, 0.0f, // 0.
// // left-bottom-front
// faceRight, faceBottom, 0.0f, //
520
1. right-bottom-front
// faceLeft, faceTop, 0.0f, // 2.
left-top-front
// faceRight, faceTop, 0.0f, // 3.
right-top-front
// };
float[] vertices = { // Vertices
for a face
-1.0f, -1.0f, 0.0f, // 0. left-
bottom-front
1.0f, -1.0f, 0.0f,
// 1. right-bottom-front
-1.0f, 1.0f, 0.0f,
// 2. left-top-front
1.0f, 1.0f, 0.0f //
3. right-top-front
};
vertexBuffer.put(vertices); //
Populate
}
vertexBuffer.position(0); // Rewind
// Allocate texture buffer. An float has
4 bytes. Repeat for 6 faces.
float[] texCoords = { 0.0f, 1.0f, // A.
left-bottom
1.0f, 1.0f, // B. right-
bottom
0.0f, 0.0f, // C. left-top
1.0f, 0.0f // D. right-top
};
ByteBuffer tbb = ByteBuff-
er.allocateDirect(texCoords.length * 4
* numFaces);
tbb.order(ByteOrder.nativeOrder());
texBuffer = tbb.asFloatBuffer();
for (int face = 0; face < numFaces;
face++) {
texBuffer.put(texCoords);
}
texBuffer.position(0); // Rewind
}
// Render the shape (Buat lantai)
public void draw(GL10 gl) {
gl.glFrontFace(GL10.GL_CCW);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRA
Y);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0,
texBuffer);
// lantai
gl.glPushMatrix();
gl.glRotatef(90, 1.0f, 0.0f, 0.0f);
gl.glTranslatef(0f, 0f, cubeHalfSize);
521
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[6]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARR
AY);
}
// Render the shape (Buat tembok belakang)
public void draw_tembok_blk(GL10 gl) {
gl.glFrontFace(GL10.GL_CCW);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRA
Y);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0,
texBuffer);
// tembok
gl.glPushMatrix();
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[7]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARR
AY);
}
// Render the shape (Buat tembok samping)
public void draw_tembok_smp(GL10 gl) {
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glFrontFace(GL10.GL_CCW);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRA
Y);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0,
texBuffer);
522
// tembok
gl.glPushMatrix();
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[8]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARR
AY);
gl.glDisable(GL10.GL_TEXTURE_2D);
}
// Render the shape (Buat atap)
public void draw_atap(GL10 gl) {
gl.glFrontFace(GL10.GL_CCW);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRA
Y);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0,
texBuffer);
// tembok
gl.glPushMatrix();
gl.glTranslatef(0f, 0f, cubeHalfSize);
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
tureIDs[14]);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,
0, 4);
gl.glPopMatrix();
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARR
AY);
}
// Load images into 6 GL textures
public void loadTexture(GL10 gl, Context c) {
gl.glGenTextures(15, textureIDs, 0); //
Generate texture-ID array for 6
// IDs
// Generate OpenGL texture images
for (int face = 0; face < numFaces;
face++) {
gl.glBindTexture(GL10.GL_TEXTURE_2D, tex-
523
tureIDs[face]);
// Build Texture from loaded bit-
map for the currently-bind texture
// ID
gl.glTexParameterf(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MIN_FILTER,
GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,
GL10.GL_TEXTURE_MAG_FILTER,
GL10.GL_LINEAR);
GLU-
tils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap[face], 0);
bitmap[face].recycle();
}
}
}
TextureRegion.java
package com.ligthing; class TextureRegion { //--Members--// public float u1, v1; // Top/Left U,V Coordinates public float u2, v2; // Bottom/Right U,V Coordinates //--Constructor--// // D: calculate U,V coordinates from specified texture coordinates // A: texWidth, texHeight - the width and height of the texture the region is for // x, y - the top/left (x,y) of the region on the texture (in pixels) // width, height - the width and height of the region on the texture (in pixels) public TextureRegion(float texWidth, float texHeight, float x, float y, float width, float height) { this.u1 = x / texWidth; // Calculate U1 this.v1 = y / texHeight;
524
// Calculate V1 this.u2 = this.u1 + ( width / texWidth ); // Calculate U2 this.v2 = this.v1 + ( height / texHeight ); // Calculate V2 } }
TransObject.java
package com.ligthing;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLES20;
public class TransObject {
private float vertices[] = {
-0.5f, -0.5f, 0.0f, // V1 -
first vertex (x,y,z)
-0.5f, 0.5f, 0.0f, //
V2
0.5f, 0.5f, 0.0f, //
V3
0.5f, -0.5f, 0.0f, // V4
-0.5f, -0.5f, 0.0f //
V5
};
private float vertices_color[] = {
1.0f, 0.0f, 0.0f, 1.0f, //
CV1 - first color (red,green,blue)
0.0f, 1.0f, 0.0f, 1.0f, //
CV2
0.0f, 0.0f, 1.0f, 1.0f, //
CV3
0.0f, 1.0f, 0.0f, 1.0f, //
CV4
1.0f, 0.0f, 0.0f, 1.0f
// CV5
};
// list vertices kubus
private float vertices_kubus[]= {
0.0f,0.0f,1.0f,
1.0f,0.0f,1.0f,
0.0f,1.0f,1.0f,
1.0f,1.0f,1.0f,
0.0f,0.0f,0.0f,
1.0f,0.0f,0.0f,
525
0.0f,1.0f,0.0f,
1.0f,1.0f,0.0f
};
// list color (kombinasi angka nol dan satu)
private float colors_kubus[] = {
0.0f,0.0f,0.0f,1.0f,
1.0f,0.0f,0.0f,1.0f,
1.0f,1.0f,0.0f,1.0f,
0.0f,1.0f,0.0f,1.0f,
0.0f,0.0f,1.0f,1.0f,
1.0f,0.0f,1.0f,1.0f,
1.0f,1.0f,1.0f,1.0f,
0.0f,1.0f,1.0f,1.0f
};
private byte[] indices_kubus = {
0,1,3, // depan 1
3,2,0, // depan 2
4,5,7, // belakang 1
7,6,4, // belakang 2
2,3,7, // atas 1
7,6,2, // atas 2
0,1,5, // bawah 1
5,4,0, // bawah 2
1,5,7, // kanan 1
7,3,1, // kanan 2
0,4,6, // kiri 1
6,4,0, // kiri 2
0,2,6, // kiri 3
6,2,0 // kiri 4
};
private byte[] indices_kubus2 = { // Vertex indi-
ces of the 6 kotak
0,1,3, // depan 1
3,2,0, // depan 2
4,5,7, // belakang 1
7,6,4, // belakang 2
2,3,7, // atas 1
7,6,2, // atas 2
0,1,5, // bawah 1
5,4,0, // bawah 2
1,5,7, // kanan 1
7,3,1, // kanan 2
0,4,6, // kiri 1
6,2,0, // kiri 3
526
4,6,2,
2,0,4
};
private ByteBuffer mIndexBuffer; // Buffer for
index-array
private float vertices_circle[]={0.0f,0.0f,0.0f};
private float verti-
ces_circle_color[]={0.0f,0.0f,0.0f,0.5f};
private float vertices_line[]={0.0f,0.0f,0.0f};
private float verti-
ces_line_color[]={0.0f,0.0f,0.0f,1.0f};
private int batas_sudut=360;
float jari_jari;
float a,b;
float x,y;
float step=3.0f,step_line=0.2f;
float x1,y1;
float x2,y2;
private int
loop,loop_color,loop_line,loop_line_color;
public TransObject() {
// ============ start to generate verti-
ces to circle ==========================
//Inisialisasi
jari_jari=1.0f;
// Titik Pusat
a = 0.0f; b = 0.0f ;
x=a+jari_jari; y=b;
loop=3;
loop_color=4;
vertices_circle=new
float[(int)(3*batas_sudut/step)*3];
vertices_circle_color=new
float[(int)(3*batas_sudut/step)*4];
for(float
teta=0;teta<=2*batas_sudut;teta+=step){
vertices_circle[loop] = (float) ((x-
a)*Math.cos((teta/180)*(22/7)) - ((y-
b)*Math.sin((teta/180)*(22/7))) + a);
vertices_circle[loop+1] = (float) ((x-
a)*Math.sin((teta/180)*(22/7)) - ((y-
b)*Math.cos((teta/180)*(22/7))) + b);
vertices_circle[loop+2]=0;
loop+=3;
//mengenerate warna untuk setiap vertex
vertices_circle_color[loop_color]=(float)
((x-a)*Math.cos((teta/180)*(22/7)) - ((y-
b)*Math.sin((teta/180)*(22/7))) + a);
verti-
ces_circle_color[loop_color+1]=(float) ((x-
a)*Math.sin((teta/180)*(22/7)) - ((y-
527
b)*Math.cos((teta/180)*(22/7))) + b);
vertices_circle_color[loop_color+2]=0.5f;
vertices_circle_color[loop_color+3]=0.5f;
loop_color+=4;
}
// ============= end for generate vertices to
circle ====================
// ============ start to generate vertices to
line ==========================
x1 = -1.0f; y1 = -1.0f;
x2= 1.0f; y2 = 1.0f;
loop_line=3;
loop_line_color=4;
vertices_line=new float[(int)(2*(x2-
x1)/step_line)*3];
vertices_line_color=new float[(int)(2*(x2-
x1)/step_line)*4];
float m = (y2-y1)/(x2-x1);
for(x=x1;x<=x2;x+=step_line){
vertices_line[loop_line] = (float) (x);
vertices_line[loop_line+1] = (float)
(m*(x-x1)+y1);
vertices_line[loop_line+2]=0;
loop_line+=3;
//mengenerate warna untuk setiap vertex
verti-
ces_line_color[loop_line_color]=(float) (0.5*x);
verti-
ces_line_color[loop_line_color+1]=(float) (0.5*m*(x-
x1)+y1);
verti-
ces_line_color[loop_line_color+2]=1.0f;
verti-
ces_line_color[loop_line_color+3]=1.0f;
loop_line_color+=4;
}
// ============= end for generate vertices to
line ====================
}
// Point to our vertex buffer, return buffer
holding the vertices
public static FloatBuffer makeFloatBuffer(float[]
arr){
ByteBuffer bb = ByteBuff-
er.allocateDirect(arr.length * 4);
bb.order(ByteOrder.nativeOrder());
FloatBuffer fb = bb.asFloatBuffer();
fb.put(arr);
fb.position(0);
return fb;
}
// Setup index-array buffer. Indices in byte.
528
public static ByteBuffer makeByteBuffer(byte[]
arr){
ByteBuffer bb = ByteBuff-
er.allocateDirect(arr.length);
bb.put(arr);
bb.position(0);
return bb;
}
/** The draw method for the primitive object with
the GL context */
public void draw_kubus(GL10 gl) {
gl.glFrontFace(GL10.GL_CCW); // Front
face in counter-clockwise
// orientation
// Enable arrays and define their buffers
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices_kubus));
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
gl.glColorPointer(4, GL10.GL_FLOAT, 0,
makeFloatBuffer(colors_kubus));
gl.glDrawElements(GL10.GL_TRIANGLES, in-
dices_kubus.length,
GL10.GL_UNSIGNED_BYTE,
makeByteBuffer(indices_kubus));
//gl.glDrawElements(GL10.GL_LINE_STRIP,
indices_kubus2.length,
//GL10.GL_UNSIGNED_BYTE,
makeByteBuffer(indices_kubus2));
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}
public void draw_points(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// set the colour for the points (pem-
berian warna untuk titik)
gl.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
// Point to our vertex buffer (mendata
nilai lokasi/posisi titik)
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(new float [] {
1.0f, 1.0f, 0.0f,
// V1 - first vertex (x,y,z)
1.0f, 0.8f, 0.0f,
// V2
529
1.0f, 0.6f, 0.0f,
// V3
1.0f, 0.4f, 0.0f,
// V4
1.0f, 0.2f, 0.0f,
// V5
1.0f, 0.0f, 0.0f,
// V6
1.0f, -0.2f, 0.0f,
// V7
1.0f, -0.4f, 0.0f,
// V8
1.0f, -0.6f, 0.0f,
// V9
1.0f, -0.8f, 0.0f,
// V10
1.0f, -1.0f, 0.0f,
// V11
0.8f, -1.0f, 0.0f,
// V12
0.6f, -1.0f, 0.0f,
// V13
0.4f, -1.0f, 0.0f,
// V14
0.2f, -1.0f, 0.0f,
// V15
0.0f, -1.0f, 0.0f,
// V16
-0.2f, -1.0f, 0.0f, //
V17
-0.4f, -1.0f, 0.0f, //
V18
-0.6f, -1.0f, 0.0f, //
V19
-0.7f, -1.0f, 0.0f, //
V20
-0.8f, -1.0f, 0.0f, //
V21
-1.0f, -1.0f, 0.0f, //
V22
}));
// Draw the vertices as points (menggam-
bar titik-titik)
gl.glDrawArrays(GL10.GL_POINTS, 0, 22);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
//gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}
public void draw_line(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
530
//gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// set the colour for the line (pemberian
warna untuk garis)
gl.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
// Point to our vertex buffer (mendata
nilai lokasi/posisi titik yang menyusun garis)
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(new float [] {
1.0f, 1.0f, 0.0f,
// V1 - first vertex (x,y,z)
-1.0f, -1.0f, 0.0f, //
V2 - second vertex
}));
// Draw the vertices as lines (menggambar
garis dari titik-titik)
gl.glDrawArrays(GL10.GL_LINES, 0, 2);
/*gl.glDrawElements(GL10.GL_LINES, 2,
GL10.GL_UNSIGNED_SHORT, makeFloatBuffer(new
float [] {
1.0f, 1.0f, 0.0f,
// V1 - first vertex (x,y,z)
-1.0f, -1.0f, 0.0f, //
V2 - second vertex
}));*/
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
//gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}
public void draw_line_color(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// set the colour for the line (pemberian
warna untuk garis)
gl.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
// Point to our vertex buffer (mendata
nilai lokasi/posisi titik yang menyusun garis)
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices_line));
//memetakan warna untuk setiap vertex
gl.glColorPointer(4, GL10.GL_FLOAT, 0, make-
FloatBuffer(vertices_line_color));
// Draw the vertices as lines (menggambar
garis dari titik-titik)
gl.glDrawArrays(GL10.GL_LINE_STRIP, 0,
531
(int) (2*(x2-x1)/step_line));
/*gl.glDrawElements(GL10.GL_LINES, 2,
GL10.GL_UNSIGNED_SHORT, makeFloatBuffer(new
float [] {
1.0f, 1.0f, 0.0f,
// V1 - first vertex (x,y,z)
-1.0f, -1.0f, 0.0f, //
V2 - second vertex
}));*/
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}
public void draw_circle(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// set the colour for the object circle
gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
//create VBO from buffer with glBuffer-
Data()
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, make-
FloatBuffer(vertices_circle));
//draw circle as filled shape
//gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 1,
(int) ((int) 2*batas_sudut/step));
//draw circle contours
//gl.glDrawArrays(GL10.GL_LINES, 1, (int)
((int) 2*batas_sudut/step)); // membuat garis putus-
putus pada tepi lingkaran
gl.glDrawArrays(GL10.GL_LINES, 1, (int)
((int) 2*batas_sudut/step));
//gl.glDrawArrays(GL10.GL_LINE_STRIP, 1,
(int) ((int) 2*batas_sudut/step));
//gl.glDrawArrays(GL10.GL_POINTS, 1, (int)
((int) 2*batas_sudut/step));
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
//gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}
public void draw_circle_color(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
532
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// set the colour edge for the object
circle
gl.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
//create VBO from buffer with glBuffer-
Data()
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, make-
FloatBuffer(vertices_circle));
//memetakan warna untuk setiap vertex
gl.glColorPointer(4, GL10.GL_FLOAT, 0, make-
FloatBuffer(vertices_circle_color));
//draw circle as filled shape
gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 1,
(int) ((int) 2*batas_sudut/step));
//gl.glDrawArrays(GL10.GL_LINE_STRIP, 1,
(int) ((int) 2*batas_sudut/step));
//gl.glDrawElements(GL10.GL_TRIANGLES, (int)
((int) 2*batas_sudut/step),
// GL10.GL_UNSIGNED_SHORT, makeFloatBuff-
er(vertices_circle));
//draw circle contours
//gl.glDrawArrays(GL10.GL_LINES, 1, (int)
((int) 2*batas_sudut/step)); // membuat garis putus-
putus pada tepi lingkaran
//gl.glDrawArrays(GL10.GL_LINE_STRIP, 1,
(int) ((int) 2*batas_sudut/step));
//gl.glDrawArrays(GL10.GL_POINTS, 1, (int)
((int) 2*batas_sudut/step));
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}
public void draw_kotak(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices));
// Draw the vertices as square
gl.glColorPointer(4, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices_color));
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
533
gl.glColorPointer(4, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices_color));
gl.glDrawArrays(GL10.GL_TRIANGLES, 2, 3);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}
public void draw_segitiga(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
// set the colour for the triangle
gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,
makeFloatBuffer(new float [] {
-0.5f, -0.5f, 0.0f, //
V1 - first vertex (x,y,z)
0.5f, -0.5f, 0.0f, //
V2 - second vertex
0.0f, 0.5f, 0.0f
// V3 - third vertex
}));
// Draw the vertices as triangle
gl.glColorPointer(4, GL10.GL_FLOAT, 0,
makeFloatBuffer(vertices_color));
gl.glDrawArrays(GLES20.GL_TRIANGLES, 0,
3);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}
}
Vertices.java
package com.ligthing;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
534
import javax.microedition.khronos.opengles.GL10;
public class Vertices {
//--Constants--//
final static int POSITION_CNT_2D = 2; //
Number of Components in Vertex Position for 2D
final static int POSITION_CNT_3D = 3; //
Number of Components in Vertex Position for 3D
final static int COLOR_CNT = 4; //
Number of Components in Vertex Color
final static int TEXCOORD_CNT = 2; //
Number of Components in Vertex Texture Coords
final static int NORMAL_CNT = 3; //
Number of Components in Vertex Normal
final static int INDEX_SIZE = Short.SIZE / 8; //
Index Byte Size (Short.SIZE = bits)
//--Members--//
// NOTE: all members are constant, and initialized in
constructor!
final GL10 gl; //
GL Instance
final boolean hasColor; //
Use Color in Vertices
final boolean hasTexCoords; //
Use Texture Coords in Vertices
final boolean hasNormals; //
Use Normals in Vertices
public final int positionCnt; //
Number of Position Components (2=2D, 3=3D)
public final int vertexStride; //
Vertex Stride (Element Size of a Single Vertex)
public final int vertexSize; //
Bytesize of a Single Vertex
final IntBuffer vertices; //
Vertex Buffer
final ShortBuffer indices; //
Index Buffer
public int numVertices; //
Number of Vertices in Buffer
public int numIndices; //
Number of Indices in Buffer
final int[] tmpBuffer; //
Temp Buffer for Vertex Conversion
//--Constructor--//
// D: create the vertices/indices as specified (for
2d/3d)
// A: gl - the gl instance to use
// maxVertices - maximum vertices allowed in buff-
er
// maxIndices - maximum indices allowed in buffer
// hasColor - use color values in vertices
// hasTexCoords - use texture coordinates in ver-
tices
// hasNormals - use normals in vertices
535
// use3D - (false, default) use 2d positions (ie.
x/y only)
// (true) use 3d positions (ie. x/y/z)
public Vertices(GL10 gl, int maxVertices, int max-
Indices, boolean hasColor, boolean hasTexCoords, boolean
hasNormals) {
this( gl, maxVertices, maxIndices, hasColor, hasT-
exCoords, hasNormals, false ); // Call Overloaded Con-
structor
}
public Vertices(GL10 gl, int maxVertices, int max-
Indices, boolean hasColor, boolean hasTexCoords, boolean
hasNormals, boolean use3D) {
this.gl = gl; //
Save GL Instance
this.hasColor = hasColor; //
Save Color Flag
this.hasTexCoords = hasTexCoords; //
Save Texture Coords Flag
this.hasNormals = hasNormals; //
Save Normals Flag
this.positionCnt = use3D ? POSITION_CNT_3D :
POSITION_CNT_2D; // Set Position Component Count
this.vertexStride = this.positionCnt + ( hasColor
? COLOR_CNT : 0 ) + ( hasTexCoords ? TEXCOORD_CNT : 0 )
+ ( hasNormals ? NORMAL_CNT : 0 ); // Calculate Vertex
Stride
this.vertexSize = this.vertexStride * 4; //
Calculate Vertex Byte Size
ByteBuffer buffer = ByteBuffer.allocateDirect(
maxVertices * vertexSize ); // Allocate Buffer for Ver-
tices (Max)
buffer.order( ByteOrder.nativeOrder() ); //
Set Native Byte Order
this.vertices = buffer.asIntBuffer(); //
Save Vertex Buffer
if ( maxIndices > 0 ) { //
IF Indices Required
buffer = ByteBuffer.allocateDirect( maxIndices
* INDEX_SIZE ); // Allocate Buffer for Indices (MAX)
buffer.order( ByteOrder.nativeOrder() ); //
Set Native Byte Order
this.indices = buffer.asShortBuffer(); //
Save Index Buffer
}
else //
ELSE Indices Not Required
indices = null; //
No Index Buffer
numVertices = 0; //
Zero Vertices in Buffer
numIndices = 0; //
Zero Indices in Buffer
this.tmpBuffer = new int[maxVertices * vertexSize
/ 4]; // Create Temp Buffer
536
}
//--Set Vertices--//
// D: set the specified vertices in the vertex buffer
// NOTE: optimized to use integer buffer!
// A: vertices - array of vertices (floats) to set
// offset - offset to first vertex in array
// length - number of floats in the vertex array
(total)
// for easy setting use: vtx_cnt *
(this.vertexSize / 4)
// R: [none]
public void setVertices(float[] vertices, int offset,
int length) {
this.vertices.clear(); //
Remove Existing Vertices
int last = offset + length; //
Calculate Last Element
for ( int i = offset, j = 0; i < last; i++, j++ )
// FOR Each Specified Vertex
tmpBuffer[j] = Float.floatToRawIntBits( verti-
ces[i] ); // Set Vertex as Raw Integer Bits in Buffer
this.vertices.put( tmpBuffer, 0, length ); //
Set New Vertices
this.vertices.flip(); //
Flip Vertex Buffer
this.numVertices = length / this.vertexStride; //
Save Number of Vertices
//this.numVertices = length / ( this.vertexSize /
4 ); // Save Number of Vertices
}
//--Set Indices--//
// D: set the specified indices in the index buffer
// A: indices - array of indices (shorts) to set
// offset - offset to first index in array
// length - number of indices in array (from off-
set)
// R: [none]
public void setIndices(short[] indices, int offset,
int length) {
this.indices.clear(); //
Clear Existing Indices
this.indices.put( indices, offset, length ); //
Set New Indices
this.indices.flip(); //
Flip Index Buffer
this.numIndices = length; //
Save Number of Indices
}
//--Bind--//
// D: perform all required binding/state changes be-
fore rendering batches.
// USAGE: call once before calling draw() multiple
times for this buffer.
// A: [none]
// R: [none]
public void bind() {
537
gl.glEnableClientState( GL10.GL_VERTEX_ARRAY ); //
Enable Position in Vertices
vertices.position( 0 ); //
Set Vertex Buffer to Position
gl.glVertexPointer( positionCnt, GL10.GL_FLOAT,
vertexSize, vertices ); // Set Vertex Pointer
if ( hasColor ) { //
IF Vertices Have Color
gl.glEnableClientState( GL10.GL_COLOR_ARRAY );
// Enable Color in Vertices
vertices.position( positionCnt ); //
Set Vertex Buffer to Color
gl.glColorPointer( COLOR_CNT, GL10.GL_FLOAT,
vertexSize, vertices ); // Set Color Pointer
}
if ( hasTexCoords ) { //
IF Vertices Have Texture Coords
gl.glEnableClientState(
GL10.GL_TEXTURE_COORD_ARRAY ); // Enable Texture Coords
in Vertices
vertices.position( positionCnt + ( hasColor ?
COLOR_CNT : 0 ) ); // Set Vertex Buffer to Texture
Coords (NOTE: position based on whether color is also
specified)
gl.glTexCoordPointer( TEXCOORD_CNT,
GL10.GL_FLOAT, vertexSize, vertices ); // Set Texture
Coords Pointer
}
if ( hasNormals ) {
gl.glEnableClientState( GL10.GL_NORMAL_ARRAY );
// Enable Normals in Vertices
vertices.position( positionCnt + ( hasColor ?
COLOR_CNT : 0 ) + ( hasTexCoords ? TEXCOORD_CNT : 0 ) );
// Set Vertex Buffer to Normals (NOTE: position based on
whether color/texcoords is also specified)
gl.glNormalPointer( GL10.GL_FLOAT, vertexSize,
vertices ); // Set Normals Pointer
}
}
//--Draw--//
// D: draw the currently bound vertices in the ver-
tex/index buffers
// USAGE: can only be called after calling bind()
for this buffer.
// A: primitiveType - the type of primitive to draw
// offset - the offset in the vertex/index buffer
to start at
// numVertices - the number of vertices (indices)
to draw
// R: [none]
public void draw(int primitiveType, int offset, int
numVertices) {
if ( indices != null ) { //
IF Indices Exist
indices.position( offset ); //
538
Set Index Buffer to Specified Offset
gl.glDrawElements( primitiveType, numVertices,
GL10.GL_UNSIGNED_SHORT, indices ); // Draw Indexed
}
else { //
ELSE No Indices Exist
gl.glDrawArrays( primitiveType, offset, numVer-
tices ); // Draw Direct (Array)
}
}
//--Unbind--//
// D: clear binding states when done rendering batch-
es.
// USAGE: call once before calling draw() multiple
times for this buffer.
// A: [none]
// R: [none]
public void unbind() {
if ( hasColor ) //
IF Vertices Have Color
gl.glDisableClientState( GL10.GL_COLOR_ARRAY );
// Clear Color State
if ( hasTexCoords ) //
IF Vertices Have Texture Coords
gl.glDisableClientState(
GL10.GL_TEXTURE_COORD_ARRAY ); // Clear Texture Coords
State
if ( hasNormals ) //
IF Vertices Have Normals
gl.glDisableClientState( GL10.GL_NORMAL_ARRAY
); // Clear Normals State
}
//--Draw Full--//
// D: draw the vertices in the vertex/index buffers
// NOTE: unoptimized version! use
bind()/draw()/unbind() for batches
// A: primitiveType - the type of primitive to draw
// offset - the offset in the vertex/index buffer
to start at
// numVertices - the number of vertices (indices)
to draw
// R: [none]
public void drawFull(int primitiveType, int offset,
int numVertices) {
gl.glEnableClientState( GL10.GL_VERTEX_ARRAY ); //
Enable Position in Vertices
vertices.position( 0 ); //
Set Vertex Buffer to Position
gl.glVertexPointer( positionCnt, GL10.GL_FLOAT,
vertexSize, vertices ); // Set Vertex Pointer
if ( hasColor ) { //
IF Vertices Have Color
gl.glEnableClientState( GL10.GL_COLOR_ARRAY );
// Enable Color in Vertices
539
vertices.position( positionCnt ); //
Set Vertex Buffer to Color
gl.glColorPointer( COLOR_CNT, GL10.GL_FLOAT,
vertexSize, vertices ); // Set Color Pointer
}
if ( hasTexCoords ) { //
IF Vertices Have Texture Coords
gl.glEnableClientState(
GL10.GL_TEXTURE_COORD_ARRAY ); // Enable Texture Coords
in Vertices
vertices.position( positionCnt + ( hasColor ?
COLOR_CNT : 0 ) ); // Set Vertex Buffer to Texture
Coords (NOTE: position based on whether color is also
specified)
gl.glTexCoordPointer( TEXCOORD_CNT,
GL10.GL_FLOAT, vertexSize, vertices ); // Set Texture
Coords Pointer
}
if ( indices != null ) { //
IF Indices Exist
indices.position( offset ); //
Set Index Buffer to Specified Offset
gl.glDrawElements( primitiveType, numVertices,
GL10.GL_UNSIGNED_SHORT, indices ); // Draw Indexed
}
else { //
ELSE No Indices Exist
gl.glDrawArrays( primitiveType, offset, numVer-
tices ); // Draw Direct (Array)
}
if ( hasTexCoords ) //
IF Vertices Have Texture Coords
gl.glDisableClientState(
GL10.GL_TEXTURE_COORD_ARRAY ); // Clear Texture Coords
State
if ( hasColor ) //
IF Vertices Have Color
gl.glDisableClientState( GL10.GL_COLOR_ARRAY );
// Clear Color State
}
//--Set Vertex Elements--//
// D: use these methods to alter the values (posi-
tion, color, textcoords, normals) for vertices
// WARNING: these do NOT validate any values, en-
sure that the index AND specified
// elements EXIST before using!!
// A: x, y, z - the x,y,z position to set in buffer
// r, g, b, a - the r,g,b,a color to set in buffer
// u, v - the u,v texture coords to set in buffer
// nx, ny, nz - the x,y,z normal to set in buffer
// R: [none]
void setVtxPosition(int vtxIdx, float x, float y) {
int index = vtxIdx * vertexStride; //
Calculate Actual Index
540
vertices.put( index + 0, Float.floatToRawIntBits(
x ) ); // Set X
vertices.put( index + 1, Float.floatToRawIntBits(
y ) ); // Set Y
}
void setVtxPosition(int vtxIdx, float x, float y,
float z) {
int index = vtxIdx * vertexStride; //
Calculate Actual Index
vertices.put( index + 0, Float.floatToRawIntBits(
x ) ); // Set X
vertices.put( index + 1, Float.floatToRawIntBits(
y ) ); // Set Y
vertices.put( index + 2, Float.floatToRawIntBits(
z ) ); // Set Z
}
void setVtxColor(int vtxIdx, float r, float g, float
b, float a) {
int index = ( vtxIdx * vertexStride ) + posi-
tionCnt; // Calculate Actual Index
vertices.put( index + 0, Float.floatToRawIntBits(
r ) ); // Set Red
vertices.put( index + 1, Float.floatToRawIntBits(
g ) ); // Set Green
vertices.put( index + 2, Float.floatToRawIntBits(
b ) ); // Set Blue
vertices.put( index + 3, Float.floatToRawIntBits(
a ) ); // Set Alpha
}
void setVtxColor(int vtxIdx, float r, float g, float
b) {
int index = ( vtxIdx * vertexStride ) + posi-
tionCnt; // Calculate Actual Index
vertices.put( index + 0, Float.floatToRawIntBits(
r ) ); // Set Red
vertices.put( index + 1, Float.floatToRawIntBits(
g ) ); // Set Green
vertices.put( index + 2, Float.floatToRawIntBits(
b ) ); // Set Blue
}
void setVtxColor(int vtxIdx, float a) {
int index = ( vtxIdx * vertexStride ) + posi-
tionCnt; // Calculate Actual Index
vertices.put( index + 3, Float.floatToRawIntBits(
a ) ); // Set Alpha
}
void setVtxTexCoords(int vtxIdx, float u, float v) {
int index = ( vtxIdx * vertexStride ) + posi-
tionCnt + ( hasColor ? COLOR_CNT : 0 ); // Calculate
Actual Index
vertices.put( index + 0, Float.floatToRawIntBits(
u ) ); // Set U
vertices.put( index + 1, Float.floatToRawIntBits(
v ) ); // Set V
}
void setVtxNormal(int vtxIdx, float x, float y, float
z) {
int index = ( vtxIdx * vertexStride ) + posi-
tionCnt + ( hasColor ? COLOR_CNT : 0 ) + ( hasTexCoords
541
? TEXCOORD_CNT : 0 ); // Calculate Actual Index
vertices.put( index + 0, Float.floatToRawIntBits(
x ) ); // Set X
vertices.put( index + 1, Float.floatToRawIntBits(
y ) ); // Set Y
vertices.put( index + 2, Float.floatToRawIntBits(
z ) ); // Set Z
}
}
Gambar 7.3 Lighting Pada Interior
542
BAB 8 Model Loading & Curve
8.1 Pengertian Model Loading & Curve
Untuk membuat model, kita biasanya membuat dari awal. Tentu hali itu sangatlah merepotkan. Untuk itu diperkenalkan metode model loading, Model Loading merupakan teknik untuk loading/memuat dan merender sebuah gambar dengan format tertentu menggunakan OpenGL tanpa library gambar khusus dan juga termasuk kode yang dibutuhkan untuk melakukan loading data mentah dari gambar
Untuk model loading, kita biasanya akan menggunakan format file OBJ, yang keduanya sangat sederhana dan sangat umum. Dan sekali lagi, untuk menjaga kesederhanaan, kita hanya akan berurusan dengan file OBJ yang memiliki 1 UV dan 1 Normal.
• Beberapa Software untuk pembuatan model 3D :
– Autodesk 3ds Max, Maya
– Blender
– SketchUp
– Cinema4D
Gambar 8.1 Pembuatan Model 3D
Gambar 8.2 Aplikasi Blender
543
Macam OpenGL Model Loading
3DS Loader
MD2 Loader
OBJ Loader
PLY Loader
RAW Loader
8.2 Model Creator
Berikut adalah beberapa software yang digunakan untuk pem-buatan model 3D:
1. Autodesk 3ds Max Sebelumnya lebih dikenal dengan sebutan 3D Studio Max. Soft-ware ini dikembangkan oleh Autodesk Media and Entertainment. Software ini popular digunakan karena dapat digunakan pada platform Microsoft Windows, kemampuan mengedit yang serba bisa, dan arsitektur plugin yang banyak.
2. Maya Software ini dibuat oleh Alias Systems Corporation yang kemudi-an diakuisisi oleh Autodesk, Inc. Maya digunakan dalam industry film dan TV, juga untuk permainan video computer. Kelebihan dari program ini adalah proses pembuatan animasi yang relatif lebih mudah dibandingkan perangkat 3D lainnya.
3. Blender Blender merupakan software grafis 3D yang gratis dan popular di kalangan desainer. Selain dapat digunakan untuk membuat ani-masi 3D, software ini juga memiliki fitur untuk membuat per-mainan. Blender tersedia untuk berbagai sistem operasi, seperti Microsoft Windows, Mac OS X, Linux, IRIX, Solaris, NetBSD, FreeBSD, dan OpenBSD. Software ini berlisensi GPL dan sum-bernya tersedia secara bebas dan dapat diambil siapa saja.
4. SketchUp Sebelumnya dikenal dengan Google Sketchup, merupakan soft-ware untuk membuat bentuk-bentuk arsitektural, desain interior, teknik sipil dan mesin, film, serta desain video game. Software ini memiliki dua versi. Versi freeware bernama SketchUp Make, dan versi berbayar merupakan SketchUp Pro. Software ini diklaim mudah digunakan.
5. Cinema4D Software ini dikembangkan oleh MAXON Computer GmbH.
544
8.3 Model Loading
Source Code 8.1 Code Model Loading
SplashActivity.java
package min3d.sampleProject1;
import android.app.ListActivity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.text.util.Linkify;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import an-
droid.widget.AdapterView.AdapterContextMenuInfo;
/**
* Main menu activity
*
* @author Lee
*/
public class SplashActivity extends ListActivity
{
private final int CONTEXTID_VIEWFILE = 0;
private final int CONTEXTID_CANCEL = 1;
private String _baseSourcePath =
"http://code.google.com/p/min3d/source/browse/trunk/samp
lePro-
jects/min3dSampleProject1/src/min3d/sampleProject1/";
class ItemVo
{
public String filename;
public Class<?> cls;
public String label;
public ItemVo(String $label, Class<?>
$class, String $filename)
{
label = $label;
cls = $class;
filename = $filename;
}
}
private ItemVo[] _items = {
// new ItemVo("\"Hello, Jupiter\"",
ExampleRotatingPlanets.class, "ExampleRotatingPlan-
ets.java"),
545
// new ItemVo("Minimal example", Ex-
ampleMostMinimal.class, "ExampleMostMinimal.java"),
// new ItemVo("Vertex colors", Ex-
ampleVertexColors.class, "ExampleVertexColors.java"),
// new ItemVo("Texture", ExampleTex-
tures.class, "ExampleTextures.java"),
// new ItemVo("Usage of Vertices
class", ExampleVerticesVariations.class, "ExampleVerti-
cesVariations.java"),
// new ItemVo("Triangles, lines,
points", ExampleRenderType.class, "ExampleRender-
Type.java"),
// new ItemVo("Camera, frustum
(trackball)", ExampleCamera.class, "ExampleCam-
era.java"),
// new ItemVo("Multiple lights", Ex-
ampleMultipleLights.class, "ExampleMultiple-
Lights.java"),
// new ItemVo("Animating vertices",
ExampleAnimatingVertices.class, "ExampleAnimatingVerti-
ces.java"),
// new ItemVo("Rendering subset of
faces", ExampleSubsetOfFaces.class, "ExampleSubsetOfFac-
es.java"),
// new ItemVo("Assigning textures dy-
namically", ExampleAssigningTexturesDynamically.class,
"ExampleAssigningTexturesDynamically.java"),
// new ItemVo("MIP Mapping (on vs.
off)", ExampleMipMap.class, "ExampleMipMap.java"),
// new ItemVo("Texture wrapping", Ex-
ampleTextureWrap.class, "ExampleTextureWrap.java"),
// new ItemVo("Multiple textures",
ExampleMultiTexture.class, "ExampleMultiTexture.java"),
// new ItemVo("Texture offset", Exam-
pleTextureOffset.class, "ExampleTextureOffset.java"),
// new ItemVo("3D inside layout", Ex-
ampleInsideLayout.class, "ExampleInsideLayout.java"),
// new ItemVo("Fog Example", Example-
Fog.class, "ExampleFog.java"),
// new ItemVo("Transparent GL Sur-
face", ExampleTransparentGlSurface.class, "Transparen-
tActivity.java"),
// new ItemVo("Load model from .obj
file", ExampleLoadObjFile.class, "Example-
LoadObjFile.java"),
// new ItemVo("Load multiple models
from .obj file", ExampleLoadObjFileMultiple.class, "Ex-
ampleLoadObjFileMultiple.java"),
// new ItemVo("Load model from .3ds
file", ExampleLoad3DSFile.class, "Example-
Load3DSFile.java"),
// new ItemVo("Load animated .md2
file", ExampleLoadMD2File.class, "Example-
LoadMD2File.java"),
// new ItemVo("Keyframe animation",
ExampleKeyframeAnimation.class, "ExampleKeyframeAnima-
tion.java"),
// new ItemVo("Using the accelerome-
ter", ExampleAccelerometer.class, "ExampleAccelerome-
546
ter.java")
// new ItemVo("Tugas 3 GrafKom", Ex-
ampleAccelerometer.class, "ExampleAccelerometer.java"),
new ItemVo("Tugas 3 GrafKom", tu-
gas.class, "tugas.java")
};
@Override
public void onCreate(Bundle savedInstanceState)
{
String[] strings = new String[_items.length];
for (int i = 0; i < _items.length; i++) {
strings[i] = _items[i].label;
}
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_activity);
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, strings));
TextView tv = (TextView)
this.findViewById(R.id.splashTitle);
Linkify.addLinks(tv, 0x07);
registerForContextMenu(getListView());
// TEST ONLY:
// this.startActivity( new Intent(this, Exam-
pleTransparentGlSurface.class ) );
}
@Override
public void onListItemClick(ListView parent, View v,
int position, long id)
{
this.startActivity( new Intent(this,
_items[position].cls ) );
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
super.onCreateOptionsMenu(menu);
int i = 0;
menu.add(0, 0, i++, "project home");
menu.add(0, 1, i++, "author blog");
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
Intent i;
switch (item.getItemId())
{
case 0:
i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(
this.getResources().getString(R.string.projectUrl) ));
startActivity(i);
return true;
case 1:
i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(
547
this.getResources().getString(R.string.myBlogUrl) ));
startActivity(i);
return true;
}
return false;
}
@Override
public void onCreateContextMenu(ContextMenu menu,
View v, ContextMenuInfo menuInfo)
{
super.onCreateContextMenu(menu, v, menu-
Info);
menu.add(0, CONTEXTID_VIEWFILE, 0, "View
source on Google Code");
menu.add(0, CONTEXTID_CANCEL, 0, "Can-
cel");
}
@Override
public boolean onContextItemSelected(MenuItem
item)
{
AdapterContextMenuInfo info = (Adapter-
ContextMenuInfo) item.getMenuInfo();
switch (item.getItemId())
{
case CONTEXTID_VIEWFILE:
Intent i = new In-
tent(Intent.ACTION_VIEW);
String url = _baseSourcePath + _items[
(int)info.id ].filename;
i.setData(Uri.parse(url));
startActivity(i);
return true;
case CONTEXTID_CANCEL:
// do nothing
return true;
default:
return su-
per.onContextItemSelected(item);
}
}
}
tugas.java
package com.ligthing;
package min3d.sampleProject1;
import min3d.core.Object3dContainer;
import min3d.core.RendererActivity;
import min3d.objectPrimitives.SkyBox;
import min3d.parser.IParser;
import min3d.parser.Parser;
import min3d.vos.Light;
import min3d.vos.Number3d;
import android.content.pm.ActivityInfo;
import android.hardware.Sensor;
548
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
public class tugas extends RendererActivity {
// private final float FILTERING_FACTOR = .3f;
private SkyBox mSkyBox;
private SensorManager mSensorManager;
private Sensor mAccelerometer;
private Number3d mAccVals;
private Object3dContainer monster;
private Object3dContainer pokemon;
// @Override
// public void onCreate(Bundle savedInstanceS-
tate) {
// super.onCreate(savedInstanceState);
// setRequestedOrienta-
tion(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
// mSensorManager = (SensorManager) getSystem-
Service(SENSOR_SERVICE);
// mAccelerometer =
// mSensorManag-
er.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
// mAccVals = new Number3d();
// }
public void initScene() {
scene.lights().add(new Light());
mSkyBox = new SkyBox(5.0f, 2);
// mSkyBox.addTexture(SkyBox.Face.North,
R.drawable.wood_back, "north");
// mSkyBox.addTexture(SkyBox.Face.East,
R.drawable.wood_right, "east");
// mSkyBox.addTexture(SkyBox.Face.South,
R.drawable.wood_back, "south");
// mSkyBox.addTexture(SkyBox.Face.West,
R.drawable.wood_left, "west");
// mSkyBox.addTexture(SkyBox.Face.Up,
R.drawable.ceiling, "up");
// mSkyBox.addTexture(SkyBox.Face.Down,
R.drawable.floor, "down");
mSkyBox.addTexture(SkyBox.Face.North,
R.drawable.gambar_latar, "north");
mSkyBox.addTexture(SkyBox.Face.East,
R.drawable.gambar_latar, "east");
mSkyBox.addTexture(SkyBox.Face.South,
R.drawable.gambar_latar, "south");
mSkyBox.addTexture(SkyBox.Face.West,
R.drawable.gambar_latar, "west");
mSkyBox.addTexture(SkyBox.Face.Up,
R.drawable.malam, "up");
mSkyBox.addTexture(SkyBox.Face.Down,
R.drawable.tanah, "down");
// mSkyBox.scale().y = 0.8f;
// mSkyBox.scale().z = 2.0f;
549
mSkyBox.scale().y = 1.0f;
mSkyBox.scale().z = 5.0f;
scene.addChild(mSkyBox);
// yang sukses diload
// groudon (pokemon)
// frog
// plant
// capsule
// rancor (monster)
// cube
// Membuat objek pokemon
IParser parser1 = Par-
ser.createParser(Parser.Type.OBJ, getResources(),
"min3d.sampleProject1:raw/plant_obj", true);
parser1.parse();
pokemon = parser1.getParsedObject();
pokemon.scale().x = pokemon.scale().y =
pokemon.scale().z = 0.3f;
pokemon.position().x = -1.0f;
// pokemon.position().y = 0.5f;
// pokemon.position().y = -2.5f;
pokemon.position().y = -2.0f;
pokemon.position().z = -3;
// pokemon.rotation().x = 90;
scene.addChild(pokemon);
// Membuat objek MONSTER
IParser parserx = Par-
ser.createParser(Parser.Type.OBJ, getResources(),
"min3d.sampleProject1:raw/frog_obj", true);
parserx.parse();
monster = parserx.getParsedObject();
monster.scale().x = monster.scale().y =
monster.scale().z = 0.01f;
monster.position().x = 1.5f;
// monster.position().y = 0.5f;
monster.position().y = -2.0f;
// monster.position().y = -2.0f;
monster.position().z = -3;
scene.addChild(monster);
// mSensorManager.registerListener(this,
mAccelerometer,
// SensorManager.SENSOR_DELAY_UI);
}
// @Override
// public void onAccuracyChanged(Sensor sensor,
int accuracy) {
// // TODO Auto-generated method stub
// }
//
// @Override
550
// public void onSensorChanged(SensorEvent event)
{
// if (event.sensor.getType() != Sen-
sor.TYPE_ACCELEROMETER)
// return;
//
// // low-pass filter to make the movement more
stable
// mAccVals.x = (float) (-event.values[1] *
FILTERING_FACTOR + mAccVals.x *
// (1.0 - FILTERING_FACTOR));
// mAccVals.y = (float) (event.values[0] *
FILTERING_FACTOR + mAccVals.y *
// (1.0 - FILTERING_FACTOR));
//
// scene.camera().position.x = mAccVals.x * .2f;
// scene.camera().position.y = mAccVals.y * .2f;
//
// scene.camera().target.x = -
scene.camera().position.x;
// scene.camera().target.y = -
scene.camera().position.y;
// }
@Override
public void updateScene() {
pokemon.rotation().y++;
monster.rotation().y++;
// objModel.rotation().z++;
}
}
Gambar 8.3 Model Loading (objek belum diberi texture)
551
8.4 Fractal Curve
Salah satu bentuk kurva adalah Kurva Fraktal, dimana merupakan sebuah objek dengan properti kesamaan diri yang dihasilkan oleh algoritma rekursif atau iteratif.Ini berarti citra fraktal dibuat dengan menyalin bagian kecil dari dirinya sendiri. Melukis objek menggunakan konsep fraktal dapat menghemat ukuran penyimpanan, jika dibandingkan dengan penyimpanan gambar dalam format bitmap. Objek tertentu juga dapat dibuat dengan pola yang tidak sama, misalkan pohon dengan panjang cabang-cabangnya dibuat bervariasi, dapat diatasi dengan pemberian unsur acak ke dalam algoritma fraktal, sehingga hasilnya lebih alami. Ini merupakan perpaduan seni dan matematika.
Kelebihan penggunaan kurva fraktal dalam Grafika Komputer adalah karena banyak objek nyata dalam dunia tidak hanya dapat diwakili dengan prisma dan elips sederhana, misalnya kurva matematika yang tetap (sin, cos, etc).Walaupun kurva dapat menyatakan fenomena alam, namun jika didasarkan pada pembuatan kurva, maka objek yang dibuat bisa menjadi sangat komplek.Fraktal sangat berguna untuk mewakili bentuk alami seperti pohon, gunung, air, lapangan, awan dan lain-lain.Jenis Kurva:
1. Kurva Fraktal Koch Langkah-langkah dari Kurva Koch:
a. Dimulai dengan sebuah garis lurus:
Gambar 8.4 Garis Lurus
b. Membagi garis lurus menjadi 3 bagian:
Gambar 8.5 Garis Lurus yang telah dibagi menjadi 3 bagian
c. Muncul bentuk segitiga garis dibagian tengah garis lurus yang sudah dibagi mejadi 3 bagian:
Gambar 8.6 Garis Lurus yang telah dibentuk segitiga di tengah bagiannya
552
Gambar 8.7 Kurva Fraktal Koch
2. Kurva Fraktal LindenMayer (L System)
Gambar 8.8 Kurva Fraktal LindenMayer (L System)
3. Kurva Fraktal Polinom
Dalam matematika, polinomial atau suku banyak (juga ditulis sukubanyak) adalah pernyataan matematika yang melibatkan jumlahan perkalian pangkat dalam satu atau lebih variabel dengan koefisien. Sebuah polinomial dalam satu variabel dengan koefisien konstan memiliki bentuk seperti berikut:
553
Pangkat tertinggi pada suatu polinomial menunjukkan orde atau derajat dari polinomial tersebut.Sebuah fungsi polinomial dalam satu variabel real dapat dinyatakan dalam grafik fungsi antara lain:
Grafik dari polinomial nol f(x) = 0, adalah sumbu x.
Grafik dari polinomial berderajat nol f(x) = a0, dimana a0 ≠ 0, adalah garis horizontal dengan y memotong a0.
Grafik dari polinomial berderajat satu (atau fungsi linear) f(x) = a0 + a1x , dengan a1 ≠ 0, adalah berupa garis miring dengan y memotong di a0 dengan
kemiringan sebesar a1.
Grafik dari polinomial berderajat dua f(x) = a0 + a1x + a2x2, dengan a2 ≠ 0, adalah berupa parabola.
Grafik dari polinomial berderajat tiga f(x) = a0 + a1x + a2x2, + a3x3, dengan a3 ≠ 0, adalah berupa kurva pangkat 3.
Grafik dari polinomial berderajat dua atau lebih f(x) = a0 + a1x + a2x2 + ... + anxn , dengan an ≠ 0 and n ≥ 2, adalah berupa kurva non-linear.
Ilustrasi dari grafik-grafik tersebut adalah di bawah ini:
Gambar 8.9 Polinomial berderajat 2
Polinomial berderajat 2:
f(x) = x2 - x - 2 = (x+1)(x-2)
554
Gambar 8.10 Polinomial berderajat 3
Polinomial berderajat 3:
f(x) = x3/4 + 3x2/4 - 3x/2 - 2 = 1/4 (x+4)(x+1)(x-2)
Gambar 8.11 Polinomial berderajat 4
Polinomial berderajat 4:
f(x) = 1/14 (9Fx+4)(x+1)(x-1)(x-3) + 0.5
Gambar 8.12 Polinomial berderajat 5
Polinomial berderajat 5:
555
f(x) = 1/20 (x+4)(x+2)(x+1)(x-1)(x-3) + 2
Gambar 8.13 Polinomial berderajat 6
Polinomial berderajat 6:
f(x) = 1/30 (x+3.5)(x+2)(x+1)(x-1)(x-3)(x-4) + 2
Gambar 8.14 Polinomial berderajat 7
Polinomial berderajat 7:
f(x) = (x-3)(x-2)(x-1)(x)(x+1)(x+2)(x+3)
4. Kurva Fraktal SetMandelBrot
Fraktal Mandelbrot berarti sebuah objek dibagi menjadi kepingan-kepingan atau bagian-bagian yang tidak berketentuan.Ide ini muncul, karena objek awan tidaklah seperti bola, garis pantai tidaklah seperti tepian lingkaran, kulit kayu tidaklah licin, dan juga lintasan cahaya bukanlahmerupakan garis lurus.ContohBentuk MandelBrot:
556
Gambar 8.15 Kurva Fraktal Set MandelBrot
5. Kurva Fraktal SetJulia
SetJulia merupakan bentuk lain dari fraktal yang kompleks. Perbedaan antara Mandelbrot Set dengan Julia Set dapat dilihat pada fungsi iteratifnya. Kalau pada Mandelbrot set, iterasi, dimulai dari z0 = 0 dan nilai konstanta k nya berbeda-beda. Pada Julia Set konstanta k tetap pada nilai tertentu dan nilai awal z0 berbeda-beda. Dengan demikian Mandelbrot Set berada pada bidang k sedangkan Julia Set berada pada bidang z. Fungsi Iteratif (zn+1 = zn
2 + k ):
Sistem menghasilkan masing-masing output dengan mengkuadratkan input dan menambahkan dengan k.
Orbit input menentukan bagaimana nilai digambarkan. Orbit adalah set nilai output sebagai fungsi yang diiterasi.
Contoh : f(zn+1)= zn2 + 2 dengan z0=0, maka urutan outputnya
adalah 2, 6, 38, 1446, …
Contoh Bentuk Set Julia :
Gambar 8.16 Kurva Set Julia 1
557
Gambar 8.17 Kurva Set Julia 2
Rumus Fractal Julia:
Misal diketahui Z0 = 0 , K = 0,1 + 0,6i, i2=-1
dan Iterasi Max = 3, maka
Z1=Z2+Z3 ?
Z1=Z02 + k
= 02+0,1+0,6i
= 0,1 +0,6i
Sehingga x,y = (0,1 ; 0,6)
Z2=Z12 + k
= (0,1 +0,6i)2 +0,1+0,6i
= 0.01+0.12i+0.36i2 + 0,1+0,6i
= 0.11+0.72i+0.36i2
= -0.25+0.72i
Sehingga x,y = (-0.25 ; 0.72)
Z3=Z22 + k
= (-0.25+0.72i)2 +0,1+0,6i
= 0.0625 - 0.36i + 0.5184i + 0.1+0.6i
= -0.3559 + 0.24i
Sehingga x,y = (-0.3559 ; 0,24)