lecturer prof luqun li liluqun@gmail com teaching assistants fengyou sun haijun yang ting sun n.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
Lecturer: Prof.Luqun Li ( liluqun@gmail ) PowerPoint Presentation
Download Presentation
Lecturer: Prof.Luqun Li ( liluqun@gmail )

Loading in 2 Seconds...

play fullscreen
1 / 50

Lecturer: Prof.Luqun Li ( liluqun@gmail ) - PowerPoint PPT Presentation


  • 85 Views
  • Uploaded on

Chapter 10 Programming 3D Graphics with OpenGL. Lecturer: Prof.Luqun Li ( liluqun@gmail.com ) Teaching Assistants: Fengyou Sun, Haijun Yang, Ting Sun. 2. 1. Defining Shapes. Building an OpenGL ES Environment. 3. Drawing Shapes. 4. Applying Projection and Camera Views. 5. 6.

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

Lecturer: Prof.Luqun Li ( liluqun@gmail )


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
lecturer prof luqun li liluqun@gmail com teaching assistants fengyou sun haijun yang ting sun

Chapter 10

Programming 3D Graphics

with OpenGL

Lecturer: Prof.Luqun Li (liluqun@gmail.com)

Teaching Assistants: Fengyou Sun, Haijun Yang, Ting Sun

contents

2

1

Defining Shapes

Building an OpenGL ES Environment

3

Drawing Shapes

4

Applying Projection and Camera Views

5

6

Adding Motion

Responding to Touch Events

Contents
building an opengl es environment
Building an OpenGL ES Environment
  • Implement a GLSurfaceView and a GLSurfaceView.Renderer
  • GLSurfaceView is a view container for graphics drawn with OpenGL
  • GLSurfaceView.Renderer controls what is drawn within that view
    • GLSurfaceView is for a full-screen or near-full screen graphics view
    • TextureView is used to incorporate OpenGL ES graphics in a small portion of their layouts
declare in the manifest
Declare in the Manifest
  • To use the OpenGL ES 2.0 API :
    • <uses-feature android:glEsVersion="0x00020000" android:required="true" />
  • If your application uses texture compression :
    • <supports-gl-texture android:name="GL_OES_compressed_ETC1_RGB8_texture" />
    • <supports-gl-texture android:name="GL_OES_compressed_paletted_texture" />
create an activity
Create an Activity
  • Android applications that use OpenGL ES have activities just like any other application that has a user interface.
  • A minimal implementation of an activity that uses a GLSurfaceView
create an activity1
Create an Activity
  • public class OpenGLES20 extends Activity {
  • private GLSurfaceView mGLView;
  • @Override
  • public void onCreate(Bundle savedInstanceState) {
  • super.onCreate(savedInstanceState);
    • // Create a GLSurfaceView instance and set it
    • // as the ContentView for this Activity.
  • mGLView = new MyGLSurfaceView(this);
  • setContentView(mGLView);
  • }
  • }
build a glsurfaceview object
Build a GLSurfaceView Object
  • A GLSurfaceView is a specialized view where you can draw OpenGL ES graphics.
  • The actual drawing of objects is controlled in the GLSurfaceView.Renderer that you set on this view.
build a glsurfaceview object1
Build a GLSurfaceView Object
  • class MyGLSurfaceView extends GLSurfaceView {
  • public MyGLSurfaceView(Context context){
  • super(context);
    • // Set the Renderer for drawing on the
    • // GLSurfaceView
  • setRenderer(new MyRenderer());
  • }
  • }
build a glsurfaceview object2
Build a GLSurfaceView Object
    • // Create an OpenGL ES 2.0 context
  • setEGLContextClientVersion(2);
    • // Render the view only when there is a
    • //change in the drawing data
  • setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
build a renderer class
Build a Renderer Class
  • Three methods in a renderer called by the Android system :
  • onSurfaceCreated() - Called once to set up the view's OpenGL ES environment.
  • onDrawFrame() - Called for each redraw of the view.
  • onSurfaceChanged() - Called if the geometry of the view changes, for example when the device's screen orientation changes.
