Skip to content

Commit

Permalink
Added lesson 5: An Intro to Blending
Browse files Browse the repository at this point in the history
* Updated version to 1.0.4, version code 5.
* Updated readme.txt
* Added a cube builder function.
  • Loading branch information
learnopengles committed Oct 2, 2011
1 parent d69b42a commit fe91976
Show file tree
Hide file tree
Showing 12 changed files with 567 additions and 5 deletions.
5 changes: 4 additions & 1 deletion android/AndroidOpenGLESLessons/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.learnopengles.android"
android:versionCode="4" android:versionName="1.0.3">
android:versionCode="5" android:versionName="1.0.4">
<uses-sdk
android:minSdkVersion="8" />
<!-- We require OpenGL ES 2.0 -->
Expand Down Expand Up @@ -35,5 +35,8 @@
<activity
android:label="@string/lesson_four"
android:name=".lesson4.LessonFourActivity"/>
<activity
android:label="@string/lesson_five"
android:name=".lesson5.LessonFiveActivity"/>
</application>
</manifest>
4 changes: 3 additions & 1 deletion android/AndroidOpenGLESLessons/README.TXT
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
This project is a repository for the lessons and tutorials over at http://www.learnopengles.com/

The compiled app can be downloaded from the Android market at https://market.android.com/details?id=com.learnopengles.android
The compiled app can be downloaded from the Android market at https://market.android.com/details?id=com.learnopengles.android

The WebGL lessons can be viewed at http://www.learnopengles.com/
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions android/AndroidOpenGLESLessons/res/raw/color_fragment_shader.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
precision mediump float; // Set the default precision to medium. We don't need as high of a
// precision in the fragment shader.
varying vec4 v_Color; // This is the color from the vertex shader interpolated across the
// triangle per fragment.

// The entry point for our fragment shader.
void main()
{
// Pass through the color
gl_FragColor = v_Color;
}
17 changes: 17 additions & 0 deletions android/AndroidOpenGLESLessons/res/raw/color_vertex_shader.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
uniform mat4 u_MVPMatrix; // A constant representing the combined model/view/projection matrix.

attribute vec4 a_Position; // Per-vertex position information we will pass in.
attribute vec4 a_Color; // Per-vertex color information we will pass in.

varying vec4 v_Color; // This will be passed into the fragment shader.

// The entry point for our vertex shader.
void main()
{
// Pass through the color.
v_Color = a_Color;

// gl_Position is a special variable used to store the final position.
// Multiply the vertex by the matrix to get the final point in normalized screen coordinates.
gl_Position = u_MVPMatrix * a_Position;
}
4 changes: 3 additions & 1 deletion android/AndroidOpenGLESLessons/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,7 @@
<string name="lesson_three_subtitle">This builds on lesson two by adding per-pixel lighting.</string>
<string name="lesson_four">Lesson Four: Basic Texturing</string>
<string name="lesson_four_subtitle">This builds on lesson three by adding basic texturing.</string>

<string name="lesson_five">Lesson Five: An Intro to Blending</string>
<string name="lesson_five_subtitle">This lesson takes a look at the basics of OpenGL blending.</string>
<string name="lesson_five_startup_toast">Tap the screen to switch between blended and normal mode.</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.SimpleAdapter;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.SimpleAdapter;

import com.learnopengles.android.lesson1.LessonOneActivity;
import com.learnopengles.android.lesson2.LessonTwoActivity;
import com.learnopengles.android.lesson3.LessonThreeActivity;
import com.learnopengles.android.lesson4.LessonFourActivity;
import com.learnopengles.android.lesson5.LessonFiveActivity;

public class TableOfContents extends ListActivity
{
Expand Down Expand Up @@ -74,6 +75,15 @@ public void onCreate(Bundle savedInstanceState)
activityMapping.put(i++, LessonFourActivity.class);
}

{
final Map<String, Object> item = new HashMap<String, Object>();
item.put(ITEM_IMAGE, R.drawable.ic_lesson_five);
item.put(ITEM_TITLE, getText(R.string.lesson_five));
item.put(ITEM_SUBTITLE, getText(R.string.lesson_five_subtitle));
data.add(item);
activityMapping.put(i++, LessonFiveActivity.class);
}

final SimpleAdapter dataAdapter = new SimpleAdapter(this, data, R.layout.toc_item, new String[] {ITEM_IMAGE, ITEM_TITLE, ITEM_SUBTITLE}, new int[] {R.id.Image, R.id.Title, R.id.SubTitle});
setListAdapter(dataAdapter);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package com.learnopengles.android.common;

