diff --git a/Android_Java/Chapter_10/MultiTexture/.classpath b/Android_Java/Chapter_10/MultiTexture/.classpath new file mode 100644 index 0000000..ce8b321 --- /dev/null +++ b/Android_Java/Chapter_10/MultiTexture/.classpath @@ -0,0 +1,5 @@ + + + + + diff --git a/Android_Java/Chapter_10/MultiTexture/.project b/Android_Java/Chapter_10/MultiTexture/.project new file mode 100644 index 0000000..35ab13d --- /dev/null +++ b/Android_Java/Chapter_10/MultiTexture/.project @@ -0,0 +1,33 @@ + + + Ch10_MultiTexture + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/Android_Java/Chapter_10/MultiTexture/AndroidManifest.xml b/Android_Java/Chapter_10/MultiTexture/AndroidManifest.xml new file mode 100644 index 0000000..fb89a3d --- /dev/null +++ b/Android_Java/Chapter_10/MultiTexture/AndroidManifest.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Android_Java/Chapter_10/MultiTexture/assets/shaders/fragmentShader.frag b/Android_Java/Chapter_10/MultiTexture/assets/shaders/fragmentShader.frag new file mode 100644 index 0000000..72d9955 --- /dev/null +++ b/Android_Java/Chapter_10/MultiTexture/assets/shaders/fragmentShader.frag @@ -0,0 +1,21 @@ +#version 300 es + +precision mediump float; + +in vec2 v_texCoord; + +layout(location = 0) out vec4 outColor; + +uniform sampler2D s_baseMap; +uniform sampler2D s_lightMap; + +void main() +{ + vec4 baseColor; + vec4 lightColor; + + baseColor = texture( s_baseMap, v_texCoord ); + lightColor = texture( s_lightMap, v_texCoord ); + + outColor = baseColor * (lightColor + 0.25); +} \ No newline at end of file diff --git a/Android_Java/Chapter_10/MultiTexture/assets/shaders/vertexShader.vert b/Android_Java/Chapter_10/MultiTexture/assets/shaders/vertexShader.vert new file mode 100644 index 0000000..fcb3e8d --- /dev/null +++ b/Android_Java/Chapter_10/MultiTexture/assets/shaders/vertexShader.vert @@ -0,0 +1,12 @@ +#version 300 es + +layout(location = 0) in vec4 a_position; +layout(location = 1) in vec2 a_texCoord; + +out vec2 v_texCoord; + +void main() +{ + gl_Position = a_position; + v_texCoord = a_texCoord; +} \ No newline at end of file diff --git a/Android_Java/Chapter_10/MultiTexture/assets/textures/basemap.png b/Android_Java/Chapter_10/MultiTexture/assets/textures/basemap.png new file mode 100644 index 0000000..084fead Binary files /dev/null and b/Android_Java/Chapter_10/MultiTexture/assets/textures/basemap.png differ diff --git a/Android_Java/Chapter_10/MultiTexture/assets/textures/lightmap.png b/Android_Java/Chapter_10/MultiTexture/assets/textures/lightmap.png new file mode 100644 index 0000000..40cd00b Binary files /dev/null and b/Android_Java/Chapter_10/MultiTexture/assets/textures/lightmap.png differ diff --git a/Android_Java/Chapter_10/MultiTexture/default.properties b/Android_Java/Chapter_10/MultiTexture/default.properties new file mode 100644 index 0000000..5ccd841 --- /dev/null +++ b/Android_Java/Chapter_10/MultiTexture/default.properties @@ -0,0 +1,12 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-18 +android.library.reference.1=../../Common/ diff --git a/Android_Java/Chapter_10/MultiTexture/proguard.cfg b/Android_Java/Chapter_10/MultiTexture/proguard.cfg new file mode 100644 index 0000000..8ad7d33 --- /dev/null +++ b/Android_Java/Chapter_10/MultiTexture/proguard.cfg @@ -0,0 +1,34 @@ +-optimizationpasses 5 +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses +-dontpreverify +-verbose +-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class com.android.vending.licensing.ILicensingService + +-keepclasseswithmembernames class * { + native ; +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet, int); +} + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} diff --git a/Android_Java/Chapter_10/MultiTexture/res/drawable-hdpi/icon.png b/Android_Java/Chapter_10/MultiTexture/res/drawable-hdpi/icon.png new file mode 100644 index 0000000..8074c4c Binary files /dev/null and b/Android_Java/Chapter_10/MultiTexture/res/drawable-hdpi/icon.png differ diff --git a/Android_Java/Chapter_10/MultiTexture/res/drawable-ldpi/icon.png b/Android_Java/Chapter_10/MultiTexture/res/drawable-ldpi/icon.png new file mode 100644 index 0000000..1095584 Binary files /dev/null and b/Android_Java/Chapter_10/MultiTexture/res/drawable-ldpi/icon.png differ diff --git a/Android_Java/Chapter_10/MultiTexture/res/drawable-mdpi/icon.png b/Android_Java/Chapter_10/MultiTexture/res/drawable-mdpi/icon.png new file mode 100644 index 0000000..a07c69f Binary files /dev/null and b/Android_Java/Chapter_10/MultiTexture/res/drawable-mdpi/icon.png differ diff --git a/Android_Java/Chapter_10/MultiTexture/res/values/strings.xml b/Android_Java/Chapter_10/MultiTexture/res/values/strings.xml new file mode 100644 index 0000000..30e693a --- /dev/null +++ b/Android_Java/Chapter_10/MultiTexture/res/values/strings.xml @@ -0,0 +1,4 @@ + + + Ch10_MultiTexture + diff --git a/Android_Java/Chapter_10/MultiTexture/src/com/openglesbook/multitexture/MultiTexture.java b/Android_Java/Chapter_10/MultiTexture/src/com/openglesbook/multitexture/MultiTexture.java new file mode 100644 index 0000000..cf4834a --- /dev/null +++ b/Android_Java/Chapter_10/MultiTexture/src/com/openglesbook/multitexture/MultiTexture.java @@ -0,0 +1,65 @@ +package com.openglesbook.multitexture; + +import android.app.Activity; +import android.app.ActivityManager; +import android.content.Context; +import android.content.pm.ConfigurationInfo; +import android.opengl.GLSurfaceView; +import android.os.Bundle; +import android.util.Log; + +/** + * Activity class for example program that detects OpenGL ES 3.0. + **/ +public class MultiTexture extends Activity { + private final int CONTEXT_CLIENT_VERSION = 3; + + @Override + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + mGLSurfaceView = new GLSurfaceView(this); + if (detectOpenGLES30()) + { + // Tell the surface view we want to create an OpenGL ES 3.0-compatible + // context, and set an OpenGL ES 3.0-compatible renderer. + mGLSurfaceView.setEGLContextClientVersion(CONTEXT_CLIENT_VERSION); + mGLSurfaceView.setRenderer(new MultiTextureRenderer(this)); + } + else + { + Log.e("MultiTexture", "OpenGL ES 3.0 not supported on device. Exiting..."); + finish(); + + } + setContentView(mGLSurfaceView); + } + + private boolean detectOpenGLES30() + { + ActivityManager am = + (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); + ConfigurationInfo info = am.getDeviceConfigurationInfo(); + return (info.reqGlEsVersion >= 0x30000); + } + + @Override + protected void onResume() + { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onResume(); + mGLSurfaceView.onResume(); + } + + @Override + protected void onPause() + { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onPause(); + mGLSurfaceView.onPause(); + } + + private GLSurfaceView mGLSurfaceView; +} diff --git a/Android_Java/Chapter_10/MultiTexture/src/com/openglesbook/multitexture/MultiTextureRenderer.java b/Android_Java/Chapter_10/MultiTexture/src/com/openglesbook/multitexture/MultiTextureRenderer.java new file mode 100644 index 0000000..08919ae --- /dev/null +++ b/Android_Java/Chapter_10/MultiTexture/src/com/openglesbook/multitexture/MultiTextureRenderer.java @@ -0,0 +1,202 @@ +// +// Book: OpenGL(R) ES 3.0 Programming Guide +// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner +// ISBN-10: 0321502795 +// ISBN-13: 9780321502797 +// Publisher: Addison-Wesley Professional +// URLs: http://safari.informit.com/9780321563835 +// http://www.opengles-book.com +// + +// MultiTexture +// +// This is an example that draws a quad with a basemap and +// lightmap to demonstrate multitexturing. +// + +package com.openglesbook.multitexture; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; +import java.nio.ShortBuffer; + +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; + +import com.openglesbook.common.ESShader; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.opengl.GLES30; +import android.opengl.GLSurfaceView; +import android.opengl.GLUtils; + + +public class MultiTextureRenderer implements GLSurfaceView.Renderer +{ + + /// + // Constructor + // + public MultiTextureRenderer(Context context) + { + mContext = context; + mVertices = ByteBuffer.allocateDirect(mVerticesData.length * 4) + .order(ByteOrder.nativeOrder()).asFloatBuffer(); + mVertices.put(mVerticesData).position(0); + mIndices = ByteBuffer.allocateDirect(mIndicesData.length * 2) + .order(ByteOrder.nativeOrder()).asShortBuffer(); + mIndices.put(mIndicesData).position(0); + } + + /// + // Load texture from asset + // + private int loadTextureFromAsset ( String fileName ) + { + int[] textureId = new int[1]; + Bitmap bitmap = null; + InputStream is = null; + + try { + is = mContext.getAssets().open(fileName); + } catch (IOException ioe) { + is = null; + } + + if (is == null) + return 0; + + bitmap = BitmapFactory.decodeStream(is); + + GLES30.glGenTextures ( 1, textureId, 0 ); + GLES30.glBindTexture ( GLES30.GL_TEXTURE_2D, textureId[0] ); + + GLUtils.texImage2D(GLES30.GL_TEXTURE_2D, 0, bitmap, 0); + + GLES30.glTexParameteri ( GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_LINEAR ); + GLES30.glTexParameteri ( GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_LINEAR ); + GLES30.glTexParameteri ( GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_CLAMP_TO_EDGE ); + GLES30.glTexParameteri ( GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_CLAMP_TO_EDGE ); + + return textureId[0]; + } + + /// + // Initialize the shader and program object + // + public void onSurfaceCreated(GL10 glUnused, EGLConfig config) + { + // Load shaders from 'assets' and get a linked program object + mProgramObject = ESShader.loadProgramFromAsset(mContext, + "shaders/vertexShader.vert", + "shaders/fragmentShader.frag"); + + // Get the sampler locations + mBaseMapLoc = GLES30.glGetUniformLocation ( mProgramObject, "s_baseMap" ); + mLightMapLoc = GLES30.glGetUniformLocation ( mProgramObject, "s_lightMap" ); + + // Load the texture images from 'assets' + mBaseMapTexId = loadTextureFromAsset("textures/basemap.png"); + mLightMapTexId = loadTextureFromAsset("textures/lightmap.png"); + + GLES30.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + } + + // / + // Draw a triangle using the shader pair created in onSurfaceCreated() + // + public void onDrawFrame(GL10 glUnused) + { + // Set the view-port + GLES30.glViewport(0, 0, mWidth, mHeight); + + // Clear the color buffer + GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT); + + // Use the program object + GLES30.glUseProgram(mProgramObject); + + // Load the vertex position + mVertices.position(0); + GLES30.glVertexAttribPointer ( 0, 3, GLES30.GL_FLOAT, + false, + 5 * 4, mVertices ); + // Load the texture coordinate + mVertices.position(3); + GLES30.glVertexAttribPointer ( 1, 2, GLES30.GL_FLOAT, + false, + 5 * 4, + mVertices ); + + GLES30.glEnableVertexAttribArray ( 0 ); + GLES30.glEnableVertexAttribArray ( 1 ); + + + // Bind the base map + GLES30.glActiveTexture ( GLES30.GL_TEXTURE0 ); + GLES30.glBindTexture ( GLES30.GL_TEXTURE_2D, mBaseMapTexId ); + + // Set the base map sampler to texture unit to 0 + GLES30.glUniform1i ( mBaseMapLoc, 0 ); + + // Bind the light map + GLES30.glActiveTexture ( GLES30.GL_TEXTURE1 ); + GLES30.glBindTexture ( GLES30.GL_TEXTURE_2D, mLightMapTexId ); + + // Set the light map sampler to texture unit 1 + GLES30.glUniform1i ( mLightMapLoc, 1 ); + + GLES30.glDrawElements ( GLES30.GL_TRIANGLES, 6, GLES30.GL_UNSIGNED_SHORT, mIndices ); + } + + /// + // Handle surface changes + // + public void onSurfaceChanged(GL10 glUnused, int width, int height) + { + mWidth = width; + mHeight = height; + } + + + // Handle to a program object + private int mProgramObject; + + // Sampler location + private int mBaseMapLoc; + private int mLightMapLoc; + + // Texture handle + private int mBaseMapTexId; + private int mLightMapTexId; + + // Additional member variables + private int mWidth; + private int mHeight; + private FloatBuffer mVertices; + private ShortBuffer mIndices; + private Context mContext; + + private final float[] mVerticesData = + { + -0.5f, 0.5f, 0.0f, // Position 0 + 0.0f, 0.0f, // TexCoord 0 + -0.5f, -0.5f, 0.0f, // Position 1 + 0.0f, 1.0f, // TexCoord 1 + 0.5f, -0.5f, 0.0f, // Position 2 + 1.0f, 1.0f, // TexCoord 2 + 0.5f, 0.5f, 0.0f, // Position 3 + 1.0f, 0.0f // TexCoord 3 + }; + + private final short[] mIndicesData = + { + 0, 1, 2, 0, 2, 3 + }; + +} diff --git a/Android_Java/Chapter_14/ParticleSystem/.classpath b/Android_Java/Chapter_14/ParticleSystem/.classpath new file mode 100644 index 0000000..b76ec6c --- /dev/null +++ b/Android_Java/Chapter_14/ParticleSystem/.classpath @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/Android_Java/Chapter_14/ParticleSystem/.project b/Android_Java/Chapter_14/ParticleSystem/.project new file mode 100644 index 0000000..0e664e9 --- /dev/null +++ b/Android_Java/Chapter_14/ParticleSystem/.project @@ -0,0 +1,33 @@ + + + Ch14_ParticleSystem + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/Android_Java/Chapter_14/ParticleSystem/AndroidManifest.xml b/Android_Java/Chapter_14/ParticleSystem/AndroidManifest.xml new file mode 100644 index 0000000..8c67ded --- /dev/null +++ b/Android_Java/Chapter_14/ParticleSystem/AndroidManifest.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Android_Java/Chapter_14/ParticleSystem/assets/smoke.png b/Android_Java/Chapter_14/ParticleSystem/assets/smoke.png new file mode 100644 index 0000000..828308d Binary files /dev/null and b/Android_Java/Chapter_14/ParticleSystem/assets/smoke.png differ diff --git a/Android_Java/Chapter_14/ParticleSystem/default.properties b/Android_Java/Chapter_14/ParticleSystem/default.properties new file mode 100644 index 0000000..5ccd841 --- /dev/null +++ b/Android_Java/Chapter_14/ParticleSystem/default.properties @@ -0,0 +1,12 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-18 +android.library.reference.1=../../Common/ diff --git a/Android_Java/Chapter_14/ParticleSystem/proguard.cfg b/Android_Java/Chapter_14/ParticleSystem/proguard.cfg new file mode 100644 index 0000000..8ad7d33 --- /dev/null +++ b/Android_Java/Chapter_14/ParticleSystem/proguard.cfg @@ -0,0 +1,34 @@ +-optimizationpasses 5 +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses +-dontpreverify +-verbose +-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class com.android.vending.licensing.ILicensingService + +-keepclasseswithmembernames class * { + native ; +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet, int); +} + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} diff --git a/Android_Java/Chapter_14/ParticleSystem/res/drawable-hdpi/icon.png b/Android_Java/Chapter_14/ParticleSystem/res/drawable-hdpi/icon.png new file mode 100644 index 0000000..8074c4c Binary files /dev/null and b/Android_Java/Chapter_14/ParticleSystem/res/drawable-hdpi/icon.png differ diff --git a/Android_Java/Chapter_14/ParticleSystem/res/drawable-ldpi/icon.png b/Android_Java/Chapter_14/ParticleSystem/res/drawable-ldpi/icon.png new file mode 100644 index 0000000..1095584 Binary files /dev/null and b/Android_Java/Chapter_14/ParticleSystem/res/drawable-ldpi/icon.png differ diff --git a/Android_Java/Chapter_14/ParticleSystem/res/drawable-mdpi/icon.png b/Android_Java/Chapter_14/ParticleSystem/res/drawable-mdpi/icon.png new file mode 100644 index 0000000..a07c69f Binary files /dev/null and b/Android_Java/Chapter_14/ParticleSystem/res/drawable-mdpi/icon.png differ diff --git a/Android_Java/Chapter_14/ParticleSystem/res/values/strings.xml b/Android_Java/Chapter_14/ParticleSystem/res/values/strings.xml new file mode 100644 index 0000000..ebb4c7b --- /dev/null +++ b/Android_Java/Chapter_14/ParticleSystem/res/values/strings.xml @@ -0,0 +1,4 @@ + + + Ch14_ParticleSystem + diff --git a/Android_Java/Chapter_14/ParticleSystem/src/com/openglesbook/particlesystem/ParticleSystem.java b/Android_Java/Chapter_14/ParticleSystem/src/com/openglesbook/particlesystem/ParticleSystem.java new file mode 100644 index 0000000..1c3d193 --- /dev/null +++ b/Android_Java/Chapter_14/ParticleSystem/src/com/openglesbook/particlesystem/ParticleSystem.java @@ -0,0 +1,66 @@ +package com.openglesbook.particlesystem; + +import android.app.Activity; +import android.app.ActivityManager; +import android.content.Context; +import android.content.pm.ConfigurationInfo; +import android.opengl.GLSurfaceView; +import android.os.Bundle; +import android.util.Log; + +/** + * Activity class for example program that detects OpenGL ES 3.0. + **/ +public class ParticleSystem extends Activity { + + private final int CONTEXT_CLIENT_VERSION = 3; + + @Override + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + mGLSurfaceView = new GLSurfaceView(this); + if (detectOpenGLES30()) + { + // Tell the surface view we want to create an OpenGL ES 3.0-compatible + // context, and set an OpenGL ES 2.0-compatible renderer. + mGLSurfaceView.setEGLContextClientVersion(CONTEXT_CLIENT_VERSION); + mGLSurfaceView.setRenderer(new ParticleSystemRenderer(this)); + } + else + { + Log.e("HelloTriangle", "OpenGL ES 3.0 not supported on device. Exiting..."); + finish(); + + } + setContentView(mGLSurfaceView); + } + + private boolean detectOpenGLES30() + { + ActivityManager am = + (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); + ConfigurationInfo info = am.getDeviceConfigurationInfo(); + return (info.reqGlEsVersion >= 0x30000); + } + + @Override + protected void onResume() + { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onResume(); + mGLSurfaceView.onResume(); + } + + @Override + protected void onPause() + { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onPause(); + mGLSurfaceView.onPause(); + } + + private GLSurfaceView mGLSurfaceView; +} diff --git a/Android_Java/Chapter_14/ParticleSystem/src/com/openglesbook/particlesystem/ParticleSystemRenderer.java b/Android_Java/Chapter_14/ParticleSystem/src/com/openglesbook/particlesystem/ParticleSystemRenderer.java new file mode 100644 index 0000000..80f16a9 --- /dev/null +++ b/Android_Java/Chapter_14/ParticleSystem/src/com/openglesbook/particlesystem/ParticleSystemRenderer.java @@ -0,0 +1,302 @@ +// +// Book: OpenGL(R) ES 2.0 Programming Guide +// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner +// ISBN-10: 0321502795 +// ISBN-13: 9780321502797 +// Publisher: Addison-Wesley Professional +// URLs: http://safari.informit.com/9780321563835 +// http://www.opengles-book.com +// + +// ParticleSystem +// +// This is an example that demonstrates rendering a particle system +// using a vertex shader and point sprites. +// + +package com.openglesbook.particlesystem; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; + +import com.openglesbook.common.ESShader; + +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.opengl.GLES30; +import android.opengl.GLSurfaceView; +import android.opengl.GLUtils; +import android.os.SystemClock; + +public class ParticleSystemRenderer implements GLSurfaceView.Renderer +{ + + /// + // Constructor + // + public ParticleSystemRenderer(Context context) + { + mContext = context; + + // Fill in particle data array + for ( int i = 0; i < (NUM_PARTICLES * PARTICLE_SIZE); i+=PARTICLE_SIZE ) + { + // Lifetime of particle + mParticleData[i + 0] = ( (float)( (int)(Math.random() * 10000) % 10000) / 10000.0f );; + + // End position of particle + mParticleData[i + 1] = ( (float)( (int)(Math.random() * 10000) % 10000) / 5000.0f ) - 1.0f; + mParticleData[i + 2] = ( (float)( (int)(Math.random() * 10000) % 10000) / 5000.0f ) - 1.0f; + mParticleData[i + 3] = ( (float)( (int)(Math.random() * 10000) % 10000) / 5000.0f ) - 1.0f; + + // Start position of particle + mParticleData[i + 4] = ( (float)( (int)(Math.random() * 10000) % 10000) / 40000.0f ) - 0.125f; + mParticleData[i + 5] = ( (float)( (int)(Math.random() * 10000) % 10000) / 40000.0f ) - 0.125f; + mParticleData[i + 6] = ( (float)( (int)(Math.random() * 10000) % 10000) / 40000.0f ) - 0.125f; + } + + mParticles = ByteBuffer.allocateDirect(mParticleData.length * 4) + .order(ByteOrder.nativeOrder()).asFloatBuffer(); + mParticles.put(mParticleData).position(0); + } + + /// + // Load texture from asset + // + private int loadTextureFromAsset ( String fileName ) + { + int[] textureId = new int[1]; + Bitmap bitmap = null; + InputStream is = null; + + try { + is = mContext.getAssets().open(fileName); + } catch (IOException ioe) { + is = null; + } + + if (is == null) + return 0; + + bitmap = BitmapFactory.decodeStream(is); + + GLES30.glGenTextures ( 1, textureId, 0 ); + GLES30.glBindTexture ( GLES30.GL_TEXTURE_2D, textureId[0] ); + + GLUtils.texImage2D(GLES30.GL_TEXTURE_2D, 0, bitmap, 0); + + GLES30.glTexParameteri ( GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_LINEAR ); + GLES30.glTexParameteri ( GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_LINEAR ); + GLES30.glTexParameteri ( GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_CLAMP_TO_EDGE ); + GLES30.glTexParameteri ( GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_CLAMP_TO_EDGE ); + + return textureId[0]; + } + + /// + // Initialize the shader and program object + // + public void onSurfaceCreated(GL10 glUnused, EGLConfig config) + { + String vShaderStr = + "#version 300 es \n" + + "uniform float u_time; \n" + + "uniform vec3 u_centerPosition; \n" + + "layout(location = 0) in float a_lifetime; \n" + + "layout(location = 1) in vec3 a_startPosition; \n" + + "layout(location = 2) in vec3 a_endPosition; \n" + + "out float v_lifetime; \n" + + "void main() \n" + + "{ \n" + + " if ( u_time <= a_lifetime ) \n" + + " { \n" + + " gl_Position.xyz = a_startPosition + \n" + + " (u_time * a_endPosition); \n" + + " gl_Position.xyz += u_centerPosition; \n" + + " gl_Position.w = 1.0; \n" + + " } \n" + + " else \n" + + " gl_Position = vec4( -1000, -1000, 0, 0 ); \n" + + " v_lifetime = 1.0 - ( u_time / a_lifetime ); \n" + + " v_lifetime = clamp ( v_lifetime, 0.0, 1.0 ); \n" + + " gl_PointSize = ( v_lifetime * v_lifetime ) * 40.0; \n" + + "} \n"; + + String fShaderStr = + "#version 300 es \n" + + "precision mediump float; \n" + + "uniform vec4 u_color; \n" + + "in float v_lifetime; \n" + + "layout(location = 0) out vec4 fragColor; \n" + + "uniform sampler2D s_texture; \n" + + "void main() \n" + + "{ \n" + + " vec4 texColor; \n" + + " texColor = texture( s_texture, gl_PointCoord ); \n" + + " fragColor = vec4( u_color ) * texColor; \n" + + " fragColor.a *= v_lifetime; \n" + + "} \n"; + + // Load the shaders and get a linked program object + mProgramObject = ESShader.loadProgram(vShaderStr, fShaderStr); + + // Get the uniform locations + mTimeLoc = GLES30.glGetUniformLocation ( mProgramObject, "u_time" ); + mCenterPositionLoc = GLES30.glGetUniformLocation ( mProgramObject, "u_centerPosition" ); + mColorLoc = GLES30.glGetUniformLocation ( mProgramObject, "u_color" ); + mSamplerLoc = GLES30.glGetUniformLocation ( mProgramObject, "s_texture" ); + + GLES30.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + + // Load the texture images from 'assets' + mTextureId = loadTextureFromAsset("smoke.png"); + + // Initialize time to cause reset on first update + mTime = 1.0f; + } + + private void update() + { + if (mLastTime == 0) + mLastTime = SystemClock.uptimeMillis(); + long curTime = SystemClock.uptimeMillis(); + long elapsedTime = curTime - mLastTime; + float deltaTime = elapsedTime / 1000.0f; + mLastTime = curTime; + + mTime += deltaTime; + + GLES30.glUseProgram(mProgramObject); + + if ( mTime >= 1.0f ) + { + float [] centerPos = new float[3]; + float [] color = new float[4]; + + mTime = 0.0f; + + // Pick a new start location and color + centerPos[0] = ( (float)( (int)(Math.random() * 10000) % 10000) / 10000.0f ) - 0.5f; + centerPos[1] = ( (float)( (int)(Math.random() * 10000) % 10000) / 10000.0f ) - 0.5f; + centerPos[2] = ( (float)( (int)(Math.random() * 10000) % 10000) / 10000.0f ) - 0.5f; + + GLES30.glUniform3f ( mCenterPositionLoc, centerPos[0], centerPos[1], centerPos[2] ); + + // Random color + color[0] = ( (float)( (int)(Math.random() * 1000) % 10000) / 20000.0f ) + 0.5f; + color[1] = ( (float)( (int)(Math.random() * 1000) % 10000) / 20000.0f ) + 0.5f; + color[2] = ( (float)( (int)(Math.random() * 1000) % 10000) / 20000.0f ) + 0.5f; + color[3] = 0.5f; + + GLES30.glUniform4f ( mColorLoc, color[0], color[1], color[2], color[3] ); + } + + // Load uniform time variable + GLES30.glUniform1f ( mTimeLoc, mTime ); + } + + /// + // Draw a triangle using the shader pair created in onSurfaceCreated() + // + public void onDrawFrame(GL10 glUnused) + { + update(); + + // Set the viewport + GLES30.glViewport(0, 0, mWidth, mHeight); + + // Clear the color buffer + GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT); + + // Use the program object + GLES30.glUseProgram(mProgramObject); + + // Load the vertex attributes + //[0] + mParticles.position(0); + GLES30.glVertexAttribPointer ( ATTRIBUTE_LIFETIME_LOCATION, 1, GLES30.GL_FLOAT, + false, PARTICLE_SIZE * (4), + mParticles ); + + //[1] + mParticles.position(1); + GLES30.glVertexAttribPointer ( ATTRIBUTE_ENDPOSITION_LOCATION, 3, GLES30.GL_FLOAT, + false, PARTICLE_SIZE * (4), + mParticles ); + + //[4] + mParticles.position(4); + GLES30.glVertexAttribPointer ( ATTRIBUTE_STARTPOSITION_LOCATION, 3, GLES30.GL_FLOAT, + false, PARTICLE_SIZE * (4), + mParticles ); + + + GLES30.glEnableVertexAttribArray ( ATTRIBUTE_LIFETIME_LOCATION ); + GLES30.glEnableVertexAttribArray ( ATTRIBUTE_ENDPOSITION_LOCATION ); + GLES30.glEnableVertexAttribArray ( ATTRIBUTE_STARTPOSITION_LOCATION ); + + // Blend particles + GLES30.glEnable ( GLES30.GL_BLEND ); + GLES30.glBlendFunc ( GLES30.GL_SRC_ALPHA, GLES30.GL_ONE ); + + // Bind the texture + GLES30.glActiveTexture ( GLES30.GL_TEXTURE0 ); + GLES30.glBindTexture ( GLES30.GL_TEXTURE_2D, mTextureId ); + + // Set the sampler texture unit to 0 + GLES30.glUniform1i ( mSamplerLoc, 0 ); + + GLES30.glDrawArrays( GLES30.GL_POINTS, 0, NUM_PARTICLES ); + } + + /// + // Handle surface changes + // + public void onSurfaceChanged(GL10 glUnused, int width, int height) + { + mWidth = width; + mHeight = height; + } + + // Handle to a program object + private int mProgramObject; + + // Uniform location + private int mTimeLoc; + private int mColorLoc; + private int mCenterPositionLoc; + private int mSamplerLoc; + + // Texture handle + private int mTextureId; + + // Current time + float time; + + // Additional Member variables + private int mWidth; + private int mHeight; + private long mLastTime = 0; + + private final int NUM_PARTICLES = 1000; + private final int PARTICLE_SIZE = 7; + + private final int ATTRIBUTE_LIFETIME_LOCATION = 0; + private final int ATTRIBUTE_STARTPOSITION_LOCATION = 1; + private final int ATTRIBUTE_ENDPOSITION_LOCATION = 2; + + // Particle vertex data + private float [] mParticleData = new float[ NUM_PARTICLES * PARTICLE_SIZE ]; + + private FloatBuffer mParticles; + + private float mTime; + private Context mContext; +} diff --git a/Android_Java/Chapter_2/Hello_Triangle/.classpath b/Android_Java/Chapter_2/Hello_Triangle/.classpath new file mode 100644 index 0000000..ce8b321 --- /dev/null +++ b/Android_Java/Chapter_2/Hello_Triangle/.classpath @@ -0,0 +1,5 @@ + + + + + diff --git a/Android_Java/Chapter_2/Hello_Triangle/.project b/Android_Java/Chapter_2/Hello_Triangle/.project new file mode 100644 index 0000000..d0fce14 --- /dev/null +++ b/Android_Java/Chapter_2/Hello_Triangle/.project @@ -0,0 +1,33 @@ + + + Ch2_Hello_Triangle + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/Android_Java/Chapter_2/Hello_Triangle/AndroidManifest.xml b/Android_Java/Chapter_2/Hello_Triangle/AndroidManifest.xml new file mode 100644 index 0000000..e9b1f47 --- /dev/null +++ b/Android_Java/Chapter_2/Hello_Triangle/AndroidManifest.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Android_Java/Chapter_2/Hello_Triangle/default.properties b/Android_Java/Chapter_2/Hello_Triangle/default.properties new file mode 100644 index 0000000..5ccd841 --- /dev/null +++ b/Android_Java/Chapter_2/Hello_Triangle/default.properties @@ -0,0 +1,12 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-18 +android.library.reference.1=../../Common/ diff --git a/Android_Java/Chapter_2/Hello_Triangle/proguard.cfg b/Android_Java/Chapter_2/Hello_Triangle/proguard.cfg new file mode 100644 index 0000000..8ad7d33 --- /dev/null +++ b/Android_Java/Chapter_2/Hello_Triangle/proguard.cfg @@ -0,0 +1,34 @@ +-optimizationpasses 5 +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses +-dontpreverify +-verbose +-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class com.android.vending.licensing.ILicensingService + +-keepclasseswithmembernames class * { + native ; +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet, int); +} + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} diff --git a/Android_Java/Chapter_2/Hello_Triangle/res/drawable-hdpi/icon.png b/Android_Java/Chapter_2/Hello_Triangle/res/drawable-hdpi/icon.png new file mode 100644 index 0000000..8074c4c Binary files /dev/null and b/Android_Java/Chapter_2/Hello_Triangle/res/drawable-hdpi/icon.png differ diff --git a/Android_Java/Chapter_2/Hello_Triangle/res/drawable-ldpi/icon.png b/Android_Java/Chapter_2/Hello_Triangle/res/drawable-ldpi/icon.png new file mode 100644 index 0000000..1095584 Binary files /dev/null and b/Android_Java/Chapter_2/Hello_Triangle/res/drawable-ldpi/icon.png differ diff --git a/Android_Java/Chapter_2/Hello_Triangle/res/drawable-mdpi/icon.png b/Android_Java/Chapter_2/Hello_Triangle/res/drawable-mdpi/icon.png new file mode 100644 index 0000000..a07c69f Binary files /dev/null and b/Android_Java/Chapter_2/Hello_Triangle/res/drawable-mdpi/icon.png differ diff --git a/Android_Java/Chapter_2/Hello_Triangle/res/values/strings.xml b/Android_Java/Chapter_2/Hello_Triangle/res/values/strings.xml new file mode 100644 index 0000000..dcc2e6f --- /dev/null +++ b/Android_Java/Chapter_2/Hello_Triangle/res/values/strings.xml @@ -0,0 +1,4 @@ + + + Ch2_Hello_Triangle + diff --git a/Android_Java/Chapter_2/Hello_Triangle/src/com/openglesbook/hellotriangle/HelloTriangle.java b/Android_Java/Chapter_2/Hello_Triangle/src/com/openglesbook/hellotriangle/HelloTriangle.java new file mode 100644 index 0000000..697be8e --- /dev/null +++ b/Android_Java/Chapter_2/Hello_Triangle/src/com/openglesbook/hellotriangle/HelloTriangle.java @@ -0,0 +1,66 @@ +package com.openglesbook.hellotriangle; + +import android.app.Activity; +import android.app.ActivityManager; +import android.content.Context; +import android.content.pm.ConfigurationInfo; +import android.opengl.GLSurfaceView; +import android.os.Bundle; +import android.util.Log; + +/** + * Activity class for example program that detects OpenGL ES 3.0. + **/ +public class HelloTriangle extends Activity { + + private final int CONTEXT_CLIENT_VERSION = 3; + + @Override + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + mGLSurfaceView = new GLSurfaceView(this); + if (detectOpenGLES30()) + { + // Tell the surface view we want to create an OpenGL ES 3.0-compatible + // context, and set an OpenGL ES 3.0-compatible renderer. + mGLSurfaceView.setEGLContextClientVersion(CONTEXT_CLIENT_VERSION); + mGLSurfaceView.setRenderer(new HelloTriangleRenderer(this)); + } + else + { + Log.e("HelloTriangle", "OpenGL ES 3.0 not supported on device. Exiting..."); + finish(); + + } + setContentView(mGLSurfaceView); + } + + private boolean detectOpenGLES30() + { + ActivityManager am = + (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); + ConfigurationInfo info = am.getDeviceConfigurationInfo(); + return (info.reqGlEsVersion >= 0x30000); + } + + @Override + protected void onResume() + { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onResume(); + mGLSurfaceView.onResume(); + } + + @Override + protected void onPause() + { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onPause(); + mGLSurfaceView.onPause(); + } + + private GLSurfaceView mGLSurfaceView; +} diff --git a/Android_Java/Chapter_2/Hello_Triangle/src/com/openglesbook/hellotriangle/HelloTriangleRenderer.java b/Android_Java/Chapter_2/Hello_Triangle/src/com/openglesbook/hellotriangle/HelloTriangleRenderer.java new file mode 100644 index 0000000..9384404 --- /dev/null +++ b/Android_Java/Chapter_2/Hello_Triangle/src/com/openglesbook/hellotriangle/HelloTriangleRenderer.java @@ -0,0 +1,181 @@ +// +// Book: OpenGL(R) ES 3.0 Programming Guide +// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner +// ISBN-10: 0321502795 +// ISBN-13: 9780321502797 +// Publisher: Addison-Wesley Professional +// URLs: http://safari.informit.com/9780321563835 +// http://www.opengles-book.com +// + +// Hello_Triangle +// +// This is a simple example that draws a single triangle with +// a minimal vertex/fragment shader. The purpose of this +// example is to demonstrate the basic concepts of +// OpenGL ES 3.0 rendering. + +package com.openglesbook.hellotriangle; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; + +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; + +import android.content.Context; +import android.opengl.GLES30; +import android.opengl.GLSurfaceView; +import android.util.Log; + +public class HelloTriangleRenderer implements GLSurfaceView.Renderer +{ + + /// + // Constructor + // + public HelloTriangleRenderer(Context context) + { + mVertices = ByteBuffer.allocateDirect(mVerticesData.length * 4) + .order(ByteOrder.nativeOrder()).asFloatBuffer(); + mVertices.put(mVerticesData).position(0); + } + + /// + // Create a shader object, load the shader source, and + // compile the shader. + // + private int LoadShader(int type, String shaderSrc) + { + int shader; + int[] compiled = new int[1]; + + // Create the shader object + shader = GLES30.glCreateShader(type); + + if (shader == 0) + return 0; + + // Load the shader source + GLES30.glShaderSource(shader, shaderSrc); + + // Compile the shader + GLES30.glCompileShader(shader); + + // Check the compile status + GLES30.glGetShaderiv(shader, GLES30.GL_COMPILE_STATUS, compiled, 0); + + if (compiled[0] == 0) + { + Log.e(TAG, GLES30.glGetShaderInfoLog(shader)); + GLES30.glDeleteShader(shader); + return 0; + } + return shader; + } + + /// + // Initialize the shader and program object + // + public void onSurfaceCreated(GL10 glUnused, EGLConfig config) + { + String vShaderStr = + "#version 300 es \n" + + "in vec4 vPosition; \n" + + "void main() \n" + + "{ \n" + + " gl_Position = vPosition; \n" + + "} \n"; + + String fShaderStr = + "#version 300 es \n" + + "precision mediump float; \n" + + "out vec4 fragColor; \n" + + "void main() \n" + + "{ \n" + + " fragColor = vec4 ( 1.0, 0.0, 0.0, 1.0 ); \n" + + "} \n"; + + int vertexShader; + int fragmentShader; + int programObject; + int[] linked = new int[1]; + + // Load the vertex/fragment shaders + vertexShader = LoadShader(GLES30.GL_VERTEX_SHADER, vShaderStr); + fragmentShader = LoadShader(GLES30.GL_FRAGMENT_SHADER, fShaderStr); + + // Create the program object + programObject = GLES30.glCreateProgram(); + + if (programObject == 0) + return; + + GLES30.glAttachShader(programObject, vertexShader); + GLES30.glAttachShader(programObject, fragmentShader); + + // Bind vPosition to attribute 0 + GLES30.glBindAttribLocation(programObject, 0, "vPosition"); + + // Link the program + GLES30.glLinkProgram(programObject); + + // Check the link status + GLES30.glGetProgramiv(programObject, GLES30.GL_LINK_STATUS, linked, 0); + + if (linked[0] == 0) + { + Log.e(TAG, "Error linking program:"); + Log.e(TAG, GLES30.glGetProgramInfoLog(programObject)); + GLES30.glDeleteProgram(programObject); + return; + } + + // Store the program object + mProgramObject = programObject; + + GLES30.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + } + + // / + // Draw a triangle using the shader pair created in onSurfaceCreated() + // + public void onDrawFrame(GL10 glUnused) + { + // Set the viewport + GLES30.glViewport(0, 0, mWidth, mHeight); + + // Clear the color buffer + GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT); + + // Use the program object + GLES30.glUseProgram(mProgramObject); + + // Load the vertex data + GLES30.glVertexAttribPointer(0, 3, GLES30.GL_FLOAT, false, 0, mVertices); + GLES30.glEnableVertexAttribArray(0); + + GLES30.glDrawArrays(GLES30.GL_TRIANGLES, 0, 3); + } + + // / + // Handle surface changes + // + public void onSurfaceChanged(GL10 glUnused, int width, int height) + { + mWidth = width; + mHeight = height; + } + + // Member variables + private int mProgramObject; + private int mWidth; + private int mHeight; + private FloatBuffer mVertices; + private static String TAG = "HelloTriangleRenderer"; + + private final float[] mVerticesData = + { 0.0f, 0.5f, 0.0f, -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f }; + +} diff --git a/Android_Java/Chapter_6/Example_6_3/.classpath b/Android_Java/Chapter_6/Example_6_3/.classpath new file mode 100644 index 0000000..4d67fc6 --- /dev/null +++ b/Android_Java/Chapter_6/Example_6_3/.classpath @@ -0,0 +1,5 @@ + + + + + diff --git a/Android_Java/Chapter_6/Example_6_3/.project b/Android_Java/Chapter_6/Example_6_3/.project new file mode 100644 index 0000000..d647781 --- /dev/null +++ b/Android_Java/Chapter_6/Example_6_3/.project @@ -0,0 +1,33 @@ + + + Ch6_Example_6_3 + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/Android_Java/Chapter_6/Example_6_3/AndroidManifest.xml b/Android_Java/Chapter_6/Example_6_3/AndroidManifest.xml new file mode 100644 index 0000000..747662b --- /dev/null +++ b/Android_Java/Chapter_6/Example_6_3/AndroidManifest.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Android_Java/Chapter_6/Example_6_3/default.properties b/Android_Java/Chapter_6/Example_6_3/default.properties new file mode 100644 index 0000000..5ccd841 --- /dev/null +++ b/Android_Java/Chapter_6/Example_6_3/default.properties @@ -0,0 +1,12 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-18 +android.library.reference.1=../../Common/ diff --git a/Android_Java/Chapter_6/Example_6_3/proguard.cfg b/Android_Java/Chapter_6/Example_6_3/proguard.cfg new file mode 100644 index 0000000..8ad7d33 --- /dev/null +++ b/Android_Java/Chapter_6/Example_6_3/proguard.cfg @@ -0,0 +1,34 @@ +-optimizationpasses 5 +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses +-dontpreverify +-verbose +-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class com.android.vending.licensing.ILicensingService + +-keepclasseswithmembernames class * { + native ; +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet, int); +} + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} diff --git a/Android_Java/Chapter_6/Example_6_3/res/drawable-hdpi/icon.png b/Android_Java/Chapter_6/Example_6_3/res/drawable-hdpi/icon.png new file mode 100644 index 0000000..8074c4c Binary files /dev/null and b/Android_Java/Chapter_6/Example_6_3/res/drawable-hdpi/icon.png differ diff --git a/Android_Java/Chapter_6/Example_6_3/res/drawable-ldpi/icon.png b/Android_Java/Chapter_6/Example_6_3/res/drawable-ldpi/icon.png new file mode 100644 index 0000000..1095584 Binary files /dev/null and b/Android_Java/Chapter_6/Example_6_3/res/drawable-ldpi/icon.png differ diff --git a/Android_Java/Chapter_6/Example_6_3/res/drawable-mdpi/icon.png b/Android_Java/Chapter_6/Example_6_3/res/drawable-mdpi/icon.png new file mode 100644 index 0000000..a07c69f Binary files /dev/null and b/Android_Java/Chapter_6/Example_6_3/res/drawable-mdpi/icon.png differ diff --git a/Android_Java/Chapter_6/Example_6_3/res/values/strings.xml b/Android_Java/Chapter_6/Example_6_3/res/values/strings.xml new file mode 100644 index 0000000..68f9915 --- /dev/null +++ b/Android_Java/Chapter_6/Example_6_3/res/values/strings.xml @@ -0,0 +1,4 @@ + + + Ch6_Example_6_3 + diff --git a/Android_Java/Chapter_6/Example_6_3/src/com/openglesbook/example6_3/Example6_3.java b/Android_Java/Chapter_6/Example_6_3/src/com/openglesbook/example6_3/Example6_3.java new file mode 100644 index 0000000..40c11a5 --- /dev/null +++ b/Android_Java/Chapter_6/Example_6_3/src/com/openglesbook/example6_3/Example6_3.java @@ -0,0 +1,66 @@ +package com.openglesbook.example6_3; + +import android.app.Activity; +import android.app.ActivityManager; +import android.content.Context; +import android.content.pm.ConfigurationInfo; +import android.opengl.GLSurfaceView; +import android.os.Bundle; +import android.util.Log; + +/** + * Activity class for example program that detects OpenGL ES 3.0. + **/ +public class Example6_3 extends Activity { + + private final int CONTEXT_CLIENT_VERSION = 3; + + @Override + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + mGLSurfaceView = new GLSurfaceView(this); + if (detectOpenGLES30()) + { + // Tell the surface view we want to create an OpenGL ES 3.0-compatible + // context, and set an OpenGL ES 3.0-compatible renderer. + mGLSurfaceView.setEGLContextClientVersion(CONTEXT_CLIENT_VERSION); + mGLSurfaceView.setRenderer(new Example6_3Renderer(this)); + } + else + { + Log.e("SimpleTexture2D", "OpenGL ES 3.0 not supported on device. Exiting..."); + finish(); + + } + setContentView(mGLSurfaceView); + } + + private boolean detectOpenGLES30() + { + ActivityManager am = + (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); + ConfigurationInfo info = am.getDeviceConfigurationInfo(); + return (info.reqGlEsVersion >= 0x30000); + } + + @Override + protected void onResume() + { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onResume(); + mGLSurfaceView.onResume(); + } + + @Override + protected void onPause() + { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onPause(); + mGLSurfaceView.onPause(); + } + + private GLSurfaceView mGLSurfaceView; +} diff --git a/Android_Java/Chapter_6/Example_6_3/src/com/openglesbook/example6_3/Example6_3Renderer.java b/Android_Java/Chapter_6/Example_6_3/src/com/openglesbook/example6_3/Example6_3Renderer.java new file mode 100644 index 0000000..f97a44b --- /dev/null +++ b/Android_Java/Chapter_6/Example_6_3/src/com/openglesbook/example6_3/Example6_3Renderer.java @@ -0,0 +1,133 @@ +// +// Book: OpenGL(R) ES 3.0 Programming Guide +// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner +// ISBN-10: 0321502795 +// ISBN-13: 9780321502797 +// Publisher: Addison-Wesley Professional +// URLs: http://safari.informit.com/9780321563835 +// http://www.opengles-book.com +// + +// Example_6_3 +// +// This example demonstrates using client-side vertex arrays +// and a constant vertex attribute +// + +package com.openglesbook.example6_3; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; + +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; + +import com.openglesbook.common.ESShader; + +import android.content.Context; +import android.opengl.GLES30; +import android.opengl.GLSurfaceView; + +public class Example6_3Renderer implements GLSurfaceView.Renderer +{ + + /// + // Constructor + // + public Example6_3Renderer(Context context) + { + + mVertices = ByteBuffer.allocateDirect(mVerticesData.length * 4) + .order(ByteOrder.nativeOrder()).asFloatBuffer(); + mVertices.put(mVerticesData).position(0); + } + + /// + // Initialize the shader and program object + // + public void onSurfaceCreated(GL10 glUnused, EGLConfig config) + { + String vShaderStr = + "#version 300 es \n" + + "layout(location = 0) in vec4 a_color; \n" + + "layout(location = 1) in vec4 a_position; \n" + + "out vec4 v_color; \n" + + "void main() \n" + + "{ \n" + + " v_color = a_color; \n" + + " gl_Position = a_position; \n" + + "}"; + + + String fShaderStr = + "#version 300 es \n" + + "precision mediump float; \n" + + "in vec4 v_color; \n" + + "out vec4 o_fragColor; \n" + + "void main() \n" + + "{ \n" + + " o_fragColor = v_color; \n" + + "}" ; + + // Load the shaders and get a linked program object + mProgramObject = ESShader.loadProgram(vShaderStr, fShaderStr); + + GLES30.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + } + + // / + // Draw a triangle using the shader pair created in onSurfaceCreated() + // + public void onDrawFrame(GL10 glUnused) + { + // Set the viewport + GLES30.glViewport(0, 0, mWidth, mHeight); + + // Clear the color buffer + GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT); + + // Use the program object + GLES30.glUseProgram(mProgramObject); + + // Set the vertex color to red + GLES30.glVertexAttrib4f( 0, 1.0f, 0.0f, 0.0f, 1.0f ); + + // Load the vertex position + mVertices.position(0); + GLES30.glVertexAttribPointer ( 1, 3, GLES30.GL_FLOAT, + false, + 0, mVertices ); + + GLES30.glEnableVertexAttribArray ( 1 ); + + GLES30.glDrawArrays ( GLES30.GL_TRIANGLES, 0, 3 ); + + GLES30.glDisableVertexAttribArray ( 1 ); + } + + /// + // Handle surface changes + // + public void onSurfaceChanged(GL10 glUnused, int width, int height) + { + mWidth = width; + mHeight = height; + } + + + // Handle to a program object + private int mProgramObject; + + // Additional member variables + private int mWidth; + private int mHeight; + private FloatBuffer mVertices; + + private final float[] mVerticesData = + { + 0.0f, 0.5f, 0.0f, // v0 + -0.5f, -0.5f, 0.0f, // v1 + 0.5f, -0.5f, 0.0f // v2 + }; +} diff --git a/Android_Java/Chapter_6/Example_6_6/.classpath b/Android_Java/Chapter_6/Example_6_6/.classpath new file mode 100644 index 0000000..4d67fc6 --- /dev/null +++ b/Android_Java/Chapter_6/Example_6_6/.classpath @@ -0,0 +1,5 @@ + + + + + diff --git a/Android_Java/Chapter_6/Example_6_6/.project b/Android_Java/Chapter_6/Example_6_6/.project new file mode 100644 index 0000000..e41d267 --- /dev/null +++ b/Android_Java/Chapter_6/Example_6_6/.project @@ -0,0 +1,33 @@ + + + Ch6_Example_6_6 + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/Android_Java/Chapter_6/Example_6_6/AndroidManifest.xml b/Android_Java/Chapter_6/Example_6_6/AndroidManifest.xml new file mode 100644 index 0000000..5e59d29 --- /dev/null +++ b/Android_Java/Chapter_6/Example_6_6/AndroidManifest.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Android_Java/Chapter_6/Example_6_6/default.properties b/Android_Java/Chapter_6/Example_6_6/default.properties new file mode 100644 index 0000000..5ccd841 --- /dev/null +++ b/Android_Java/Chapter_6/Example_6_6/default.properties @@ -0,0 +1,12 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-18 +android.library.reference.1=../../Common/ diff --git a/Android_Java/Chapter_6/Example_6_6/proguard.cfg b/Android_Java/Chapter_6/Example_6_6/proguard.cfg new file mode 100644 index 0000000..8ad7d33 --- /dev/null +++ b/Android_Java/Chapter_6/Example_6_6/proguard.cfg @@ -0,0 +1,34 @@ +-optimizationpasses 5 +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses +-dontpreverify +-verbose +-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class com.android.vending.licensing.ILicensingService + +-keepclasseswithmembernames class * { + native ; +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet, int); +} + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} diff --git a/Android_Java/Chapter_6/Example_6_6/res/drawable-hdpi/icon.png b/Android_Java/Chapter_6/Example_6_6/res/drawable-hdpi/icon.png new file mode 100644 index 0000000..8074c4c Binary files /dev/null and b/Android_Java/Chapter_6/Example_6_6/res/drawable-hdpi/icon.png differ diff --git a/Android_Java/Chapter_6/Example_6_6/res/drawable-ldpi/icon.png b/Android_Java/Chapter_6/Example_6_6/res/drawable-ldpi/icon.png new file mode 100644 index 0000000..1095584 Binary files /dev/null and b/Android_Java/Chapter_6/Example_6_6/res/drawable-ldpi/icon.png differ diff --git a/Android_Java/Chapter_6/Example_6_6/res/drawable-mdpi/icon.png b/Android_Java/Chapter_6/Example_6_6/res/drawable-mdpi/icon.png new file mode 100644 index 0000000..a07c69f Binary files /dev/null and b/Android_Java/Chapter_6/Example_6_6/res/drawable-mdpi/icon.png differ diff --git a/Android_Java/Chapter_6/Example_6_6/res/values/strings.xml b/Android_Java/Chapter_6/Example_6_6/res/values/strings.xml new file mode 100644 index 0000000..47003db --- /dev/null +++ b/Android_Java/Chapter_6/Example_6_6/res/values/strings.xml @@ -0,0 +1,4 @@ + + + Ch6_Example_6_6 + diff --git a/Android_Java/Chapter_6/Example_6_6/src/com/openglesbook/example6_6/Example6_6.java b/Android_Java/Chapter_6/Example_6_6/src/com/openglesbook/example6_6/Example6_6.java new file mode 100644 index 0000000..f2b61e5 --- /dev/null +++ b/Android_Java/Chapter_6/Example_6_6/src/com/openglesbook/example6_6/Example6_6.java @@ -0,0 +1,66 @@ +package com.openglesbook.example6_6; + +import android.app.Activity; +import android.app.ActivityManager; +import android.content.Context; +import android.content.pm.ConfigurationInfo; +import android.opengl.GLSurfaceView; +import android.os.Bundle; +import android.util.Log; + +/** + * Activity class for example program that detects OpenGL ES 3.0. + **/ +public class Example6_6 extends Activity { + + private final int CONTEXT_CLIENT_VERSION = 3; + + @Override + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + mGLSurfaceView = new GLSurfaceView(this); + if (detectOpenGLES30()) + { + // Tell the surface view we want to create an OpenGL ES 3.0-compatible + // context, and set an OpenGL ES 3.0-compatible renderer. + mGLSurfaceView.setEGLContextClientVersion(CONTEXT_CLIENT_VERSION); + mGLSurfaceView.setRenderer(new Example6_6Renderer(this)); + } + else + { + Log.e("SimpleTexture2D", "OpenGL ES 3.0 not supported on device. Exiting..."); + finish(); + + } + setContentView(mGLSurfaceView); + } + + private boolean detectOpenGLES30() + { + ActivityManager am = + (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); + ConfigurationInfo info = am.getDeviceConfigurationInfo(); + return (info.reqGlEsVersion >= 0x30000); + } + + @Override + protected void onResume() + { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onResume(); + mGLSurfaceView.onResume(); + } + + @Override + protected void onPause() + { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onPause(); + mGLSurfaceView.onPause(); + } + + private GLSurfaceView mGLSurfaceView; +} diff --git a/Android_Java/Chapter_6/Example_6_6/src/com/openglesbook/example6_6/Example6_6Renderer.java b/Android_Java/Chapter_6/Example_6_6/src/com/openglesbook/example6_6/Example6_6Renderer.java new file mode 100644 index 0000000..521a4f4 --- /dev/null +++ b/Android_Java/Chapter_6/Example_6_6/src/com/openglesbook/example6_6/Example6_6Renderer.java @@ -0,0 +1,215 @@ +// +// Book: OpenGL(R) ES 3.0 Programming Guide +// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner +// ISBN-10: 0321502795 +// ISBN-13: 9780321502797 +// Publisher: Addison-Wesley Professional +// URLs: http://safari.informit.com/9780321563835 +// http://www.opengles-book.com +// + +// Example_6_6 +// +// This example demonstrates drawing a primitive with +// a separate VBO per attribute +// +// + +package com.openglesbook.example6_6; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; +import java.nio.ShortBuffer; + +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; + +import com.openglesbook.common.ESShader; + +import android.content.Context; +import android.opengl.GLES30; +import android.opengl.GLSurfaceView; + +public class Example6_6Renderer implements GLSurfaceView.Renderer +{ + + /// + // Constructor + // + public Example6_6Renderer(Context context) + { + mVertices = ByteBuffer.allocateDirect(mVerticesData.length * 4) + .order(ByteOrder.nativeOrder()).asFloatBuffer(); + mVertices.put(mVerticesData).position(0); + + mColors = ByteBuffer.allocateDirect(mColorData.length * 4) + .order(ByteOrder.nativeOrder()).asFloatBuffer(); + mColors.put(mColorData).position(0); + + mIndices = ByteBuffer.allocateDirect(mIndicesData.length * 2) + .order(ByteOrder.nativeOrder()).asShortBuffer(); + mIndices.put(mIndicesData).position(0); + } + + /// + // Initialize the shader and program object + // + public void onSurfaceCreated(GL10 glUnused, EGLConfig config) + { + String vShaderStr = + "#version 300 es \n" + + "layout(location = 0) in vec4 a_position; \n" + + "layout(location = 1) in vec4 a_color; \n" + + "out vec4 v_color; \n" + + "void main() \n" + + "{ \n" + + " v_color = a_color; \n" + + " gl_Position = a_position; \n" + + "}"; + + + String fShaderStr = + "#version 300 es \n" + + "precision mediump float; \n" + + "in vec4 v_color; \n" + + "out vec4 o_fragColor; \n" + + "void main() \n" + + "{ \n" + + " o_fragColor = v_color; \n" + + "}" ; + + // Load the shaders and get a linked program object + mProgramObject = ESShader.loadProgram(vShaderStr, fShaderStr); + + mVBOIds[0] = 0; + mVBOIds[1] = 0; + mVBOIds[2] = 0; + + GLES30.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + } + + // / + // Draw a triangle using the shader pair created in onSurfaceCreated() + // + public void onDrawFrame(GL10 glUnused) + { + // Set the viewport + GLES30.glViewport(0, 0, mWidth, mHeight); + + // Clear the color buffer + GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT); + + // Use the program object + GLES30.glUseProgram(mProgramObject); + + drawPrimitiveWithVBOs(); + } + + private void drawPrimitiveWithVBOs() + { + int numVertices = 3; + int numIndices = 3; + + // mVBOIds[0] - used to store vertex position + // mVBOIds[1] - used to store vertex color + // mVBOIds[2] - used to store element indices + if ( mVBOIds[0] == 0 && mVBOIds[1] == 0 && mVBOIds[2] == 0) + { + // Only allocate on the first draw + GLES30.glGenBuffers(3, mVBOIds, 0); + + mVertices.position(0); + GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mVBOIds[0]); + GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, vtxStrides[0] * numVertices, + mVertices, GLES30.GL_STATIC_DRAW); + + mColors.position(0); + GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mVBOIds[1]); + GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, vtxStrides[1] * numVertices, + mColors, GLES30.GL_STATIC_DRAW); + + mIndices.position(0); + GLES30.glBindBuffer(GLES30.GL_ELEMENT_ARRAY_BUFFER, mVBOIds[2]); + GLES30.glBufferData(GLES30.GL_ELEMENT_ARRAY_BUFFER, 2 * numIndices, + mIndices, GLES30.GL_STATIC_DRAW); + } + + GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mVBOIds[0]); + + GLES30.glEnableVertexAttribArray(VERTEX_POS_INDX); + GLES30.glVertexAttribPointer(VERTEX_POS_INDX, VERTEX_POS_SIZE, + GLES30.GL_FLOAT, false, vtxStrides[0], 0); + + GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mVBOIds[1]); + + GLES30.glEnableVertexAttribArray(VERTEX_COLOR_INDX); + GLES30.glVertexAttribPointer(VERTEX_COLOR_INDX, VERTEX_COLOR_SIZE, + GLES30.GL_FLOAT, false, vtxStrides[1], 0); + + GLES30.glBindBuffer(GLES30.GL_ELEMENT_ARRAY_BUFFER, mVBOIds[2]); + + GLES30.glDrawElements(GLES30.GL_TRIANGLES, numIndices, + GLES30.GL_UNSIGNED_SHORT, 0); + + GLES30.glDisableVertexAttribArray(VERTEX_POS_INDX); + GLES30.glDisableVertexAttribArray(VERTEX_COLOR_INDX); + + GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, 0); + GLES30.glBindBuffer(GLES30.GL_ELEMENT_ARRAY_BUFFER, 0); + } + + /// + // Handle surface changes + // + public void onSurfaceChanged(GL10 glUnused, int width, int height) + { + mWidth = width; + mHeight = height; + } + + // Handle to a program object + private int mProgramObject; + + // Additional member variables + private int mWidth; + private int mHeight; + private FloatBuffer mVertices; + private FloatBuffer mColors; + private ShortBuffer mIndices; + + // VertexBufferObject Ids + private int [] mVBOIds = new int[3]; + + // 3 vertices, with (x,y,z) ,(r, g, b, a) per-vertex + private final float[] mVerticesData = + { + 0.0f, 0.5f, 0.0f, // v0 + -0.5f, -0.5f, 0.0f, // v1 + 0.5f, -0.5f, 0.0f // v2 + }; + + private final short[] mIndicesData = + { + 0, 1, 2 + }; + + private final float [] mColorData = + { + 1.0f, 0.0f, 0.0f, 1.0f, // c0 + 0.0f, 1.0f, 0.0f, 1.0f, // c1 + 0.0f, 0.0f, 1.0f, 1.0f // c2 + }; + + final int VERTEX_POS_SIZE = 3; // x, y and z + final int VERTEX_COLOR_SIZE = 4; // r, g, b, and a + + final int VERTEX_POS_INDX = 0; + final int VERTEX_COLOR_INDX = 1; + + private int vtxStrides[] = + { + VERTEX_POS_SIZE * 4, + VERTEX_COLOR_SIZE * 4 + }; +} diff --git a/Android_Java/Chapter_6/VertexArrayObjects/.classpath b/Android_Java/Chapter_6/VertexArrayObjects/.classpath new file mode 100644 index 0000000..4d67fc6 --- /dev/null +++ b/Android_Java/Chapter_6/VertexArrayObjects/.classpath @@ -0,0 +1,5 @@ + + + + + diff --git a/Android_Java/Chapter_6/VertexArrayObjects/.project b/Android_Java/Chapter_6/VertexArrayObjects/.project new file mode 100644 index 0000000..3e90c2d --- /dev/null +++ b/Android_Java/Chapter_6/VertexArrayObjects/.project @@ -0,0 +1,33 @@ + + + Ch6_VertexArrayObjects + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/Android_Java/Chapter_6/VertexArrayObjects/AndroidManifest.xml b/Android_Java/Chapter_6/VertexArrayObjects/AndroidManifest.xml new file mode 100644 index 0000000..d38c0a5 --- /dev/null +++ b/Android_Java/Chapter_6/VertexArrayObjects/AndroidManifest.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Android_Java/Chapter_6/VertexArrayObjects/default.properties b/Android_Java/Chapter_6/VertexArrayObjects/default.properties new file mode 100644 index 0000000..5ccd841 --- /dev/null +++ b/Android_Java/Chapter_6/VertexArrayObjects/default.properties @@ -0,0 +1,12 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-18 +android.library.reference.1=../../Common/ diff --git a/Android_Java/Chapter_6/VertexArrayObjects/proguard.cfg b/Android_Java/Chapter_6/VertexArrayObjects/proguard.cfg new file mode 100644 index 0000000..8ad7d33 --- /dev/null +++ b/Android_Java/Chapter_6/VertexArrayObjects/proguard.cfg @@ -0,0 +1,34 @@ +-optimizationpasses 5 +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses +-dontpreverify +-verbose +-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class com.android.vending.licensing.ILicensingService + +-keepclasseswithmembernames class * { + native ; +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet, int); +} + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} diff --git a/Android_Java/Chapter_6/VertexArrayObjects/res/drawable-hdpi/icon.png b/Android_Java/Chapter_6/VertexArrayObjects/res/drawable-hdpi/icon.png new file mode 100644 index 0000000..8074c4c Binary files /dev/null and b/Android_Java/Chapter_6/VertexArrayObjects/res/drawable-hdpi/icon.png differ diff --git a/Android_Java/Chapter_6/VertexArrayObjects/res/drawable-ldpi/icon.png b/Android_Java/Chapter_6/VertexArrayObjects/res/drawable-ldpi/icon.png new file mode 100644 index 0000000..1095584 Binary files /dev/null and b/Android_Java/Chapter_6/VertexArrayObjects/res/drawable-ldpi/icon.png differ diff --git a/Android_Java/Chapter_6/VertexArrayObjects/res/drawable-mdpi/icon.png b/Android_Java/Chapter_6/VertexArrayObjects/res/drawable-mdpi/icon.png new file mode 100644 index 0000000..a07c69f Binary files /dev/null and b/Android_Java/Chapter_6/VertexArrayObjects/res/drawable-mdpi/icon.png differ diff --git a/Android_Java/Chapter_6/VertexArrayObjects/res/values/strings.xml b/Android_Java/Chapter_6/VertexArrayObjects/res/values/strings.xml new file mode 100644 index 0000000..948033b --- /dev/null +++ b/Android_Java/Chapter_6/VertexArrayObjects/res/values/strings.xml @@ -0,0 +1,4 @@ + + + Ch6_VertexArrayObjects + diff --git a/Android_Java/Chapter_6/VertexArrayObjects/src/com/openglesbook/VertexArrayObjects/VAO.java b/Android_Java/Chapter_6/VertexArrayObjects/src/com/openglesbook/VertexArrayObjects/VAO.java new file mode 100644 index 0000000..0819f4a --- /dev/null +++ b/Android_Java/Chapter_6/VertexArrayObjects/src/com/openglesbook/VertexArrayObjects/VAO.java @@ -0,0 +1,66 @@ +package com.openglesbook.VertexArrayObjects; + +import android.app.Activity; +import android.app.ActivityManager; +import android.content.Context; +import android.content.pm.ConfigurationInfo; +import android.opengl.GLSurfaceView; +import android.os.Bundle; +import android.util.Log; + +/** + * Activity class for example program that detects OpenGL ES 3.0. + **/ +public class VAO extends Activity { + + private final int CONTEXT_CLIENT_VERSION = 3; + + @Override + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + mGLSurfaceView = new GLSurfaceView(this); + if (detectOpenGLES30()) + { + // Tell the surface view we want to create an OpenGL ES 3.0-compatible + // context, and set an OpenGL ES 3.0-compatible renderer. + mGLSurfaceView.setEGLContextClientVersion(CONTEXT_CLIENT_VERSION); + mGLSurfaceView.setRenderer(new VAORenderer(this)); + } + else + { + Log.e("SimpleTexture2D", "OpenGL ES 3.0 not supported on device. Exiting..."); + finish(); + + } + setContentView(mGLSurfaceView); + } + + private boolean detectOpenGLES30() + { + ActivityManager am = + (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); + ConfigurationInfo info = am.getDeviceConfigurationInfo(); + return (info.reqGlEsVersion >= 0x30000); + } + + @Override + protected void onResume() + { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onResume(); + mGLSurfaceView.onResume(); + } + + @Override + protected void onPause() + { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onPause(); + mGLSurfaceView.onPause(); + } + + private GLSurfaceView mGLSurfaceView; +} diff --git a/Android_Java/Chapter_6/VertexArrayObjects/src/com/openglesbook/VertexArrayObjects/VAORenderer.java b/Android_Java/Chapter_6/VertexArrayObjects/src/com/openglesbook/VertexArrayObjects/VAORenderer.java new file mode 100644 index 0000000..d32f79d --- /dev/null +++ b/Android_Java/Chapter_6/VertexArrayObjects/src/com/openglesbook/VertexArrayObjects/VAORenderer.java @@ -0,0 +1,193 @@ +// +// Book: OpenGL(R) ES 3.0 Programming Guide +// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner +// ISBN-10: 0321502795 +// ISBN-13: 9780321502797 +// Publisher: Addison-Wesley Professional +// URLs: http://safari.informit.com/9780321563835 +// http://www.opengles-book.com +// + +// VertexArrayObjects +// +// This is a simple example drawing a primitive with +// Vertex Array Objects (VAOs) +// + +package com.openglesbook.VertexArrayObjects; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; +import java.nio.ShortBuffer; + +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; + +import com.openglesbook.common.ESShader; + +import android.content.Context; +import android.opengl.GLES30; +import android.opengl.GLSurfaceView; + +public class VAORenderer implements GLSurfaceView.Renderer +{ + + /// + // Constructor + // + public VAORenderer(Context context) + { + mVertices = ByteBuffer.allocateDirect(mVerticesData.length * 4) + .order(ByteOrder.nativeOrder()).asFloatBuffer(); + mVertices.put(mVerticesData).position(0); + + mIndices = ByteBuffer.allocateDirect(mIndicesData.length * 2) + .order(ByteOrder.nativeOrder()).asShortBuffer(); + mIndices.put(mIndicesData).position(0); + } + + /// + // Initialize the shader and program object + // + public void onSurfaceCreated(GL10 glUnused, EGLConfig config) + { + String vShaderStr = + "#version 300 es \n" + + "layout(location = 0) in vec4 a_position; \n" + + "layout(location = 1) in vec4 a_color; \n" + + "out vec4 v_color; \n" + + "void main() \n" + + "{ \n" + + " v_color = a_color; \n" + + " gl_Position = a_position; \n" + + "}"; + + + String fShaderStr = + "#version 300 es \n" + + "precision mediump float; \n" + + "in vec4 v_color; \n" + + "out vec4 o_fragColor; \n" + + "void main() \n" + + "{ \n" + + " o_fragColor = v_color; \n" + + "}" ; + + // Load the shaders and get a linked program object + mProgramObject = ESShader.loadProgram(vShaderStr, fShaderStr); + + // Generate VBO Ids and load the VBOs with data + GLES30.glGenBuffers(2, mVBOIds, 0); + + GLES30.glBindBuffer ( GLES30.GL_ARRAY_BUFFER, mVBOIds[0] ); + + mVertices.position(0); + GLES30.glBufferData ( GLES30.GL_ARRAY_BUFFER, mVerticesData.length * 4, + mVertices, GLES30.GL_STATIC_DRAW); + + GLES30.glBindBuffer ( GLES30.GL_ELEMENT_ARRAY_BUFFER, mVBOIds[1]); + + mIndices.position(0); + GLES30.glBufferData ( GLES30.GL_ELEMENT_ARRAY_BUFFER, 2 * mIndicesData.length, + mIndices, GLES30.GL_STATIC_DRAW ); + + // Generate VAO Id + GLES30.glGenVertexArrays ( 1, mVAOId, 0 ); + + // Bind the VAO and then setup the vertex + // attributes + GLES30.glBindVertexArray ( mVAOId[0] ); + + GLES30.glBindBuffer( GLES30.GL_ARRAY_BUFFER, mVBOIds[0] ); + GLES30.glBindBuffer( GLES30.GL_ELEMENT_ARRAY_BUFFER, mVBOIds[1] ); + + GLES30.glEnableVertexAttribArray( VERTEX_POS_INDX ); + GLES30.glEnableVertexAttribArray( VERTEX_COLOR_INDX ); + + GLES30.glVertexAttribPointer ( VERTEX_POS_INDX, VERTEX_POS_SIZE, + GLES30.GL_FLOAT, false, VERTEX_STRIDE, + 0 ); + + GLES30.glVertexAttribPointer ( VERTEX_COLOR_INDX, VERTEX_COLOR_SIZE, + GLES30.GL_FLOAT, false, VERTEX_STRIDE, + (VERTEX_POS_SIZE * 4) ); + + // Reset to the default VAO + GLES30.glBindVertexArray ( 0 ); + + GLES30.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + } + + // / + // Draw a triangle using the shader pair created in onSurfaceCreated() + // + public void onDrawFrame(GL10 glUnused) + { + // Set the viewport + GLES30.glViewport(0, 0, mWidth, mHeight); + + // Clear the color buffer + GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT); + + // Use the program object + GLES30.glUseProgram(mProgramObject); + + // Bind the VAO + GLES30.glBindVertexArray ( mVAOId[0] ); + + // Draw with the VAO settings + GLES30.glDrawElements ( GLES30.GL_TRIANGLES, mIndicesData.length, GLES30.GL_UNSIGNED_SHORT, 0 ); + + // Return to the default VAO + GLES30.glBindVertexArray ( 0 ); + } + + /// + // Handle surface changes + // + public void onSurfaceChanged(GL10 glUnused, int width, int height) + { + mWidth = width; + mHeight = height; + } + + // Handle to a program object + private int mProgramObject; + + // Additional member variables + private int mWidth; + private int mHeight; + private FloatBuffer mVertices; + private ShortBuffer mIndices; + + // VertexBufferObject Ids + private int [] mVBOIds = new int[2]; + + // VertexArrayObject Id + private int [] mVAOId = new int[1]; + + // 3 vertices, with (x,y,z) ,(r, g, b, a) per-vertex + private final float[] mVerticesData = + { + 0.0f, 0.5f, 0.0f, // v0 + 1.0f, 0.0f, 0.0f, 1.0f, // c0 + -0.5f, -0.5f, 0.0f, // v1 + 0.0f, 1.0f, 0.0f, 1.0f, // c1 + 0.5f, -0.5f, 0.0f, // v2 + 0.0f, 0.0f, 1.0f, 1.0f, // c2 + }; + + private final short[] mIndicesData = + { + 0, 1, 2 + }; + + final int VERTEX_POS_SIZE = 3; // x, y and z + final int VERTEX_COLOR_SIZE = 4; // r, g, b, and a + + final int VERTEX_POS_INDX = 0; + final int VERTEX_COLOR_INDX = 1; + + final int VERTEX_STRIDE = ( 4 * ( VERTEX_POS_SIZE + VERTEX_COLOR_SIZE ) ); +} diff --git a/Android_Java/Chapter_6/VertexBufferObjects/.classpath b/Android_Java/Chapter_6/VertexBufferObjects/.classpath new file mode 100644 index 0000000..4d67fc6 --- /dev/null +++ b/Android_Java/Chapter_6/VertexBufferObjects/.classpath @@ -0,0 +1,5 @@ + + + + + diff --git a/Android_Java/Chapter_6/VertexBufferObjects/.project b/Android_Java/Chapter_6/VertexBufferObjects/.project new file mode 100644 index 0000000..559cc10 --- /dev/null +++ b/Android_Java/Chapter_6/VertexBufferObjects/.project @@ -0,0 +1,33 @@ + + + Ch6_VertexBufferObjects + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/Android_Java/Chapter_6/VertexBufferObjects/AndroidManifest.xml b/Android_Java/Chapter_6/VertexBufferObjects/AndroidManifest.xml new file mode 100644 index 0000000..d554f76 --- /dev/null +++ b/Android_Java/Chapter_6/VertexBufferObjects/AndroidManifest.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Android_Java/Chapter_6/VertexBufferObjects/default.properties b/Android_Java/Chapter_6/VertexBufferObjects/default.properties new file mode 100644 index 0000000..5ccd841 --- /dev/null +++ b/Android_Java/Chapter_6/VertexBufferObjects/default.properties @@ -0,0 +1,12 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-18 +android.library.reference.1=../../Common/ diff --git a/Android_Java/Chapter_6/VertexBufferObjects/proguard.cfg b/Android_Java/Chapter_6/VertexBufferObjects/proguard.cfg new file mode 100644 index 0000000..8ad7d33 --- /dev/null +++ b/Android_Java/Chapter_6/VertexBufferObjects/proguard.cfg @@ -0,0 +1,34 @@ +-optimizationpasses 5 +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses +-dontpreverify +-verbose +-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class com.android.vending.licensing.ILicensingService + +-keepclasseswithmembernames class * { + native ; +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet, int); +} + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} diff --git a/Android_Java/Chapter_6/VertexBufferObjects/res/drawable-hdpi/icon.png b/Android_Java/Chapter_6/VertexBufferObjects/res/drawable-hdpi/icon.png new file mode 100644 index 0000000..8074c4c Binary files /dev/null and b/Android_Java/Chapter_6/VertexBufferObjects/res/drawable-hdpi/icon.png differ diff --git a/Android_Java/Chapter_6/VertexBufferObjects/res/drawable-ldpi/icon.png b/Android_Java/Chapter_6/VertexBufferObjects/res/drawable-ldpi/icon.png new file mode 100644 index 0000000..1095584 Binary files /dev/null and b/Android_Java/Chapter_6/VertexBufferObjects/res/drawable-ldpi/icon.png differ diff --git a/Android_Java/Chapter_6/VertexBufferObjects/res/drawable-mdpi/icon.png b/Android_Java/Chapter_6/VertexBufferObjects/res/drawable-mdpi/icon.png new file mode 100644 index 0000000..a07c69f Binary files /dev/null and b/Android_Java/Chapter_6/VertexBufferObjects/res/drawable-mdpi/icon.png differ diff --git a/Android_Java/Chapter_6/VertexBufferObjects/res/values/strings.xml b/Android_Java/Chapter_6/VertexBufferObjects/res/values/strings.xml new file mode 100644 index 0000000..24aebf8 --- /dev/null +++ b/Android_Java/Chapter_6/VertexBufferObjects/res/values/strings.xml @@ -0,0 +1,4 @@ + + + Ch6_VertexBufferObjects + diff --git a/Android_Java/Chapter_6/VertexBufferObjects/src/com/openglesbook/VertexBufferObjects/VBO.java b/Android_Java/Chapter_6/VertexBufferObjects/src/com/openglesbook/VertexBufferObjects/VBO.java new file mode 100644 index 0000000..51d0e49 --- /dev/null +++ b/Android_Java/Chapter_6/VertexBufferObjects/src/com/openglesbook/VertexBufferObjects/VBO.java @@ -0,0 +1,66 @@ +package com.openglesbook.VertexBufferObjects; + +import android.app.Activity; +import android.app.ActivityManager; +import android.content.Context; +import android.content.pm.ConfigurationInfo; +import android.opengl.GLSurfaceView; +import android.os.Bundle; +import android.util.Log; + +/** + * Activity class for example program that detects OpenGL ES 3.0. + **/ +public class VBO extends Activity { + + private final int CONTEXT_CLIENT_VERSION = 3; + + @Override + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + mGLSurfaceView = new GLSurfaceView(this); + if (detectOpenGLES30()) + { + // Tell the surface view we want to create an OpenGL ES 3.0-compatible + // context, and set an OpenGL ES 3.0-compatible renderer. + mGLSurfaceView.setEGLContextClientVersion(CONTEXT_CLIENT_VERSION); + mGLSurfaceView.setRenderer(new VBORenderer(this)); + } + else + { + Log.e("SimpleTexture2D", "OpenGL ES 3.0 not supported on device. Exiting..."); + finish(); + + } + setContentView(mGLSurfaceView); + } + + private boolean detectOpenGLES30() + { + ActivityManager am = + (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); + ConfigurationInfo info = am.getDeviceConfigurationInfo(); + return (info.reqGlEsVersion >= 0x30000); + } + + @Override + protected void onResume() + { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onResume(); + mGLSurfaceView.onResume(); + } + + @Override + protected void onPause() + { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onPause(); + mGLSurfaceView.onPause(); + } + + private GLSurfaceView mGLSurfaceView; +} diff --git a/Android_Java/Chapter_6/VertexBufferObjects/src/com/openglesbook/VertexBufferObjects/VBORenderer.java b/Android_Java/Chapter_6/VertexBufferObjects/src/com/openglesbook/VertexBufferObjects/VBORenderer.java new file mode 100644 index 0000000..dca5fd5 --- /dev/null +++ b/Android_Java/Chapter_6/VertexBufferObjects/src/com/openglesbook/VertexBufferObjects/VBORenderer.java @@ -0,0 +1,237 @@ +// +// Book: OpenGL(R) ES 3.0 Programming Guide +// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner +// ISBN-10: 0321502795 +// ISBN-13: 9780321502797 +// Publisher: Addison-Wesley Professional +// URLs: http://safari.informit.com/9780321563835 +// http://www.opengles-book.com +// + +// VertexBufferObjects +// +// This example demonstrates drawing a primitive with +// and without Vertex Buffer Objects (VBOs) +// + +package com.openglesbook.VertexBufferObjects; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; +import java.nio.ShortBuffer; + +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; + +import com.openglesbook.common.ESShader; + +import android.content.Context; +import android.opengl.GLES30; +import android.opengl.GLSurfaceView; + +public class VBORenderer implements GLSurfaceView.Renderer +{ + + /// + // Constructor + // + public VBORenderer(Context context) + { + mVertices = ByteBuffer.allocateDirect(mVerticesData.length * 4) + .order(ByteOrder.nativeOrder()).asFloatBuffer(); + mVertices.put(mVerticesData).position(0); + + // Offset the vertex positions so both can be seen + for ( int i = 0; i < 3; i++ ) + { + mVerticesData[ i * (VERTEX_POS_SIZE + VERTEX_COLOR_SIZE) + 0] += 1.0f; + } + + mVertices1 = ByteBuffer.allocateDirect(mVerticesData.length * 4) + .order(ByteOrder.nativeOrder()).asFloatBuffer(); + mVertices1.put(mVerticesData).position(0); + + mIndices = ByteBuffer.allocateDirect(mIndicesData.length * 2) + .order(ByteOrder.nativeOrder()).asShortBuffer(); + mIndices.put(mIndicesData).position(0); + } + + /// + // Initialize the shader and program object + // + public void onSurfaceCreated(GL10 glUnused, EGLConfig config) + { + String vShaderStr = + "#version 300 es \n" + + "layout(location = 0) in vec4 a_position; \n" + + "layout(location = 1) in vec4 a_color; \n" + + "out vec4 v_color; \n" + + "void main() \n" + + "{ \n" + + " v_color = a_color; \n" + + " gl_Position = a_position; \n" + + "}"; + + + String fShaderStr = + "#version 300 es \n" + + "precision mediump float; \n" + + "in vec4 v_color; \n" + + "out vec4 o_fragColor; \n" + + "void main() \n" + + "{ \n" + + " o_fragColor = v_color; \n" + + "}" ; + + // Load the shaders and get a linked program object + mProgramObject = ESShader.loadProgram(vShaderStr, fShaderStr); + + mVBOIds[0] = 0; + mVBOIds[1] = 0; + + GLES30.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + } + + // / + // Draw a triangle using the shader pair created in onSurfaceCreated() + // + public void onDrawFrame(GL10 glUnused) + { + // Set the viewport + GLES30.glViewport(0, 0, mWidth, mHeight); + + // Clear the color buffer + GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT); + + // Use the program object + GLES30.glUseProgram(mProgramObject); + + // without VBOs + drawPrimitiveWithoutVBOs(); + + // with VBOs + drawPrimitiveWithVBOs(); + } + + private void drawPrimitiveWithoutVBOs() + { + int numIndices = 3; + int vtxStride = 4 * (VERTEX_POS_SIZE + VERTEX_COLOR_SIZE); + + GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, 0); + GLES30.glBindBuffer(GLES30.GL_ELEMENT_ARRAY_BUFFER, 0); + + GLES30.glEnableVertexAttribArray(VERTEX_POS_INDX); + GLES30.glEnableVertexAttribArray(VERTEX_COLOR_INDX); + + mVertices.position(0); + GLES30.glVertexAttribPointer(VERTEX_POS_INDX, VERTEX_POS_SIZE, + GLES30.GL_FLOAT, false, vtxStride, mVertices); + + mVertices.position(VERTEX_POS_SIZE); + GLES30.glVertexAttribPointer(VERTEX_COLOR_INDX, VERTEX_COLOR_SIZE, + GLES30.GL_FLOAT, false, vtxStride, mVertices); + + GLES30.glDrawElements(GLES30.GL_TRIANGLES, numIndices, + GLES30.GL_UNSIGNED_SHORT, mIndices); + + GLES30.glDisableVertexAttribArray(VERTEX_POS_INDX); + GLES30.glDisableVertexAttribArray(VERTEX_COLOR_INDX); + } + + private void drawPrimitiveWithVBOs() + { + int offset = 0; + int numVertices = 3; + int numIndices = 3; + int vtxStride = 4 * (VERTEX_POS_SIZE + VERTEX_COLOR_SIZE); + + // mVBOIds[0] - used to store vertex attribute data + // mVBOIds[l] - used to store element indices + if ( mVBOIds[0] == 0 && mVBOIds[1] == 0) + { + // Only allocate on the first draw + GLES30.glGenBuffers(2, mVBOIds, 0); + + mVertices1.position(0); + GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mVBOIds[0]); + GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, vtxStride * numVertices, + mVertices1, GLES30.GL_STATIC_DRAW); + + mIndices.position(0); + GLES30.glBindBuffer(GLES30.GL_ELEMENT_ARRAY_BUFFER, mVBOIds[1]); + GLES30.glBufferData(GLES30.GL_ELEMENT_ARRAY_BUFFER, 2 * numIndices, + mIndices, GLES30.GL_STATIC_DRAW); + } + + GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mVBOIds[0]); + GLES30.glBindBuffer(GLES30.GL_ELEMENT_ARRAY_BUFFER, mVBOIds[1]); + + GLES30.glEnableVertexAttribArray(VERTEX_POS_INDX); + GLES30.glEnableVertexAttribArray(VERTEX_COLOR_INDX); + + GLES30.glVertexAttribPointer(VERTEX_POS_INDX, VERTEX_POS_SIZE, + GLES30.GL_FLOAT, false, vtxStride, offset); + offset += VERTEX_POS_SIZE * 4; + + GLES30.glVertexAttribPointer(VERTEX_COLOR_INDX, VERTEX_COLOR_SIZE, + GLES30.GL_FLOAT, false, vtxStride, offset); + + GLES30.glDrawElements(GLES30.GL_TRIANGLES, numIndices, + GLES30.GL_UNSIGNED_SHORT, 0); + + GLES30.glDisableVertexAttribArray(VERTEX_POS_INDX); + GLES30.glDisableVertexAttribArray(VERTEX_COLOR_INDX); + + GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, 0); + GLES30.glBindBuffer(GLES30.GL_ELEMENT_ARRAY_BUFFER, 0); + } + + /// + // Handle surface changes + // + public void onSurfaceChanged(GL10 glUnused, int width, int height) + { + mWidth = width; + mHeight = height; + } + + // Handle to a program object + private int mProgramObject; + + // Additional member variables + private int mWidth; + private int mHeight; + private FloatBuffer mVertices; + private FloatBuffer mVertices1; + private ShortBuffer mIndices; + + // VertexBufferObject Ids + private int [] mVBOIds = new int[2]; + + // 3 vertices, with (x,y,z) ,(r, g, b, a) per-vertex + private final float[] mVerticesData = + { + -0.5f, 0.5f, 0.0f, // v0 + 1.0f, 0.0f, 0.0f, 1.0f, // c0 + -1.0f, -0.5f, 0.0f, // v1 + 0.0f, 1.0f, 0.0f, 1.0f, // c1 + 0.0f, -0.5f, 0.0f, // v2 + 0.0f, 0.0f, 1.0f, 1.0f, // c2 + }; + + // Index buffer data + private final short[] mIndicesData = + { + 0, 1, 2 + }; + + final int VERTEX_POS_SIZE = 3; // x, y and z + final int VERTEX_COLOR_SIZE = 4; // r, g, b, and a + + final int VERTEX_POS_INDX = 0; + final int VERTEX_COLOR_INDX = 1; + + final int VERTEX_STRIDE = ( 4 * ( VERTEX_POS_SIZE + VERTEX_COLOR_SIZE ) ); +} diff --git a/Android_Java/Chapter_8/Simple_VertexShader/.classpath b/Android_Java/Chapter_8/Simple_VertexShader/.classpath new file mode 100644 index 0000000..ce8b321 --- /dev/null +++ b/Android_Java/Chapter_8/Simple_VertexShader/.classpath @@ -0,0 +1,5 @@ + + + + + diff --git a/Android_Java/Chapter_8/Simple_VertexShader/.project b/Android_Java/Chapter_8/Simple_VertexShader/.project new file mode 100644 index 0000000..481b0b7 --- /dev/null +++ b/Android_Java/Chapter_8/Simple_VertexShader/.project @@ -0,0 +1,33 @@ + + + Ch8_Simple_VertexShader + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/Android_Java/Chapter_8/Simple_VertexShader/AndroidManifest.xml b/Android_Java/Chapter_8/Simple_VertexShader/AndroidManifest.xml new file mode 100644 index 0000000..6174d2c --- /dev/null +++ b/Android_Java/Chapter_8/Simple_VertexShader/AndroidManifest.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Android_Java/Chapter_8/Simple_VertexShader/default.properties b/Android_Java/Chapter_8/Simple_VertexShader/default.properties new file mode 100644 index 0000000..5ccd841 --- /dev/null +++ b/Android_Java/Chapter_8/Simple_VertexShader/default.properties @@ -0,0 +1,12 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-18 +android.library.reference.1=../../Common/ diff --git a/Android_Java/Chapter_8/Simple_VertexShader/proguard.cfg b/Android_Java/Chapter_8/Simple_VertexShader/proguard.cfg new file mode 100644 index 0000000..8ad7d33 --- /dev/null +++ b/Android_Java/Chapter_8/Simple_VertexShader/proguard.cfg @@ -0,0 +1,34 @@ +-optimizationpasses 5 +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses +-dontpreverify +-verbose +-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class com.android.vending.licensing.ILicensingService + +-keepclasseswithmembernames class * { + native ; +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet, int); +} + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} diff --git a/Android_Java/Chapter_8/Simple_VertexShader/res/drawable-hdpi/icon.png b/Android_Java/Chapter_8/Simple_VertexShader/res/drawable-hdpi/icon.png new file mode 100644 index 0000000..8074c4c Binary files /dev/null and b/Android_Java/Chapter_8/Simple_VertexShader/res/drawable-hdpi/icon.png differ diff --git a/Android_Java/Chapter_8/Simple_VertexShader/res/drawable-ldpi/icon.png b/Android_Java/Chapter_8/Simple_VertexShader/res/drawable-ldpi/icon.png new file mode 100644 index 0000000..1095584 Binary files /dev/null and b/Android_Java/Chapter_8/Simple_VertexShader/res/drawable-ldpi/icon.png differ diff --git a/Android_Java/Chapter_8/Simple_VertexShader/res/drawable-mdpi/icon.png b/Android_Java/Chapter_8/Simple_VertexShader/res/drawable-mdpi/icon.png new file mode 100644 index 0000000..a07c69f Binary files /dev/null and b/Android_Java/Chapter_8/Simple_VertexShader/res/drawable-mdpi/icon.png differ diff --git a/Android_Java/Chapter_8/Simple_VertexShader/res/values/strings.xml b/Android_Java/Chapter_8/Simple_VertexShader/res/values/strings.xml new file mode 100644 index 0000000..3662cbf --- /dev/null +++ b/Android_Java/Chapter_8/Simple_VertexShader/res/values/strings.xml @@ -0,0 +1,4 @@ + + + SimpleVertexShader + diff --git a/Android_Java/Chapter_8/Simple_VertexShader/src/com/openglesbook/simplevertexshader/SimpleVertexShader.java b/Android_Java/Chapter_8/Simple_VertexShader/src/com/openglesbook/simplevertexshader/SimpleVertexShader.java new file mode 100644 index 0000000..f1c2527 --- /dev/null +++ b/Android_Java/Chapter_8/Simple_VertexShader/src/com/openglesbook/simplevertexshader/SimpleVertexShader.java @@ -0,0 +1,66 @@ +package com.openglesbook.simplevertexshader; + +import android.app.Activity; +import android.app.ActivityManager; +import android.content.Context; +import android.content.pm.ConfigurationInfo; +import android.opengl.GLSurfaceView; +import android.os.Bundle; +import android.util.Log; + +/** + * Activity class for example program that detects OpenGL ES 3.0. + **/ +public class SimpleVertexShader extends Activity { + + private final int CONTEXT_CLIENT_VERSION = 3; + + @Override + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + mGLSurfaceView = new GLSurfaceView(this); + if (detectOpenGLES30()) + { + // Tell the surface view we want to create an OpenGL ES 3.0-compatible + // context, and set an OpenGL ES 2.0-compatible renderer. + mGLSurfaceView.setEGLContextClientVersion(CONTEXT_CLIENT_VERSION); + mGLSurfaceView.setRenderer(new SimpleVertexShaderRenderer(this)); + } + else + { + Log.e("HelloTriangle", "OpenGL ES 3.0 not supported on device. Exiting..."); + finish(); + + } + setContentView(mGLSurfaceView); + } + + private boolean detectOpenGLES30() + { + ActivityManager am = + (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); + ConfigurationInfo info = am.getDeviceConfigurationInfo(); + return (info.reqGlEsVersion >= 0x30000); + } + + @Override + protected void onResume() + { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onResume(); + mGLSurfaceView.onResume(); + } + + @Override + protected void onPause() + { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onPause(); + mGLSurfaceView.onPause(); + } + + private GLSurfaceView mGLSurfaceView; +} diff --git a/Android_Java/Chapter_8/Simple_VertexShader/src/com/openglesbook/simplevertexshader/SimpleVertexShaderRenderer.java b/Android_Java/Chapter_8/Simple_VertexShader/src/com/openglesbook/simplevertexshader/SimpleVertexShaderRenderer.java new file mode 100644 index 0000000..9148f05 --- /dev/null +++ b/Android_Java/Chapter_8/Simple_VertexShader/src/com/openglesbook/simplevertexshader/SimpleVertexShaderRenderer.java @@ -0,0 +1,184 @@ +// +// Book: OpenGL(R) ES 2.0 Programming Guide +// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner +// ISBN-10: 0321502795 +// ISBN-13: 9780321502797 +// Publisher: Addison-Wesley Professional +// URLs: http://safari.informit.com/9780321563835 +// http://www.opengles-book.com +// + +// Simple_VertexShader +// +// This is a simple example that draws a rotating cube in perspective +// using a vertex shader to transform the object +// + +package com.openglesbook.simplevertexshader; + +import com.openglesbook.common.ESShapes; +import com.openglesbook.common.ESShader; +import com.openglesbook.common.ESTransform; + +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; + +import android.content.Context; +import android.opengl.GLES30; +import android.opengl.GLSurfaceView; +import android.os.SystemClock; + +public class SimpleVertexShaderRenderer implements GLSurfaceView.Renderer +{ + + /// + // Constructor + // + public SimpleVertexShaderRenderer(Context context) + { + + } + + /// + // Initialize the shader and program object + // + public void onSurfaceCreated(GL10 glUnused, EGLConfig config) + { + String vShaderStr = + "#version 300 es \n" + + "uniform mat4 u_mvpMatrix; \n" + + "layout(location = 0) in vec4 a_position; \n" + + "layout(location = 1) in vec4 a_color; \n" + + "out vec4 v_color; \n" + + "void main() \n" + + "{ \n" + + " v_color = a_color; \n" + + " gl_Position = u_mvpMatrix * a_position; \n" + + "} \n"; + + String fShaderStr = + "#version 300 es \n" + + "precision mediump float; \n" + + "in vec4 v_color; \n" + + "layout(location = 0) out vec4 outColor; \n" + + "void main() \n" + + "{ \n" + + " outColor = v_color; \n" + + "} \n"; + + // Load the shaders and get a linked program object + mProgramObject = ESShader.loadProgram(vShaderStr, fShaderStr); + + // Get the uniform locations + mMVPLoc = GLES30.glGetUniformLocation(mProgramObject, "u_mvpMatrix"); + + // Generate the vertex data + mCube.genCube(1.0f); + + // Starting rotation angle for the cube + mAngle = 45.0f; + + GLES30.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + } + + private void update() + { + if (mLastTime == 0) + mLastTime = SystemClock.uptimeMillis(); + long curTime = SystemClock.uptimeMillis(); + long elapsedTime = curTime - mLastTime; + float deltaTime = elapsedTime / 1000.0f; + mLastTime = curTime; + + ESTransform perspective = new ESTransform(); + ESTransform modelview = new ESTransform(); + float aspect; + + // Compute a rotation angle based on time to rotate the cube + mAngle += (deltaTime * 40.0f); + if (mAngle >= 360.0f) + mAngle -= 360.0f; + + // Compute the window aspect ratio + aspect = (float) mWidth / (float) mHeight; + + // Generate a perspective matrix with a 60 degree FOV + perspective.matrixLoadIdentity(); + perspective.perspective(60.0f, aspect, 1.0f, 20.0f); + + // Generate a model view matrix to rotate/translate the cube + modelview.matrixLoadIdentity(); + + // Translate away from the viewer + modelview.translate(0.0f, 0.0f, -2.0f); + + // Rotate the cube + modelview.rotate(mAngle, 1.0f, 0.0f, 1.0f); + + // Compute the final MVP by multiplying the + // modevleiw and perspective matrices together + mMVPMatrix.matrixMultiply(modelview.get(), perspective.get()); + } + + /// + // Draw a triangle using the shader pair created in onSurfaceCreated() + // + public void onDrawFrame(GL10 glUnused) + { + update(); + + // Set the viewport + GLES30.glViewport(0, 0, mWidth, mHeight); + + // Clear the color buffer + GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT); + + // Use the program object + GLES30.glUseProgram(mProgramObject); + + // Load the vertex data + GLES30.glVertexAttribPointer(0, 3, GLES30.GL_FLOAT, false, + 0, mCube.getVertices()); + GLES30.glEnableVertexAttribArray(0); + + // Set the vertex color to red + GLES30.glVertexAttrib4f( 1, 1.0f, 0.0f, 0.0f, 1.0f ); + + // Load the MVP matrix + GLES30.glUniformMatrix4fv(mMVPLoc, 1, false, + mMVPMatrix.getAsFloatBuffer()); + + // Draw the cube + GLES30.glDrawElements(GLES30.GL_TRIANGLES, mCube.getNumIndices(), + GLES30.GL_UNSIGNED_SHORT, mCube.getIndices()); + } + + /// + // Handle surface changes + // + public void onSurfaceChanged(GL10 glUnused, int width, int height) + { + mWidth = width; + mHeight = height; + } + + // Handle to a program object + private int mProgramObject; + + // Uniform locations + private int mMVPLoc; + + // Vertex data + private ESShapes mCube = new ESShapes(); + + // Rotation angle + private float mAngle; + + // MVP matrix + private ESTransform mMVPMatrix = new ESTransform(); + + // Additional Member variables + private int mWidth; + private int mHeight; + private long mLastTime = 0; +} diff --git a/Android_Java/Chapter_9/MipMap2D/.classpath b/Android_Java/Chapter_9/MipMap2D/.classpath new file mode 100644 index 0000000..ce8b321 --- /dev/null +++ b/Android_Java/Chapter_9/MipMap2D/.classpath @@ -0,0 +1,5 @@ + + + + + diff --git a/Android_Java/Chapter_9/MipMap2D/.project b/Android_Java/Chapter_9/MipMap2D/.project new file mode 100644 index 0000000..86f4b5b --- /dev/null +++ b/Android_Java/Chapter_9/MipMap2D/.project @@ -0,0 +1,33 @@ + + + Ch9_MipMap2D + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/Android_Java/Chapter_9/MipMap2D/AndroidManifest.xml b/Android_Java/Chapter_9/MipMap2D/AndroidManifest.xml new file mode 100644 index 0000000..4d3e05e --- /dev/null +++ b/Android_Java/Chapter_9/MipMap2D/AndroidManifest.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Android_Java/Chapter_9/MipMap2D/assets/shaders/fragmentShader.frag b/Android_Java/Chapter_9/MipMap2D/assets/shaders/fragmentShader.frag new file mode 100644 index 0000000..446bb3f --- /dev/null +++ b/Android_Java/Chapter_9/MipMap2D/assets/shaders/fragmentShader.frag @@ -0,0 +1,14 @@ +#version 300 es + +precision mediump float; + +in vec2 v_texCoord; + +layout(location = 0) out vec4 outColor; + +uniform sampler2D s_texture; + +void main() +{ + outColor = texture( s_texture, v_texCoord ); +} \ No newline at end of file diff --git a/Android_Java/Chapter_9/MipMap2D/assets/shaders/vertexShader.vert b/Android_Java/Chapter_9/MipMap2D/assets/shaders/vertexShader.vert new file mode 100644 index 0000000..f59c13a --- /dev/null +++ b/Android_Java/Chapter_9/MipMap2D/assets/shaders/vertexShader.vert @@ -0,0 +1,16 @@ +#version 300 es + +uniform float u_offset; + +layout(location = 0) in vec4 a_position; +layout(location = 1) in vec2 a_texCoord; + +out vec2 v_texCoord; + +void main() +{ + gl_Position = a_position; + gl_Position.x += u_offset; + + v_texCoord = a_texCoord; +} \ No newline at end of file diff --git a/Android_Java/Chapter_9/MipMap2D/default.properties b/Android_Java/Chapter_9/MipMap2D/default.properties new file mode 100644 index 0000000..5ccd841 --- /dev/null +++ b/Android_Java/Chapter_9/MipMap2D/default.properties @@ -0,0 +1,12 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-18 +android.library.reference.1=../../Common/ diff --git a/Android_Java/Chapter_9/MipMap2D/proguard.cfg b/Android_Java/Chapter_9/MipMap2D/proguard.cfg new file mode 100644 index 0000000..8ad7d33 --- /dev/null +++ b/Android_Java/Chapter_9/MipMap2D/proguard.cfg @@ -0,0 +1,34 @@ +-optimizationpasses 5 +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses +-dontpreverify +-verbose +-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class com.android.vending.licensing.ILicensingService + +-keepclasseswithmembernames class * { + native ; +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet, int); +} + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} diff --git a/Android_Java/Chapter_9/MipMap2D/res/drawable-hdpi/icon.png b/Android_Java/Chapter_9/MipMap2D/res/drawable-hdpi/icon.png new file mode 100644 index 0000000..8074c4c Binary files /dev/null and b/Android_Java/Chapter_9/MipMap2D/res/drawable-hdpi/icon.png differ diff --git a/Android_Java/Chapter_9/MipMap2D/res/drawable-ldpi/icon.png b/Android_Java/Chapter_9/MipMap2D/res/drawable-ldpi/icon.png new file mode 100644 index 0000000..1095584 Binary files /dev/null and b/Android_Java/Chapter_9/MipMap2D/res/drawable-ldpi/icon.png differ diff --git a/Android_Java/Chapter_9/MipMap2D/res/drawable-mdpi/icon.png b/Android_Java/Chapter_9/MipMap2D/res/drawable-mdpi/icon.png new file mode 100644 index 0000000..a07c69f Binary files /dev/null and b/Android_Java/Chapter_9/MipMap2D/res/drawable-mdpi/icon.png differ diff --git a/Android_Java/Chapter_9/MipMap2D/res/values/strings.xml b/Android_Java/Chapter_9/MipMap2D/res/values/strings.xml new file mode 100644 index 0000000..637300f --- /dev/null +++ b/Android_Java/Chapter_9/MipMap2D/res/values/strings.xml @@ -0,0 +1,4 @@ + + + Ch9_MipMap2D + diff --git a/Android_Java/Chapter_9/MipMap2D/src/com/openglesbook/mipmap2d/MipMap2D.java b/Android_Java/Chapter_9/MipMap2D/src/com/openglesbook/mipmap2d/MipMap2D.java new file mode 100644 index 0000000..b32dbb3 --- /dev/null +++ b/Android_Java/Chapter_9/MipMap2D/src/com/openglesbook/mipmap2d/MipMap2D.java @@ -0,0 +1,65 @@ +package com.openglesbook.mipmap2d; + +import android.app.Activity; +import android.app.ActivityManager; +import android.content.Context; +import android.content.pm.ConfigurationInfo; +import android.opengl.GLSurfaceView; +import android.os.Bundle; +import android.util.Log; + +/** + * Activity class for example program that detects OpenGL ES 3.0. + **/ +public class MipMap2D extends Activity { + + private final int CONTEXT_CLIENT_VERSION = 3; + + @Override + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + mGLSurfaceView = new GLSurfaceView(this); + if (detectOpenGLES30()) + { + // Tell the surface view we want to create an OpenGL ES 3.0-compatible + // context, and set an OpenGL ES 2.0-compatible renderer. + mGLSurfaceView.setEGLContextClientVersion(CONTEXT_CLIENT_VERSION); + mGLSurfaceView.setRenderer(new MipMap2DRenderer(this)); + } + else + { + Log.e("MipMap2D", "OpenGL ES 3.0 not supported on device. Exiting..."); + finish(); + } + setContentView(mGLSurfaceView); + } + + private boolean detectOpenGLES30() + { + ActivityManager am = + (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); + ConfigurationInfo info = am.getDeviceConfigurationInfo(); + return (info.reqGlEsVersion >= 0x30000); + } + + @Override + protected void onResume() + { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onResume(); + mGLSurfaceView.onResume(); + } + + @Override + protected void onPause() + { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onPause(); + mGLSurfaceView.onPause(); + } + + private GLSurfaceView mGLSurfaceView; +} diff --git a/Android_Java/Chapter_9/MipMap2D/src/com/openglesbook/mipmap2d/MipMap2DRenderer.java b/Android_Java/Chapter_9/MipMap2D/src/com/openglesbook/mipmap2d/MipMap2DRenderer.java new file mode 100644 index 0000000..1eac4ad --- /dev/null +++ b/Android_Java/Chapter_9/MipMap2D/src/com/openglesbook/mipmap2d/MipMap2DRenderer.java @@ -0,0 +1,332 @@ +// +// Book: OpenGL(R) ES 3.0 Programming Guide +// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner +// ISBN-10: 0321502795 +// ISBN-13: 9780321502797 +// Publisher: Addison-Wesley Professional +// URLs: http://safari.informit.com/9780321563835 +// http://www.opengles-book.com +// + +// MipMap2D +// +// This is a simple example that demonstrates generating a mipmap chain +// and rendering with it +// + +package com.openglesbook.mipmap2d; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; +import java.nio.ShortBuffer; + +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; + +import com.openglesbook.common.ESShader; + +import android.content.Context; +import android.opengl.GLES30; +import android.opengl.GLSurfaceView; + +public class MipMap2DRenderer implements GLSurfaceView.Renderer +{ + + /// + // Constructor + // + public MipMap2DRenderer(Context context) + { + mContext = context; + + mVertices = ByteBuffer.allocateDirect(mVerticesData.length * 4) + .order(ByteOrder.nativeOrder()).asFloatBuffer(); + mVertices.put(mVerticesData).position(0); + mIndices = ByteBuffer.allocateDirect(mIndicesData.length * 2) + .order(ByteOrder.nativeOrder()).asShortBuffer(); + mIndices.put(mIndicesData).position(0); + } + + /// + // From an RGB8 source image, generate the next level mipmap + // + private byte[] genMipMap2D( byte[] src,int srcWidth, int srcHeight, int dstWidth, int dstHeight ) + { + int x, + y; + int texelSize = 3; + + byte[] dst = new byte[texelSize * (dstWidth) * (dstHeight)]; + + for ( y = 0; y < dstHeight; y++ ) + { + for( x = 0; x < dstWidth; x++ ) + { + int[] srcIndex = new int[4]; + float r = 0.0f, + g = 0.0f, + b = 0.0f; + int sample; + + // Compute the offsets for 2x2 grid of pixels in previous + // image to perform box filter + srcIndex[0] = + (((y * 2) * srcWidth) + (x * 2)) * texelSize; + srcIndex[1] = + (((y * 2) * srcWidth) + (x * 2 + 1)) * texelSize; + srcIndex[2] = + ((((y * 2) + 1) * srcWidth) + (x * 2)) * texelSize; + srcIndex[3] = + ((((y * 2) + 1) * srcWidth) + (x * 2 + 1)) * texelSize; + + // Sum all pixels + for ( sample = 0; sample < 4; sample++ ) + { + r += src[srcIndex[sample]]; + g += src[srcIndex[sample] + 1]; + b += src[srcIndex[sample] + 2]; + } + + // Average results + r /= 4.0; + g /= 4.0; + b /= 4.0; + + // Store resulting pixels + dst[ ( y * (dstWidth) + x ) * texelSize ] = (byte)( r ); + dst[ ( y * (dstWidth) + x ) * texelSize + 1] = (byte)( g ); + dst[ ( y * (dstWidth) + x ) * texelSize + 2] = (byte)( b ); + } + } + return dst; + } + + /// + // Generate an RGB8 checkerboard image + // + private byte[] genCheckImage( int width, int height, int checkSize ) + { + int x, + y; + byte[] pixels = new byte[width * height * 3]; + + + for ( y = 0; y < height; y++ ) + for ( x = 0; x < width; x++ ) + { + byte rColor = 0; + byte bColor = 0; + + if ( ( x / checkSize ) % 2 == 0 ) + { + rColor = (byte)(127 * ( ( y / checkSize ) % 2 )); + bColor = (byte)(127 * ( 1 - ( ( y / checkSize ) % 2 ) )); + } + else + { + bColor = (byte)(127 * ( ( y / checkSize ) % 2 )); + rColor = (byte)(127 * ( 1 - ( ( y / checkSize ) % 2 ) )); + } + + pixels[(y * height + x) * 3] = rColor; + pixels[(y * height + x) * 3 + 1] = 0; + pixels[(y * height + x) * 3 + 2] = bColor; + } + + return pixels; + } + + + /// + // Create a mipmapped 2D texture image + // + private int createMipMappedTexture2D( ) + { + // Texture object handle + int[] textureId = new int[1]; + int width = 256, + height = 256; + int level; + byte[] pixels; + byte[] prevImage; + byte[] newImage; + + pixels = genCheckImage( width, height, 8 ); + + // Generate a texture object + GLES30.glGenTextures ( 1, textureId, 0 ); + + // Bind the texture object + GLES30.glBindTexture ( GLES30.GL_TEXTURE_2D, textureId[0] ); + + // Load mipmap level 0 + ByteBuffer pixelBuffer = ByteBuffer.allocateDirect(width * height * 3); + pixelBuffer.put(pixels).position(0); + + GLES30.glTexImage2D ( GLES30.GL_TEXTURE_2D, 0, GLES30.GL_RGB, width, height, + 0, GLES30.GL_RGB, GLES30.GL_UNSIGNED_BYTE, pixelBuffer ); + + level = 1; + prevImage = pixels; + + while ( width > 1 && height > 1 ) + { + int newWidth, + newHeight; + + newWidth = width / 2; + if ( newWidth <= 0 ) + newWidth = 1; + + newHeight = height / 2; + if ( newHeight <= 0 ) + newHeight = 1; + + // Generate the next mipmap level + newImage = genMipMap2D( prevImage, width, height, newWidth, newHeight ); + + // Load the mipmap level + pixelBuffer = ByteBuffer.allocateDirect(newWidth * newHeight * 3); + pixelBuffer.put(newImage).position(0); + GLES30.glTexImage2D( GLES30.GL_TEXTURE_2D, level, GLES30.GL_RGB, + newWidth, newHeight, 0, GLES30.GL_RGB, + GLES30.GL_UNSIGNED_BYTE, pixelBuffer ); + + // Set the previous image for the next iteration + prevImage = newImage; + level++; + + // Half the width and height + width = newWidth; + height = newHeight; + } + + + // Set the filtering mode + GLES30.glTexParameteri ( GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_NEAREST_MIPMAP_NEAREST ); + GLES30.glTexParameteri ( GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_LINEAR ); + + return textureId[0]; + + } + + + /// + // Initialize the shader and program object + // + public void onSurfaceCreated(GL10 glUnused, EGLConfig config) + { + + + // Load the shaders from "assets" and get a linked program object + mProgramObject = ESShader.loadProgramFromAsset(mContext, + "shaders/vertexShader.vert", + "shaders/fragmentShader.frag"); + + // Get the sampler location + mSamplerLoc = GLES30.glGetUniformLocation ( mProgramObject, "s_texture" ); + + // Get the offset location + mOffsetLoc = GLES30.glGetUniformLocation( mProgramObject, "u_offset" ); + + // Load the texture + mTextureId = createMipMappedTexture2D(); + + GLES30.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + } + + /// + // Draw a triangle using the shader pair created in onSurfaceCreated() + // + public void onDrawFrame(GL10 glUnused) + { + // Set the viewport + GLES30.glViewport(0, 0, mWidth, mHeight); + + // Clear the color buffer + GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT); + + // Use the program object + GLES30.glUseProgram(mProgramObject); + + // Load the vertex position + mVertices.position(0); + GLES30.glVertexAttribPointer ( 0, 4, GLES30.GL_FLOAT, + false, + 6 * 4, mVertices ); + // Load the texture coordinate + mVertices.position(4); + GLES30.glVertexAttribPointer ( 1, 2, GLES30.GL_FLOAT, + false, + 6 * 4, + mVertices ); + + GLES30.glEnableVertexAttribArray( 0 ); + GLES30.glEnableVertexAttribArray( 1 ); + + // Bind the texture + GLES30.glActiveTexture ( GLES30.GL_TEXTURE0 ); + GLES30.glBindTexture ( GLES30.GL_TEXTURE_2D, mTextureId ); + + // Set the sampler texture unit to 0 + GLES30.glUniform1i ( mSamplerLoc, 0 ); + + // Draw quad with nearest sampling + GLES30.glTexParameteri ( GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_NEAREST ); + GLES30.glUniform1f ( mOffsetLoc, -0.6f ); + GLES30.glDrawElements ( GLES30.GL_TRIANGLES, 6, GLES30.GL_UNSIGNED_SHORT, mIndices ); + + // Draw quad with trilinear filtering + GLES30.glTexParameteri ( GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_LINEAR_MIPMAP_LINEAR ); + GLES30.glUniform1f ( mOffsetLoc, 0.6f ); + GLES30.glDrawElements ( GLES30.GL_TRIANGLES, 6, GLES30.GL_UNSIGNED_SHORT, mIndices ); + } + + /// + // Handle surface changes + // + public void onSurfaceChanged(GL10 glUnused, int width, int height) + { + mWidth = width; + mHeight = height; + } + + + // Handle to a program object + private int mProgramObject; + + // Sampler location + private int mSamplerLoc; + + // Offset location + private int mOffsetLoc; + + // Texture handle + private int mTextureId; + + // Additional member variables + private int mWidth; + private int mHeight; + private FloatBuffer mVertices; + private ShortBuffer mIndices; + + private final float[] mVerticesData = + { + -0.5f, 0.5f, 0.0f, 1.5f, // Position 0 + 0.0f, 0.0f, // TexCoord 0 + -0.5f, -0.5f, 0.0f, 0.75f, // Position 1 + 0.0f, 1.0f, // TexCoord 1 + 0.5f, -0.5f, 0.0f, 0.75f, // Position 2 + 1.0f, 1.0f, // TexCoord 2 + 0.5f, 0.5f, 0.0f, 1.5f, // Position 3 + 1.0f, 0.0f // TexCoord 3 + }; + + private final short[] mIndicesData = + { + 0, 1, 2, 0, 2, 3 + }; + + private Context mContext; +} diff --git a/Android_Java/Chapter_9/Simple_Texture2D/.classpath b/Android_Java/Chapter_9/Simple_Texture2D/.classpath new file mode 100644 index 0000000..ce8b321 --- /dev/null +++ b/Android_Java/Chapter_9/Simple_Texture2D/.classpath @@ -0,0 +1,5 @@ + + + + + diff --git a/Android_Java/Chapter_9/Simple_Texture2D/.project b/Android_Java/Chapter_9/Simple_Texture2D/.project new file mode 100644 index 0000000..42ecaa0 --- /dev/null +++ b/Android_Java/Chapter_9/Simple_Texture2D/.project @@ -0,0 +1,33 @@ + + + Ch9_Simple_Texture2D + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/Android_Java/Chapter_9/Simple_Texture2D/AndroidManifest.xml b/Android_Java/Chapter_9/Simple_Texture2D/AndroidManifest.xml new file mode 100644 index 0000000..441943a --- /dev/null +++ b/Android_Java/Chapter_9/Simple_Texture2D/AndroidManifest.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Android_Java/Chapter_9/Simple_Texture2D/default.properties b/Android_Java/Chapter_9/Simple_Texture2D/default.properties new file mode 100644 index 0000000..5ccd841 --- /dev/null +++ b/Android_Java/Chapter_9/Simple_Texture2D/default.properties @@ -0,0 +1,12 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-18 +android.library.reference.1=../../Common/ diff --git a/Android_Java/Chapter_9/Simple_Texture2D/proguard.cfg b/Android_Java/Chapter_9/Simple_Texture2D/proguard.cfg new file mode 100644 index 0000000..8ad7d33 --- /dev/null +++ b/Android_Java/Chapter_9/Simple_Texture2D/proguard.cfg @@ -0,0 +1,34 @@ +-optimizationpasses 5 +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses +-dontpreverify +-verbose +-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class com.android.vending.licensing.ILicensingService + +-keepclasseswithmembernames class * { + native ; +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet, int); +} + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} diff --git a/Android_Java/Chapter_9/Simple_Texture2D/res/drawable-hdpi/icon.png b/Android_Java/Chapter_9/Simple_Texture2D/res/drawable-hdpi/icon.png new file mode 100644 index 0000000..8074c4c Binary files /dev/null and b/Android_Java/Chapter_9/Simple_Texture2D/res/drawable-hdpi/icon.png differ diff --git a/Android_Java/Chapter_9/Simple_Texture2D/res/drawable-ldpi/icon.png b/Android_Java/Chapter_9/Simple_Texture2D/res/drawable-ldpi/icon.png new file mode 100644 index 0000000..1095584 Binary files /dev/null and b/Android_Java/Chapter_9/Simple_Texture2D/res/drawable-ldpi/icon.png differ diff --git a/Android_Java/Chapter_9/Simple_Texture2D/res/drawable-mdpi/icon.png b/Android_Java/Chapter_9/Simple_Texture2D/res/drawable-mdpi/icon.png new file mode 100644 index 0000000..a07c69f Binary files /dev/null and b/Android_Java/Chapter_9/Simple_Texture2D/res/drawable-mdpi/icon.png differ diff --git a/Android_Java/Chapter_9/Simple_Texture2D/res/values/strings.xml b/Android_Java/Chapter_9/Simple_Texture2D/res/values/strings.xml new file mode 100644 index 0000000..7a469b0 --- /dev/null +++ b/Android_Java/Chapter_9/Simple_Texture2D/res/values/strings.xml @@ -0,0 +1,4 @@ + + + Ch9_Simple_Texture2D + diff --git a/Android_Java/Chapter_9/Simple_Texture2D/src/com/openglesbook/simpletexture2d/SimpleTexture2D.java b/Android_Java/Chapter_9/Simple_Texture2D/src/com/openglesbook/simpletexture2d/SimpleTexture2D.java new file mode 100644 index 0000000..4ec8c40 --- /dev/null +++ b/Android_Java/Chapter_9/Simple_Texture2D/src/com/openglesbook/simpletexture2d/SimpleTexture2D.java @@ -0,0 +1,66 @@ +package com.openglesbook.simpletexture2d; + +import android.app.Activity; +import android.app.ActivityManager; +import android.content.Context; +import android.content.pm.ConfigurationInfo; +import android.opengl.GLSurfaceView; +import android.os.Bundle; +import android.util.Log; + +/** + * Activity class for example program that detects OpenGL ES 3.0. + **/ +public class SimpleTexture2D extends Activity { + + private final int CONTEXT_CLIENT_VERSION = 3; + + @Override + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + mGLSurfaceView = new GLSurfaceView(this); + if (detectOpenGLES30()) + { + // Tell the surface view we want to create an OpenGL ES 3.0-compatible + // context, and set an OpenGL ES 3.0-compatible renderer. + mGLSurfaceView.setEGLContextClientVersion(CONTEXT_CLIENT_VERSION); + mGLSurfaceView.setRenderer(new SimpleTexture2DRenderer(this)); + } + else + { + Log.e("SimpleTexture2D", "OpenGL ES 3.0 not supported on device. Exiting..."); + finish(); + + } + setContentView(mGLSurfaceView); + } + + private boolean detectOpenGLES30() + { + ActivityManager am = + (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); + ConfigurationInfo info = am.getDeviceConfigurationInfo(); + return (info.reqGlEsVersion >= 0x30000); + } + + @Override + protected void onResume() + { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onResume(); + mGLSurfaceView.onResume(); + } + + @Override + protected void onPause() + { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onPause(); + mGLSurfaceView.onPause(); + } + + private GLSurfaceView mGLSurfaceView; +} diff --git a/Android_Java/Chapter_9/Simple_Texture2D/src/com/openglesbook/simpletexture2d/SimpleTexture2DRenderer.java b/Android_Java/Chapter_9/Simple_Texture2D/src/com/openglesbook/simpletexture2d/SimpleTexture2DRenderer.java new file mode 100644 index 0000000..2595259 --- /dev/null +++ b/Android_Java/Chapter_9/Simple_Texture2D/src/com/openglesbook/simpletexture2d/SimpleTexture2DRenderer.java @@ -0,0 +1,209 @@ +// +// Book: OpenGL(R) ES 3.0 Programming Guide +// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner +// ISBN-10: 0321502795 +// ISBN-13: 9780321502797 +// Publisher: Addison-Wesley Professional +// URLs: http://safari.informit.com/9780321563835 +// http://www.opengles-book.com +// + +// Simple_Texture2D +// +// This is a simple example that draws a quad with a 2D +// texture image. The purpose of this example is to demonstrate +// the basics of 2D texturing +// + +package com.openglesbook.simpletexture2d; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; +import java.nio.ShortBuffer; + +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; + +import com.openglesbook.common.ESShader; + +import android.content.Context; +import android.opengl.GLES30; +import android.opengl.GLSurfaceView; + +public class SimpleTexture2DRenderer implements GLSurfaceView.Renderer +{ + + /// + // Constructor + // + public SimpleTexture2DRenderer(Context context) + { + + mVertices = ByteBuffer.allocateDirect(mVerticesData.length * 4) + .order(ByteOrder.nativeOrder()).asFloatBuffer(); + mVertices.put(mVerticesData).position(0); + mIndices = ByteBuffer.allocateDirect(mIndicesData.length * 2) + .order(ByteOrder.nativeOrder()).asShortBuffer(); + mIndices.put(mIndicesData).position(0); + } + + // + // Create a simple 2x2 texture image with four different colors + // + private int createSimpleTexture2D( ) + { + // Texture object handle + int[] textureId = new int[1]; + + // 2x2 Image, 3 bytes per pixel (R, G, B) + byte[] pixels = + { + (byte) 0xff, 0, 0, // Red + 0, (byte) 0xff, 0, // Green + 0, 0, (byte) 0xff, // Blue + (byte) 0xff, (byte) 0xff, 0 // Yellow + }; + ByteBuffer pixelBuffer = ByteBuffer.allocateDirect(4*3); + pixelBuffer.put(pixels).position(0); + + // Use tightly packed data + GLES30.glPixelStorei ( GLES30.GL_UNPACK_ALIGNMENT, 1 ); + + // Generate a texture object + GLES30.glGenTextures ( 1, textureId, 0 ); + + // Bind the texture object + GLES30.glBindTexture ( GLES30.GL_TEXTURE_2D, textureId[0] ); + + // Load the texture + GLES30.glTexImage2D ( GLES30.GL_TEXTURE_2D, 0, GLES30.GL_RGB, 2, 2, 0, GLES30.GL_RGB, GLES30.GL_UNSIGNED_BYTE, pixelBuffer ); + + // Set the filtering mode + GLES30.glTexParameteri ( GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_NEAREST ); + GLES30.glTexParameteri ( GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_NEAREST ); + + return textureId[0]; + } + + /// + // Initialize the shader and program object + // + public void onSurfaceCreated(GL10 glUnused, EGLConfig config) + { + String vShaderStr = + "#version 300 es \n" + + "layout(location = 0) in vec4 a_position; \n" + + "layout(location = 1) in vec2 a_texCoord; \n" + + "out vec2 v_texCoord; \n" + + "void main() \n" + + "{ \n" + + " gl_Position = a_position; \n" + + " v_texCoord = a_texCoord; \n" + + "} \n"; + + String fShaderStr = + "#version 300 es \n" + + "precision mediump float; \n" + + "in vec2 v_texCoord; \n" + + "layout(location = 0) out vec4 outColor; \n" + + "uniform sampler2D s_texture; \n" + + "void main() \n" + + "{ \n" + + " outColor = texture( s_texture, v_texCoord ); \n" + + "} \n"; + + // Load the shaders and get a linked program object + mProgramObject = ESShader.loadProgram(vShaderStr, fShaderStr); + + // Get the sampler location + mSamplerLoc = GLES30.glGetUniformLocation ( mProgramObject, "s_texture" ); + + // Load the texture + mTextureId = createSimpleTexture2D (); + + GLES30.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + } + + // / + // Draw a triangle using the shader pair created in onSurfaceCreated() + // + public void onDrawFrame(GL10 glUnused) + { + // Set the viewport + GLES30.glViewport(0, 0, mWidth, mHeight); + + // Clear the color buffer + GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT); + + // Use the program object + GLES30.glUseProgram(mProgramObject); + + // Load the vertex position + mVertices.position(0); + GLES30.glVertexAttribPointer ( 0, 3, GLES30.GL_FLOAT, + false, + 5 * 4, mVertices ); + // Load the texture coordinate + mVertices.position(3); + GLES30.glVertexAttribPointer ( 1, 2, GLES30.GL_FLOAT, + false, + 5 * 4, + mVertices ); + + GLES30.glEnableVertexAttribArray ( 0 ); + GLES30.glEnableVertexAttribArray ( 1 ); + + // Bind the texture + GLES30.glActiveTexture ( GLES30.GL_TEXTURE0 ); + GLES30.glBindTexture ( GLES30.GL_TEXTURE_2D, mTextureId ); + + // Set the sampler texture unit to 0 + GLES30.glUniform1i ( mSamplerLoc, 0 ); + + GLES30.glDrawElements ( GLES30.GL_TRIANGLES, 6, GLES30.GL_UNSIGNED_SHORT, mIndices ); + } + + /// + // Handle surface changes + // + public void onSurfaceChanged(GL10 glUnused, int width, int height) + { + mWidth = width; + mHeight = height; + } + + + // Handle to a program object + private int mProgramObject; + + // Sampler location + private int mSamplerLoc; + + // Texture handle + private int mTextureId; + + // Additional member variables + private int mWidth; + private int mHeight; + private FloatBuffer mVertices; + private ShortBuffer mIndices; + + private final float[] mVerticesData = + { + -0.5f, 0.5f, 0.0f, // Position 0 + 0.0f, 0.0f, // TexCoord 0 + -0.5f, -0.5f, 0.0f, // Position 1 + 0.0f, 1.0f, // TexCoord 1 + 0.5f, -0.5f, 0.0f, // Position 2 + 1.0f, 1.0f, // TexCoord 2 + 0.5f, 0.5f, 0.0f, // Position 3 + 1.0f, 0.0f // TexCoord 3 + }; + + private final short[] mIndicesData = + { + 0, 1, 2, 0, 2, 3 + }; + +} diff --git a/Android_Java/Chapter_9/Simple_TextureCubemap/.classpath b/Android_Java/Chapter_9/Simple_TextureCubemap/.classpath new file mode 100644 index 0000000..ce8b321 --- /dev/null +++ b/Android_Java/Chapter_9/Simple_TextureCubemap/.classpath @@ -0,0 +1,5 @@ + + + + + diff --git a/Android_Java/Chapter_9/Simple_TextureCubemap/.project b/Android_Java/Chapter_9/Simple_TextureCubemap/.project new file mode 100644 index 0000000..9083c72 --- /dev/null +++ b/Android_Java/Chapter_9/Simple_TextureCubemap/.project @@ -0,0 +1,33 @@ + + + Ch9_Simple_TextureCubemap + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/Android_Java/Chapter_9/Simple_TextureCubemap/AndroidManifest.xml b/Android_Java/Chapter_9/Simple_TextureCubemap/AndroidManifest.xml new file mode 100644 index 0000000..f2c12aa --- /dev/null +++ b/Android_Java/Chapter_9/Simple_TextureCubemap/AndroidManifest.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Android_Java/Chapter_9/Simple_TextureCubemap/default.properties b/Android_Java/Chapter_9/Simple_TextureCubemap/default.properties new file mode 100644 index 0000000..5ccd841 --- /dev/null +++ b/Android_Java/Chapter_9/Simple_TextureCubemap/default.properties @@ -0,0 +1,12 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-18 +android.library.reference.1=../../Common/ diff --git a/Android_Java/Chapter_9/Simple_TextureCubemap/proguard.cfg b/Android_Java/Chapter_9/Simple_TextureCubemap/proguard.cfg new file mode 100644 index 0000000..8ad7d33 --- /dev/null +++ b/Android_Java/Chapter_9/Simple_TextureCubemap/proguard.cfg @@ -0,0 +1,34 @@ +-optimizationpasses 5 +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses +-dontpreverify +-verbose +-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class com.android.vending.licensing.ILicensingService + +-keepclasseswithmembernames class * { + native ; +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet, int); +} + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} diff --git a/Android_Java/Chapter_9/Simple_TextureCubemap/res/drawable-hdpi/icon.png b/Android_Java/Chapter_9/Simple_TextureCubemap/res/drawable-hdpi/icon.png new file mode 100644 index 0000000..8074c4c Binary files /dev/null and b/Android_Java/Chapter_9/Simple_TextureCubemap/res/drawable-hdpi/icon.png differ diff --git a/Android_Java/Chapter_9/Simple_TextureCubemap/res/drawable-ldpi/icon.png b/Android_Java/Chapter_9/Simple_TextureCubemap/res/drawable-ldpi/icon.png new file mode 100644 index 0000000..1095584 Binary files /dev/null and b/Android_Java/Chapter_9/Simple_TextureCubemap/res/drawable-ldpi/icon.png differ diff --git a/Android_Java/Chapter_9/Simple_TextureCubemap/res/drawable-mdpi/icon.png b/Android_Java/Chapter_9/Simple_TextureCubemap/res/drawable-mdpi/icon.png new file mode 100644 index 0000000..a07c69f Binary files /dev/null and b/Android_Java/Chapter_9/Simple_TextureCubemap/res/drawable-mdpi/icon.png differ diff --git a/Android_Java/Chapter_9/Simple_TextureCubemap/res/values/strings.xml b/Android_Java/Chapter_9/Simple_TextureCubemap/res/values/strings.xml new file mode 100644 index 0000000..48c317a --- /dev/null +++ b/Android_Java/Chapter_9/Simple_TextureCubemap/res/values/strings.xml @@ -0,0 +1,4 @@ + + + Ch9_Simple_TextureCubemap + diff --git a/Android_Java/Chapter_9/Simple_TextureCubemap/src/com/openglesbook/simpletexturecubemap/SimpleTextureCubemap.java b/Android_Java/Chapter_9/Simple_TextureCubemap/src/com/openglesbook/simpletexturecubemap/SimpleTextureCubemap.java new file mode 100644 index 0000000..ac28107 --- /dev/null +++ b/Android_Java/Chapter_9/Simple_TextureCubemap/src/com/openglesbook/simpletexturecubemap/SimpleTextureCubemap.java @@ -0,0 +1,65 @@ +package com.openglesbook.simpletexturecubemap; + +import android.app.Activity; +import android.app.ActivityManager; +import android.content.Context; +import android.content.pm.ConfigurationInfo; +import android.opengl.GLSurfaceView; +import android.os.Bundle; +import android.util.Log; + +/** + * Activity class for example program that detects OpenGL ES 3.0. + **/ +public class SimpleTextureCubemap extends Activity { + + private final int CONTEXT_CLIENT_VERSION = 3; + + @Override + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + mGLSurfaceView = new GLSurfaceView(this); + if (detectOpenGLES30()) + { + // Tell the surface view we want to create an OpenGL ES 3.0-compatible + // context, and set an OpenGL ES 3.0-compatible renderer. + mGLSurfaceView.setEGLContextClientVersion(CONTEXT_CLIENT_VERSION); + mGLSurfaceView.setRenderer(new SimpleTextureCubemapRenderer(this)); + } + else + { + Log.e("SimpleTextureCubemap", "OpenGL ES 3.0 not supported on device. Exiting..."); + finish(); + } + setContentView(mGLSurfaceView); + } + + private boolean detectOpenGLES30() + { + ActivityManager am = + (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); + ConfigurationInfo info = am.getDeviceConfigurationInfo(); + return (info.reqGlEsVersion >= 0x30000); + } + + @Override + protected void onResume() + { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onResume(); + mGLSurfaceView.onResume(); + } + + @Override + protected void onPause() + { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onPause(); + mGLSurfaceView.onPause(); + } + + private GLSurfaceView mGLSurfaceView; +} diff --git a/Android_Java/Chapter_9/Simple_TextureCubemap/src/com/openglesbook/simpletexturecubemap/SimpleTextureCubemapRenderer.java b/Android_Java/Chapter_9/Simple_TextureCubemap/src/com/openglesbook/simpletexturecubemap/SimpleTextureCubemapRenderer.java new file mode 100644 index 0000000..e0a0195 --- /dev/null +++ b/Android_Java/Chapter_9/Simple_TextureCubemap/src/com/openglesbook/simpletexturecubemap/SimpleTextureCubemapRenderer.java @@ -0,0 +1,212 @@ +// +// Book: OpenGL(R) ES 2.0 Programming Guide +// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner +// ISBN-10: 0321502795 +// ISBN-13: 9780321502797 +// Publisher: Addison-Wesley Professional +// URLs: http://safari.informit.com/9780321563835 +// http://www.opengles-book.com +// + +// MipMap2D +// +// This is a simple example that demonstrates generating a mipmap chain +// and rendering with it +// + +package com.openglesbook.simpletexturecubemap; + +import java.nio.ByteBuffer; + +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; + +import com.openglesbook.common.ESShader; +import com.openglesbook.common.ESShapes; + +import android.content.Context; +import android.opengl.GLES30; +import android.opengl.GLSurfaceView; + +public class SimpleTextureCubemapRenderer implements GLSurfaceView.Renderer +{ + /// + // Constructor + // + public SimpleTextureCubemapRenderer(Context context) + { + } + + /// + // Create a simple cubemap with a 1x1 face with a different + // color for each face + private int createSimpleTextureCubemap( ) + { + int[] textureId = new int[1]; + + // Face 0 - Red + byte[] cubePixels0 = { 127, 0, 0 }; + // Face 1 - Green + byte[] cubePixels1 = { 0, 127, 0 }; + // Face 2 - Blue + byte[] cubePixels2 = { 0, 0, 127 }; + // Face 3 - Yellow + byte[] cubePixels3 = { 127, 127, 0 }; + // Face 4 - Purple + byte[] cubePixels4 = { 127, 0, 127 }; + // Face 5 - White + byte[] cubePixels5 = { 127, 127, 127 }; + + ByteBuffer cubePixels = ByteBuffer.allocateDirect(3); + + // Generate a texture object + GLES30.glGenTextures ( 1, textureId, 0 ); + + // Bind the texture object + GLES30.glBindTexture ( GLES30.GL_TEXTURE_CUBE_MAP, textureId[0] ); + + // Load the cube face - Positive X + cubePixels.put(cubePixels0).position(0); + GLES30.glTexImage2D ( GLES30.GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GLES30.GL_RGB, 1, 1, 0, + GLES30.GL_RGB, GLES30.GL_UNSIGNED_BYTE, cubePixels ); + + // Load the cube face - Negative X + cubePixels.put(cubePixels1).position(0); + GLES30.glTexImage2D ( GLES30.GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GLES30.GL_RGB, 1, 1, 0, + GLES30.GL_RGB, GLES30.GL_UNSIGNED_BYTE, cubePixels ); + + // Load the cube face - Positive Y + cubePixels.put(cubePixels2).position(0); + GLES30.glTexImage2D ( GLES30.GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GLES30.GL_RGB, 1, 1, 0, + GLES30.GL_RGB, GLES30.GL_UNSIGNED_BYTE, cubePixels ); + + // Load the cube face - Negative Y + cubePixels.put(cubePixels3).position(0); + GLES30.glTexImage2D ( GLES30.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GLES30.GL_RGB, 1, 1, 0, + GLES30.GL_RGB, GLES30.GL_UNSIGNED_BYTE, cubePixels ); + + // Load the cube face - Positive Z + cubePixels.put(cubePixels4).position(0); + GLES30.glTexImage2D ( GLES30.GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GLES30.GL_RGB, 1, 1, 0, + GLES30.GL_RGB, GLES30.GL_UNSIGNED_BYTE, cubePixels ); + + // Load the cube face - Negative Z + cubePixels.put(cubePixels5).position(0); + GLES30.glTexImage2D ( GLES30.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GLES30.GL_RGB, 1, 1, 0, + GLES30.GL_RGB, GLES30.GL_UNSIGNED_BYTE, cubePixels ); + + // Set the filtering mode + GLES30.glTexParameteri ( GLES30.GL_TEXTURE_CUBE_MAP, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_NEAREST ); + GLES30.glTexParameteri ( GLES30.GL_TEXTURE_CUBE_MAP, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_NEAREST ); + + return textureId[0]; + } + + /// + // Initialize the shader and program object + // + public void onSurfaceCreated(GL10 glUnused, EGLConfig config) + { + String vShaderStr = + + "#version 300 es \n" + + "layout(location = 0) in vec4 a_position; \n" + + "layout(location = 1) in vec3 a_normal; \n" + + "out vec3 v_normal; \n" + + "void main() \n" + + "{ \n" + + " gl_Position = a_position; \n" + + " v_normal = a_normal; \n" + + "} \n"; + + String fShaderStr = + + "#version 300 es \n" + + "precision mediump float; \n" + + "in vec3 v_normal; \n" + + "layout(location = 0) out vec4 outColor; \n" + + "uniform samplerCube s_texture; \n" + + "void main() \n" + + "{ \n" + + " outColor = texture( s_texture, v_normal ); \n" + + "} \n"; + + // Load the shaders and get a linked program object + mProgramObject = ESShader.loadProgram(vShaderStr, fShaderStr); + + // Get the sampler location + mSamplerLoc = GLES30.glGetUniformLocation ( mProgramObject, "s_texture" ); + + // Load the texture + mTextureId = createSimpleTextureCubemap (); + + // Generate the vertex data + mSphere.genSphere( 20, 0.75f ); + + GLES30.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + } + + /// + // Draw a triangle using the shader pair created in onSurfaceCreated() + // + public void onDrawFrame(GL10 glUnused) + { + // Set the viewport + GLES30.glViewport(0, 0, mWidth, mHeight); + + // Clear the color buffer + GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT); + + GLES30.glCullFace(GLES30.GL_BACK); + GLES30.glEnable(GLES30.GL_CULL_FACE); + + // Use the program object + GLES30.glUseProgram(mProgramObject); + + // Load the vertex position + GLES30.glVertexAttribPointer ( 0, 3, GLES30.GL_FLOAT, + false, 0, mSphere.getVertices()); + // Load the texture coordinate + + GLES30.glVertexAttribPointer ( 1, 3, GLES30.GL_FLOAT, + false, 0, mSphere.getNormals()); + + GLES30.glEnableVertexAttribArray( 0 ); + GLES30.glEnableVertexAttribArray( 1 ); + + // Bind the texture + GLES30.glActiveTexture ( GLES30.GL_TEXTURE0 ); + GLES30.glBindTexture ( GLES30.GL_TEXTURE_CUBE_MAP, mTextureId ); + + // Set the sampler texture unit to 0 + GLES30.glUniform1i ( mSamplerLoc, 0 ); + + GLES30.glDrawElements ( GLES30.GL_TRIANGLES, mSphere.getNumIndices(), GLES30.GL_UNSIGNED_SHORT, mSphere.getIndices() ); + } + + /// + // Handle surface changes + // + public void onSurfaceChanged(GL10 glUnused, int width, int height) + { + mWidth = width; + mHeight = height; + } + + + // Handle to a program object + private int mProgramObject; + + // Sampler location + private int mSamplerLoc; + + // Texture ID + private int mTextureId; + + // Vertex data + private ESShapes mSphere = new ESShapes(); + + // Additional member variables + private int mWidth; + private int mHeight; +} diff --git a/Android_Java/Chapter_9/TextureWrap/.classpath b/Android_Java/Chapter_9/TextureWrap/.classpath new file mode 100644 index 0000000..ce8b321 --- /dev/null +++ b/Android_Java/Chapter_9/TextureWrap/.classpath @@ -0,0 +1,5 @@ + + + + + diff --git a/Android_Java/Chapter_9/TextureWrap/.project b/Android_Java/Chapter_9/TextureWrap/.project new file mode 100644 index 0000000..c559ab7 --- /dev/null +++ b/Android_Java/Chapter_9/TextureWrap/.project @@ -0,0 +1,33 @@ + + + Ch9_TextureWrap + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/Android_Java/Chapter_9/TextureWrap/AndroidManifest.xml b/Android_Java/Chapter_9/TextureWrap/AndroidManifest.xml new file mode 100644 index 0000000..a43f3ab --- /dev/null +++ b/Android_Java/Chapter_9/TextureWrap/AndroidManifest.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Android_Java/Chapter_9/TextureWrap/default.properties b/Android_Java/Chapter_9/TextureWrap/default.properties new file mode 100644 index 0000000..5ccd841 --- /dev/null +++ b/Android_Java/Chapter_9/TextureWrap/default.properties @@ -0,0 +1,12 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-18 +android.library.reference.1=../../Common/ diff --git a/Android_Java/Chapter_9/TextureWrap/proguard.cfg b/Android_Java/Chapter_9/TextureWrap/proguard.cfg new file mode 100644 index 0000000..8ad7d33 --- /dev/null +++ b/Android_Java/Chapter_9/TextureWrap/proguard.cfg @@ -0,0 +1,34 @@ +-optimizationpasses 5 +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses +-dontpreverify +-verbose +-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class com.android.vending.licensing.ILicensingService + +-keepclasseswithmembernames class * { + native ; +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet, int); +} + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} diff --git a/Android_Java/Chapter_9/TextureWrap/res/drawable-hdpi/icon.png b/Android_Java/Chapter_9/TextureWrap/res/drawable-hdpi/icon.png new file mode 100644 index 0000000..8074c4c Binary files /dev/null and b/Android_Java/Chapter_9/TextureWrap/res/drawable-hdpi/icon.png differ diff --git a/Android_Java/Chapter_9/TextureWrap/res/drawable-ldpi/icon.png b/Android_Java/Chapter_9/TextureWrap/res/drawable-ldpi/icon.png new file mode 100644 index 0000000..1095584 Binary files /dev/null and b/Android_Java/Chapter_9/TextureWrap/res/drawable-ldpi/icon.png differ diff --git a/Android_Java/Chapter_9/TextureWrap/res/drawable-mdpi/icon.png b/Android_Java/Chapter_9/TextureWrap/res/drawable-mdpi/icon.png new file mode 100644 index 0000000..a07c69f Binary files /dev/null and b/Android_Java/Chapter_9/TextureWrap/res/drawable-mdpi/icon.png differ diff --git a/Android_Java/Chapter_9/TextureWrap/res/values/strings.xml b/Android_Java/Chapter_9/TextureWrap/res/values/strings.xml new file mode 100644 index 0000000..44b8696 --- /dev/null +++ b/Android_Java/Chapter_9/TextureWrap/res/values/strings.xml @@ -0,0 +1,4 @@ + + + Ch9_TextureWrap + diff --git a/Android_Java/Chapter_9/TextureWrap/src/com/openglesbook/texturewrap/TextureWrap.java b/Android_Java/Chapter_9/TextureWrap/src/com/openglesbook/texturewrap/TextureWrap.java new file mode 100644 index 0000000..5d0ddb9 --- /dev/null +++ b/Android_Java/Chapter_9/TextureWrap/src/com/openglesbook/texturewrap/TextureWrap.java @@ -0,0 +1,65 @@ +package com.openglesbook.texturewrap; + +import android.app.Activity; +import android.app.ActivityManager; +import android.content.Context; +import android.content.pm.ConfigurationInfo; +import android.opengl.GLSurfaceView; +import android.os.Bundle; +import android.util.Log; + +/** + * Activity class for example program that detects OpenGL ES 3.0. + **/ +public class TextureWrap extends Activity { + + private final int CONTEXT_CLIENT_VERSION = 3; + + @Override + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + mGLSurfaceView = new GLSurfaceView(this); + if (detectOpenGLES30()) + { + // Tell the surface view we want to create an OpenGL ES 3.0-compatible + // context, and set an OpenGL ES 3.0-compatible renderer. + mGLSurfaceView.setEGLContextClientVersion(CONTEXT_CLIENT_VERSION); + mGLSurfaceView.setRenderer(new TextureWrapRenderer(this)); + } + else + { + Log.e("TextureWrap", "OpenGL ES 3.0 not supported on device. Exiting..."); + finish(); + } + setContentView(mGLSurfaceView); + } + + private boolean detectOpenGLES30() + { + ActivityManager am = + (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); + ConfigurationInfo info = am.getDeviceConfigurationInfo(); + return (info.reqGlEsVersion >= 0x30000); + } + + @Override + protected void onResume() + { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onResume(); + mGLSurfaceView.onResume(); + } + + @Override + protected void onPause() + { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onPause(); + mGLSurfaceView.onPause(); + } + + private GLSurfaceView mGLSurfaceView; +} diff --git a/Android_Java/Chapter_9/TextureWrap/src/com/openglesbook/texturewrap/TextureWrapRenderer.java b/Android_Java/Chapter_9/TextureWrap/src/com/openglesbook/texturewrap/TextureWrapRenderer.java new file mode 100644 index 0000000..2ac8be3 --- /dev/null +++ b/Android_Java/Chapter_9/TextureWrap/src/com/openglesbook/texturewrap/TextureWrapRenderer.java @@ -0,0 +1,263 @@ +// +// Book: OpenGL(R) ES 3.0 Programming Guide +// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner +// ISBN-10: 0321502795 +// ISBN-13: 9780321502797 +// Publisher: Addison-Wesley Professional +// URLs: http://safari.informit.com/9780321563835 +// http://www.opengles-book.com +// + +// TextureWrap +// +// This is an example that demonstrates the three texture +// wrap modes available on 2D textures +// + +package com.openglesbook.texturewrap; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; +import java.nio.ShortBuffer; + +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; + +import com.openglesbook.common.ESShader; + +import android.content.Context; +import android.opengl.GLES30; +import android.opengl.GLSurfaceView; + +public class TextureWrapRenderer implements GLSurfaceView.Renderer +{ + + /// + // Constructor + // + public TextureWrapRenderer(Context context) + { + + mVertices = ByteBuffer.allocateDirect(mVerticesData.length * 4) + .order(ByteOrder.nativeOrder()).asFloatBuffer(); + mVertices.put(mVerticesData).position(0); + mIndices = ByteBuffer.allocateDirect(mIndicesData.length * 2) + .order(ByteOrder.nativeOrder()).asShortBuffer(); + mIndices.put(mIndicesData).position(0); + } + + /// + // Generate an RGB8 checkerboard image + // + private ByteBuffer genCheckImage( int width, int height, int checkSize ) + { + int x, + y; + byte[] pixels = new byte[width * height * 3]; + + + for ( y = 0; y < height; y++ ) + for ( x = 0; x < width; x++ ) + { + byte rColor = 0; + byte bColor = 0; + + if ( ( x / checkSize ) % 2 == 0 ) + { + rColor = (byte)(127 * ( ( y / checkSize ) % 2 )); + bColor = (byte)(127 * ( 1 - ( ( y / checkSize ) % 2 ) )); + } + else + { + bColor = (byte)(127 * ( ( y / checkSize ) % 2 )); + rColor = (byte)(127 * ( 1 - ( ( y / checkSize ) % 2 ) )); + } + + pixels[(y * height + x) * 3] = rColor; + pixels[(y * height + x) * 3 + 1] = 0; + pixels[(y * height + x) * 3 + 2] = bColor; + } + + ByteBuffer result = ByteBuffer.allocateDirect(width*height*3); + result.put(pixels).position(0); + return result; + } + + /// + // Create a 2D texture image + // + private int createTexture2D( ) + { + // Texture object handle + int[] textureId = new int[1]; + int width = 256, + height = 256; + ByteBuffer pixels; + + pixels = genCheckImage( width, height, 64 ); + + // Generate a texture object + GLES30.glGenTextures ( 1, textureId, 0 ); + + // Bind the texture object + GLES30.glBindTexture ( GLES30.GL_TEXTURE_2D, textureId[0] ); + + // Load mipmap level 0 + GLES30.glTexImage2D ( GLES30.GL_TEXTURE_2D, 0, GLES30.GL_RGB, width, height, + 0, GLES30.GL_RGB, GLES30.GL_UNSIGNED_BYTE, pixels ); + + // Set the filtering mode + GLES30.glTexParameteri ( GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_LINEAR ); + GLES30.glTexParameteri ( GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_LINEAR ); + + return textureId[0]; + } + + + + /// + // Initialize the shader and program object + // + public void onSurfaceCreated(GL10 glUnused, EGLConfig config) + { + String vShaderStr = + "#version 300 es \n" + + "uniform float u_offset; \n" + + "layout(location = 0) in vec4 a_position; \n" + + "layout(location = 1) in vec2 a_texCoord; \n" + + "out vec2 v_texCoord; \n" + + "void main() \n" + + "{ \n" + + " gl_Position = a_position; \n" + + " gl_Position.x += u_offset; \n" + + " v_texCoord = a_texCoord; \n" + + "} \n"; + + String fShaderStr = + "#version 300 es \n" + + "precision mediump float; \n" + + "in vec2 v_texCoord; \n" + + "layout(location = 0) out vec4 outColor; \n" + + "uniform sampler2D s_texture; \n" + + "void main() \n" + + "{ \n" + + " outColor = texture( s_texture, v_texCoord ); \n" + + "} \n"; + + // Load the shaders and get a linked program object + mProgramObject = ESShader.loadProgram(vShaderStr, fShaderStr); + + // Get the sampler location + mSamplerLoc = GLES30.glGetUniformLocation ( mProgramObject, "s_texture" ); + + // Get the offset location + mOffsetLoc = GLES30.glGetUniformLocation( mProgramObject, "u_offset" ); + + // Load the texture + mTextureId = createTexture2D (); + + GLES30.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + } + + /// + // Draw a triangle using the shader pair created in onSurfaceCreated() + // + public void onDrawFrame(GL10 glUnused) + { + // Set the viewport + GLES30.glViewport(0, 0, mWidth, mHeight); + + // Clear the color buffer + GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT); + + // Use the program object + GLES30.glUseProgram(mProgramObject); + + // Load the vertex position + mVertices.position(0); + GLES30.glVertexAttribPointer ( 0, 4, GLES30.GL_FLOAT, + false, + 6 * 4, mVertices ); + // Load the texture coordinate + mVertices.position(4); + GLES30.glVertexAttribPointer ( 1, 2, GLES30.GL_FLOAT, + false, + 6 * 4, + mVertices ); + + GLES30.glEnableVertexAttribArray( 0 ); + GLES30.glEnableVertexAttribArray( 1 ); + + // Bind the texture + GLES30.glActiveTexture ( GLES30.GL_TEXTURE0 ); + GLES30.glBindTexture ( GLES30.GL_TEXTURE_2D, mTextureId ); + + // Set the sampler texture unit to 0 + GLES30.glUniform1i ( mSamplerLoc, 0 ); + + // Draw quad with repeat wrap mode + GLES30.glTexParameteri ( GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_REPEAT ); + GLES30.glTexParameteri ( GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_REPEAT ); + GLES30.glUniform1f ( mOffsetLoc, -0.7f ); + GLES30.glDrawElements ( GLES30.GL_TRIANGLES, 6, GLES30.GL_UNSIGNED_SHORT, mIndices ); + + // Draw quad with clamp to edge wrap mode + GLES30.glTexParameteri ( GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_CLAMP_TO_EDGE ); + GLES30.glTexParameteri ( GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_CLAMP_TO_EDGE ); + GLES30.glUniform1f ( mOffsetLoc, 0.0f ); + GLES30.glDrawElements ( GLES30.GL_TRIANGLES, 6, GLES30.GL_UNSIGNED_SHORT, mIndices ); + + // Draw quad with mirrored repeat + GLES30.glTexParameteri ( GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_MIRRORED_REPEAT ); + GLES30.glTexParameteri ( GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_MIRRORED_REPEAT ); + GLES30.glUniform1f ( mOffsetLoc, 0.7f ); + GLES30.glDrawElements ( GLES30.GL_TRIANGLES, 6, GLES30.GL_UNSIGNED_SHORT, mIndices ); + } + + /// + // Handle surface changes + // + public void onSurfaceChanged(GL10 glUnused, int width, int height) + { + mWidth = width; + mHeight = height; + } + + + // Handle to a program object + private int mProgramObject; + + // Sampler location + private int mSamplerLoc; + + // Offset location + private int mOffsetLoc; + + // Texture handle + private int mTextureId; + + // Additional member variables + private int mWidth; + private int mHeight; + private FloatBuffer mVertices; + private ShortBuffer mIndices; + + private final float[] mVerticesData = + { + -0.3f, 0.3f, 0.0f, 1.0f, // Position 0 + -1.0f, -1.0f, // TexCoord 0 + -0.3f, -0.3f, 0.0f, 1.0f, // Position 1 + -1.0f, 2.0f, // TexCoord 1 + 0.3f, -0.3f, 0.0f, 1.0f, // Position 2 + 2.0f, 2.0f, // TexCoord 2 + 0.3f, 0.3f, 0.0f, 1.0f, // Position 3 + 2.0f, -1.0f // TexCoord 3 + }; + + private final short[] mIndicesData = + { + 0, 1, 2, 0, 2, 3 + }; + +} diff --git a/Android_Java/Common/.classpath b/Android_Java/Common/.classpath new file mode 100644 index 0000000..ce8b321 --- /dev/null +++ b/Android_Java/Common/.classpath @@ -0,0 +1,5 @@ + + + + + diff --git a/Android_Java/Common/.project b/Android_Java/Common/.project new file mode 100644 index 0000000..4a3847a --- /dev/null +++ b/Android_Java/Common/.project @@ -0,0 +1,33 @@ + + + Common + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/Android_Java/Common/AndroidManifest.xml b/Android_Java/Common/AndroidManifest.xml new file mode 100644 index 0000000..c3572aa --- /dev/null +++ b/Android_Java/Common/AndroidManifest.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/Android_Java/Common/default.properties b/Android_Java/Common/default.properties new file mode 100644 index 0000000..32d7696 --- /dev/null +++ b/Android_Java/Common/default.properties @@ -0,0 +1,12 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-18 +android.library=true diff --git a/Android_Java/Common/proguard.cfg b/Android_Java/Common/proguard.cfg new file mode 100644 index 0000000..8ad7d33 --- /dev/null +++ b/Android_Java/Common/proguard.cfg @@ -0,0 +1,34 @@ +-optimizationpasses 5 +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses +-dontpreverify +-verbose +-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class com.android.vending.licensing.ILicensingService + +-keepclasseswithmembernames class * { + native ; +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet, int); +} + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} diff --git a/Android_Java/Common/res/drawable-hdpi/icon.png b/Android_Java/Common/res/drawable-hdpi/icon.png new file mode 100644 index 0000000..8074c4c Binary files /dev/null and b/Android_Java/Common/res/drawable-hdpi/icon.png differ diff --git a/Android_Java/Common/res/drawable-ldpi/icon.png b/Android_Java/Common/res/drawable-ldpi/icon.png new file mode 100644 index 0000000..1095584 Binary files /dev/null and b/Android_Java/Common/res/drawable-ldpi/icon.png differ diff --git a/Android_Java/Common/res/drawable-mdpi/icon.png b/Android_Java/Common/res/drawable-mdpi/icon.png new file mode 100644 index 0000000..a07c69f Binary files /dev/null and b/Android_Java/Common/res/drawable-mdpi/icon.png differ diff --git a/Android_Java/Common/res/values/strings.xml b/Android_Java/Common/res/values/strings.xml new file mode 100644 index 0000000..e57957d --- /dev/null +++ b/Android_Java/Common/res/values/strings.xml @@ -0,0 +1,4 @@ + + + Common + diff --git a/Android_Java/Common/src/com/openglesbook/common/ESShader.java b/Android_Java/Common/src/com/openglesbook/common/ESShader.java new file mode 100644 index 0000000..357bd83 --- /dev/null +++ b/Android_Java/Common/src/com/openglesbook/common/ESShader.java @@ -0,0 +1,235 @@ +// +// Book: OpenGL(R) ES 3.0 Programming Guide +// Authors: Dan Ginsburg, Dave Shreiner, Aaftab Munshi +// ISBN-10: 0321502795 +// ISBN-13: 9780321502797 +// Publisher: Addison-Wesley Professional +// URLs: http://safari.informit.com/9780321563835 +// http://www.opengles-book.com +// + +// ESShader +// +// Utility functions for loading GLSL ES 3.0 shaders and creating program objects. +// + +package com.openglesbook.common; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; + +import android.content.Context; +import android.opengl.GLES30; +import android.util.Log; + +public class ESShader { + // + /// + /// \brief Read a shader source into a String + /// \param context Application context + /// \param fileName Name of shader file + /// \return A String object containing shader source, otherwise null + // + private static String readShader(Context context, String fileName) { + String shaderSource = null; + + if (fileName == null) + return shaderSource; + + // Read the shader file from assets + InputStream is = null; + byte [] buffer; + + try { + is = context.getAssets().open(fileName); + + // Create a buffer that has the same size as the InputStream + buffer = new byte[is.available()]; + + // Read the text file as a stream, into the buffer + is.read(buffer); + + ByteArrayOutputStream os = new ByteArrayOutputStream(); + + // Write this buffer to the output stream + os.write (buffer); + + // Close input and output streams + os.close(); + is.close(); + + shaderSource = os.toString(); + } catch (IOException ioe) { + is = null; + } + + if (is == null) + return shaderSource; + + return shaderSource; + } + + // + /// + /// \brief Load a shader, check for compile errors, print error messages to + /// output log + /// \param type Type of shader (GL_VERTEX_SHADER or GL_FRAGMENT_SHADER) + /// \param shaderSrc Shader source string + /// \return A new shader object on success, 0 on failure + // + public static int loadShader(int type, String shaderSrc) { + int shader; + int[] compiled = new int[1]; + + // Create the shader object + shader = GLES30.glCreateShader(type); + + if (shader == 0) + return 0; + + // Load the shader source + GLES30.glShaderSource(shader, shaderSrc); + + // Compile the shader + GLES30.glCompileShader(shader); + + // Check the compile status + GLES30.glGetShaderiv(shader, GLES30.GL_COMPILE_STATUS, compiled, 0); + + if (compiled[0] == 0) { + Log.e("ESShader", GLES30.glGetShaderInfoLog(shader)); + GLES30.glDeleteShader(shader); + return 0; + } + return shader; + } + + // + /// + /// \brief Load a vertex and fragment shader, create a program object, link + /// program. + /// Errors output to log. + /// \param vertShaderSrc Vertex shader source code + /// \param fragShaderSrc Fragment shader source code + /// \return A new program object linked with the vertex/fragment shader + /// pair, 0 on failure + // + public static int loadProgram(String vertShaderSrc, String fragShaderSrc) { + int vertexShader; + int fragmentShader; + int programObject; + int[] linked = new int[1]; + + // Load the vertex/fragment shaders + vertexShader = loadShader(GLES30.GL_VERTEX_SHADER, vertShaderSrc); + if (vertexShader == 0) + return 0; + + fragmentShader = loadShader(GLES30.GL_FRAGMENT_SHADER, fragShaderSrc); + if (fragmentShader == 0) { + GLES30.glDeleteShader(vertexShader); + return 0; + } + + // Create the program object + programObject = GLES30.glCreateProgram(); + + if (programObject == 0) + return 0; + + GLES30.glAttachShader(programObject, vertexShader); + GLES30.glAttachShader(programObject, fragmentShader); + + // Link the program + GLES30.glLinkProgram(programObject); + + // Check the link status + GLES30.glGetProgramiv(programObject, GLES30.GL_LINK_STATUS, linked, 0); + + if (linked[0] == 0) { + Log.e("ESShader", "Error linking program:"); + Log.e("ESShader", GLES30.glGetProgramInfoLog(programObject)); + GLES30.glDeleteProgram(programObject); + return 0; + } + + // Free up no longer needed shader resources + GLES30.glDeleteShader(vertexShader); + GLES30.glDeleteShader(fragmentShader); + + return programObject; + } + + // + /// + /// \brief Load a vertex and fragment shader from "assets", create a program object, link + /// program. + /// Errors output to log. + /// \param vertShaderFileName Vertex shader source file name + /// \param fragShaderFileName Fragment shader source file name + /// \return A new program object linked with the vertex/fragment shader + /// pair, 0 on failure + // + public static int loadProgramFromAsset(Context context, String vertexShaderFileName, String fragShaderFileName) { + int vertexShader; + int fragmentShader; + int programObject; + int[] linked = new int[1]; + + String vertShaderSrc = null; + String fragShaderSrc = null; + + // Read vertex shader from assets + vertShaderSrc = readShader(context, vertexShaderFileName); + + if (vertShaderSrc == null) + return 0; + + // Read fragment shader from assets + fragShaderSrc = readShader(context, fragShaderFileName); + + if (fragShaderSrc == null) + return 0; + + // Load the vertex shader + vertexShader = loadShader(GLES30.GL_VERTEX_SHADER, vertShaderSrc); + if (vertexShader == 0) + return 0; + + // Load the fragment shader + fragmentShader = loadShader(GLES30.GL_FRAGMENT_SHADER, fragShaderSrc); + if (fragmentShader == 0) { + GLES30.glDeleteShader(vertexShader); + return 0; + } + + // Create the program object + programObject = GLES30.glCreateProgram(); + + if (programObject == 0) + return 0; + + GLES30.glAttachShader(programObject, vertexShader); + GLES30.glAttachShader(programObject, fragmentShader); + + // Link the program + GLES30.glLinkProgram(programObject); + + // Check the link status + GLES30.glGetProgramiv(programObject, GLES30.GL_LINK_STATUS, linked, 0); + + if (linked[0] == 0) { + Log.e("ESShader", "Error linking program:"); + Log.e("ESShader", GLES30.glGetProgramInfoLog(programObject)); + GLES30.glDeleteProgram(programObject); + return 0; + } + + // Free up no longer needed shader resources + GLES30.glDeleteShader(vertexShader); + GLES30.glDeleteShader(fragmentShader); + + return programObject; + } +} diff --git a/Android_Java/Common/src/com/openglesbook/common/ESShapes.java b/Android_Java/Common/src/com/openglesbook/common/ESShapes.java new file mode 100644 index 0000000..724b573 --- /dev/null +++ b/Android_Java/Common/src/com/openglesbook/common/ESShapes.java @@ -0,0 +1,175 @@ +// +// Book: OpenGL(R) ES 2.0 Programming Guide +// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner +// ISBN-10: 0321502795 +// ISBN-13: 9780321502797 +// Publisher: Addison-Wesley Professional +// URLs: http://safari.informit.com/9780321563835 +// http://www.opengles-book.com +// + +// ESShapes +// +// Utility cass for generating shapes +// + +package com.openglesbook.common; + +import java.lang.Math; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; +import java.nio.ShortBuffer; + +public class ESShapes { + + public int genSphere(int numSlices, float radius) { + int i; + int j; + int numParallels = numSlices; + int numVertices = (numParallels + 1) * (numSlices + 1); + int numIndices = numParallels * numSlices * 6; + float angleStep = ((2.0f * (float) Math.PI) / numSlices); + + // Allocate memory for buffers + mVertices = ByteBuffer.allocateDirect(numVertices * 3 * 4) + .order(ByteOrder.nativeOrder()).asFloatBuffer(); + mNormals = ByteBuffer.allocateDirect(numVertices * 3 * 4) + .order(ByteOrder.nativeOrder()).asFloatBuffer(); + mTexCoords = ByteBuffer.allocateDirect(numVertices * 2 * 4) + .order(ByteOrder.nativeOrder()).asFloatBuffer(); + mIndices = ByteBuffer.allocateDirect(numIndices * 2) + .order(ByteOrder.nativeOrder()).asShortBuffer(); + + for (i = 0; i < numParallels + 1; i++) { + for (j = 0; j < numSlices + 1; j++) { + int vertex = (i * (numSlices + 1) + j) * 3; + + mVertices + .put(vertex + 0, + (float) (radius + * Math.sin(angleStep * (float) i) * Math + .sin(angleStep * (float) j))); + + mVertices.put(vertex + 1, + (float) (radius * Math.cos(angleStep * (float) i))); + mVertices + .put(vertex + 2, + (float) (radius + * Math.sin(angleStep * (float) i) * Math + .cos(angleStep * (float) j))); + + mNormals.put(vertex + 0, mVertices.get(vertex + 0) / radius); + mNormals.put(vertex + 1, mVertices.get(vertex + 1) / radius); + mNormals.put(vertex + 2, mVertices.get(vertex + 2) / radius); + + int texIndex = (i * (numSlices + 1) + j) * 2; + mTexCoords.put(texIndex + 0, (float) j / (float) numSlices); + mTexCoords.put(texIndex + 1, (1.0f - (float) i) + / (float) (numParallels - 1)); + } + } + + int index = 0; + for (i = 0; i < numParallels; i++) { + for (j = 0; j < numSlices; j++) { + mIndices.put(index++, (short) (i * (numSlices + 1) + j)); + mIndices.put(index++, (short) ((i + 1) * (numSlices + 1) + j)); + mIndices.put(index++, + (short) ((i + 1) * (numSlices + 1) + (j + 1))); + + mIndices.put(index++, (short) (i * (numSlices + 1) + j)); + mIndices.put(index++, + (short) ((i + 1) * (numSlices + 1) + (j + 1))); + mIndices.put(index++, (short) (i * (numSlices + 1) + (j + 1))); + + } + } + mNumIndices = numIndices; + + return numIndices; + } + + public int genCube(float scale) { + int i; + int numVertices = 24; + int numIndices = 36; + + float[] cubeVerts = { -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, 0.5f, + -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, + 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, -0.5f, -0.5f, + -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, + -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, + 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, + -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, + 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, }; + + float[] cubeNormals = { 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, + -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, + 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, + 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, + -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, + 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, }; + + float[] cubeTex = { 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, + 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, }; + + // Allocate memory for buffers + mVertices = ByteBuffer.allocateDirect(numVertices * 3 * 4) + .order(ByteOrder.nativeOrder()).asFloatBuffer(); + mNormals = ByteBuffer.allocateDirect(numVertices * 3 * 4) + .order(ByteOrder.nativeOrder()).asFloatBuffer(); + mTexCoords = ByteBuffer.allocateDirect(numVertices * 2 * 4) + .order(ByteOrder.nativeOrder()).asFloatBuffer(); + mIndices = ByteBuffer.allocateDirect(numIndices * 2) + .order(ByteOrder.nativeOrder()).asShortBuffer(); + + mVertices.put(cubeVerts).position(0); + for (i = 0; i < numVertices * 3; i++) { + mVertices.put(i, mVertices.get(i) * scale); + } + + mNormals.put(cubeNormals).position(0); + mTexCoords.put(cubeTex).position(0); + + short[] cubeIndices = { 0, 2, 1, 0, 3, 2, 4, 5, 6, 4, 6, 7, 8, 9, 10, + 8, 10, 11, 12, 15, 14, 12, 14, 13, 16, 17, 18, 16, 18, 19, 20, + 23, 22, 20, 22, 21 }; + + mIndices.put(cubeIndices).position(0); + mNumIndices = numIndices; + return numIndices; + } + + public FloatBuffer getVertices() { + return mVertices; + } + + public FloatBuffer getNormals() { + return mNormals; + } + + public FloatBuffer getTexCoords() { + return mTexCoords; + } + + public ShortBuffer getIndices() { + return mIndices; + } + + public int getNumIndices() { + return mNumIndices; + } + + // Member variables + private FloatBuffer mVertices; + private FloatBuffer mNormals; + private FloatBuffer mTexCoords; + private ShortBuffer mIndices; + private int mNumIndices; +} diff --git a/Android_Java/Common/src/com/openglesbook/common/ESTransform.java b/Android_Java/Common/src/com/openglesbook/common/ESTransform.java new file mode 100644 index 0000000..212f1e0 --- /dev/null +++ b/Android_Java/Common/src/com/openglesbook/common/ESTransform.java @@ -0,0 +1,214 @@ +package com.openglesbook.common; + +import java.lang.Math; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; + +public class ESTransform { + public ESTransform() { + mMatrixFloatBuffer = ByteBuffer.allocateDirect(16 * 4) + .order(ByteOrder.nativeOrder()).asFloatBuffer(); + } + + public void scale(float sx, float sy, float sz) { + mMatrix[0 * 4 + 0] *= sx; + mMatrix[0 * 4 + 1] *= sx; + mMatrix[0 * 4 + 2] *= sx; + mMatrix[0 * 4 + 3] *= sx; + + mMatrix[1 * 4 + 0] *= sy; + mMatrix[1 * 4 + 1] *= sy; + mMatrix[1 * 4 + 2] *= sy; + mMatrix[1 * 4 + 3] *= sy; + + mMatrix[2 * 4 + 0] *= sz; + mMatrix[2 * 4 + 1] *= sz; + mMatrix[2 * 4 + 2] *= sz; + mMatrix[2 * 4 + 3] *= sz; + } + + public void translate(float tx, float ty, float tz) { + mMatrix[3 * 4 + 0] += (mMatrix[0 * 4 + 0] * tx + mMatrix[1 * 4 + 0] + * ty + mMatrix[2 * 4 + 0] * tz); + mMatrix[3 * 4 + 1] += (mMatrix[0 * 4 + 1] * tx + mMatrix[1 * 4 + 1] + * ty + mMatrix[2 * 4 + 1] * tz); + mMatrix[3 * 4 + 2] += (mMatrix[0 * 4 + 2] * tx + mMatrix[1 * 4 + 2] + * ty + mMatrix[2 * 4 + 2] * tz); + mMatrix[3 * 4 + 3] += (mMatrix[0 * 4 + 3] * tx + mMatrix[1 * 4 + 3] + * ty + mMatrix[2 * 4 + 3] * tz); + } + + public void rotate(float angle, float x, float y, float z) { + float sinAngle, cosAngle; + float mag = (float) Math.sqrt((double) (x * x + y * y + z * z)); + + sinAngle = (float) Math.sin((double) (angle * Math.PI / 180.0)); + cosAngle = (float) Math.cos((double) (angle * Math.PI / 180.0)); + if (mag > 0.0f) { + float xx, yy, zz, xy, yz, zx, xs, ys, zs; + float oneMinusCos; + float[] rotMat = new float[16]; + + x /= mag; + y /= mag; + z /= mag; + + xx = x * x; + yy = y * y; + zz = z * z; + xy = x * y; + yz = y * z; + zx = z * x; + xs = x * sinAngle; + ys = y * sinAngle; + zs = z * sinAngle; + oneMinusCos = 1.0f - cosAngle; + + rotMat[0 * 4 + 0] = (oneMinusCos * xx) + cosAngle; + rotMat[0 * 4 + 1] = (oneMinusCos * xy) - zs; + rotMat[0 * 4 + 2] = (oneMinusCos * zx) + ys; + rotMat[0 * 4 + 3] = 0.0F; + + rotMat[1 * 4 + 0] = (oneMinusCos * xy) + zs; + rotMat[1 * 4 + 1] = (oneMinusCos * yy) + cosAngle; + rotMat[1 * 4 + 2] = (oneMinusCos * yz) - xs; + rotMat[1 * 4 + 3] = 0.0F; + + rotMat[2 * 4 + 0] = (oneMinusCos * zx) - ys; + rotMat[2 * 4 + 1] = (oneMinusCos * yz) + xs; + rotMat[2 * 4 + 2] = (oneMinusCos * zz) + cosAngle; + rotMat[2 * 4 + 3] = 0.0F; + + rotMat[3 * 4 + 0] = 0.0F; + rotMat[3 * 4 + 1] = 0.0F; + rotMat[3 * 4 + 2] = 0.0F; + rotMat[3 * 4 + 3] = 1.0F; + + matrixMultiply(rotMat, mMatrix); + } + } + + public void frustum(float left, float right, float bottom, float top, + float nearZ, float farZ) { + float deltaX = right - left; + float deltaY = top - bottom; + float deltaZ = farZ - nearZ; + float[] frust = new float[16]; + + if ((nearZ <= 0.0f) || (farZ <= 0.0f) || (deltaX <= 0.0f) + || (deltaY <= 0.0f) || (deltaZ <= 0.0f)) + return; + + frust[0 * 4 + 0] = 2.0f * nearZ / deltaX; + frust[0 * 4 + 1] = frust[0 * 4 + 2] = frust[0 * 4 + 3] = 0.0f; + + frust[1 * 4 + 1] = 2.0f * nearZ / deltaY; + frust[1 * 4 + 0] = frust[1 * 4 + 2] = frust[1 * 4 + 3] = 0.0f; + + frust[2 * 4 + 0] = (right + left) / deltaX; + frust[2 * 4 + 1] = (top + bottom) / deltaY; + frust[2 * 4 + 2] = -(nearZ + farZ) / deltaZ; + frust[2 * 4 + 3] = -1.0f; + + frust[3 * 4 + 2] = -2.0f * nearZ * farZ / deltaZ; + frust[3 * 4 + 0] = frust[3 * 4 + 1] = frust[3 * 4 + 3] = 0.0f; + + matrixMultiply(frust, mMatrix); + } + + public void perspective(float fovy, float aspect, float nearZ, float farZ) { + float frustumW, frustumH; + + frustumH = (float) Math.tan(fovy / 360.0 * Math.PI) * nearZ; + frustumW = frustumH * aspect; + + frustum(-frustumW, frustumW, -frustumH, frustumH, nearZ, farZ); + } + + public void ortho(float left, float right, float bottom, float top, + float nearZ, float farZ) { + float deltaX = right - left; + float deltaY = top - bottom; + float deltaZ = farZ - nearZ; + float[] orthoMat = makeIdentityMatrix(); + + if ((deltaX == 0.0f) || (deltaY == 0.0f) || (deltaZ == 0.0f)) + return; + + orthoMat[0 * 4 + 0] = 2.0f / deltaX; + orthoMat[3 * 4 + 0] = -(right + left) / deltaX; + orthoMat[1 * 4 + 1] = 2.0f / deltaY; + orthoMat[3 * 4 + 1] = -(top + bottom) / deltaY; + orthoMat[2 * 4 + 2] = -2.0f / deltaZ; + orthoMat[3 * 4 + 2] = -(nearZ + farZ) / deltaZ; + + matrixMultiply(orthoMat, mMatrix); + } + + public void matrixMultiply(float[] srcA, float[] srcB) { + float[] tmp = new float[16]; + int i; + + for (i = 0; i < 4; i++) { + tmp[i * 4 + 0] = (srcA[i * 4 + 0] * srcB[0 * 4 + 0]) + + (srcA[i * 4 + 1] * srcB[1 * 4 + 0]) + + (srcA[i * 4 + 2] * srcB[2 * 4 + 0]) + + (srcA[i * 4 + 3] * srcB[3 * 4 + 0]); + + tmp[i * 4 + 1] = (srcA[i * 4 + 0] * srcB[0 * 4 + 1]) + + (srcA[i * 4 + 1] * srcB[1 * 4 + 1]) + + (srcA[i * 4 + 2] * srcB[2 * 4 + 1]) + + (srcA[i * 4 + 3] * srcB[3 * 4 + 1]); + + tmp[i * 4 + 2] = (srcA[i * 4 + 0] * srcB[0 * 4 + 2]) + + (srcA[i * 4 + 1] * srcB[1 * 4 + 2]) + + (srcA[i * 4 + 2] * srcB[2 * 4 + 2]) + + (srcA[i * 4 + 3] * srcB[3 * 4 + 2]); + + tmp[i * 4 + 3] = (srcA[i * 4 + 0] * srcB[0 * 4 + 3]) + + (srcA[i * 4 + 1] * srcB[1 * 4 + 3]) + + (srcA[i * 4 + 2] * srcB[2 * 4 + 3]) + + (srcA[i * 4 + 3] * srcB[3 * 4 + 3]); + } + + mMatrix = tmp; + } + + public void matrixLoadIdentity() { + for (int i = 0; i < 16; i++) + mMatrix[i] = 0.0f; + + mMatrix[0 * 4 + 0] = 1.0f; + mMatrix[1 * 4 + 1] = 1.0f; + mMatrix[2 * 4 + 2] = 1.0f; + mMatrix[3 * 4 + 3] = 1.0f; + } + + private float[] makeIdentityMatrix() { + float[] result = new float[16]; + + for (int i = 0; i < 16; i++) + result[i] = 0.0f; + + result[0 * 4 + 0] = 1.0f; + result[1 * 4 + 1] = 1.0f; + result[2 * 4 + 2] = 1.0f; + result[3 * 4 + 3] = 1.0f; + + return result; + } + + public FloatBuffer getAsFloatBuffer() { + mMatrixFloatBuffer.put(mMatrix).position(0); + return mMatrixFloatBuffer; + } + + public float[] get() { + return mMatrix; + } + + private float[] mMatrix = new float[16]; + private FloatBuffer mMatrixFloatBuffer; + +} \ No newline at end of file