am 18fc7b85: am ba795593: am 9b432bbe: am e49fbfa2: Merge "docs: Fix various issues with incorrect code samples." into lmp-docs
automerge: 6ee9018
* commit '6ee90183ab79f9c3b5216a9b0b6518de7679734a':
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>
|
for memory and processing efficiency.</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
|
public class MyGLRenderer implements GLSurfaceView.Renderer {
|
||||||
...
|
|
||||||
|
|
||||||
// initialize a triangle
|
...
|
||||||
mTriangle = new Triangle();
|
private Triangle mTriangle;
|
||||||
// initialize a square
|
private Square mSquare;
|
||||||
mSquare = new Square();
|
|
||||||
|
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
|
||||||
|
...
|
||||||
|
|
||||||
|
// initialize a triangle
|
||||||
|
mTriangle = new Triangle();
|
||||||
|
// initialize a square
|
||||||
|
mSquare = new Square();
|
||||||
|
}
|
||||||
|
...
|
||||||
}
|
}
|
||||||
</pre>
|
</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.
|
<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
|
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>
|
<pre>
|
||||||
private final String vertexShaderCode =
|
public class Triangle {
|
||||||
"attribute vec4 vPosition;" +
|
|
||||||
"void main() {" +
|
|
||||||
" gl_Position = vPosition;" +
|
|
||||||
"}";
|
|
||||||
|
|
||||||
private final String fragmentShaderCode =
|
private final String vertexShaderCode =
|
||||||
"precision mediump float;" +
|
"attribute vec4 vPosition;" +
|
||||||
"uniform vec4 vColor;" +
|
"void main() {" +
|
||||||
"void main() {" +
|
" gl_Position = vPosition;" +
|
||||||
" gl_FragColor = vColor;" +
|
"}";
|
||||||
"}";
|
|
||||||
|
private final String fragmentShaderCode =
|
||||||
|
"precision mediump float;" +
|
||||||
|
"uniform vec4 vColor;" +
|
||||||
|
"void main() {" +
|
||||||
|
" gl_FragColor = vColor;" +
|
||||||
|
"}";
|
||||||
|
|
||||||
|
...
|
||||||
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>Shaders contain OpenGL Shading Language (GLSL) code that must be compiled prior to using it in
|
<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() {
|
public class Triangle() {
|
||||||
...
|
...
|
||||||
|
|
||||||
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
|
private final int mProgram;
|
||||||
int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
|
|
||||||
|
|
||||||
mProgram = GLES20.glCreateProgram(); // create empty OpenGL ES Program
|
public Triangle() {
|
||||||
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
|
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>
|
</pre>
|
||||||
|
|
||||||
@@ -145,6 +174,12 @@ color values to the shape’s vertex shader and fragment shader, and then execut
|
|||||||
function.</p>
|
function.</p>
|
||||||
|
|
||||||
<pre>
|
<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() {
|
public void draw() {
|
||||||
// Add program to OpenGL ES environment
|
// Add program to OpenGL ES environment
|
||||||
GLES20.glUseProgram(mProgram);
|
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
|
<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
|
{@code draw()} method from within your renderer’s {@link
|
||||||
android.opengl.GLSurfaceView.Renderer#onDrawFrame onDrawFrame()} method. When you run the
|
android.opengl.GLSurfaceView.Renderer#onDrawFrame onDrawFrame()} method:
|
||||||
application, it should look something like this:</p>
|
|
||||||
|
<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">
|
<img src="{@docRoot}images/opengl/ogl-triangle.png">
|
||||||
<p class="img-caption">
|
<p class="img-caption">
|
||||||
|
|||||||
@@ -129,28 +129,22 @@ just create an inner class in the activity that uses it:</p>
|
|||||||
<pre>
|
<pre>
|
||||||
class MyGLSurfaceView extends GLSurfaceView {
|
class MyGLSurfaceView extends GLSurfaceView {
|
||||||
|
|
||||||
|
private final MyGLRenderer mRenderer;
|
||||||
|
|
||||||
public MyGLSurfaceView(Context context){
|
public MyGLSurfaceView(Context context){
|
||||||
super(context);
|
super(context);
|
||||||
|
|
||||||
|
// Create an OpenGL ES 2.0 context
|
||||||
|
setEGLContextClientVersion(2);
|
||||||
|
|
||||||
|
mRenderer = new MyGLRenderer();
|
||||||
|
|
||||||
// Set the Renderer for drawing on the GLSurfaceView
|
// Set the Renderer for drawing on the GLSurfaceView
|
||||||
setRenderer(new MyRenderer());
|
setRenderer(mRenderer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</pre>
|
</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
|
<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
|
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}
|
{@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>
|
</ul>
|
||||||
|
|
||||||
<p>Here is a very basic implementation of an OpenGL ES renderer, that does nothing more than draw a
|
<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>
|
<pre>
|
||||||
public class MyGLRenderer implements GLSurfaceView.Renderer {
|
public class MyGLRenderer implements GLSurfaceView.Renderer {
|
||||||
@@ -208,7 +202,7 @@ public class MyGLRenderer implements GLSurfaceView.Renderer {
|
|||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>That’s all there is to it! The code examples above create a simple Android application that
|
<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
|
creating these classes, you have laid the foundation you need to start drawing graphic elements with
|
||||||
OpenGL.</p>
|
OpenGL.</p>
|
||||||
|
|
||||||
|
|||||||
@@ -45,16 +45,17 @@ to a shape with rotation.</p>
|
|||||||
|
|
||||||
<h2 id="rotate">Rotate a Shape</h2>
|
<h2 id="rotate">Rotate a Shape</h2>
|
||||||
|
|
||||||
<p>Rotating a drawing object with OpenGL ES 2.0 is relatively simple. You create another
|
<p>Rotating a drawing object with OpenGL ES 2.0 is relatively simple. In your renderer, create
|
||||||
transformation matrix (a rotation matrix) and then combine it with your projection and
|
another transformation matrix (a rotation matrix) and then combine it with your projection and
|
||||||
camera view transformation matrices:</p>
|
camera view transformation matrices:</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
private float[] mRotationMatrix = new float[16];
|
private float[] mRotationMatrix = new float[16];
|
||||||
public void onDrawFrame(GL10 gl) {
|
public void onDrawFrame(GL10 gl) {
|
||||||
...
|
|
||||||
float[] scratch = new float[16];
|
float[] scratch = new float[16];
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
// Create a rotation transformation for the triangle
|
// Create a rotation transformation for the triangle
|
||||||
long time = SystemClock.uptimeMillis() % 4000L;
|
long time = SystemClock.uptimeMillis() % 4000L;
|
||||||
float angle = 0.090f * ((int) time);
|
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>
|
android.opengl.Matrix#frustumM Matrix.frustumM()} method:</p>
|
||||||
|
|
||||||
<pre>
|
<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
|
@Override
|
||||||
public void onSurfaceChanged(GL10 unused, int width, int height) {
|
public void onSurfaceChanged(GL10 unused, int width, int height) {
|
||||||
GLES20.glViewport(0, 0, width, 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>
|
<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
|
<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
|
part of the drawing process in your renderer. In the following example code, the camera view
|
||||||
calculated using the {@link android.opengl.Matrix#setLookAtM Matrix.setLookAtM()} method and then
|
transformation is calculated using the {@link android.opengl.Matrix#setLookAtM Matrix.setLookAtM()}
|
||||||
combined with the previously calculated projection matrix. The combined transformation matrices
|
method and then combined with the previously calculated projection matrix. The combined
|
||||||
are then passed to the drawn shape.</p>
|
transformation matrices are then passed to the drawn shape.</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
@Override
|
@Override
|
||||||
@@ -119,7 +124,32 @@ public void onDrawFrame(GL10 unused) {
|
|||||||
<h2 id="#transform">Apply Projection and Camera Transformations</h2>
|
<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
|
<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>
|
transformation matrix and apply it to the shape:</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
@@ -127,14 +157,16 @@ public void draw(float[] mvpMatrix) { // pass in the calculated transformation m
|
|||||||
...
|
...
|
||||||
|
|
||||||
// get handle to shape's transformation matrix
|
// 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
|
// 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
|
// Draw the triangle
|
||||||
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
|
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
|
||||||
...
|
|
||||||
|
// Disable vertex array
|
||||||
|
GLES20.glDisableVertexAttribArray(mPositionHandle);
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,10 @@ android.opengl.GLSurfaceView#onTouchEvent onTouchEvent()} to listen for touch ev
|
|||||||
an angle of rotation for a shape.</p>
|
an angle of rotation for a shape.</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
|
private final float TOUCH_SCALE_FACTOR = 180.0f / 320;
|
||||||
|
private float mPreviousX;
|
||||||
|
private float mPreviousY;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onTouchEvent(MotionEvent e) {
|
public boolean onTouchEvent(MotionEvent e) {
|
||||||
// MotionEvent reports input details from the touch screen
|
// MotionEvent reports input details from the touch screen
|
||||||
@@ -77,7 +81,7 @@ public boolean onTouchEvent(MotionEvent e) {
|
|||||||
|
|
||||||
mRenderer.setAngle(
|
mRenderer.setAngle(
|
||||||
mRenderer.getAngle() +
|
mRenderer.getAngle() +
|
||||||
((dx + dy) * TOUCH_SCALE_FACTOR); // = 180.0f / 320
|
((dx + dy) * TOUCH_SCALE_FACTOR));
|
||||||
requestRender();
|
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
|
<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
|
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}.
|
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>
|
<pre>
|
||||||
public class MyGLRenderer implements GLSurfaceView.Renderer {
|
public class MyGLRenderer implements GLSurfaceView.Renderer {
|
||||||
...
|
...
|
||||||
|
|
||||||
public volatile float mAngle;
|
public volatile float mAngle;
|
||||||
|
|
||||||
|
public float getAngle() {
|
||||||
|
return mAngle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAngle(float angle) {
|
||||||
|
mAngle = angle;
|
||||||
|
}
|
||||||
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user