build a renderer class1
Build a Renderer Class
  • public class MyGL20Renderer implements GLSurfaceView.Renderer {
  • public void onSurfaceCreated(GL10 unused, EGLConfig config) {
  • // Set the background frame color
  • GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
  • }
  • public void onDrawFrame(GL10 unused) {
  • // Redraw background color
  • GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
  • }
  • public void onSurfaceChanged(GL10 unused, int width, int height) {
  • GLES20.glViewport(0, 0, width, height);
  • }
  • }
contents1

2

1

Defining Shapes

Building an OpenGL ES Environment

3

Drawing Shapes

4

Applying Projection and Camera Views

5

6

Adding Motion

Responding to Touch Events

Contents
opengl coordinate system
OpenGL coordinate system
  • OpenGL assumes a square, uniform coordinate system and, by default, happily draws those coordinates onto your typically non-square screen as if it is perfectly square.
  • To solve this problem, you can apply OpenGL projection modes and camera views to transform coordinates so your graphic objects have the correct proportions on any display.
opengl coordinate system1
OpenGL coordinate system
  • Default OpenGL coordinate system (left) mapped to a typical Android device screen (right)
define a triangle
Define a Triangle
  • OpenGL ES allows you to define drawn objects using coordinates in three-dimensional space. So, before you can draw a triangle, you must define its coordinates.
    • Define a vertex array of floating point numbers for the coordinates
    • Write these coordinates into a ByteBuffer
define a triangle1
Define a Triangle
  • class Triangle {
  • private FloatBuffer vertexBuffer; // number of coordinates per vertex in this array
  • static final int COORDS_PER_VERTEX = 3;
  • static float triangleCoords[] = {
  • // in counterclockwise order:
  • 0.0f, 0.622008459f, 0.0f, // top
  • -0.5f, -0.311004243f, 0.0f, // bottom left
  • 0.5f, -0.311004243f, 0.0f // bottom right
  • };
  • // Set color with red, green, blue and alpha
  • // (opacity) values
  • float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f };
define a triangle2
Define a Triangle
  • public Triangle() {
  • // initialize vertex byte buffer for shape coordinates
  • ByteBuffer bb = ByteBuffer.allocateDirect(
  • // (number of coordinate values * 4 bytes per float)
  • triangleCoords.length * 4);
  • // use the device hardware's native byte order
  • bb.order(ByteOrder.nativeOrder());
  • // create a floating point buffer from the ByteBuffer
  • vertexBuffer = bb.asFloatBuffer();
  • // add the coordinates to the FloatBuffer vertex
  • Buffer.put(triangleCoords);
  • // set the buffer to read the first coordinate
  • vertexBuffer.position(0);
  • }
  • }
define a square
Define a Square
  • Define the vertices in a counterclockwise order for both triangles that represent this shape, and put the values in a ByteBuffer.
  • Use a drawing list to avoid defining the two coordinates shared by each triangle twice
define a square1
Define a Square
  • class Square {
  • private FloatBuffer vertexBuffer;
  • private ShortBuffer drawListBuffer;
  • //number of coordinates per vertex in this array
  • static final int COORDS_PER_VERTEX = 3;
  • static float squareCoords[] = {
  • -0.5f, 0.5f, 0.0f, // top left
  • -0.5f, -0.5f, 0.0f, // bottom left
  • 0.5f, -0.5f, 0.0f, // bottom right
  • 0.5f, 0.5f, 0.0f };
  • // top right
  • private short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices
define a square2
Define a Square
  • public Square() {
  • // initialize vertex byte buffer for shape coordinates
  • ByteBuffer bb = ByteBuffer.allocateDirect(
  • // (# of coordinate values * 4 bytes per float)
  • squareCoords.length * 4);
  • bb.order(ByteOrder.nativeOrder());
  • vertexBuffer = bb.asFloatBuffer();
  • vertexBuffer.put(squareCoords);
  • vertexBuffer.position(0);
  • // initialize byte buffer for the draw list
  • ByteBuffer dlb = ByteBuffer.allocateDirect(
  • // (# of coordinate values * 2 bytes per short)
  • drawOrder.length * 2);
  • dlb.order(ByteOrder.nativeOrder());
  • drawListBuffer = dlb.asShortBuffer();
  • drawListBuffer.put(drawOrder);
  • drawListBuffer.position(0);
  • }
  • }
contents2

2

1

Defining Shapes

Building an OpenGL ES Environment

3

Drawing Shapes

4

Applying Projection and Camera Views

5

6