public class ShapeBuilder
{
public static float[] generateCubeData(float[] point1,
float[] point2,
float[] point3,
float[] point4,
float[] point5,
float[] point6,
float[] point7,
float[] point8,
int elementsPerPoint)
{
// Given a cube with the points defined as follows:
// front left top, front right top, front left bottom, front right bottom,
// back left top, back right top, back left bottom, back right bottom,
// return an array of 6 sides, 2 triangles per side, 3 vertices per triangle, and 4 floats per vertex.
final int FRONT = 0;
final int RIGHT = 1;
final int BACK = 2;
final int LEFT = 3;
final int TOP = 4;
final int BOTTOM = 5;

final int size = elementsPerPoint * 6 * 6;
final float[] cubeData = new float[size];

for (int face = 0; face < 6; face ++)
{
// Relative to the side, p1 = top left, p2 = top right, p3 = bottom left, p4 = bottom right
final float[] p1, p2, p3, p4;

// Select the points for this face
if (face == FRONT)
{
p1 = point1; p2 = point2; p3 = point3; p4 = point4;
}
else if (face == RIGHT)
{
p1 = point2; p2 = point6; p3 = point4; p4 = point8;
}
else if (face == BACK)
{
p1 = point6; p2 = point5; p3 = point8; p4 = point7;
}
else if (face == LEFT)
{
p1 = point5; p2 = point1; p3 = point7; p4 = point3;
}
else if (face == TOP)
{
p1 = point5; p2 = point6; p3 = point1; p4 = point2;
}
else // if (side == BOTTOM)
{
p1 = point8; p2 = point7; p3 = point4; p4 = point3;
}

// In OpenGL counter-clockwise winding is default. This means that when we look at a triangle,
// if the points are counter-clockwise we are looking at the "front". If not we are looking at
// the back. OpenGL has an optimization where all back-facing triangles are culled, since they
// usually represent the backside of an object and aren't visible anyways.

// Build the triangles
// 1---3,6
// | / |
// 2,4--5
int offset = face * elementsPerPoint * 6;

for (int i = 0; i < elementsPerPoint; i++) { cubeData[offset++] = p1[i]; }
for (int i = 0; i < elementsPerPoint; i++) { cubeData[offset++] = p3[i]; }
for (int i = 0; i < elementsPerPoint; i++) { cubeData[offset++] = p2[i]; }
for (int i = 0; i < elementsPerPoint; i++) { cubeData[offset++] = p3[i]; }
for (int i = 0; i < elementsPerPoint; i++) { cubeData[offset++] = p4[i]; }
for (int i = 0; i < elementsPerPoint; i++) { cubeData[offset++] = p2[i]; }
}

return cubeData;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
public class LessonFourRenderer implements GLSurfaceView.Renderer
{
/** Used for debug logs. */
private static final String TAG = "LessonTwoRenderer";
private static final String TAG = "LessonFourRenderer";

private final Context mActivityContext;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.learnopengles.android.lesson5;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ConfigurationInfo;
import android.os.Bundle;
import android.widget.Toast;

import com.learnopengles.android.R;

public class LessonFiveActivity extends Activity
{
/** Hold a reference to our GLSurfaceView */
private LessonFiveGLSurfaceView mGLSurfaceView;

private static final String SHOWED_TOAST = "showed_toast";

@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);

mGLSurfaceView = new LessonFiveGLSurfaceView(this);

// Check if the system supports OpenGL ES 2.0.
final ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
final boolean supportsEs2 = configurationInfo.reqGlEsVersion >= 0x20000;

if (supportsEs2)
{
// Request an OpenGL ES 2.0 compatible context.
mGLSurfaceView.setEGLContextClientVersion(2);

// Set the renderer to our demo renderer, defined below.
mGLSurfaceView.setRenderer(new LessonFiveRenderer(this));
}
else
{
// This is where you could create an OpenGL ES 1.x compatible
// renderer if you wanted to support both ES 1 and ES 2.
return;
}

setContentView(mGLSurfaceView);

// Show a short help message to the user.
if (savedInstanceState == null || !savedInstanceState.getBoolean(SHOWED_TOAST, false))
{
Toast.makeText(this, R.string.lesson_five_startup_toast, Toast.LENGTH_SHORT).show();
}
}

@Override
protected void onResume()
{
// The activity must call the GL surface view's onResume() on activity onResume().
super.onResume();
mGLSurfaceView.onResume();
}

@Override
protected void onPause()
{
// The activity must call the GL surface view's onPause() on activity onPause().
super.onPause();
mGLSurfaceView.onPause();
}

@Override
protected void onSaveInstanceState (Bundle outState)
{
outState.putBoolean(SHOWED_TOAST, true);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.learnopengles.android.lesson5;

import android.content.Context;
import android.opengl.GLSurfaceView;
import android.view.MotionEvent;

public class LessonFiveGLSurfaceView extends GLSurfaceView
{
private LessonFiveRenderer mRenderer;

public LessonFiveGLSurfaceView(Context context)
{
super(context);
}

@Override
public boolean onTouchEvent(MotionEvent event)
{
if (event != null)
{
if (event.getAction() == MotionEvent.ACTION_DOWN)
{
if (mRenderer != null)
{
// Ensure we call switchMode() on the OpenGL thread.
// queueEvent() is a method of GLSurfaceView that will do this for us.
queueEvent(new Runnable()
{
@Override
public void run()
{
mRenderer.switchMode();
}
});

return true;
}
}
}

return super.onTouchEvent(event);
}

// Hides superclass method.
public void setRenderer(LessonFiveRenderer renderer)
{
mRenderer = renderer;
super.setRenderer(renderer);
}
}
Loading

0 comments on commit fe91976

Please sign in to comment.