am 9b432bbe: am e49fbfa2: Merge "docs: Fix various issues with incorrect code samples." into lmp-docs
* commit '9b432bbece3cca6316b2638a947983e21c65917f': docs: Fix various issues with incorrect code samples.
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 7.3 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 9.5 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 7.0 KiB |
@@ -50,13 +50,21 @@ android.opengl.GLSurfaceView.Renderer#onSurfaceCreated onSurfaceCreated()} metho
|
||||
for memory and processing efficiency.</p>
|
||||
|
||||
<pre>
|
||||
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
|
||||
...
|
||||
public class MyGLRenderer implements GLSurfaceView.Renderer {
|
||||
|
||||
// initialize a triangle
|
||||
mTriangle = new Triangle();
|
||||
// initialize a square
|
||||
mSquare = new Square();
|
||||
...
|
||||
private Triangle mTriangle;
|
||||
private Square mSquare;
|
||||
|
||||
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
|
||||
...
|
||||
|
||||
// initialize a triangle
|
||||
mTriangle = new Triangle();
|
||||
// initialize a square
|
||||
mSquare = new Square();
|
||||
}
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
|
||||
@@ -77,21 +85,27 @@ one or more shapes.</li>
|
||||
|
||||
<p>You need at least one vertex shader to draw a shape and one fragment shader to color that shape.
|
||||
These shaders must be complied and then added to an OpenGL ES program, which is then used to draw
|
||||
the shape. Here is an example of how to define basic shaders you can use to draw a shape:</p>
|
||||
the shape. Here is an example of how to define basic shaders you can use to draw a shape in the
|
||||
<code>Triangle</code> class:</p>
|
||||
|
||||
<pre>
|
||||
private final String vertexShaderCode =
|
||||
"attribute vec4 vPosition;" +
|
||||
"void main() {" +
|
||||
" gl_Position = vPosition;" +
|
||||
"}";
|
||||
public class Triangle {
|
||||
|
||||
private final String fragmentShaderCode =
|
||||
"precision mediump float;" +
|
||||
"uniform vec4 vColor;" +
|
||||
"void main() {" +
|
||||
" gl_FragColor = vColor;" +
|
||||
"}";
|
||||
private final String vertexShaderCode =
|
||||
"attribute vec4 vPosition;" +
|
||||
"void main() {" +
|
||||
" gl_Position = vPosition;" +
|
||||
"}";
|
||||
|
||||
private final String fragmentShaderCode =
|
||||
"precision mediump float;" +
|
||||
"uniform vec4 vColor;" +
|
||||
"void main() {" +
|
||||
" gl_FragColor = vColor;" +
|
||||
"}";
|
||||
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>Shaders contain OpenGL Shading Language (GLSL) code that must be compiled prior to using it in
|
||||
@@ -125,13 +139,28 @@ get created once and then cached for later use.</p>
|
||||
public class Triangle() {
|
||||
...
|
||||
|
||||
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
|
||||
int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
|
||||
private final int mProgram;
|
||||
|
||||
mProgram = GLES20.glCreateProgram(); // create empty OpenGL ES Program
|
||||
GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader to program
|
||||
GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
|
||||
GLES20.glLinkProgram(mProgram); // creates OpenGL ES program executables
|
||||
public Triangle() {
|
||||
...
|
||||
|
||||
int vertexShader = MyGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER,
|
||||
vertexShaderCode);
|
||||
int fragmentShader = MyGLRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER,
|
||||
fragmentShaderCode);
|
||||
|
||||
// create empty OpenGL ES Program
|
||||
mProgram = GLES20.glCreateProgram();
|
||||
|
||||
// add the vertex shader to program
|
||||
GLES20.glAttachShader(mProgram, vertexShader);
|
||||
|
||||
// add the fragment shader to program
|
||||
GLES20.glAttachShader(mProgram, fragmentShader);
|
||||
|
||||
// creates OpenGL ES program executables
|
||||
GLES20.glLinkProgram(mProgram);
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
||||
@@ -145,6 +174,12 @@ color values to the shape’s vertex shader and fragment shader, and then execut
|
||||
function.</p>
|
||||
|
||||
<pre>
|
||||
private int mPositionHandle;
|
||||
private int mColorHandle;
|
||||
|
||||
private final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX;
|
||||
private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex
|
||||
|
||||
public void draw() {
|
||||
// Add program to OpenGL ES environment
|
||||
GLES20.glUseProgram(mProgram);
|
||||
@@ -176,8 +211,17 @@ public void draw() {
|
||||
|
||||
<p>Once you have all this code in place, drawing this object just requires a call to the
|
||||
{@code draw()} method from within your renderer’s {@link
|
||||
android.opengl.GLSurfaceView.Renderer#onDrawFrame onDrawFrame()} method. When you run the
|
||||
application, it should look something like this:</p>
|
||||
android.opengl.GLSurfaceView.Renderer#onDrawFrame onDrawFrame()} method:
|
||||
|
||||
<pre>
|
||||
public void onDrawFrame(GL10 unused) {
|
||||
...
|
||||
|
||||
mTriangle.draw();
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>When you run the application, it should look something like this:</p>
|
||||
|
||||
<img src="{@docRoot}images/opengl/ogl-triangle.png">
|
||||
<p class="img-caption">
|
||||
|
||||
@@ -129,28 +129,22 @@ just create an inner class in the activity that uses it:</p>
|
||||
<pre>
|
||||
class MyGLSurfaceView extends GLSurfaceView {
|
||||
|
||||
private final MyGLRenderer mRenderer;
|
||||
|
||||
public MyGLSurfaceView(Context context){
|
||||
super(context);
|
||||
|
||||
// Create an OpenGL ES 2.0 context
|
||||
setEGLContextClientVersion(2);
|
||||
|
||||
mRenderer = new MyGLRenderer();
|
||||
|
||||
// Set the Renderer for drawing on the GLSurfaceView
|
||||
setRenderer(new MyRenderer());
|
||||
setRenderer(mRenderer);
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>When using OpenGL ES 2.0, you must add another call to your {@link android.opengl.GLSurfaceView}
|
||||
constructor, specifying that you want to use the 2.0 API:</p>
|
||||
|
||||
<pre>
|
||||
// Create an OpenGL ES 2.0 context
|
||||
setEGLContextClientVersion(2);
|
||||
</pre>
|
||||
|
||||
<p class="note"><strong>Note:</strong> If you are using the OpenGL ES 2.0 API, make sure you declare
|
||||
this in your application manifest. For more information, see <a href="#manifest">Declare OpenGL ES
|
||||
Use
|
||||
in the Manifest</a>.</p>
|
||||
|
||||
<p>One other optional addition to your {@link android.opengl.GLSurfaceView} implementation is to set
|
||||
the render mode to only draw the view when there is a change to your drawing data using the
|
||||
{@link android.opengl.GLSurfaceView#RENDERMODE_WHEN_DIRTY GLSurfaceView.RENDERMODE_WHEN_DIRTY}
|
||||
@@ -186,7 +180,7 @@ the geometry of the view changes, for example when the device's screen orientati
|
||||
</ul>
|
||||
|
||||
<p>Here is a very basic implementation of an OpenGL ES renderer, that does nothing more than draw a
|
||||
gray background in the {@link android.opengl.GLSurfaceView}:</p>
|
||||
black background in the {@link android.opengl.GLSurfaceView}:</p>
|
||||
|
||||
<pre>
|
||||
public class MyGLRenderer implements GLSurfaceView.Renderer {
|
||||
@@ -208,7 +202,7 @@ public class MyGLRenderer implements GLSurfaceView.Renderer {
|
||||
</pre>
|
||||
|
||||
<p>That’s all there is to it! The code examples above create a simple Android application that
|
||||
displays a gray screen using OpenGL. While this code does not do anything very interesting, by
|
||||
displays a black screen using OpenGL. While this code does not do anything very interesting, by
|
||||
creating these classes, you have laid the foundation you need to start drawing graphic elements with
|
||||
OpenGL.</p>
|
||||
|
||||
|
||||
@@ -45,16 +45,17 @@ to a shape with rotation.</p>
|
||||
|
||||
<h2 id="rotate">Rotate a Shape</h2>
|
||||
|
||||
<p>Rotating a drawing object with OpenGL ES 2.0 is relatively simple. You create another
|
||||
transformation matrix (a rotation matrix) and then combine it with your projection and
|
||||
<p>Rotating a drawing object with OpenGL ES 2.0 is relatively simple. In your renderer, create
|
||||
another transformation matrix (a rotation matrix) and then combine it with your projection and
|
||||
camera view transformation matrices:</p>
|
||||
|
||||
<pre>
|
||||
private float[] mRotationMatrix = new float[16];
|
||||
public void onDrawFrame(GL10 gl) {
|
||||
...
|
||||
float[] scratch = new float[16];
|
||||
|
||||
...
|
||||
|
||||
// Create a rotation transformation for the triangle
|
||||
long time = SystemClock.uptimeMillis() % 4000L;
|
||||
float angle = 0.090f * ((int) time);
|
||||
|
||||
@@ -71,6 +71,11 @@ projection transformation {@link android.opengl.Matrix} using the {@link
|
||||
android.opengl.Matrix#frustumM Matrix.frustumM()} method:</p>
|
||||
|
||||
<pre>
|
||||
// mMVPMatrix is an abbreviation for "Model View Projection Matrix"
|
||||
private final float[] mMVPMatrix = new float[16];
|
||||
private final float[] mProjectionMatrix = new float[16];
|
||||
private final float[] mViewMatrix = new float[16];
|
||||
|
||||
@Override
|
||||
public void onSurfaceChanged(GL10 unused, int width, int height) {
|
||||
GLES20.glViewport(0, 0, width, height);
|
||||
@@ -95,10 +100,10 @@ view transformation in order for anything to show up on screen.</p>
|
||||
<h2 id="camera-view">Define a Camera View</h2>
|
||||
|
||||
<p>Complete the process of transforming your drawn objects by adding a camera view transformation as
|
||||
part of the drawing process. In the following example code, the camera view transformation is
|
||||
calculated using the {@link android.opengl.Matrix#setLookAtM Matrix.setLookAtM()} method and then
|
||||
combined with the previously calculated projection matrix. The combined transformation matrices
|
||||
are then passed to the drawn shape.</p>
|
||||
part of the drawing process in your renderer. In the following example code, the camera view
|
||||
transformation is calculated using the {@link android.opengl.Matrix#setLookAtM Matrix.setLookAtM()}
|
||||
method and then combined with the previously calculated projection matrix. The combined
|
||||
transformation matrices are then passed to the drawn shape.</p>
|
||||
|
||||
<pre>
|
||||
@Override
|
||||
@@ -119,7 +124,32 @@ public void onDrawFrame(GL10 unused) {
|
||||
<h2 id="#transform">Apply Projection and Camera Transformations</h2>
|
||||
|
||||
<p>In order to use the combined projection and camera view transformation matrix shown in the
|
||||
previews sections, modify the {@code draw()} method of your graphic objects to accept the combined
|
||||
previews sections, first add a matrix variable to the <em>vertex shader</em> previously defined
|
||||
in the <code>Triangle</code> class:</p>
|
||||
|
||||
<pre>
|
||||
public class Triangle {
|
||||
|
||||
private final String vertexShaderCode =
|
||||
// This matrix member variable provides a hook to manipulate
|
||||
// the coordinates of the objects that use this vertex shader
|
||||
<strong>"uniform mat4 uMVPMatrix;" +</strong>
|
||||
"attribute vec4 vPosition;" +
|
||||
"void main() {" +
|
||||
// the matrix must be included as a modifier of gl_Position
|
||||
// Note that the uMVPMatrix factor *must be first* in order
|
||||
// for the matrix multiplication product to be correct.
|
||||
" gl_Position = <strong>uMVPMatrix</strong> * vPosition;" +
|
||||
"}";
|
||||
|
||||
// Use to access and set the view transformation
|
||||
private int mMVPMatrixHandle;
|
||||
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>Next, modify the {@code draw()} method of your graphic objects to accept the combined
|
||||
transformation matrix and apply it to the shape:</p>
|
||||
|
||||
<pre>
|
||||
@@ -127,14 +157,16 @@ public void draw(float[] mvpMatrix) { // pass in the calculated transformation m
|
||||
...
|
||||
|
||||
// get handle to shape's transformation matrix
|
||||
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
|
||||
<strong>mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");</strong>
|
||||
|
||||
// Pass the projection and view transformation to the shader
|
||||
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
|
||||
<strong>GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);</strong>
|
||||
|
||||
// Draw the triangle
|
||||
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
|
||||
...
|
||||
|
||||
// Disable vertex array
|
||||
GLES20.glDisableVertexAttribArray(mPositionHandle);
|
||||
}
|
||||
</pre>
|
||||
|
||||
|
||||
@@ -50,6 +50,10 @@ android.opengl.GLSurfaceView#onTouchEvent onTouchEvent()} to listen for touch ev
|
||||
an angle of rotation for a shape.</p>
|
||||
|
||||
<pre>
|
||||
private final float TOUCH_SCALE_FACTOR = 180.0f / 320;
|
||||
private float mPreviousX;
|
||||
private float mPreviousY;
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent e) {
|
||||
// MotionEvent reports input details from the touch screen
|
||||
@@ -77,7 +81,7 @@ public boolean onTouchEvent(MotionEvent e) {
|
||||
|
||||
mRenderer.setAngle(
|
||||
mRenderer.getAngle() +
|
||||
((dx + dy) * TOUCH_SCALE_FACTOR); // = 180.0f / 320
|
||||
((dx + dy) * TOUCH_SCALE_FACTOR));
|
||||
requestRender();
|
||||
}
|
||||
|
||||
@@ -108,12 +112,22 @@ public MyGLSurfaceView(Context context) {
|
||||
<p>The example code above requires that you expose the rotation angle through your renderer by
|
||||
adding a public member. Since the renderer code is running on a separate thread from the main user
|
||||
interface thread of your application, you must declare this public variable as {@code volatile}.
|
||||
Here is the code to do that:</p>
|
||||
Here is the code to declare the variable and expose the getter and setter pair:</p>
|
||||
|
||||
<pre>
|
||||
public class MyGLRenderer implements GLSurfaceView.Renderer {
|
||||
...
|
||||
|
||||
public volatile float mAngle;
|
||||
|
||||
public float getAngle() {
|
||||
return mAngle;
|
||||
}
|
||||
|
||||
public void setAngle(float angle) {
|
||||
mAngle = angle;
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user