Adding Motion

Responding to Touch Events

Contents
initialize shapes
Initialize Shapes
    • Initialize and load the shapes in the onSurfaceCreated()
  • public void onSurfaceCreated(GL10 unused, EGLConfig config) {
  • ...
  • // initialize a triangle
  • mTriangle = new Triangle();
  • // initialize a square
  • mSquare = new Square();
  • }
draw a shape
Draw a Shape
  • You must define the following:
    • Vertex Shader - OpenGL ES graphics code for rendering the vertices of a shape.
    • Fragment Shader - OpenGL ES code for rendering the face of a shape with colors or textures.
    • Program - An OpenGL ES object that contains the shaders you want to use for drawing one or more shapes.
draw a shape1
Draw a Shape
    • Define basic shaders
  • 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;" +
  • "}";
draw a shape2
Draw a Shape
    • Compile OpenGL Shading Language (GLSL) code
  • public static int loadShader(int type, String shaderCode){
  • // create a vertex shader type
  • //(GLES20.GL_VERTEX_SHADER)
  • // or a fragment shader type
  • //(GLES20.GL_FRAGMENT_SHADER)
  • int shader = GLES20.glCreateShader(type);
  • // add the source code to the shader and compile it
  • GLES20.glShaderSource(shader, shaderCode);
  • GLES20.glCompileShader(shader);
  • return shader;
  • }
draw a shape3
Draw a Shape
  • In order to draw your shape,
    • you must compile the shader code,
    • add them to a OpenGL ES program object
    • and then link the program.
draw a shape4
Draw a Shape
  • public Triangle() {
  • ...
  • int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
  • int fragmentShader = 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);
  • }
draw a shape5
Draw a Shape
  • Drawing shapes with OpenGL ES requires that you specify several parameters to tell the rendering pipeline what you want to draw and how to draw it.
  • Since drawing options can vary by shape, it's a good idea to have your shape classes contain their own drawing logic.
draw a shape6
Draw a Shape
  • public void draw() {
  • // Add program to OpenGL ES environment
  • GLES20.glUseProgram(mProgram);
  • // get handle to vertex shader's vPosition member
  • mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
  • // Enable a handle to the triangle vertices
  • GLES20.glEnableVertexAttribArray(mPositionHandle);
  • // Prepare the triangle coordinate data
  • GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, vertexStride, vertexBuffer);
draw a shape7
Draw a Shape
  • // get handle to fragment shader's vColor member
  • mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
  • // Set color for drawing the triangle
  • GLES20.glUniform4fv(mColorHandle, 1, color, 0);
  • // Draw the triangle
  • GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
  • // Disable vertex array
  • GLES20.glDisableVertexAttribArray(mPositionHandle);
  • }
draw a shape8
Draw a Shape
  • Call draw() from within your renderer’s onDrawFrame() method
contents3

2

1

Defining Shapes

Building an OpenGL ES Environment

3

Drawing Shapes

4

Applying Projection and Camera Views

5

6

Adding Motion

Responding to Touch Events

Contents
applying projection and camera views
Applying Projection and Camera Views
  • Projection - This transformation adjusts the coordinates of drawn objects based on the width and height of the GLSurfaceView where they are displayed.
  • Camera View - This transformation adjusts the coordinates of drawn objects based on a virtual camera position.
define a projection
Define a Projection
  • @Override
  • public void onSurfaceChanged(GL10 unused, int width, int height) {
  • GLES20.glViewport(0, 0, width, height);
  • float ratio = (float) width / height;
  • // this projection matrix is applied to object coordinates
  • // in the onDrawFrame() method
  • Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
  • }
define a camera view
Define a Camera View
  • @Override
  • public void onDrawFrame(GL10 unused) {
  • ...
  • // Set the camera position (View matrix)
  • Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
  • // Calculate the projection and view transformation
  • Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);
  • // Draw shape
  • mTriangle.draw(mMVPMatrix);
  • }
apply projection and camera
Apply Projection and Camera
  • public void draw(float[] mvpMatrix) {
  • // pass in the calculated transformation matrix
  • ...
  • // get handle to shape's transformation matrix
  • mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
  • // Apply the projection and view transformation
  • GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
  • // Draw the triangle
  • GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
  • ...
  • }
triangle transformed
Triangle Transformed
  • Triangle drawn with a projection and camera view applied.
