├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── dictionaries │ └── youyang.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── Lesson1 ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── opengl │ │ └── youyang │ │ └── opengllessons │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── opengl │ │ │ └── youyang │ │ │ └── opengllessons │ │ │ ├── BackgroundRender.java │ │ │ └── MainActivity.java │ └── res │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── opengl │ └── youyang │ └── opengllessons │ └── ExampleUnitTest.java ├── Lesson4 ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── opengl │ │ └── youyang │ │ └── myapplication │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── opengl │ │ │ └── youyang │ │ │ └── myapplication │ │ │ ├── ColorShaderProgram.java │ │ │ ├── GLSwitchView.java │ │ │ ├── LogConfig.java │ │ │ ├── MainActivity.java │ │ │ ├── PointRender.java │ │ │ ├── ShaderHelper.java │ │ │ ├── ShaderProgram.java │ │ │ ├── SplashActivity.java │ │ │ ├── TextResourceReader.java │ │ │ └── TextureHelper.java │ └── res │ │ ├── drawable │ │ ├── img_guider4.png │ │ ├── img_guider_checkin.png │ │ ├── img_loading.jpg │ │ ├── img_loadings.jpg │ │ ├── test_1.png │ │ ├── test_2.png │ │ └── test_3.png │ │ ├── layout │ │ └── act_select.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── raw │ │ ├── point_fragment_shader.glsl │ │ ├── point_vertext_shader.glsl │ │ ├── translate10_fragment_shader.glsl │ │ ├── translate1_fragment_shader.glsl │ │ ├── translate2_fragment_shader.glsl │ │ ├── translate3_fragment_shader.glsl │ │ ├── translate4_fragment_shader.glsl │ │ ├── translate5_fragment_shader.glsl │ │ ├── translate6_fragment_shader.glsl │ │ ├── translate7_fragment_shader.glsl │ │ ├── translate8_fragment_shader.glsl │ │ └── translate9_fragment_shader.glsl │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── opengl │ └── youyang │ └── myapplication │ └── ExampleUnitTest.java ├── Lesson6 ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── test │ │ └── youyang │ │ └── wallpaper │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── test │ │ │ └── youyang │ │ │ └── wallpaper │ │ │ ├── ColorShaderProgram.java │ │ │ ├── GLWallPaperService.java │ │ │ ├── LogConfig.java │ │ │ ├── MainActivity.java │ │ │ ├── PointRender.java │ │ │ ├── ShaderHelper.java │ │ │ ├── ShaderProgram.java │ │ │ ├── TextResourceReader.java │ │ │ └── TextureHelper.java │ └── res │ │ ├── drawable │ │ └── ic_launcher.png │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── raw │ │ ├── point_fragment_shader.glsl │ │ ├── point_fragment_shader1.glsl │ │ └── point_vertext_shader.glsl │ │ ├── values-w820dp │ │ └── dimens.xml │ │ ├── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ │ └── xml │ │ └── wallpaper.xml │ └── test │ └── java │ └── com │ └── test │ └── youyang │ └── wallpaper │ └── ExampleUnitTest.java ├── README.md ├── build.gradle ├── device-2016-08-16-174717.png ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── lesson1.png ├── lesson2.png ├── lesson2 ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── opengl │ │ └── youyang │ │ └── lesson2 │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── opengl │ │ │ └── youyang │ │ │ └── lesson2 │ │ │ ├── ColorShaderProgram.java │ │ │ ├── LogConfig.java │ │ │ ├── MainActivity.java │ │ │ ├── PointRender.java │ │ │ ├── ShaderHelper.java │ │ │ ├── ShaderProgram.java │ │ │ └── TextResourceReader.java │ └── res │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── raw │ │ ├── point_fragment_shader.glsl │ │ └── point_vertext_shader.glsl │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── opengl │ └── youyang │ └── lesson2 │ └── ExampleUnitTest.java ├── lesson3.png ├── lesson3 ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── opengl │ │ └── youyang │ │ └── myapplication │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── opengl │ │ │ └── youyang │ │ │ └── myapplication │ │ │ ├── ColorShaderProgram.java │ │ │ ├── LogConfig.java │ │ │ ├── MainActivity.java │ │ │ ├── PointRender.java │ │ │ ├── ShaderHelper.java │ │ │ ├── ShaderProgram.java │ │ │ └── TextResourceReader.java │ └── res │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── raw │ │ ├── point_fragment_shader.glsl │ │ └── point_vertext_shader.glsl │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── opengl │ └── youyang │ └── myapplication │ └── ExampleUnitTest.java ├── lesson4.gif ├── lesson5.gif ├── lesson5 ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── opengl │ │ └── youyang │ │ └── lesson5 │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── opengl │ │ │ └── youyang │ │ │ └── lesson5 │ │ │ ├── ColorShaderProgram.java │ │ │ ├── LogConfig.java │ │ │ ├── MainActivity.java │ │ │ ├── PreviewGLRender.java │ │ │ ├── ShaderHelper.java │ │ │ ├── ShaderProgram.java │ │ │ ├── TextResourceReader.java │ │ │ ├── TextureHelper.java │ │ │ └── ViewListener.java │ └── res │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── raw │ │ ├── point_fragment_shader.glsl │ │ └── point_vertext_shader.glsl │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── opengl │ └── youyang │ └── lesson5 │ └── ExampleUnitTest.java ├── lesson6.gif ├── projectFilesBackup └── .idea │ └── workspace.xml └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | OpenGLLessons -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/dictionaries/youyang.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | Android Lint 39 | 40 | 41 | Java 42 | 43 | 44 | Probable bugsJava 45 | 46 | 47 | RELAX NG 48 | 49 | 50 | 51 | 52 | Android 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 74 | 75 | 76 | 77 | 78 | 1.7 79 | 80 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Lesson1/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /Lesson1/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.2" 6 | 7 | defaultConfig { 8 | applicationId "com.opengl.youyang.opengllessons" 9 | minSdkVersion 9 10 | targetSdkVersion 23 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | testCompile 'junit:junit:4.12' 25 | compile 'com.android.support:appcompat-v7:23.3.0' 26 | } 27 | -------------------------------------------------------------------------------- /Lesson1/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/youyang/Library/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /Lesson1/src/androidTest/java/com/opengl/youyang/opengllessons/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.opengl.youyang.opengllessons; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /Lesson1/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Lesson1/src/main/java/com/opengl/youyang/opengllessons/BackgroundRender.java: -------------------------------------------------------------------------------- 1 | package com.opengl.youyang.opengllessons; 2 | 3 | import android.opengl.GLES20; 4 | import android.opengl.GLSurfaceView; 5 | 6 | import javax.microedition.khronos.egl.EGLConfig; 7 | import javax.microedition.khronos.opengles.GL10; 8 | 9 | /** 10 | * Created by youyang on 16/5/24. 11 | */ 12 | public class BackgroundRender implements GLSurfaceView.Renderer { 13 | 14 | private float mRed; 15 | private float mGreen; 16 | 17 | @Override 18 | public void onSurfaceCreated(GL10 gl, EGLConfig config) { 19 | GLES20.glClearColor(0.0f,0.5f,0.3f,0.4f); 20 | } 21 | 22 | @Override 23 | public void onSurfaceChanged(GL10 gl, int width, int height) { 24 | GLES20.glViewport(0,0,width,height); 25 | } 26 | 27 | @Override 28 | public void onDrawFrame(GL10 gl) { 29 | GLES20.glClearColor(mRed,mGreen,0.3f,0.4f); 30 | GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); 31 | } 32 | 33 | public void setBackgroundColor(float x, float y) { 34 | mRed = x%1.0f; 35 | mGreen = y%1.0f; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Lesson1/src/main/java/com/opengl/youyang/opengllessons/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.opengl.youyang.opengllessons; 2 | 3 | import android.app.ActivityManager; 4 | import android.content.Context; 5 | import android.opengl.GLSurfaceView; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.os.Bundle; 8 | import android.util.Log; 9 | import android.view.MotionEvent; 10 | import android.view.View; 11 | import android.widget.Toast; 12 | 13 | public class MainActivity extends AppCompatActivity { 14 | //第一课教你 如何绘制一个背景 15 | /** 16 | * 主要涉及到的知识有 17 | * 1.如何判断当前手机是否支持opengl 18 | * 2.如何创建渲染器 19 | * 3.设置渲染模式 20 | * 4.响应触摸事件时 如何保证异步渲染,和主线程的触摸事件保持同步 21 | * 5.如何设置背景 22 | */ 23 | 24 | private GLSurfaceView mGLSurfaceView; 25 | 26 | @Override 27 | protected void onCreate(Bundle savedInstanceState) { 28 | 29 | super.onCreate(savedInstanceState); 30 | mGLSurfaceView = new GLSurfaceView(this); 31 | 32 | //第一步 检验是否支持opengl 2.0 33 | final boolean isSuppotES2=isSupportES2(); 34 | //第二步创建渲染器 35 | final BackgroundRender render = new BackgroundRender(); 36 | 37 | if(isSuppotES2){ 38 | //设定egl版本 39 | mGLSurfaceView.setEGLContextClientVersion(2); 40 | //设置渲染器,设置完这一步之后相当于开启了 另一条渲染线程 41 | mGLSurfaceView.setRenderer(render); 42 | //设置渲染模式 一直渲染 43 | mGLSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY); 44 | }else { 45 | Toast.makeText(this,"该手机不支持opengl es 2.0" ,Toast.LENGTH_LONG).show(); 46 | return; 47 | } 48 | 49 | setContentView(mGLSurfaceView); 50 | 51 | mGLSurfaceView.setOnTouchListener(new View.OnTouchListener() { 52 | @Override 53 | public boolean onTouch(View v, final MotionEvent event) { 54 | 55 | if(event !=null){ 56 | mGLSurfaceView.queueEvent(new Runnable() { 57 | @Override 58 | public void run() { 59 | render.setBackgroundColor(event.getX(),event.getY()); 60 | Log.d("opengl","event.getX():"+event.getX()+", event.getY():"+event.getY()); 61 | } 62 | }); 63 | return true; 64 | }else { 65 | return false; 66 | } 67 | 68 | } 69 | }); 70 | } 71 | 72 | 73 | 74 | @Override 75 | protected void onResume() { 76 | super.onResume(); 77 | mGLSurfaceView.onResume(); 78 | } 79 | 80 | @Override 81 | protected void onPause() { 82 | super.onPause(); 83 | mGLSurfaceView.onPause(); 84 | } 85 | 86 | /** 87 | * 检验是否支持opengl 2.0 88 | * @return 89 | */ 90 | private boolean isSupportES2() { 91 | return ((ActivityManager) getSystemService(Context.ACTIVITY_SERVICE)) 92 | .getDeviceConfigurationInfo().reqGlEsVersion >= 0x20000; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /Lesson1/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 17 | 18 | -------------------------------------------------------------------------------- /Lesson1/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/Lesson1/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /Lesson1/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/Lesson1/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /Lesson1/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/Lesson1/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Lesson1/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/Lesson1/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Lesson1/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/Lesson1/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Lesson1/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /Lesson1/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /Lesson1/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /Lesson1/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Lesson1 3 | 4 | -------------------------------------------------------------------------------- /Lesson1/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Lesson1/src/test/java/com/opengl/youyang/opengllessons/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.opengl.youyang.opengllessons; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * To work on unit tests, switch the Test Artifact in the Build Variants mGLSurfaceView. 9 | */ 10 | public class ExampleUnitTest { 11 | @Test 12 | public void addition_isCorrect() throws Exception { 13 | assertEquals(4, 2 + 2); 14 | } 15 | } -------------------------------------------------------------------------------- /Lesson4/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /Lesson4/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.2" 6 | 7 | defaultConfig { 8 | applicationId "com.opengl.youyang.myapplication" 9 | minSdkVersion 9 10 | targetSdkVersion 23 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | testCompile 'junit:junit:4.12' 25 | compile 'com.android.support:appcompat-v7:23.3.0' 26 | } 27 | -------------------------------------------------------------------------------- /Lesson4/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/youyang/Library/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /Lesson4/src/androidTest/java/com/opengl/youyang/myapplication/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.opengl.youyang.myapplication; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /Lesson4/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Lesson4/src/main/java/com/opengl/youyang/myapplication/ColorShaderProgram.java: -------------------------------------------------------------------------------- 1 | package com.opengl.youyang.myapplication; 2 | 3 | import android.content.Context; 4 | import android.opengl.GLES20; 5 | 6 | /** 7 | * Created by youyang on 15-4-19. 8 | */ 9 | public class ColorShaderProgram extends ShaderProgram{ 10 | private final int u_ColorLocation; 11 | private final int aPositionLocation; 12 | private final int aTexturreCoordLocation; 13 | private final int u_Progress; 14 | private final int u_InterpolationPower; 15 | private final int u_From; 16 | private final int u_To; 17 | // private final int u_Resolution; 18 | 19 | 20 | 21 | public ColorShaderProgram(Context context,int index){ 22 | super(context,index); 23 | u_ColorLocation= GLES20.glGetUniformLocation(mProgram,U_COLOR); 24 | aPositionLocation=GLES20.glGetAttribLocation(mProgram,A_POSITION); 25 | aTexturreCoordLocation = GLES20.glGetAttribLocation(mProgram,A_TEXCOOR); 26 | u_Progress = GLES20.glGetUniformLocation(mProgram,U_PROGRESS); 27 | u_InterpolationPower = GLES20.glGetUniformLocation(mProgram,U_INTERPOLATIONPOWER); 28 | u_From = GLES20.glGetUniformLocation(mProgram,U_FROM); 29 | u_To = GLES20.glGetUniformLocation(mProgram,U_TO); 30 | } 31 | 32 | public void setUniforms(float r,float g,float b){ 33 | GLES20.glUniform4f(u_ColorLocation,r,g,b,1f); 34 | } 35 | 36 | //from, to;progress interpolationPower 37 | public void setUniformProgressAndInterpolationPower(float progress, float interpolationPower){ 38 | GLES20.glUniform1f(u_Progress,progress); 39 | GLES20.glUniform1f(u_InterpolationPower,interpolationPower); 40 | 41 | } 42 | 43 | public int getPositionAttributionLocation(){ 44 | return aPositionLocation; 45 | } 46 | 47 | public int getTexCoodAttributionLocation(){ 48 | return aTexturreCoordLocation; 49 | } 50 | 51 | public int getUniformFromLocation(){ 52 | return u_From; 53 | } 54 | 55 | public int getUniformToLocation(){ 56 | return u_To; 57 | } 58 | 59 | 60 | } 61 | -------------------------------------------------------------------------------- /Lesson4/src/main/java/com/opengl/youyang/myapplication/GLSwitchView.java: -------------------------------------------------------------------------------- 1 | package com.opengl.youyang.myapplication; 2 | 3 | import android.content.Context; 4 | import android.opengl.GLSurfaceView; 5 | import android.util.AttributeSet; 6 | import android.util.DisplayMetrics; 7 | import android.util.Log; 8 | import android.view.MotionEvent; 9 | import android.view.WindowManager; 10 | import android.view.animation.DecelerateInterpolator; 11 | import android.widget.Scroller; 12 | 13 | /** 14 | * Created by youyang on 16/7/24. 15 | */ 16 | public class GLSwitchView extends GLSurfaceView { 17 | 18 | 19 | float process = 0.0f; 20 | int count = 0; 21 | 22 | float limit = 1.0f; 23 | private int[] size; 24 | float moveX = 0; 25 | 26 | private Scroller mScroller; 27 | 28 | private RenderListener mRenderListener; 29 | 30 | public GLSwitchView(Context context) { 31 | super(context); 32 | init(context); 33 | } 34 | 35 | private void init(Context context) { 36 | mScroller = new Scroller(context, new DecelerateInterpolator()); 37 | mFlingRunnable = new FlingRunnable(); 38 | size = getScreenSize(context); 39 | } 40 | 41 | public void setRenderListener(RenderListener renderListener) { 42 | mRenderListener = renderListener; 43 | } 44 | 45 | /** 46 | * 方法描述:获取屏幕宽高 47 | */ 48 | public static int[] getScreenSize(Context context) { 49 | WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 50 | DisplayMetrics localDisplayMetrics = new DisplayMetrics(); 51 | windowManager.getDefaultDisplay() 52 | .getMetrics(localDisplayMetrics); 53 | int mScreenHeight = localDisplayMetrics.heightPixels; 54 | int mScreenWidth = localDisplayMetrics.widthPixels; 55 | int[] size = {mScreenWidth, mScreenHeight}; 56 | return size; 57 | } 58 | 59 | public GLSwitchView(Context context, AttributeSet attrs) { 60 | super(context, attrs); 61 | init(context); 62 | } 63 | 64 | @Override 65 | public boolean onTouchEvent(MotionEvent event) { 66 | 67 | mCurrentX = event.getX(); 68 | mCurrentY = event.getY(); 69 | 70 | handleTouchCommon(event); 71 | switch (event.getAction()) { 72 | case MotionEvent.ACTION_DOWN: 73 | break; 74 | case MotionEvent.ACTION_MOVE: 75 | moveX = event.getX(); 76 | 77 | queueEvent(new Runnable() { 78 | @Override 79 | public void run() { 80 | process = Math.abs(moveX / size[0]); 81 | if(mRenderListener!=null){ 82 | mRenderListener.setProcess(process); 83 | } 84 | Log.d("youyang", "process :" + process); 85 | } 86 | }); 87 | 88 | break; 89 | case MotionEvent.ACTION_CANCEL: 90 | case MotionEvent.ACTION_UP: 91 | 92 | break; 93 | default: 94 | break; 95 | } 96 | mPreY = mCurrentY; 97 | mPreX = mCurrentX; 98 | 99 | requestRender(); 100 | return true; 101 | } 102 | 103 | /** 104 | * 上一页下一页的趋势 0空闲状态;1 上一页;2 下一页;3菜单;4长按事件 105 | */ 106 | private int mScrollDirection = DIRECTION_VOID; 107 | /** 108 | * 空闲状态or点击状态 109 | */ 110 | public static final int DIRECTION_VOID = 0x0004; 111 | /** 112 | * 上一页 113 | */ 114 | public static final int DIRECTION_LAST = 0x0005; 115 | /** 116 | * 下一页o 117 | */ 118 | public static final int DIRECTION_NEXT = 0x0006; 119 | 120 | /** 121 | * touch事件down时的y轴坐标 122 | */ 123 | private float mTouchDownY; 124 | /** 125 | * 一次完整touch事件中上一次的x轴坐标 126 | */ 127 | private float mLastTouchX; 128 | /** 129 | * 一次完整touch事件中上一次的y轴坐标 130 | */ 131 | private float mLastTouchY; 132 | 133 | /** 134 | * touch事件down时的x轴坐标 135 | */ 136 | private float mTouchDownX; 137 | 138 | private float mPreY; 139 | private float mCurrentY; 140 | private float mDy; 141 | 142 | private float mPreX; 143 | private float mCurrentX; 144 | private float mDx; 145 | private float mMoveX = 0; 146 | private float mMoveY; 147 | private FlingRunnable mFlingRunnable; 148 | 149 | 150 | /** 151 | * 处理触摸事件的公共部分 152 | */ 153 | private void handleTouchCommon(MotionEvent event) { 154 | switch (event.getAction() & MotionEvent.ACTION_MASK) { 155 | case MotionEvent.ACTION_DOWN: 156 | mScrollDirection = DIRECTION_VOID; 157 | mTouchDownX = event.getX(); 158 | mTouchDownY = event.getY(); 159 | break; 160 | 161 | case MotionEvent.ACTION_MOVE: 162 | mDy = mCurrentY - mPreY; 163 | mDx = mCurrentX - mPreX; 164 | 165 | if (mDx > 0) { 166 | mScrollDirection = DIRECTION_LAST; 167 | } else if (mDx < 0) { 168 | mScrollDirection = DIRECTION_NEXT; 169 | } 170 | mMoveX = event.getX(); 171 | mMoveY = event.getY(); 172 | 173 | break; 174 | 175 | case MotionEvent.ACTION_UP: 176 | case MotionEvent.ACTION_CANCEL: 177 | mLastTouchX = event.getX(); 178 | mLastTouchY = event.getY(); 179 | startScollAnimation(false); 180 | break; 181 | default: 182 | break; 183 | } 184 | } 185 | 186 | 187 | private void startScollAnimation(boolean isTouch) { 188 | int distance = 0; 189 | // 翻下一页 190 | if (mScrollDirection == DIRECTION_NEXT) { 191 | if (mDx <= 0) { 192 | // 手左右来回划,最后滑的方向是从右往左 193 | // distance = mTouchDownX - mLastTouchX > 0 ? (int) (mTouchDownX - mLastTouchX) 194 | // - mWidth : (int) (mLastTouchX - mWidth); 195 | distance = (int) - mLastTouchX; 196 | } else { 197 | distance = mTouchDownX - mLastTouchX > 0 ? (int) (mTouchDownX - mLastTouchX) : 0; 198 | } 199 | } else if (mScrollDirection == DIRECTION_LAST) { 200 | // 手左右来回划,最后滑的方向是从右往左 201 | if (mDx < 0) { 202 | distance = mTouchDownX - mLastTouchX < 0 ? (int) (mTouchDownX - mLastTouchX) : 0; 203 | } else { 204 | distance = (int) (size[0] - mLastTouchX + mTouchDownX); 205 | } 206 | } 207 | if (isTouch) { 208 | if (mScrollDirection == DIRECTION_LAST) { 209 | mFlingRunnable.startByTouch(size[0]); 210 | } else if (mScrollDirection == DIRECTION_NEXT) { 211 | mFlingRunnable.startByTouch(-size[0]); 212 | } 213 | } else { 214 | if (distance == 0) { 215 | distance = 1; 216 | } 217 | mFlingRunnable.startByTouch(distance); 218 | } 219 | 220 | } 221 | 222 | class FlingRunnable implements Runnable { 223 | private static final int TOUCH_ANIMATION_DURATION = 350; 224 | private static final int MIN_ANIMATION_DURATION = 2000; 225 | private int mLastFlingX; 226 | 227 | /** 228 | * 移除消息队列里的上个动作 229 | */ 230 | private void startCommon() { 231 | removeCallbacks(this); 232 | } 233 | 234 | /** 235 | * 另外开启一个线程来横向滑动书页 236 | * 237 | * @param distance 滑动的距离 238 | */ 239 | public void startByTouch(int distance) { 240 | startUsingDistance(distance, TOUCH_ANIMATION_DURATION); 241 | } 242 | 243 | /** 244 | * 异步书页偏移的 实际执行方法 245 | * 246 | * @param distance 偏移距离 247 | * @param during 持续时间 248 | */ 249 | public void startUsingDistance(int distance, int during) { 250 | if (distance == 0) 251 | return; 252 | startCommon(); 253 | mLastFlingX = 0; 254 | // 起始点为(0,0),x偏移量为 -distance ,y的偏移量为 0,持续时间 255 | mScroller.startScroll(0, 0, -distance, 0, Math.max(MIN_ANIMATION_DURATION, Math.abs(distance) * during / size[0])); 256 | post(this); 257 | } 258 | 259 | /** 260 | * 停止滑动 261 | */ 262 | private void endFling() { 263 | mScroller.forceFinished(true); 264 | } 265 | 266 | @Override 267 | public void run() { 268 | 269 | boolean more = mScroller.computeScrollOffset();// 返回true的话则动画还没有结束 270 | final int x = mScroller.getCurrX();// 返回滚动时 当前的x坐标 271 | // Log.d("youyang", "mScroller.getCurrX()" + x); 272 | int delta = mLastFlingX - x; 273 | if (delta != 0) { 274 | mMoveX += delta; 275 | Log.d("youyang", "size[0]" + size[0] + ", size[1]:" + size[1]); 276 | 277 | float process = Math.abs(mMoveX) / (size[0]); 278 | Log.d("youyang", "process" + process); 279 | if(mRenderListener!=null){ 280 | mRenderListener.setProcess(process); 281 | } 282 | requestRender(); 283 | } 284 | if (more) { 285 | mLastFlingX = x; 286 | post(this); 287 | } else { 288 | endFling(); 289 | } 290 | 291 | } 292 | } 293 | 294 | interface RenderListener{ 295 | void setProcess(float process); 296 | } 297 | } 298 | -------------------------------------------------------------------------------- /Lesson4/src/main/java/com/opengl/youyang/myapplication/LogConfig.java: -------------------------------------------------------------------------------- 1 | package com.opengl.youyang.myapplication; 2 | 3 | /** 4 | * Created by youyang on 15-4-13. 5 | */ 6 | public class LogConfig { 7 | public static final boolean ON=true; 8 | } 9 | -------------------------------------------------------------------------------- /Lesson4/src/main/java/com/opengl/youyang/myapplication/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.opengl.youyang.myapplication; 2 | 3 | import android.app.Activity; 4 | import android.app.ActivityManager; 5 | import android.content.Context; 6 | import android.opengl.GLSurfaceView; 7 | import android.os.Bundle; 8 | import android.support.v7.app.AppCompatActivity; 9 | import android.view.WindowManager; 10 | import android.widget.Toast; 11 | 12 | /** 13 | * 着色器 是 软件与GPU硬件的桥梁,可以通过着色器去控制GPU去进行高性能的绘制。 如果不使用着色器,我们就只能通过cpu去进行渲染,两者的效率天差地别。 14 | * 15 | * 这节课开始接触着色器,用着色器 绘制一个普通的顶点Point 1.学会写简单的着色器 2.了解如何加载着色器 3.学会如何在java代码中动态给着色器的属性赋值 16 | */ 17 | 18 | public class MainActivity extends Activity implements GLSwitchView.RenderListener{ 19 | 20 | GLSwitchView mView; 21 | PointRender mRender; 22 | 23 | @Override 24 | protected void onCreate(Bundle savedInstanceState) { 25 | 26 | super.onCreate(savedInstanceState); 27 | getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 28 | mView = new GLSwitchView(this); 29 | //第一步 检验是否支持opengl 2.0 30 | final boolean isSuppotES2 = isSupportES2(); 31 | //第二步创建渲染器 32 | int index = getIntent().getIntExtra("index",0); 33 | mRender = new PointRender(this,index); 34 | if (isSuppotES2) { 35 | //设定egl版本 36 | mView.setEGLContextClientVersion(2); 37 | //设置渲染器,设置完这一步之后相当于开启了 另一条渲染线程 38 | mView.setRenderer(mRender); 39 | //设置渲染模式 一直渲染 40 | 41 | if(index == 0){ 42 | mView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY); 43 | } else { 44 | mView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); 45 | } 46 | 47 | 48 | mView.setRenderListener(this); 49 | } else { 50 | Toast.makeText(this, "该手机不支持opengl es 2.0", Toast.LENGTH_LONG).show(); 51 | return; 52 | } 53 | setContentView(mView); 54 | } 55 | 56 | 57 | @Override 58 | protected void onResume() { 59 | super.onResume(); 60 | mView.onResume(); 61 | } 62 | 63 | @Override 64 | protected void onPause() { 65 | super.onPause(); 66 | mView.onPause(); 67 | } 68 | 69 | 70 | /** 71 | * 检验是否支持opengl 2.0 72 | */ 73 | private boolean isSupportES2() { 74 | return ((ActivityManager) getSystemService(Context.ACTIVITY_SERVICE)) 75 | .getDeviceConfigurationInfo().reqGlEsVersion >= 0x20000; 76 | } 77 | 78 | 79 | @Override 80 | public void setProcess(float process) { 81 | mRender.setProcess(process); 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /Lesson4/src/main/java/com/opengl/youyang/myapplication/PointRender.java: -------------------------------------------------------------------------------- 1 | package com.opengl.youyang.myapplication; 2 | 3 | import android.content.Context; 4 | import android.opengl.GLES20; 5 | import android.opengl.GLSurfaceView; 6 | import android.os.SystemClock; 7 | 8 | import java.nio.ByteBuffer; 9 | import java.nio.ByteOrder; 10 | import java.nio.FloatBuffer; 11 | 12 | import javax.microedition.khronos.egl.EGLConfig; 13 | import javax.microedition.khronos.opengles.GL10; 14 | 15 | /** 16 | * Created by youyang on 16/5/24. 17 | */ 18 | public class PointRender implements GLSurfaceView.Renderer { 19 | 20 | private FloatBuffer mFloatBuffer; 21 | private FloatBuffer mTextureBuffer; 22 | 23 | private Context mContext; 24 | 25 | float mProgress = 0; 26 | 27 | int mIndex = 0; 28 | public PointRender(Context context,int index) { 29 | mContext = context; 30 | mIndex = index; 31 | } 32 | 33 | private int[] mResources = new int[2]; 34 | 35 | // float[] mVertex = new float[]{ 36 | // 0f,0f 37 | // } ; 38 | 39 | float aPoint = 1f; 40 | float[] mVertex = new float[]{ 41 | -aPoint, aPoint, 42 | -aPoint, -aPoint, 43 | aPoint, -aPoint, 44 | 45 | aPoint, -aPoint, 46 | aPoint, aPoint, 47 | -aPoint, aPoint 48 | 49 | }; 50 | 51 | float[] mTextureCoord = new float[]{ 52 | 0f, 0f, 53 | 0f, 1f, 54 | 1f, 1f, 55 | 56 | 1f, 1f, 57 | 1f, 0f, 58 | 0f, 0f 59 | }; 60 | 61 | int[] ids; 62 | private ColorShaderProgram mColorShaderProgram; 63 | 64 | 65 | @Override 66 | public void onSurfaceCreated(GL10 gl, EGLConfig config) { 67 | mColorShaderProgram = new ColorShaderProgram(mContext,mIndex); 68 | GLES20.glClearColor(0f, 0f, 0f, 0f); 69 | GLES20.glEnable(GLES20.GL_DEPTH_TEST); 70 | GLES20.glDisable(GLES20.GL_CULL_FACE); 71 | 72 | mResources[0] = R.drawable.img_loadings; 73 | mResources[1] = R.drawable.img_loading; 74 | // mResources[0] = R.drawable.test_1; 75 | // mResources[1] = R.drawable.test_2; 76 | ids = TextureHelper.loadTexture(mContext,mResources); 77 | 78 | mFloatBuffer = ByteBuffer.allocateDirect(mVertex.length * 4).order(ByteOrder.nativeOrder()) 79 | .asFloatBuffer().put(mVertex); 80 | mTextureBuffer = ByteBuffer.allocateDirect(mVertex.length * 4).order(ByteOrder.nativeOrder()) 81 | .asFloatBuffer().put(mTextureCoord); 82 | mFloatBuffer.position(0); 83 | mTextureBuffer.position(0); 84 | 85 | // mFloatBuffer.position(0); 86 | } 87 | 88 | public void setProcess(float m){ 89 | this.mProgress = m; 90 | } 91 | 92 | @Override 93 | public void onSurfaceChanged(GL10 gl, int width, int height) { 94 | GLES20.glViewport(0, 0, width, height); 95 | } 96 | 97 | public void setIds(int[] resources){ 98 | // this.ids =TextureHelper.loadTexture(mContext,resources); 99 | } 100 | 101 | @Override 102 | public void onDrawFrame(GL10 gl) { 103 | GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT); 104 | // GLES20.glDrawArrays(GLES20.GL_POINTS,0,1); 105 | mColorShaderProgram.useProgram(); 106 | // mColorShaderProgram.setUniforms(0.9f, 0.4f, 0.9f); 107 | 108 | // if(mIndex == 0){ 109 | // mColorShaderProgram.setUniformProgressAndInterpolationPower(SystemClock.currentThreadTimeMillis(),5f); 110 | // }else{ 111 | mColorShaderProgram.setUniformProgressAndInterpolationPower(mProgress,5f); 112 | // } 113 | 114 | 115 | 116 | GLES20.glVertexAttribPointer(mColorShaderProgram.getPositionAttributionLocation(), 2, GLES20.GL_FLOAT, false, 2 * 4, mFloatBuffer); 117 | GLES20.glVertexAttribPointer(mColorShaderProgram.getTexCoodAttributionLocation(), 2, GLES20.GL_FLOAT, false, 2 * 4, mTextureBuffer); 118 | GLES20.glEnableVertexAttribArray(mColorShaderProgram.getPositionAttributionLocation()); 119 | GLES20.glEnableVertexAttribArray(mColorShaderProgram.getTexCoodAttributionLocation()); 120 | 121 | GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 122 | GLES20.glUniform1i(mColorShaderProgram.getUniformFromLocation(), 0); 123 | GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,ids[0]); 124 | 125 | GLES20.glActiveTexture(GLES20.GL_TEXTURE1); 126 | GLES20.glUniform1i(mColorShaderProgram.getUniformToLocation(), 1); 127 | GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,ids[1]); 128 | 129 | GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 6); 130 | } 131 | 132 | } 133 | -------------------------------------------------------------------------------- /Lesson4/src/main/java/com/opengl/youyang/myapplication/ShaderHelper.java: -------------------------------------------------------------------------------- 1 | package com.opengl.youyang.myapplication; 2 | 3 | import android.opengl.GLES20; 4 | import android.util.Log; 5 | 6 | /** 7 | * Created by youyang on 15-4-13. 8 | */ 9 | public class ShaderHelper { 10 | private static final String TAG="ShaderHelper"; 11 | 12 | public static int compileVertexShader(String shaderCode){ 13 | return compileShader(GLES20.GL_VERTEX_SHADER,shaderCode); 14 | } 15 | 16 | public static int compileFragmentShader(String shaderCode){ 17 | return compileShader(GLES20.GL_FRAGMENT_SHADER,shaderCode); 18 | } 19 | 20 | private static int compileShader(int type ,String shaderCode){ 21 | //创建着色器 获取着色器对象的id 22 | final int shaderObjectId=GLES20.glCreateShader(type); 23 | if(shaderObjectId==0){ 24 | if(LogConfig.ON){ 25 | Log.w(TAG,"无法创建新的shader"); 26 | } 27 | return 0; 28 | } 29 | //上传和编译着色器的源码 30 | GLES20.glShaderSource(shaderObjectId, shaderCode); 31 | GLES20.glCompileShader(shaderObjectId); 32 | 33 | final int[] compileStatus=new int[1]; 34 | GLES20.glGetShaderiv(shaderObjectId,GLES20.GL_COMPILE_STATUS,compileStatus,0); 35 | if(LogConfig.ON){ 36 | Log.v(TAG,"编译源码的结果是:"+GLES20.glGetShaderInfoLog(shaderObjectId)); 37 | 38 | } 39 | 40 | if(compileStatus[0]==0){ 41 | GLES20.glDeleteShader(shaderObjectId); 42 | return 0; 43 | } 44 | 45 | return shaderObjectId; 46 | } 47 | 48 | public static int linkProgram(int vertexShaderId ,int fragmentShaderId){ 49 | final int programObjectId=GLES20.glCreateProgram(); 50 | if(programObjectId==0){ 51 | if(LogConfig.ON){ 52 | Log.w(TAG,"无法创建新的程序"); 53 | } 54 | return 0; 55 | } 56 | //绑定顶点着色器和片元着色器 57 | GLES20.glAttachShader(programObjectId,vertexShaderId); 58 | GLES20.glAttachShader(programObjectId, fragmentShaderId); 59 | 60 | GLES20.glLinkProgram(programObjectId); 61 | final int[] linkStatus =new int[1]; 62 | GLES20.glGetProgramiv(programObjectId, GLES20.GL_LINK_STATUS, linkStatus, 0); 63 | if(LogConfig.ON){ 64 | Log.v(TAG,"程序连接结果是:"+GLES20.glGetProgramInfoLog(programObjectId)); 65 | } 66 | 67 | if(linkStatus[0]==0){ 68 | GLES20.glDeleteProgram(programObjectId); 69 | if(LogConfig.ON){ 70 | Log.w(TAG,"连接程序失败"); 71 | } 72 | return 0; 73 | } 74 | return programObjectId; 75 | } 76 | 77 | 78 | /** 79 | * 检验当前的程序是否低效 无法运行 80 | * @param programPbjectId 81 | * @return 82 | */ 83 | public static boolean validateProgram(int programPbjectId){ 84 | GLES20.glValidateProgram(programPbjectId); 85 | final int [] validateStatus=new int[1]; 86 | GLES20.glGetProgramiv(programPbjectId,GLES20.GL_VALIDATE_STATUS,validateStatus,0); 87 | Log.v(TAG,"更新程序状态:"+validateStatus[0]+"\nLog"+GLES20.glGetProgramInfoLog(programPbjectId)); 88 | return validateStatus[0]!=0; 89 | } 90 | 91 | 92 | /** 93 | * 链接顶点着色器和片段着色器,返回程序id 94 | * @param vertexShaderSource 95 | * @param fragmentShaderSource 96 | * @return 97 | */ 98 | public static int buildProgram(String vertexShaderSource,String fragmentShaderSource){ 99 | int program; 100 | int vertexShader=compileVertexShader(vertexShaderSource); 101 | int fragmentShader=compileFragmentShader(fragmentShaderSource); 102 | program=linkProgram(vertexShader,fragmentShader); 103 | 104 | if (LogConfig.ON){ 105 | validateProgram(program); 106 | } 107 | return program; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /Lesson4/src/main/java/com/opengl/youyang/myapplication/ShaderProgram.java: -------------------------------------------------------------------------------- 1 | package com.opengl.youyang.myapplication; 2 | 3 | import android.content.Context; 4 | import android.opengl.GLES20; 5 | 6 | /** 7 | * Created by youyang on 15-4-18. 8 | */ 9 | public class ShaderProgram { 10 | //uniform 常量 11 | protected static final String U_COLOR = "uColor"; 12 | protected static final String U_FROM = "from";//from, to;progress interpolationPower 13 | protected static final String U_PROGRESS = "progress"; 14 | protected static final String U_TO = "to"; 15 | protected static final String U_INTERPOLATIONPOWER = "interpolationPower"; 16 | // protected static final String U_RESOLUTION = "resolution"; 17 | 18 | //attribute常量 19 | protected static final String A_POSITION = "a_Position"; 20 | protected static final String A_TEXCOOR = "a_TexCoor"; 21 | 22 | 23 | protected int mProgram; 24 | 25 | protected ShaderProgram(Context context, int index) { 26 | switch (index){ 27 | case 0: 28 | mProgram = ShaderHelper.buildProgram(TextResourceReader.readTextResourceFromRaw(context, 29 | R.raw.point_vertext_shader), TextResourceReader.readTextResourceFromRaw(context, 30 | R.raw.translate1_fragment_shader)); 31 | break; 32 | case 1: 33 | mProgram = ShaderHelper.buildProgram(TextResourceReader.readTextResourceFromRaw(context, 34 | R.raw.point_vertext_shader), TextResourceReader.readTextResourceFromRaw(context, 35 | R.raw.translate2_fragment_shader)); 36 | break; 37 | case 2: 38 | mProgram = ShaderHelper.buildProgram(TextResourceReader.readTextResourceFromRaw(context, 39 | R.raw.point_vertext_shader), TextResourceReader.readTextResourceFromRaw(context, 40 | R.raw.translate3_fragment_shader)); 41 | break; 42 | case 3: 43 | mProgram = ShaderHelper.buildProgram(TextResourceReader.readTextResourceFromRaw(context, 44 | R.raw.point_vertext_shader), TextResourceReader.readTextResourceFromRaw(context, 45 | R.raw.translate4_fragment_shader)); 46 | break; 47 | case 4: 48 | mProgram = ShaderHelper.buildProgram(TextResourceReader.readTextResourceFromRaw(context, 49 | R.raw.point_vertext_shader), TextResourceReader.readTextResourceFromRaw(context, 50 | R.raw.translate5_fragment_shader)); 51 | break; 52 | case 5: 53 | mProgram = ShaderHelper.buildProgram(TextResourceReader.readTextResourceFromRaw(context, 54 | R.raw.point_vertext_shader), TextResourceReader.readTextResourceFromRaw(context, 55 | R.raw.translate6_fragment_shader)); 56 | break; 57 | case 6: 58 | mProgram = ShaderHelper.buildProgram(TextResourceReader.readTextResourceFromRaw(context, 59 | R.raw.point_vertext_shader), TextResourceReader.readTextResourceFromRaw(context, 60 | R.raw.translate7_fragment_shader)); 61 | break; 62 | case 7: 63 | mProgram = ShaderHelper.buildProgram(TextResourceReader.readTextResourceFromRaw(context, 64 | R.raw.point_vertext_shader), TextResourceReader.readTextResourceFromRaw(context, 65 | R.raw.translate8_fragment_shader)); 66 | break; 67 | case 8: 68 | mProgram = ShaderHelper.buildProgram(TextResourceReader.readTextResourceFromRaw(context, 69 | R.raw.point_vertext_shader), TextResourceReader.readTextResourceFromRaw(context, 70 | R.raw.translate10_fragment_shader)); 71 | break; 72 | case 9: 73 | mProgram = ShaderHelper.buildProgram(TextResourceReader.readTextResourceFromRaw(context, 74 | R.raw.point_vertext_shader), TextResourceReader.readTextResourceFromRaw(context, 75 | R.raw.point_fragment_shader)); 76 | break; 77 | 78 | } 79 | 80 | } 81 | 82 | public void useProgram(){ 83 | GLES20.glUseProgram(mProgram); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Lesson4/src/main/java/com/opengl/youyang/myapplication/SplashActivity.java: -------------------------------------------------------------------------------- 1 | package com.opengl.youyang.myapplication; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.graphics.Matrix; 6 | import android.os.Bundle; 7 | import android.view.View; 8 | import android.widget.Button; 9 | 10 | /** 11 | * Created by youyang on 16/7/19. 12 | */ 13 | public class SplashActivity extends Activity implements View.OnClickListener { 14 | 15 | Intent intent; 16 | @Override 17 | protected void onCreate(Bundle savedInstanceState) { 18 | 19 | super.onCreate(savedInstanceState); 20 | setContentView(R.layout.act_select); 21 | intent = new Intent(SplashActivity.this,MainActivity.class); 22 | 23 | Button button1 = (Button) findViewById(R.id.button1); 24 | Button button2 = (Button) findViewById(R.id.button2); 25 | Button button3 = (Button) findViewById(R.id.button3); 26 | Button button4 = (Button) findViewById(R.id.button4); 27 | Button button5 = (Button) findViewById(R.id.button5); 28 | Button button6 = (Button) findViewById(R.id.button6); 29 | Button button7 = (Button) findViewById(R.id.button7); 30 | Button button8 = (Button) findViewById(R.id.button8); 31 | Button button9 = (Button) findViewById(R.id.button9); 32 | Button button10 = (Button) findViewById(R.id.button10); 33 | 34 | 35 | button1.setOnClickListener(this); 36 | button2.setOnClickListener(this); 37 | button3.setOnClickListener(this); 38 | button4.setOnClickListener(this); 39 | button5.setOnClickListener(this); 40 | button6.setOnClickListener(this); 41 | button7.setOnClickListener(this); 42 | button8.setOnClickListener(this); 43 | button9.setOnClickListener(this); 44 | button10.setOnClickListener(this); 45 | } 46 | 47 | @Override 48 | public void onClick(View v) { 49 | switch (v.getId()){ 50 | case R.id.button1: 51 | intent.putExtra("index",0); 52 | break; 53 | case R.id.button2: 54 | intent.putExtra("index",1); 55 | break; 56 | case R.id.button3: 57 | intent.putExtra("index",2); 58 | break; 59 | case R.id.button4: 60 | intent.putExtra("index",3); 61 | break; 62 | case R.id.button5: 63 | intent.putExtra("index",4); 64 | break; 65 | case R.id.button6: 66 | intent.putExtra("index",5); 67 | break; 68 | case R.id.button7: 69 | intent.putExtra("index",6); 70 | break; 71 | case R.id.button8: 72 | intent.putExtra("index",7); 73 | break; 74 | case R.id.button9: 75 | intent.putExtra("index",8); 76 | break; 77 | case R.id.button10: 78 | intent.putExtra("index",9); 79 | break; 80 | 81 | } 82 | startActivity(intent); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /Lesson4/src/main/java/com/opengl/youyang/myapplication/TextResourceReader.java: -------------------------------------------------------------------------------- 1 | package com.opengl.youyang.myapplication; 2 | 3 | import android.content.Context; 4 | 5 | import java.io.BufferedReader; 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | import java.io.InputStreamReader; 9 | 10 | /** 11 | * Created by youyang on 15-4-12. 12 | */ 13 | public class TextResourceReader { 14 | 15 | public static String readTextResourceFromRaw(Context context,int resourceId){ 16 | StringBuilder body=new StringBuilder(); 17 | try{ 18 | InputStream inputStream=context.getResources().openRawResource(resourceId); 19 | InputStreamReader inputStreamReader=new InputStreamReader(inputStream); 20 | BufferedReader bufferedReader=new BufferedReader(inputStreamReader); 21 | String nextLine; 22 | while((nextLine=bufferedReader.readLine())!=null){ 23 | body.append(nextLine); 24 | body.append('\n'); 25 | } 26 | } catch (IOException e) { 27 | e.printStackTrace(); 28 | throw new RuntimeException("无法打开raw中的资源resourceId:"+resourceId); 29 | } 30 | return body.toString(); 31 | 32 | }; 33 | } 34 | -------------------------------------------------------------------------------- /Lesson4/src/main/java/com/opengl/youyang/myapplication/TextureHelper.java: -------------------------------------------------------------------------------- 1 | package com.opengl.youyang.myapplication; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.graphics.BitmapFactory; 6 | import android.graphics.Canvas; 7 | import android.opengl.GLES20; 8 | import android.opengl.GLUtils; 9 | import android.util.Log; 10 | 11 | /** 12 | * Created by youyang on 15-4-17. 13 | */ 14 | public class TextureHelper { 15 | public static final String TAG = "TextureHelper"; 16 | 17 | public static int[] loadTexture(Context context, int[] resourceIds) { 18 | if(resourceIds == null || resourceIds.length==0){ 19 | return null; 20 | } 21 | final int[] textureObjectIds = new int[resourceIds.length]; 22 | 23 | GLES20.glGenTextures(2, textureObjectIds, 0); 24 | for(int i = 0;i> 1); 76 | n = n | (n >> 2); 77 | n = n | (n >> 4); 78 | n = n | (n >> 8); 79 | n = n | (n >> 16); 80 | n = n | (n >> 32); 81 | return n + 1; 82 | } 83 | 84 | /** 85 | * Generates nearest power of two sized Bitmap for give Bitmap. Returns this 86 | * new Bitmap using default return statement + original texture coordinates 87 | * are stored into RectF. 88 | */ 89 | private static Bitmap getTexture(Bitmap bitmap) { 90 | // Bitmap original size. 91 | int w = bitmap.getWidth(); 92 | int h = bitmap.getHeight(); 93 | // Bitmap size expanded to next power of two. This is done due to 94 | // the requirement on many devices, texture width and height should 95 | // be power of two. 96 | int newW = getNextHighestPO2(w); 97 | int newH = getNextHighestPO2(h); 98 | 99 | // TODO: Is there another way to create a bigger Bitmap and copy 100 | // original Bitmap to it more efficiently? Immutable bitmap anyone? 101 | Bitmap bitmapTex = Bitmap.createBitmap(newW, newH, bitmap.getConfig()); 102 | Canvas c = new Canvas(bitmapTex); 103 | c.drawBitmap(bitmap, 0, 0, null); 104 | 105 | // Calculate final texture coordinates. 106 | float texX = (float) w / newW; 107 | float texY = (float) h / newH; 108 | return bitmapTex; 109 | } 110 | 111 | public static int loadCubeMap(Context context, int[] cubeResource) { 112 | final int[] textureObjectIds = new int[1]; 113 | GLES20.glGenTextures(1, textureObjectIds, 0); 114 | if (textureObjectIds[0] == 0) { 115 | if (LogConfig.ON) { 116 | Log.w(TAG, "无法生成一个纹理对象"); 117 | } 118 | return 0; 119 | } 120 | final BitmapFactory.Options options = new BitmapFactory.Options(); 121 | options.inScaled = false; 122 | final Bitmap[] cubeBitmaps = new Bitmap[6]; 123 | 124 | for (int i = 0; i < 6; i++) { 125 | cubeBitmaps[i] = BitmapFactory.decodeResource(context.getResources(), cubeResource[i], options); 126 | 127 | if (cubeBitmaps[i] == null) { 128 | if (LogConfig.ON) { 129 | Log.w(TAG, "ResourceId:" + cubeResource[i] + "无法加载纹理"); 130 | } 131 | GLES20.glDeleteTextures(1, textureObjectIds, 0); 132 | return 0; 133 | } 134 | } 135 | 136 | GLES20.glBindTexture(GLES20.GL_TEXTURE_CUBE_MAP, textureObjectIds[0]); 137 | GLES20.glTexParameteri(GLES20.GL_TEXTURE_CUBE_MAP, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); 138 | GLES20.glTexParameteri(GLES20.GL_TEXTURE_CUBE_MAP, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); 139 | 140 | GLUtils.texImage2D(GLES20.GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, cubeBitmaps[0], 0); 141 | GLUtils.texImage2D(GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, cubeBitmaps[1], 0); 142 | 143 | GLUtils.texImage2D(GLES20.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, cubeBitmaps[2], 0); 144 | GLUtils.texImage2D(GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, cubeBitmaps[3], 0); 145 | 146 | GLUtils.texImage2D(GLES20.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, cubeBitmaps[4], 0); 147 | GLUtils.texImage2D(GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, cubeBitmaps[5], 0); 148 | 149 | GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); 150 | 151 | for (Bitmap bitmap : cubeBitmaps) { 152 | bitmap.recycle(); 153 | } 154 | 155 | return textureObjectIds[0]; 156 | 157 | } 158 | 159 | } 160 | -------------------------------------------------------------------------------- /Lesson4/src/main/res/drawable/img_guider4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/Lesson4/src/main/res/drawable/img_guider4.png -------------------------------------------------------------------------------- /Lesson4/src/main/res/drawable/img_guider_checkin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/Lesson4/src/main/res/drawable/img_guider_checkin.png -------------------------------------------------------------------------------- /Lesson4/src/main/res/drawable/img_loading.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/Lesson4/src/main/res/drawable/img_loading.jpg -------------------------------------------------------------------------------- /Lesson4/src/main/res/drawable/img_loadings.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/Lesson4/src/main/res/drawable/img_loadings.jpg -------------------------------------------------------------------------------- /Lesson4/src/main/res/drawable/test_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/Lesson4/src/main/res/drawable/test_1.png -------------------------------------------------------------------------------- /Lesson4/src/main/res/drawable/test_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/Lesson4/src/main/res/drawable/test_2.png -------------------------------------------------------------------------------- /Lesson4/src/main/res/drawable/test_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/Lesson4/src/main/res/drawable/test_3.png -------------------------------------------------------------------------------- /Lesson4/src/main/res/layout/act_select.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 |