contents4

2

1

Defining Shapes

Building an OpenGL ES Environment

3

Drawing Shapes

4

Applying Projection and Camera Views

5

6

Adding Motion

Responding to Touch Events

Contents
adding motion
Adding Motion
  • OpenGL ES provides additional capabilities for moving and transforming drawn objects in three dimensions or in other unique ways to create compelling user experiences.
rotate a shape
Rotate a Shape
  • private float[] mRotationMatrix = new float[16];
  • public void onDrawFrame(GL10 gl) {
  • ...
  • // Create a rotation transformation for the triangle
  • long time = SystemClock.uptimeMillis() % 4000L;
  • float angle = 0.090f * ((int) time);
  • Matrix.setRotateM(mRotationMatrix, 0, mAngle, 0, 0, -1.0f);
  • // Combine the rotation matrix with the projection and camera view
  • Matrix.multiplyMM(mMVPMatrix, 0, mRotationMatrix, 0, mMVPMatrix, 0);
  • // Draw triangle
  • mTriangle.draw(mMVPMatrix);
  • }
enable continuous rendering
Enable Continuous Rendering
  • public MyGLSurfaceView(Context context) {
  • ...
  • // Render the view only when there is a change in the drawing data
  • //setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
  • // comment out for auto-rotation
  • }
    • Unless you have objects changing without any user interaction, it’s usually a good idea have this flag turned on.
contents5

2

1

Defining Shapes

Building an OpenGL ES Environment

3

Drawing Shapes

4

Applying Projection and Camera Views

5

6

Adding Motion

Responding to Touch Events

Contents
responding to touch events
Responding to Touch Events
  • The key to making your OpenGL ES application touch interactive is expanding your implementation of GLSurfaceView to override the onTouchEvent() to listen for touch events.
setup a touch listener
Setup a Touch Listener
  • @Override
  • public boolean onTouchEvent(MotionEvent e) {
  • // MotionEvent reports input details from the touch screen
  • // and other input controls. In this case, you are only
  • // interested in events where the touch position changed.
  • float x = e.getX();
  • float y = e.getY();
  • switch (e.getAction()) {
  • case MotionEvent.ACTION_MOVE:
  • float dx = x - mPreviousX;
  • float dy = y - mPreviousY;
setup a touch listener1
Setup a Touch Listener
  • // reverse direction of rotation above the mid-line
  • if (y > getHeight() / 2) {
  • dx = dx * -1 ;
  • }
  • // reverse direction of rotation to left of the mid-line
  • if (x < getWidth() / 2) {
  • dy = dy * -1 ;
  • }
  • mRenderer.mAngle += (dx + dy) * TOUCH_SCALE_FACTOR; // = 180.0f / 320
  • requestRender();
  • }
  • mPreviousX = x;
  • mPreviousY = y;
  • return true;
  • }
set render mode
Set Render Mode
  • public MyGLSurfaceView(Context context) {
  • ...
  • // Render the view only when there is a change in the drawing data
  • setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
  • }
expose the rotation angle
Expose the Rotation Angle
  • Add a public member and declare this public variable as volatile
  • public class MyGLRenderer implements GLSurfaceView.Renderer {
  • ...
  • public volatile float mAngle;
apply rotation
Apply Rotation
  • public void onDrawFrame(GL10 gl) {
  • ...
  • // Create a rotation for the triangle
  • // long time = SystemClock.uptimeMillis() % 4000L;
  • // float angle = 0.090f * ((int) time);
  • Matrix.setRotateM(mRotationMatrix, 0, mAngle, 0, 0, -1.0f);
  • // Combine the rotation matrix with the projection and camera view
  • Matrix.multiplyMM(mMVPMatrix, 0, mRotationMatrix, 0, mMVPMatrix, 0);
  • // Draw triangle
  • mTriangle.draw(mMVPMatrix);
  • }
responding to touch events1
Responding to Touch Events
  • Triangle being rotated with touch input
summary
Summary
  • This class walks you through the basics of developing applications that use OpenGL, including setup, drawing objects, moving drawn elements and responding to touch input.
  • The example code in this class uses the OpenGL ES 2.0 APIs, which is the recommended API version to use with current Android devices. For more information about versions of OpenGL ES, see the OpenGL developer guide.