├── .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 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
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 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
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 |
73 |
74 |
75 |
76 |
77 |
78 | 1.7
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
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 |
5 |
6 |
7 |
8 |
9 |
10 |
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 |
13 |
20 |
27 |
35 |
42 |
43 |
51 |
58 |
66 |
73 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/Lesson4/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/Lesson4/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Lesson4/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/Lesson4/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Lesson4/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/Lesson4/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Lesson4/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/Lesson4/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Lesson4/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/Lesson4/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Lesson4/src/main/res/raw/point_fragment_shader.glsl:
--------------------------------------------------------------------------------
1 | //precision mediump float;
2 | //uniform sampler2D from, to;
3 | //uniform float progress;
4 | //varying vec2 vTextureCoord;
5 | ////final float res[] = {(float) gwidth, (float) gheight, 1.0f};
6 | //// default interpolationPower = 5;
7 | //uniform float interpolationPower;
8 | //
9 | //void main() {
10 | // vec4 fTex = texture2D(from,vTextureCoord);
11 | // vec4 tTex = texture2D(to,vTextureCoord);
12 | // gl_FragColor = mix(distance(fTex,tTex)>progress?fTex:tTex,
13 | // tTex,
14 | // pow(progress,interpolationPower));
15 | //}
16 |
17 |
18 | precision mediump float;
19 | // General parameters
20 | uniform sampler2D from;
21 | uniform sampler2D to;
22 | uniform float progress;
23 | varying vec2 vTextureCoord;
24 |
25 | const vec2 direction = vec2(1.0,-1.0);
26 | const float smoothness = 0.5;
27 |
28 | const vec2 center = vec2(0.5, 0.5);
29 |
30 | void main() {
31 | vec2 v = normalize(direction);
32 | v /= abs(v.x)+abs(v.y);
33 | float d = v.x * center.x + v.y * center.y;
34 | float m = smoothstep(-smoothness, 0.0, v.x * vTextureCoord.x + v.y * vTextureCoord.y - (d-0.5+progress*(1.+smoothness)));
35 | gl_FragColor = mix(texture2D(to, vTextureCoord), texture2D(from, vTextureCoord), m);
36 | }
37 |
38 |
39 | //precision mediump float;
40 | //uniform sampler2D from, to;
41 | //uniform float progress;
42 | //varying vec2 vTextureCoord;
43 | //
44 | //const vec2 squares = vec2(10.0,10.0);
45 | //const vec2 direction = vec2(1.0,-0.5);
46 | //const float smoothness = 1.6;
47 | //
48 | //const vec2 center = vec2(0.5, 0.5);
49 | //
50 | //void main() {
51 | // vec2 v = normalize(direction);
52 | // if (v != vec2(0.0))
53 | // v /= abs(v.x)+abs(v.y);
54 | // float d = v.x * center.x + v.y * center.y;
55 | // float offset = smoothness;
56 | // float pr = smoothstep(-offset, 0.0, v.x * vTextureCoord.x + v.y * vTextureCoord.y - (d-0.5+progress*(1.+offset)));
57 | // vec2 squarep = fract(vTextureCoord*vec2(squares));
58 | // vec2 squaremin = vec2(pr/2.0);
59 | // vec2 squaremax = vec2(1.0 - pr/2.0);
60 | // float a = all(lessThan(squaremin, squarep)) && all(lessThan(squarep, squaremax)) ? 1.0 : 0.0;
61 | // gl_FragColor = mix(texture2D(from, vTextureCoord), texture2D(to, vTextureCoord), a);
62 | //}
63 |
--------------------------------------------------------------------------------
/Lesson4/src/main/res/raw/point_vertext_shader.glsl:
--------------------------------------------------------------------------------
1 | attribute vec2 a_Position;
2 | attribute vec2 a_TexCoor;
3 | varying vec2 vTextureCoord;
4 | void main() {
5 | gl_Position = vec4(a_Position,0.0,1.0);
6 | vTextureCoord = a_TexCoor;
7 | }
8 |
9 |
--------------------------------------------------------------------------------
/Lesson4/src/main/res/raw/translate10_fragment_shader.glsl:
--------------------------------------------------------------------------------
1 | precision mediump float;
2 | uniform sampler2D from, to;
3 | uniform float progress;
4 | varying vec2 vTextureCoord;
5 |
6 | void main() {
7 |
8 | if (progress >= 0.0) {
9 | if (vTextureCoord.y >= progress) {
10 | gl_FragColor = texture2D(from, vTextureCoord - vec2(0.0, progress));
11 | }
12 | else {
13 | vec2 uv;
14 | if (progress > 0.0){
15 | uv = vec2(0.0, progress - 1.0);
16 | }
17 | gl_FragColor = texture2D(to, vTextureCoord - uv);
18 | }
19 | }
20 | else if (progress <= 0.0) {
21 | if (vTextureCoord.y <= (1.0 + progress))
22 | gl_FragColor = texture2D(from, vTextureCoord - vec2(0.0, progress));
23 | else {
24 | vec2 uv;
25 | if (progress < 0.0)
26 | uv = vec2(0.0, progress + 1.0);
27 | gl_FragColor = texture2D(to, vTextureCoord - uv);
28 | }
29 | }
30 | else
31 | gl_FragColor = vec4(0.0);
32 | }
--------------------------------------------------------------------------------
/Lesson4/src/main/res/raw/translate1_fragment_shader.glsl:
--------------------------------------------------------------------------------
1 | precision mediump float;
2 | uniform sampler2D from, to;
3 | uniform float progress;
4 | varying vec2 vTextureCoord;
5 |
6 | const vec2 squares = vec2(10.0,10.0);
7 | const vec2 direction = vec2(1.0,-0.5);
8 | const float smoothness = 1.6;
9 |
10 | const vec2 center = vec2(0.5, 0.5);
11 |
12 | void main() {
13 | vec2 v = normalize(direction);
14 | if (v != vec2(0.0))
15 | v /= abs(v.x)+abs(v.y);
16 | float d = v.x * center.x + v.y * center.y;
17 | float offset = smoothness;
18 | float pr = smoothstep(-offset, 0.0, v.x * vTextureCoord.x + v.y * vTextureCoord.y - (d-0.5+progress*(1.+offset)));
19 | vec2 squarep = fract(vTextureCoord*vec2(squares));
20 | vec2 squaremin = vec2(pr/2.0);
21 | vec2 squaremax = vec2(1.0 - pr/2.0);
22 | float a = all(lessThan(squaremin, squarep)) && all(lessThan(squarep, squaremax)) ? 1.0 : 0.0;
23 | gl_FragColor = mix(texture2D(from, vTextureCoord), texture2D(to, vTextureCoord), a);
24 | }
25 |
--------------------------------------------------------------------------------
/Lesson4/src/main/res/raw/translate2_fragment_shader.glsl:
--------------------------------------------------------------------------------
1 | precision mediump float;
2 | uniform sampler2D from,to;
3 | uniform float progress;
4 | varying vec2 vTextureCoord;
5 |
6 | vec2 offset(float progress, float x, float theta) {
7 | float phase = progress*progress + progress + theta;
8 | float shifty = 0.03*progress*cos(10.0*(progress+x));
9 | return vec2(0, shifty);
10 | }
11 |
12 | void main(){
13 | gl_FragColor = mix(texture2D(from,vTextureCoord+offset(progress,vTextureCoord.x,0.0)),texture2D(to,vTextureCoord+offset(1.0-progress,vTextureCoord.x,3.14)),progress);
14 | }
--------------------------------------------------------------------------------
/Lesson4/src/main/res/raw/translate3_fragment_shader.glsl:
--------------------------------------------------------------------------------
1 | precision mediump float;
2 | // General parameters
3 | uniform sampler2D from;
4 | uniform sampler2D to;
5 | uniform float progress;
6 | varying vec2 vTextureCoord;
7 |
8 | const float smoothness = 0.3;
9 | const bool opening = true;
10 |
11 | const vec2 center = vec2(0.5, 0.5);
12 | const float SQRT_2 = 1.414213562373;
13 |
14 | void main() {
15 | float x = opening ? progress : 1.-progress;
16 | float m = smoothstep(-smoothness, 0.0, SQRT_2*distance(center, vTextureCoord) - x*(1.+smoothness));
17 | gl_FragColor = mix(texture2D(from, vTextureCoord), texture2D(to, vTextureCoord), opening ? 1.-m : m);
18 | }
19 |
--------------------------------------------------------------------------------
/Lesson4/src/main/res/raw/translate4_fragment_shader.glsl:
--------------------------------------------------------------------------------
1 | precision mediump float;
2 | uniform sampler2D from, to;
3 | uniform float progress;
4 | varying vec2 vTextureCoord;
5 | uniform float interpolationPower;
6 |
7 | const float PI = 3.141592653589793;
8 |
9 | float Linear_ease(in float begin, in float change, in float duration, in float time) {
10 | return change * time / duration + begin;
11 | }
12 |
13 | float Exponential_easeInOut(in float begin, in float change, in float duration, in float time) {
14 | if (time == 0.0)
15 | return begin;
16 | else if (time == duration)
17 | return begin + change;
18 | time = time / (duration / 2.0);
19 | if (time < 1.0)
20 | return change / 2.0 * pow(2.0, 10.0 * (time - 1.0)) + begin;
21 | return change / 2.0 * (-pow(2.0, -10.0 * (time - 1.0)) + 2.0) + begin;
22 | }
23 |
24 | float Sinusoidal_easeInOut(in float begin, in float change, in float duration, in float time) {
25 | return -change / 2.0 * (cos(PI * time / duration) - 1.0) + begin;
26 | }
27 |
28 | /* random number between 0 and 1 */
29 | float random(in vec3 scale, in float seed) {
30 | /* use the fragment position for randomness */
31 | return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);
32 | }
33 |
34 | vec3 crossFade(in vec2 uv, in float dissolve) {
35 | return mix(texture2D(from, uv).rgb, texture2D(to, uv).rgb, dissolve);
36 | }
37 |
38 | void main() {
39 | // Linear interpolate center across center half of the image
40 | vec2 center = vec2(Linear_ease(0.25, 0.5, 1.0, progress), 0.5);
41 | float dissolve = Exponential_easeInOut(0.0, 1.0, 1.0, progress);
42 |
43 | // Mirrored sinusoidal loop. 0->interpolationPower then interpolationPower->0
44 | float interpolationPower = Sinusoidal_easeInOut(0.0, interpolationPower, 0.5, progress);
45 |
46 | vec3 color = vec3(0.0);
47 | float total = 0.0;
48 | vec2 toCenter = center - vTextureCoord;
49 |
50 | /* randomize the lookup values to hide the fixed number of samples */
51 | float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);
52 |
53 | for (float t = 0.0; t <= 40.0; t++) {
54 | float percent = (t + offset) / 40.0;
55 | float weight = 4.0 * (percent - percent * percent);
56 | color += crossFade(vTextureCoord + toCenter * percent * interpolationPower, dissolve) * weight;
57 | total += weight;
58 | }
59 | gl_FragColor = vec4(color / total, 1.0);
60 | }
--------------------------------------------------------------------------------
/Lesson4/src/main/res/raw/translate5_fragment_shader.glsl:
--------------------------------------------------------------------------------
1 | precision mediump float;
2 |
3 | // General parameters
4 | uniform sampler2D from;
5 | uniform sampler2D to;
6 | uniform float progress;
7 | varying vec2 vTextureCoord;
8 | // Custom parameters
9 | const vec2 size = vec2(4.0,4.0);
10 | const float pause = 0.1;
11 | const float dividerSize = 0.05;
12 |
13 | const vec4 dividerColor = vec4(0.0, 0.0, 0.0, 1.0);
14 | const float randomOffset = 0.1;
15 |
16 | float rand (vec2 co) {
17 | return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
18 | }
19 |
20 | float getDelta(vec2 p) {
21 | vec2 rectanglePos = floor(vec2(size) * p);
22 | vec2 rectangleSize = vec2(1.0 / vec2(size).x, 1.0 / vec2(size).y);
23 |
24 | float top = rectangleSize.y * (rectanglePos.y + 1.0);
25 | float bottom = rectangleSize.y * rectanglePos.y;
26 | float left = rectangleSize.x * rectanglePos.x;
27 | float right = rectangleSize.x * (rectanglePos.x + 1.0);
28 |
29 | float minX = min(abs(p.x - left), abs(p.x - right));
30 | float minY = min(abs(p.y - top), abs(p.y - bottom));
31 | return min(minX, minY);
32 | }
33 |
34 | float getDividerSize() {
35 | vec2 rectangleSize = vec2(1.0 / vec2(size).x, 1.0 / vec2(size).y);
36 | return min(rectangleSize.x, rectangleSize.y) * dividerSize;
37 | }
38 |
39 | void showDivider (vec2 p) {
40 | float currentProg = progress / pause;
41 |
42 | float a = 1.0;
43 | if(getDelta(p) < getDividerSize()) {
44 | a = 1.0 - currentProg;
45 | }
46 |
47 | gl_FragColor = mix(dividerColor, texture2D(from, p), a);
48 | }
49 |
50 | void hideDivider (vec2 p) {
51 | float currentProg = (progress - 1.0 + pause) / pause;
52 |
53 | float a = 1.0;
54 | if(getDelta(p) < getDividerSize()) {
55 | a = currentProg;
56 | }
57 |
58 | gl_FragColor = mix(dividerColor, texture2D(to, p), a);
59 | }
60 |
61 | void main() {
62 | if(progress < pause) {
63 | showDivider(vTextureCoord);
64 | } else if(progress < 1.0 - pause){
65 | if(getDelta(vTextureCoord) < getDividerSize()) {
66 | gl_FragColor = dividerColor;
67 | } else {
68 | float currentProg = (progress - pause) / (1.0 - pause * 2.0);
69 | vec2 q = vTextureCoord;
70 | vec2 rectanglePos = floor(vec2(size) * q);
71 |
72 | float r = rand(rectanglePos) - randomOffset;
73 | float cp = smoothstep(0.0, 1.0 - r, currentProg);
74 |
75 | float rectangleSize = 1.0 / vec2(size).x;
76 | float delta = rectanglePos.x * rectangleSize;
77 | float offset = rectangleSize / 2.0 + delta;
78 |
79 | vec2 ta = vTextureCoord;
80 | ta.x = (vTextureCoord.x - offset)/abs(cp - 0.5)*0.5 + offset;
81 | vec4 a = texture2D(from, ta);
82 | vec4 b = texture2D(to, ta);
83 |
84 | float s = step(abs(vec2(size).x * (q.x - delta) - 0.5), abs(cp - 0.5));
85 | gl_FragColor = vec4(mix(b, a, step(cp, 0.5)).rgb * s, 1.0);
86 | }
87 | } else {
88 | hideDivider(vTextureCoord);
89 | }
90 | }
--------------------------------------------------------------------------------
/Lesson4/src/main/res/raw/translate6_fragment_shader.glsl:
--------------------------------------------------------------------------------
1 | precision mediump float;
2 |
3 | // General parameters
4 | uniform sampler2D from,to;
5 | uniform float progress;
6 | varying vec2 vTextureCoord;
7 |
8 | const float amplitude = 30.0;
9 | const float speed = 30.0;
10 |
11 | void main()
12 | {
13 | vec2 dir = vTextureCoord - vec2(.5);
14 | float dist = length(dir);
15 |
16 | if (dist > progress) {
17 | gl_FragColor = mix(texture2D(from, vTextureCoord), texture2D(to, vTextureCoord), progress);
18 | } else {
19 | vec2 offset = dir * sin(dist * amplitude - progress * speed);
20 | gl_FragColor = mix(texture2D(from, vTextureCoord + offset), texture2D(to, vTextureCoord), progress);
21 | }
22 | }
--------------------------------------------------------------------------------
/Lesson4/src/main/res/raw/translate7_fragment_shader.glsl:
--------------------------------------------------------------------------------
1 | precision mediump float;
2 | uniform sampler2D from, to;
3 | uniform float progress;
4 | varying vec2 vTextureCoord;
5 | const float strength=0.1;
6 |
7 | void main() {
8 | vec4 ca = texture2D(from, vTextureCoord);
9 | vec4 cb = texture2D(to, vTextureCoord);
10 |
11 | vec2 oa = (((ca.rg+ca.b)*0.5)*2.0-1.0);
12 | vec2 ob = (((cb.rg+cb.b)*0.5)*2.0-1.0);
13 | vec2 oc = mix(oa,ob,0.5)*strength;
14 |
15 | float w0 = progress;
16 | float w1 = 1.0-w0;
17 | gl_FragColor = mix(texture2D(from, vTextureCoord+oc*w0), texture2D(to, vTextureCoord-oc*w1), progress);
18 | }
--------------------------------------------------------------------------------
/Lesson4/src/main/res/raw/translate8_fragment_shader.glsl:
--------------------------------------------------------------------------------
1 | precision mediump float;
2 | uniform sampler2D from, to;
3 | uniform float progress;
4 | varying vec2 vTextureCoord;
5 |
6 | // HSV functions are from http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl
7 |
8 | vec3 hsv2rgb(vec3 c) {
9 | const vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
10 | vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
11 | return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
12 | }
13 |
14 | vec3 rgb2hsv(vec3 c) {
15 | const vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
16 | vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
17 | vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
18 |
19 | float d = q.x - min(q.w, q.y);
20 | return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + 0.001)), d / (q.x + 0.001), q.x);
21 | }
22 |
23 | void main() {
24 | vec3 a = rgb2hsv(texture2D(from, vTextureCoord).rgb);
25 | vec3 b = rgb2hsv(texture2D(to, vTextureCoord).rgb);
26 | vec3 m = mix(a, b, progress);
27 | gl_FragColor = vec4(hsv2rgb(m), 1.0);
28 | }
--------------------------------------------------------------------------------
/Lesson4/src/main/res/raw/translate9_fragment_shader.glsl:
--------------------------------------------------------------------------------
1 | precision mediump float;
2 | uniform sampler2D from, to;
3 | uniform float progress;
4 | varying vec2 vTextureCoord;
5 |
6 | void main()
7 | {
8 | vec2 uv = vTextureCoord - .5;
9 | float t = progress * .1 + ((.25 + .05 * sin(progress * .1))/(length(uv.xy) + .07)) * 2.2;
10 | float si = sin(t);
11 | float co = cos(t);
12 | mat2 ma = mat2(co, si, -si, co);
13 |
14 | float v1, v2, v3;
15 | v1 = v2 = v3 = 0.0;
16 |
17 | float s = 0.0;
18 | for (int i = 0; i < 90; i++)
19 | {
20 | vec3 p = s * vec3(uv, 0.0);
21 | p.xy *= ma;
22 | p += vec3(.22, .3, s - 1.5 - sin(progress * .13) * .1);
23 | for (int i = 0; i < 8; i++) p = abs(p) / dot(p,p) - 0.659;
24 | v1 += dot(p,p) * .0015 * (1.8 + sin(length(uv.xy * 13.0) + .5 - progress * .2));
25 | v2 += dot(p,p) * .0013 * (1.5 + sin(length(uv.xy * 14.5) + 1.2 - progress * .3));
26 | v3 += length(p.xy*10.) * .0003;
27 | s += .035;
28 | }
29 |
30 | float len = length(uv);
31 | v1 *= smoothstep(.7, .0, len);
32 | v2 *= smoothstep(.5, .0, len);
33 | v3 *= smoothstep(.9, .0, len);
34 |
35 | vec3 col = vec3( v3 * (1.5 + sin(progress * .2) * .4),
36 | (v1 + v3) * .3,
37 | v2) + smoothstep(0.2, .0, len) * .85 + smoothstep(.0, .6, v3) * .3;
38 |
39 | gl_FragColor=vec4(min(pow(abs(col), vec3(1.2)), 1.0), 1.0);
40 | }
--------------------------------------------------------------------------------
/Lesson4/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/Lesson4/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/Lesson4/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/Lesson4/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Lesson4
3 |
4 |
--------------------------------------------------------------------------------
/Lesson4/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Lesson4/src/test/java/com/opengl/youyang/myapplication/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.opengl.youyang.myapplication;
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 mView.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------
/Lesson6/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/Lesson6/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 24
5 | buildToolsVersion "24.0.2"
6 |
7 | defaultConfig {
8 | applicationId "com.test.youyang.wallpaper"
9 | minSdkVersion 14
10 | targetSdkVersion 24
11 | versionCode 1
12 | versionName "1.0"
13 |
14 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
15 |
16 | }
17 | buildTypes {
18 | release {
19 | minifyEnabled false
20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
21 | }
22 | }
23 | }
24 |
25 | dependencies {
26 | compile fileTree(dir: 'libs', include: ['*.jar'])
27 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
28 | exclude group: 'com.android.support', module: 'support-annotations'
29 | })
30 | compile 'com.android.support:appcompat-v7:24.2.1'
31 | testCompile 'junit:junit:4.12'
32 | }
33 |
--------------------------------------------------------------------------------
/Lesson6/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 |
--------------------------------------------------------------------------------
/Lesson6/src/androidTest/java/com/test/youyang/wallpaper/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.test.youyang.wallpaper;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumentation test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.test.youyang.wallpaper", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Lesson6/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
27 |
28 |
29 |
30 |
31 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/Lesson6/src/main/java/com/test/youyang/wallpaper/ColorShaderProgram.java:
--------------------------------------------------------------------------------
1 | package com.test.youyang.wallpaper;
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){
22 | super(context);
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){
38 | GLES20.glUniform1f(u_Progress,progress);
39 | }
40 |
41 | public int getPositionAttributionLocation(){
42 | return aPositionLocation;
43 | }
44 |
45 | public int getTexCoodAttributionLocation(){
46 | return aTexturreCoordLocation;
47 | }
48 |
49 | public int getUniformFromLocation(){
50 | return u_From;
51 | }
52 |
53 | public int getUniformToLocation(){
54 | return u_To;
55 | }
56 |
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/Lesson6/src/main/java/com/test/youyang/wallpaper/GLWallPaperService.java:
--------------------------------------------------------------------------------
1 | package com.test.youyang.wallpaper;
2 |
3 | import android.app.ActivityManager;
4 | import android.content.Context;
5 | import android.opengl.GLSurfaceView;
6 | import android.os.Build;
7 | import android.service.wallpaper.WallpaperService;
8 | import android.view.SurfaceHolder;
9 | import android.widget.Toast;
10 |
11 | /**
12 | * Created by youyang on 2017/1/19.
13 | */
14 |
15 | public class GLWallPaperService extends WallpaperService {
16 |
17 | private GLWallPaperSurfaceView mGLSurfaceView;
18 |
19 | GLEngine mEngine = new GLEngine();
20 |
21 | private boolean renderSet;
22 |
23 | // Thread mRenderThread = new Thread(){
24 | // @Override
25 | // public void run() {
26 | // super.run();
27 | // while (true){
28 | // if(mVisible){
29 | // SystemClock.sleep(150);
30 | // if(mGLSurfaceView !=null){
31 | // mGLSurfaceView.requestRender();
32 | // }
33 | // }
34 | //
35 | // }
36 | //
37 | // }
38 | // };
39 | private boolean mVisible;
40 |
41 | @Override
42 | public Engine onCreateEngine() {
43 | // mEngine = new GLEngine();
44 | return mEngine;
45 | }
46 |
47 | public class GLEngine extends Engine {
48 | @Override
49 | public void onCreate(SurfaceHolder surfaceHolder) {
50 | super.onCreate(surfaceHolder);
51 | initGLWallPaper();
52 | // mRenderThread.start();
53 | }
54 |
55 | @Override
56 | public void onVisibilityChanged(boolean visible) {
57 | super.onVisibilityChanged(visible);
58 | mVisible = visible;
59 | if(renderSet){
60 | if(visible){
61 | mGLSurfaceView.onResume();
62 | }else{
63 | mGLSurfaceView.onPause();
64 | }
65 | }
66 | }
67 |
68 | @Override
69 | public void onDestroy() {
70 | super.onDestroy();
71 | mGLSurfaceView.onWallPaperDestroy();
72 | }
73 | }
74 |
75 |
76 |
77 | private void initGLWallPaper() {
78 |
79 | mGLSurfaceView = new GLWallPaperSurfaceView(this);
80 |
81 | //第一步 检验是否支持opengl 2.0
82 | final boolean isSuppotES2=isSupportES2();
83 | //第二步创建渲染器
84 | final PointRender render = new PointRender(this);
85 |
86 | if(isSuppotES2){
87 | //设定egl版本
88 | mGLSurfaceView.setEGLContextClientVersion(2);
89 | //设置渲染器,设置完这一步之后相当于开启了 另一条渲染线程
90 | mGLSurfaceView.setRenderer(render);
91 | //设置渲染模式 一直渲染
92 | mGLSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
93 | renderSet = true;
94 |
95 | if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
96 | mGLSurfaceView.setPreserveEGLContextOnPause(true);
97 | }
98 | }else {
99 | Toast.makeText(this,"该手机不支持opengl es 2.0" ,Toast.LENGTH_LONG).show();
100 | return;
101 | }
102 |
103 | }
104 |
105 | /**
106 | * 检验是否支持opengl 2.0
107 | * @return
108 | */
109 | private boolean isSupportES2() {
110 | return ((ActivityManager) getSystemService(Context.ACTIVITY_SERVICE))
111 | .getDeviceConfigurationInfo().reqGlEsVersion >= 0x20000;
112 | }
113 |
114 | class GLWallPaperSurfaceView extends GLSurfaceView{
115 |
116 | public GLWallPaperSurfaceView(Context context) {
117 | super(context);
118 | }
119 |
120 | @Override
121 | public SurfaceHolder getHolder() {
122 | return mEngine.getSurfaceHolder();
123 | }
124 |
125 | public void onWallPaperDestroy(){
126 | super.onDetachedFromWindow();
127 | }
128 | }
129 |
130 | }
131 |
--------------------------------------------------------------------------------
/Lesson6/src/main/java/com/test/youyang/wallpaper/LogConfig.java:
--------------------------------------------------------------------------------
1 | package com.test.youyang.wallpaper;
2 |
3 | /**
4 | * Created by youyang on 15-4-13.
5 | */
6 | public class LogConfig {
7 | public static final boolean ON=true;
8 | }
9 |
--------------------------------------------------------------------------------
/Lesson6/src/main/java/com/test/youyang/wallpaper/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.test.youyang.wallpaper;
2 |
3 | import android.support.v7.app.AppCompatActivity;
4 | import android.os.Bundle;
5 |
6 | public class MainActivity extends AppCompatActivity {
7 |
8 | @Override
9 | protected void onCreate(Bundle savedInstanceState) {
10 | super.onCreate(savedInstanceState);
11 | // setContentView(R.layout.activity_main);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Lesson6/src/main/java/com/test/youyang/wallpaper/PointRender.java:
--------------------------------------------------------------------------------
1 | package com.test.youyang.wallpaper;
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 | public PointRender(Context context) {
26 | mContext = context;
27 | }
28 |
29 | private int[] mResources = new int[2];
30 |
31 | float aPoint = 1f;
32 | float[] mVertex = new float[]{
33 | -aPoint, aPoint,
34 | -aPoint, -aPoint,
35 | aPoint, -aPoint,
36 |
37 | aPoint, -aPoint,
38 | aPoint, aPoint,
39 | -aPoint, aPoint
40 |
41 | };
42 |
43 | float[] mTextureCoord = new float[]{
44 | 0f, 0f,
45 | 0f, 1f,
46 | 1f, 1f,
47 |
48 | 1f, 1f,
49 | 1f, 0f,
50 | 0f, 0f
51 | };
52 |
53 | int[] ids;
54 | private ColorShaderProgram mColorShaderProgram;
55 |
56 | float time = 0;
57 | @Override
58 | public void onSurfaceCreated(GL10 gl, EGLConfig config) {
59 |
60 | // time = SystemClock.currentThreadTimeMillis();
61 | mColorShaderProgram = new ColorShaderProgram(mContext);
62 | GLES20.glClearColor(0f, 0f, 0f, 0f);
63 | GLES20.glEnable(GLES20.GL_DEPTH_TEST);
64 | GLES20.glDisable(GLES20.GL_CULL_FACE);
65 | ids = TextureHelper.loadTexture(mContext, mResources);
66 | mFloatBuffer = ByteBuffer.allocateDirect(mVertex.length * 4).order(ByteOrder.nativeOrder())
67 | .asFloatBuffer().put(mVertex);
68 | mTextureBuffer = ByteBuffer.allocateDirect(mVertex.length * 4).order(ByteOrder.nativeOrder())
69 | .asFloatBuffer().put(mTextureCoord);
70 | mFloatBuffer.position(0);
71 | mTextureBuffer.position(0);
72 | }
73 |
74 | @Override
75 | public void onSurfaceChanged(GL10 gl, int width, int height) {
76 | GLES20.glViewport(0, 0, width, height);
77 | }
78 |
79 | @Override
80 | public void onDrawFrame(GL10 gl) {
81 | time +=0.1f;
82 | limitFrameRate(15);
83 |
84 | GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
85 | mColorShaderProgram.useProgram();
86 | mColorShaderProgram.setUniformProgressAndInterpolationPower(time);
87 | GLES20.glVertexAttribPointer(mColorShaderProgram.getPositionAttributionLocation(), 2, GLES20.GL_FLOAT, false, 2 * 4, mFloatBuffer);
88 | GLES20.glVertexAttribPointer(mColorShaderProgram.getTexCoodAttributionLocation(), 2, GLES20.GL_FLOAT, false, 2 * 4, mTextureBuffer);
89 | GLES20.glEnableVertexAttribArray(mColorShaderProgram.getPositionAttributionLocation());
90 | GLES20.glEnableVertexAttribArray(mColorShaderProgram.getTexCoodAttributionLocation());
91 | GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 6);
92 | }
93 |
94 | private long frameStartTime;
95 |
96 | private void limitFrameRate(int i) {
97 | long frameTime = SystemClock.elapsedRealtime() - frameStartTime;
98 | long expectTime = 1000/i ;
99 | long timeToSleep = expectTime - frameTime;
100 |
101 | if(timeToSleep > 0){
102 | SystemClock.sleep(timeToSleep);
103 | }
104 | frameStartTime = SystemClock.elapsedRealtime();
105 | }
106 |
107 | }
108 |
--------------------------------------------------------------------------------
/Lesson6/src/main/java/com/test/youyang/wallpaper/ShaderHelper.java:
--------------------------------------------------------------------------------
1 | package com.test.youyang.wallpaper;
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 |
--------------------------------------------------------------------------------
/Lesson6/src/main/java/com/test/youyang/wallpaper/ShaderProgram.java:
--------------------------------------------------------------------------------
1 | package com.test.youyang.wallpaper;
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) {
26 | mProgram = ShaderHelper.buildProgram(TextResourceReader.readTextResourceFromRaw(context,
27 | R.raw.point_vertext_shader), TextResourceReader.readTextResourceFromRaw(context,
28 | R.raw.point_fragment_shader));
29 | }
30 |
31 | public void useProgram(){
32 | GLES20.glUseProgram(mProgram);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Lesson6/src/main/java/com/test/youyang/wallpaper/TextResourceReader.java:
--------------------------------------------------------------------------------
1 | package com.test.youyang.wallpaper;
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 |
--------------------------------------------------------------------------------
/Lesson6/src/main/java/com/test/youyang/wallpaper/TextureHelper.java:
--------------------------------------------------------------------------------
1 | package com.test.youyang.wallpaper;
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 |
--------------------------------------------------------------------------------
/Lesson6/src/main/res/drawable/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/Lesson6/src/main/res/drawable/ic_launcher.png
--------------------------------------------------------------------------------
/Lesson6/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
18 |
19 |
--------------------------------------------------------------------------------
/Lesson6/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/Lesson6/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Lesson6/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/Lesson6/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Lesson6/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/Lesson6/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Lesson6/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/Lesson6/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Lesson6/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/Lesson6/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/Lesson6/src/main/res/raw/point_fragment_shader.glsl:
--------------------------------------------------------------------------------
1 | precision mediump float;
2 | uniform sampler2D from, to;
3 | uniform float progress;
4 | varying vec2 vTextureCoord;
5 |
6 | void main()
7 | {
8 | vec2 uv = vTextureCoord - .5;
9 | float t = progress * .1 + ((.25 + .05 * sin(progress * .1))/(length(uv.xy) + .07)) * 2.2;
10 | float si = sin(t);
11 | float co = cos(t);
12 | mat2 ma = mat2(co, si, -si, co);
13 |
14 | float v1, v2, v3;
15 | v1 = v2 = v3 = 0.0;
16 |
17 | float s = 0.0;
18 | for (int i = 0; i < 90; i++)
19 | {
20 | vec3 p = s * vec3(uv, 0.0);
21 | p.xy *= ma;
22 | p += vec3(.22, .3, s - 1.5 - sin(progress * .13) * .1);
23 | for (int i = 0; i < 8; i++) p = abs(p) / dot(p,p) - 0.659;
24 | v1 += dot(p,p) * .0015 * (1.8 + sin(length(uv.xy * 13.0) + .5 - progress * .2));
25 | v2 += dot(p,p) * .0013 * (1.5 + sin(length(uv.xy * 14.5) + 1.2 - progress * .3));
26 | v3 += length(p.xy*10.) * .0003;
27 | s += .035;
28 | }
29 |
30 | float len = length(uv);
31 | v1 *= smoothstep(.7, .0, len);
32 | v2 *= smoothstep(.5, .0, len);
33 | v3 *= smoothstep(.9, .0, len);
34 |
35 | vec3 col = vec3( v3 * (1.5 + sin(progress * .2) * .4),
36 | (v1 + v3) * .3,
37 | v2) + smoothstep(0.2, .0, len) * .85 + smoothstep(.0, .6, v3) * .3;
38 |
39 | gl_FragColor=vec4(min(pow(abs(col), vec3(1.2)), 1.0), 1.0);
40 | }
--------------------------------------------------------------------------------
/Lesson6/src/main/res/raw/point_fragment_shader1.glsl:
--------------------------------------------------------------------------------
1 | precision mediump float;
2 | const float cloudscale = 1.1;
3 | const float speed = 0.03;
4 | const float clouddark = 0.5;
5 | const float cloudlight = 0.3;
6 | const float cloudcover = 0.2;
7 | const float cloudalpha = 8.0;
8 | const float skytint = 0.5;
9 | const vec3 skycolour1 = vec3(0.2, 0.4, 0.6);
10 | const vec3 skycolour2 = vec3(0.4, 0.7, 1.0);
11 | const mat2 m = mat2( 1.6, 1.2, -1.2, 1.6 );
12 | uniform sampler2D from, to;
13 | uniform float progress;
14 | varying vec2 vTextureCoord;
15 |
16 | vec2 hash( vec2 p ) {
17 | p = vec2(dot(p,vec2(127.1,311.7)), dot(p,vec2(269.5,183.3)));
18 | return -1.0 + 2.0*fract(sin(p)*43758.5453123);
19 | }
20 |
21 | float noise( in vec2 p ) {
22 | const float K1 = 0.366025404; // (sqrt(3)-1)/2;
23 | const float K2 = 0.211324865; // (3-sqrt(3))/6;
24 | vec2 i = floor(p + (p.x+p.y)*K1);
25 | vec2 a = p - i + (i.x+i.y)*K2;
26 | vec2 o = (a.x>a.y) ? vec2(1.0,0.0) : vec2(0.0,1.0); //vec2 of = 0.5 + 0.5*vec2(sign(a.x-a.y), sign(a.y-a.x));
27 | vec2 b = a - o + K2;
28 | vec2 c = a - 1.0 + 2.0*K2;
29 | vec3 h = max(0.5-vec3(dot(a,a), dot(b,b), dot(c,c) ), 0.0 );
30 | vec3 n = h*h*h*h*vec3( dot(a,hash(i+0.0)), dot(b,hash(i+o)), dot(c,hash(i+1.0)));
31 | return dot(n, vec3(70.0));
32 | }
33 |
34 | float fbm(vec2 n) {
35 | float total = 0.0, amplitude = 0.1;
36 | for (int i = 0; i < 7; i++) {
37 | total += noise(n) * amplitude;
38 | n = m * n;
39 | amplitude *= 0.4;
40 | }
41 | return total;
42 | }
43 |
44 | // -----------------------------------------------
45 |
46 | void main() {
47 | vec2 p = vTextureCoord;
48 | vec2 uv = p*vec2(0.5,1.0);
49 | float time = progress * speed;
50 | float q = fbm(uv * cloudscale * 0.5);
51 |
52 | //ridged noise shape
53 | float r = 0.0;
54 | uv *= cloudscale;
55 | uv -= q - time;
56 | float weight = 0.8;
57 | for (int i=0; i<8; i++){
58 | r += abs(weight*noise( uv ));
59 | uv = m*uv + time;
60 | weight *= 0.7;
61 | }
62 |
63 | //noise shape
64 | float f = 0.0;
65 | uv = p*vec2(0.5,1.0);
66 | uv *= cloudscale;
67 | uv -= q - time;
68 | weight = 0.7;
69 | for (int i=0; i<8; i++){
70 | f += weight*noise( uv );
71 | uv = m*uv + time;
72 | weight *= 0.6;
73 | }
74 |
75 | f *= r + f;
76 |
77 | //noise colour
78 | float c = 0.0;
79 | time = progress * speed * 2.0;
80 | uv = p*vec2(0.5,1.0);
81 | uv *= cloudscale*2.0;
82 | uv -= q - time;
83 | weight = 0.4;
84 | for (int i=0; i<7; i++){
85 | c += weight*noise( uv );
86 | uv = m*uv + time;
87 | weight *= 0.6;
88 | }
89 |
90 | //noise ridge colour
91 | float c1 = 0.0;
92 | time = progress * speed * 3.0;
93 | uv = p*vec2(0.5,1.0);
94 | uv *= cloudscale*3.0;
95 | uv -= q - time;
96 | weight = 0.4;
97 | for (int i=0; i<7; i++){
98 | c1 += abs(weight*noise( uv ));
99 | uv = m*uv + time;
100 | weight *= 0.6;
101 | }
102 |
103 | c += c1;
104 |
105 | vec3 skycolour = mix(skycolour2, skycolour1, p.y);
106 | vec3 cloudcolour = vec3(1.1, 1.1, 0.9) * clamp((clouddark + cloudlight*c), 0.0, 1.0);
107 |
108 | f = cloudcover + cloudalpha*f*r;
109 |
110 | vec3 result = mix(skycolour, clamp(skytint * skycolour + cloudcolour, 0.0, 1.0), clamp(f + c, 0.0, 1.0));
111 |
112 | gl_FragColor = vec4( result, 1.0 );
113 | }
114 |
--------------------------------------------------------------------------------
/Lesson6/src/main/res/raw/point_vertext_shader.glsl:
--------------------------------------------------------------------------------
1 | attribute vec2 a_Position;
2 | attribute vec2 a_TexCoor;
3 | varying vec2 vTextureCoord;
4 | void main() {
5 | gl_Position = vec4(a_Position,0.0,1.0);
6 | vTextureCoord = a_TexCoor;
7 | }
8 |
9 |
--------------------------------------------------------------------------------
/Lesson6/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/Lesson6/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/Lesson6/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/Lesson6/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | WallPaper
3 |
4 |
--------------------------------------------------------------------------------
/Lesson6/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Lesson6/src/main/res/xml/wallpaper.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Lesson6/src/test/java/com/test/youyang/wallpaper/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.test.youyang.wallpaper;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # OpenGLLessons
2 | ## 这是一个关于如何在android手机上写opengl的教程。
3 |
4 | * Lesson1讲述如何在手机上画出一个单色背景。主要涉及到的是OpenGL初始化过程,以及OpenGL的版本判断。另外添加了一些触摸响应。滑动改变背景色
5 |
6 |

7 |
8 |
9 | -----
10 | * Lesson2讲述如何在手机上绘制一个点。虽然仅仅只是绘制一个点,但是这里却开始涉及到着色器的概念。我们需要编写简单的着色器,并对其进行加载,编译。然后从外部程序传递顶点坐标。这些代码虽然繁琐,但是写完后变化不大,以后可以一直用。
11 |
12 |

13 |
14 |
15 | -----
16 |
17 | * Lesson3讲述的是如何通过两个三角形绘制一个矩形。这里讲述了简单的归一化坐标以及OpenGL的顶点数据组织方式。
18 |
19 |
20 |

21 |
22 |
23 | -----
24 | * Lesson4 展示的是利用opengl实现的页面切换特效。有趣的切换效果,可以用来代替ViewPager做一些绚丽的效果。
25 |
26 |
27 |

28 |
29 |
30 | -----
31 |
32 | * Lesson5 讲述的是用opengl实现展示相机预览。顺便加了一个边缘识别的卷积算子。
33 |
34 |
35 |

36 |
37 |
38 | -----
39 |
40 | * Lesson6 演示的是一个opengl实现的3D 屏保。没用任何图片或视频,仅仅靠数学公式 约束每一个像素点,形成美丽的星河,有没有很酷。
41 |
42 |
43 |

44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.1.0'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | }
19 | }
20 |
21 | task clean(type: Delete) {
22 | delete rootProject.buildDir
23 | }
24 |
--------------------------------------------------------------------------------
/device-2016-08-16-174717.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/device-2016-08-16-174717.png
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Dec 28 10:00:20 PST 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/lesson1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/lesson1.png
--------------------------------------------------------------------------------
/lesson2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/lesson2.png
--------------------------------------------------------------------------------
/lesson2/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/lesson2/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.lesson2"
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 |
--------------------------------------------------------------------------------
/lesson2/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 |
--------------------------------------------------------------------------------
/lesson2/src/androidTest/java/com/opengl/youyang/lesson2/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.opengl.youyang.lesson2;
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 | }
--------------------------------------------------------------------------------
/lesson2/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/lesson2/src/main/java/com/opengl/youyang/lesson2/ColorShaderProgram.java:
--------------------------------------------------------------------------------
1 | package com.opengl.youyang.lesson2;
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 |
13 | public ColorShaderProgram(Context context){
14 | super(context,R.raw.point_vertext_shader,R.raw.point_fragment_shader);
15 | //获取对应的着色器里的变量
16 | u_ColorLocation= GLES20.glGetUniformLocation(mProgram,U_COLOR);
17 | aPositionLocation=GLES20.glGetAttribLocation(mProgram,A_POSITION);
18 | }
19 |
20 | /**
21 | * 控制片元着色器里的颜色值
22 | * @param r
23 | * @param g
24 | * @param b
25 | */
26 | public void setUniforms(float r,float g,float b){
27 | GLES20.glUniform4f(u_ColorLocation,r,g,b,1f);
28 | }
29 |
30 | /**
31 | * 获取着色器里的变量的句柄
32 | * @return
33 | */
34 | public int getPositionAttributionLocation(){
35 | return aPositionLocation;
36 | }
37 |
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/lesson2/src/main/java/com/opengl/youyang/lesson2/LogConfig.java:
--------------------------------------------------------------------------------
1 | package com.opengl.youyang.lesson2;
2 |
3 | /**
4 | * Created by youyang on 15-4-13.
5 | */
6 | public class LogConfig {
7 | public static final boolean ON=true;
8 | }
9 |
--------------------------------------------------------------------------------
/lesson2/src/main/java/com/opengl/youyang/lesson2/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.opengl.youyang.lesson2;
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.widget.Toast;
9 |
10 | /**
11 | * 着色器 是 软件与GPU硬件的桥梁,可以通过着色器去控制GPU去进行高性能的绘制。
12 | * 如果不使用着色器,我们就只能通过cpu去进行渲染,两者的效率天差地别。
13 | *
14 | * 这节课开始接触着色器,用着色器 绘制一个普通的顶点Point
15 | * 1.学会写简单的着色器
16 | * 2.了解如何加载着色器
17 | * 3.学会如何在java代码中动态给着色器的属性赋值
18 | */
19 |
20 | public class MainActivity extends AppCompatActivity {
21 |
22 | GLSurfaceView view;
23 |
24 | @Override
25 | protected void onCreate(Bundle savedInstanceState) {
26 |
27 | super.onCreate(savedInstanceState);
28 | view = new GLSurfaceView(this);
29 |
30 | //第一步 检验是否支持opengl 2.0
31 | final boolean isSuppotES2 = isSupportES2();
32 | //第二步创建渲染器
33 | final PointRender render = new PointRender(this);
34 |
35 | if (isSuppotES2) {
36 | //设定egl版本
37 | view.setEGLContextClientVersion(2);
38 | //设置渲染器,设置完这一步之后相当于开启了 另一条渲染线程
39 | view.setRenderer(render);
40 | //设置渲染模式 一直渲染
41 | view.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
42 | } else {
43 | Toast.makeText(this, "该手机不支持opengl es 2.0", Toast.LENGTH_LONG).show();
44 | return;
45 | }
46 | setContentView(view);
47 | }
48 |
49 |
50 | @Override
51 | protected void onResume() {
52 | super.onResume();
53 | view.onResume();
54 | }
55 |
56 | @Override
57 | protected void onPause() {
58 | super.onPause();
59 | view.onPause();
60 | }
61 |
62 | /**
63 | * 检验是否支持opengl 2.0
64 | */
65 | private boolean isSupportES2() {
66 | return ((ActivityManager) getSystemService(Context.ACTIVITY_SERVICE))
67 | .getDeviceConfigurationInfo().reqGlEsVersion >= 0x20000;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/lesson2/src/main/java/com/opengl/youyang/lesson2/PointRender.java:
--------------------------------------------------------------------------------
1 | package com.opengl.youyang.lesson2;
2 |
3 | import android.content.Context;
4 | import android.opengl.GLES20;
5 | import android.opengl.GLSurfaceView;
6 |
7 | import java.nio.ByteBuffer;
8 | import java.nio.ByteOrder;
9 | import java.nio.FloatBuffer;
10 |
11 | import javax.microedition.khronos.egl.EGLConfig;
12 | import javax.microedition.khronos.opengles.GL10;
13 |
14 | /**
15 | * Created by youyang on 16/5/24.
16 | */
17 | public class PointRender implements GLSurfaceView.Renderer {
18 |
19 | private FloatBuffer mFloatBuffer;
20 |
21 | private Context mContext;
22 |
23 | public PointRender(Context context){
24 | mContext = context;
25 | }
26 |
27 | // float[] mVertex = new float[]{
28 | // 0f,0f
29 | // } ;
30 |
31 | float aPoint = 0.8f;
32 | float[] mVertex = new float[]{
33 | -aPoint,aPoint,
34 | -aPoint,-aPoint,
35 | aPoint,-aPoint,
36 |
37 | aPoint,-aPoint,
38 | aPoint,aPoint,
39 | -aPoint,aPoint
40 |
41 | } ;
42 |
43 | private ColorShaderProgram mColorShaderProgram;
44 |
45 | @Override
46 | public void onSurfaceCreated(GL10 gl, EGLConfig config) {
47 | GLES20.glClearColor(0.0f,0.5f,0.3f,0.4f);
48 |
49 | mColorShaderProgram = new ColorShaderProgram(mContext);
50 |
51 | mFloatBuffer = ByteBuffer.allocateDirect(mVertex.length*4).order(ByteOrder.nativeOrder())
52 | .asFloatBuffer().put(mVertex);
53 | mFloatBuffer.position(0);
54 |
55 | mColorShaderProgram.useProgram();
56 | mColorShaderProgram.setUniforms(0.9f,0.4f,0.9f);
57 |
58 | GLES20.glVertexAttribPointer(mColorShaderProgram.getPositionAttributionLocation(),2,GLES20.GL_FLOAT,false,2*4,mFloatBuffer);
59 | GLES20.glEnableVertexAttribArray(mColorShaderProgram.getPositionAttributionLocation());
60 | // mFloatBuffer.position(0);
61 |
62 |
63 | }
64 |
65 | @Override
66 | public void onSurfaceChanged(GL10 gl, int width, int height) {
67 | //设置显示区域大小和位置
68 | GLES20.glViewport(0,0,width,height);
69 | }
70 |
71 | @Override
72 | public void onDrawFrame(GL10 gl) {
73 | GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
74 |
75 | // 最终的绘制方法
76 | GLES20.glDrawArrays(GLES20.GL_POINTS,0,1);
77 | // GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP,0,6);
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/lesson2/src/main/java/com/opengl/youyang/lesson2/ShaderHelper.java:
--------------------------------------------------------------------------------
1 | package com.opengl.youyang.lesson2;
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 | /**
13 | * 编译顶点着色器
14 | * @param shaderCode
15 | * @return
16 | */
17 | public static int compileVertexShader(String shaderCode){
18 | return compileShader(GLES20.GL_VERTEX_SHADER,shaderCode);
19 | }
20 |
21 | /**
22 | * 编译片元着色器
23 | * @param shaderCode
24 | * @return
25 | */
26 | public static int compileFragmentShader(String shaderCode){
27 | return compileShader(GLES20.GL_FRAGMENT_SHADER,shaderCode);
28 | }
29 |
30 | private static int compileShader(int type ,String shaderCode){
31 | //创建着色器 获取着色器对象的id
32 | final int shaderObjectId=GLES20.glCreateShader(type);
33 | if(shaderObjectId==0){
34 | if(LogConfig.ON){
35 | Log.w(TAG,"无法创建新的shader");
36 | }
37 | return 0;
38 | }
39 | //上传和编译着色器的源码
40 | GLES20.glShaderSource(shaderObjectId, shaderCode);
41 | GLES20.glCompileShader(shaderObjectId);
42 |
43 | final int[] compileStatus=new int[1];
44 | GLES20.glGetShaderiv(shaderObjectId,GLES20.GL_COMPILE_STATUS,compileStatus,0);
45 | if(LogConfig.ON){
46 | Log.v(TAG,"编译源码的结果是:"+GLES20.glGetShaderInfoLog(shaderObjectId));
47 |
48 | }
49 |
50 | if(compileStatus[0]==0){
51 | GLES20.glDeleteShader(shaderObjectId);
52 | return 0;
53 | }
54 |
55 | return shaderObjectId;
56 | }
57 |
58 | public static int linkProgram(int vertexShaderId ,int fragmentShaderId){
59 | final int programObjectId=GLES20.glCreateProgram();
60 | if(programObjectId==0){
61 | if(LogConfig.ON){
62 | Log.w(TAG,"无法创建新的程序");
63 | }
64 | return 0;
65 | }
66 | //绑定顶点着色器和片元着色器
67 | GLES20.glAttachShader(programObjectId,vertexShaderId);
68 | GLES20.glAttachShader(programObjectId, fragmentShaderId);
69 |
70 | GLES20.glLinkProgram(programObjectId);
71 | final int[] linkStatus =new int[1];
72 | GLES20.glGetProgramiv(programObjectId, GLES20.GL_LINK_STATUS, linkStatus, 0);
73 | if(LogConfig.ON){
74 | Log.v(TAG,"程序连接结果是:"+GLES20.glGetProgramInfoLog(programObjectId));
75 | }
76 |
77 | if(linkStatus[0]==0){
78 | GLES20.glDeleteProgram(programObjectId);
79 | if(LogConfig.ON){
80 | Log.w(TAG,"连接程序失败");
81 | }
82 | return 0;
83 | }
84 | return programObjectId;
85 | }
86 |
87 |
88 | /**
89 | * 检验当前的程序是否低效 无法运行
90 | * @param programPbjectId
91 | * @return
92 | */
93 | public static boolean validateProgram(int programPbjectId){
94 | GLES20.glValidateProgram(programPbjectId);
95 | final int [] validateStatus=new int[1];
96 | GLES20.glGetProgramiv(programPbjectId,GLES20.GL_VALIDATE_STATUS,validateStatus,0);
97 | Log.v(TAG,"更新程序状态:"+validateStatus[0]+"\nLog"+GLES20.glGetProgramInfoLog(programPbjectId));
98 | return validateStatus[0]!=0;
99 | }
100 |
101 |
102 | /**
103 | * 链接顶点着色器和片段着色器,返回程序id
104 | * @param vertexShaderSource
105 | * @param fragmentShaderSource
106 | * @return
107 | */
108 | public static int buildProgram(String vertexShaderSource,String fragmentShaderSource){
109 | int program;
110 | int vertexShader=compileVertexShader(vertexShaderSource);
111 | int fragmentShader=compileFragmentShader(fragmentShaderSource);
112 | program=linkProgram(vertexShader,fragmentShader);
113 |
114 | if (LogConfig.ON){
115 | validateProgram(program);
116 | }
117 | return program;
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/lesson2/src/main/java/com/opengl/youyang/lesson2/ShaderProgram.java:
--------------------------------------------------------------------------------
1 | package com.opengl.youyang.lesson2;
2 |
3 | import android.content.Context;
4 | import android.opengl.GLES20;
5 | /**
6 | * Created by youyang on 15-4-18.
7 | */
8 | public class ShaderProgram {
9 | //uniform 常量
10 | protected static final String U_COLOR = "uColor";
11 |
12 | //attribute常量
13 | protected static final String A_POSITION = "a_Position";
14 |
15 | protected final int mProgram;
16 |
17 | protected ShaderProgram(Context context, int vertexShaderResourceId, int fragmentShaderResourceId) {
18 | mProgram = ShaderHelper.buildProgram(TextResourceReader.readTextResourceFromRaw(context,
19 | vertexShaderResourceId), TextResourceReader.readTextResourceFromRaw(context,
20 | fragmentShaderResourceId));
21 | }
22 |
23 | public void useProgram(){
24 | GLES20.glUseProgram(mProgram);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/lesson2/src/main/java/com/opengl/youyang/lesson2/TextResourceReader.java:
--------------------------------------------------------------------------------
1 | package com.opengl.youyang.lesson2;
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 |
--------------------------------------------------------------------------------
/lesson2/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
17 |
18 |
--------------------------------------------------------------------------------
/lesson2/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/lesson2/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/lesson2/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/lesson2/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/lesson2/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/lesson2/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/lesson2/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/lesson2/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/lesson2/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/lesson2/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/lesson2/src/main/res/raw/point_fragment_shader.glsl:
--------------------------------------------------------------------------------
1 | precision mediump float;
2 | uniform vec4 uColor;
3 | void main() {
4 | gl_FragColor = uColor;
5 | }
6 |
--------------------------------------------------------------------------------
/lesson2/src/main/res/raw/point_vertext_shader.glsl:
--------------------------------------------------------------------------------
1 | attribute vec2 a_Position;
2 | void main() {
3 | gl_Position = vec4(a_Position,0.0,1.0);
4 | gl_PointSize = 50.0;
5 | }
6 |
--------------------------------------------------------------------------------
/lesson2/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/lesson2/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/lesson2/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/lesson2/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Lesson2
3 |
4 |
--------------------------------------------------------------------------------
/lesson2/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/lesson2/src/test/java/com/opengl/youyang/lesson2/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.opengl.youyang.lesson2;
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 view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------
/lesson3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/lesson3.png
--------------------------------------------------------------------------------
/lesson3/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/lesson3/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 14
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 |
--------------------------------------------------------------------------------
/lesson3/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 |
--------------------------------------------------------------------------------
/lesson3/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 | }
--------------------------------------------------------------------------------
/lesson3/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/lesson3/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 |
13 | public ColorShaderProgram(Context context){
14 | super(context,R.raw.point_vertext_shader,R.raw.point_fragment_shader);
15 | //获取对应的着色器里的变量
16 | u_ColorLocation= GLES20.glGetUniformLocation(mProgram,U_COLOR);
17 | aPositionLocation=GLES20.glGetAttribLocation(mProgram,A_POSITION);
18 | }
19 |
20 | /**
21 | * 控制片元着色器里的颜色值
22 | * @param r
23 | * @param g
24 | * @param b
25 | */
26 | public void setUniforms(float r,float g,float b){
27 | GLES20.glUniform4f(u_ColorLocation,r,g,b,1f);
28 | }
29 |
30 | /**
31 | * 获取着色器里的变量的句柄
32 | * @return
33 | */
34 | public int getPositionAttributionLocation(){
35 | return aPositionLocation;
36 | }
37 |
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/lesson3/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 |
--------------------------------------------------------------------------------
/lesson3/src/main/java/com/opengl/youyang/myapplication/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.opengl.youyang.myapplication;
2 |
3 | import android.app.ActivityManager;
4 | import android.content.Context;
5 | import android.opengl.GLSurfaceView;
6 | import android.os.Bundle;
7 | import android.support.v7.app.AppCompatActivity;
8 | import android.widget.Toast;
9 |
10 | /**
11 | * 着色器 是 软件与GPU硬件的桥梁,可以通过着色器去控制GPU去进行高性能的绘制。
12 | * 如果不使用着色器,我们就只能通过cpu去进行渲染,两者的效率天差地别。
13 | *
14 | * 这节课开始接触着色器,用着色器 绘制一个普通的顶点Point
15 | * 1.学会写简单的着色器
16 | * 2.了解如何加载着色器
17 | * 3.学会如何在java代码中动态给着色器的属性赋值
18 | */
19 |
20 | public class MainActivity extends AppCompatActivity {
21 |
22 | GLSurfaceView view;
23 |
24 | @Override
25 | protected void onCreate(Bundle savedInstanceState) {
26 |
27 | super.onCreate(savedInstanceState);
28 | view = new GLSurfaceView(this);
29 |
30 | //第一步 检验是否支持opengl 2.0
31 | final boolean isSuppotES2 = isSupportES2();
32 | //第二步创建渲染器
33 | final PointRender render = new PointRender(this);
34 |
35 | if (isSuppotES2) {
36 | //设定egl版本
37 | view.setEGLContextClientVersion(2);
38 | //设置渲染器,设置完这一步之后相当于开启了 另一条渲染线程
39 | view.setRenderer(render);
40 | //设置渲染模式 一直渲染
41 | view.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
42 | } else {
43 | Toast.makeText(this, "该手机不支持opengl es 2.0", Toast.LENGTH_LONG).show();
44 | return;
45 | }
46 | setContentView(view);
47 | }
48 |
49 |
50 | @Override
51 | protected void onResume() {
52 | super.onResume();
53 | view.onResume();
54 | }
55 |
56 | @Override
57 | protected void onPause() {
58 | super.onPause();
59 | view.onPause();
60 | }
61 |
62 | /**
63 | * 检验是否支持opengl 2.0
64 | */
65 | private boolean isSupportES2() {
66 | return ((ActivityManager) getSystemService(Context.ACTIVITY_SERVICE))
67 | .getDeviceConfigurationInfo().reqGlEsVersion >= 0x20000;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/lesson3/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 |
7 | import java.nio.ByteBuffer;
8 | import java.nio.ByteOrder;
9 | import java.nio.FloatBuffer;
10 |
11 | import javax.microedition.khronos.egl.EGLConfig;
12 | import javax.microedition.khronos.opengles.GL10;
13 |
14 | /**
15 | * Created by youyang on 16/5/24.
16 | */
17 | public class PointRender implements GLSurfaceView.Renderer {
18 |
19 | private FloatBuffer mFloatBuffer;
20 |
21 | private Context mContext;
22 |
23 | public PointRender(Context context){
24 | mContext = context;
25 | }
26 |
27 | // float[] mVertex = new float[]{
28 | // 0f,0f
29 | // } ;
30 |
31 | float aPoint = 0.8f;
32 | float[] mVertex = new float[]{
33 | -aPoint,aPoint,
34 | -aPoint,-aPoint,
35 | aPoint,-aPoint,
36 |
37 | aPoint,-aPoint,
38 | aPoint,aPoint,
39 | -aPoint,aPoint
40 |
41 | } ;
42 |
43 | private ColorShaderProgram mColorShaderProgram;
44 |
45 | @Override
46 | public void onSurfaceCreated(GL10 gl, EGLConfig config) {
47 | GLES20.glClearColor(0.0f,0.5f,0.3f,0.4f);
48 |
49 | mColorShaderProgram = new ColorShaderProgram(mContext);
50 |
51 | mFloatBuffer = ByteBuffer.allocateDirect(mVertex.length*4).order(ByteOrder.nativeOrder())
52 | .asFloatBuffer().put(mVertex);
53 | mFloatBuffer.position(0);
54 |
55 | mColorShaderProgram.useProgram();
56 | mColorShaderProgram.setUniforms(0.9f,0.4f,0.9f);
57 |
58 | GLES20.glVertexAttribPointer(mColorShaderProgram.getPositionAttributionLocation(),2,GLES20.GL_FLOAT,false,2*4,mFloatBuffer);
59 | GLES20.glEnableVertexAttribArray(mColorShaderProgram.getPositionAttributionLocation());
60 | // mFloatBuffer.position(0);
61 |
62 |
63 | }
64 |
65 | @Override
66 | public void onSurfaceChanged(GL10 gl, int width, int height) {
67 | //设置显示区域大小和位置
68 | GLES20.glViewport(0,0,width,height);
69 | }
70 |
71 | @Override
72 | public void onDrawFrame(GL10 gl) {
73 | GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
74 |
75 | // 最终的绘制方法
76 | // GLES20.glDrawArrays(GLES20.GL_POINTS,0,1);
77 | GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP,0,6);
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/lesson3/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 | /**
13 | * 编译顶点着色器
14 | * @param shaderCode
15 | * @return
16 | */
17 | public static int compileVertexShader(String shaderCode){
18 | return compileShader(GLES20.GL_VERTEX_SHADER,shaderCode);
19 | }
20 |
21 | /**
22 | * 编译片元着色器
23 | * @param shaderCode
24 | * @return
25 | */
26 | public static int compileFragmentShader(String shaderCode){
27 | return compileShader(GLES20.GL_FRAGMENT_SHADER,shaderCode);
28 | }
29 |
30 | private static int compileShader(int type ,String shaderCode){
31 | //创建着色器 获取着色器对象的id
32 | final int shaderObjectId=GLES20.glCreateShader(type);
33 | if(shaderObjectId==0){
34 | if(LogConfig.ON){
35 | Log.w(TAG,"无法创建新的shader");
36 | }
37 | return 0;
38 | }
39 | //上传和编译着色器的源码
40 | GLES20.glShaderSource(shaderObjectId, shaderCode);
41 | GLES20.glCompileShader(shaderObjectId);
42 |
43 | final int[] compileStatus=new int[1];
44 | GLES20.glGetShaderiv(shaderObjectId,GLES20.GL_COMPILE_STATUS,compileStatus,0);
45 | if(LogConfig.ON){
46 | Log.v(TAG,"编译源码的结果是:"+GLES20.glGetShaderInfoLog(shaderObjectId));
47 |
48 | }
49 |
50 | if(compileStatus[0]==0){
51 | GLES20.glDeleteShader(shaderObjectId);
52 | return 0;
53 | }
54 |
55 | return shaderObjectId;
56 | }
57 |
58 | public static int linkProgram(int vertexShaderId ,int fragmentShaderId){
59 | final int programObjectId=GLES20.glCreateProgram();
60 | if(programObjectId==0){
61 | if(LogConfig.ON){
62 | Log.w(TAG,"无法创建新的程序");
63 | }
64 | return 0;
65 | }
66 | //绑定顶点着色器和片元着色器
67 | GLES20.glAttachShader(programObjectId,vertexShaderId);
68 | GLES20.glAttachShader(programObjectId, fragmentShaderId);
69 |
70 | GLES20.glLinkProgram(programObjectId);
71 | final int[] linkStatus =new int[1];
72 | GLES20.glGetProgramiv(programObjectId, GLES20.GL_LINK_STATUS, linkStatus, 0);
73 | if(LogConfig.ON){
74 | Log.v(TAG,"程序连接结果是:"+GLES20.glGetProgramInfoLog(programObjectId));
75 | }
76 |
77 | if(linkStatus[0]==0){
78 | GLES20.glDeleteProgram(programObjectId);
79 | if(LogConfig.ON){
80 | Log.w(TAG,"连接程序失败");
81 | }
82 | return 0;
83 | }
84 | return programObjectId;
85 | }
86 |
87 |
88 | /**
89 | * 检验当前的程序是否低效 无法运行
90 | * @param programPbjectId
91 | * @return
92 | */
93 | public static boolean validateProgram(int programPbjectId){
94 | GLES20.glValidateProgram(programPbjectId);
95 | final int [] validateStatus=new int[1];
96 | GLES20.glGetProgramiv(programPbjectId,GLES20.GL_VALIDATE_STATUS,validateStatus,0);
97 | Log.v(TAG,"更新程序状态:"+validateStatus[0]+"\nLog"+GLES20.glGetProgramInfoLog(programPbjectId));
98 | return validateStatus[0]!=0;
99 | }
100 |
101 |
102 | /**
103 | * 链接顶点着色器和片段着色器,返回程序id
104 | * @param vertexShaderSource
105 | * @param fragmentShaderSource
106 | * @return
107 | */
108 | public static int buildProgram(String vertexShaderSource,String fragmentShaderSource){
109 | int program;
110 | int vertexShader=compileVertexShader(vertexShaderSource);
111 | int fragmentShader=compileFragmentShader(fragmentShaderSource);
112 | program=linkProgram(vertexShader,fragmentShader);
113 |
114 | if (LogConfig.ON){
115 | validateProgram(program);
116 | }
117 | return program;
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/lesson3/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 |
13 | //attribute常量
14 | protected static final String A_POSITION = "a_Position";
15 |
16 | protected final int mProgram;
17 |
18 | protected ShaderProgram(Context context, int vertexShaderResourceId, int fragmentShaderResourceId) {
19 | mProgram = ShaderHelper.buildProgram(TextResourceReader.readTextResourceFromRaw(context,
20 | vertexShaderResourceId), TextResourceReader.readTextResourceFromRaw(context,
21 | fragmentShaderResourceId));
22 | }
23 |
24 | public void useProgram(){
25 | GLES20.glUseProgram(mProgram);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/lesson3/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 |
--------------------------------------------------------------------------------
/lesson3/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
17 |
18 |
--------------------------------------------------------------------------------
/lesson3/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/lesson3/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/lesson3/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/lesson3/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/lesson3/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/lesson3/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/lesson3/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/lesson3/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/lesson3/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/lesson3/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/lesson3/src/main/res/raw/point_fragment_shader.glsl:
--------------------------------------------------------------------------------
1 | precision mediump float;
2 | uniform vec4 uColor;
3 | void main() {
4 | gl_FragColor = uColor;
5 | }
6 |
--------------------------------------------------------------------------------
/lesson3/src/main/res/raw/point_vertext_shader.glsl:
--------------------------------------------------------------------------------
1 | attribute vec2 a_Position;
2 | void main() {
3 | gl_Position = vec4(a_Position,0.0,1.0);
4 | gl_PointSize = 50.0;
5 | }
6 |
--------------------------------------------------------------------------------
/lesson3/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/lesson3/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/lesson3/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/lesson3/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Lesson3
3 |
4 |
--------------------------------------------------------------------------------
/lesson3/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/lesson3/src/test/java/com/opengl/youyang/myapplication/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.opengl.youyang.myapplication;
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 view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------
/lesson4.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/lesson4.gif
--------------------------------------------------------------------------------
/lesson5.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/lesson5.gif
--------------------------------------------------------------------------------
/lesson5/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/lesson5/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.lesson5"
9 | minSdkVersion 14
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 |
--------------------------------------------------------------------------------
/lesson5/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 |
--------------------------------------------------------------------------------
/lesson5/src/androidTest/java/com/opengl/youyang/lesson5/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.opengl.youyang.lesson5;
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 | }
--------------------------------------------------------------------------------
/lesson5/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/lesson5/src/main/java/com/opengl/youyang/lesson5/ColorShaderProgram.java:
--------------------------------------------------------------------------------
1 | package com.opengl.youyang.lesson5;
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 aTextureCoordLocation;
13 |
14 | public ColorShaderProgram(Context context){
15 | super(context,R.raw.point_vertext_shader,R.raw.point_fragment_shader);
16 | //获取对应的着色器里的变量
17 | u_ColorLocation= GLES20.glGetUniformLocation(mProgram,U_COLOR);
18 | aPositionLocation=GLES20.glGetAttribLocation(mProgram,A_POSITION);
19 | aTextureCoordLocation=GLES20.glGetAttribLocation(mProgram,A_TEXTURECOORD);
20 | }
21 |
22 | /**
23 | * 控制片元着色器里的颜色值
24 | */
25 | public void setUniforms(){
26 | // GLES20.glUniform4f(u_ColorLocation,r,g,b,1f);
27 | GLES20.glUniform1i(u_ColorLocation, 0);
28 |
29 | }
30 |
31 | /**
32 | * 获取着色器里的变量的句柄
33 | * @return
34 | */
35 | public int getPositionAttributionLocation(){
36 | return aPositionLocation;
37 | }
38 |
39 | /**
40 | * 获取着色器里 纹理映射的变量的句柄
41 | * @return
42 | */
43 | public int getTextureCoordAttributionLocation(){
44 | return aTextureCoordLocation;
45 | }
46 |
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/lesson5/src/main/java/com/opengl/youyang/lesson5/LogConfig.java:
--------------------------------------------------------------------------------
1 | package com.opengl.youyang.lesson5;
2 |
3 | /**
4 | * Created by youyang on 15-4-13.
5 | */
6 | public class LogConfig {
7 | public static final boolean ON=true;
8 | }
9 |
--------------------------------------------------------------------------------
/lesson5/src/main/java/com/opengl/youyang/lesson5/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.opengl.youyang.lesson5;
2 |
3 | import android.Manifest;
4 | import android.annotation.TargetApi;
5 | import android.app.ActivityManager;
6 | import android.content.Context;
7 | import android.content.pm.PackageManager;
8 | import android.opengl.GLSurfaceView;
9 | import android.os.Build;
10 | import android.os.Bundle;
11 | import android.support.v7.app.AppCompatActivity;
12 | import android.widget.Toast;
13 |
14 | import java.util.ArrayList;
15 | import java.util.List;
16 |
17 | /**
18 | * 着色器 是 软件与GPU硬件的桥梁,可以通过着色器去控制GPU去进行高性能的绘制。 如果不使用着色器,我们就只能通过cpu去进行渲染,两者的效率天差地别。
19 | *
20 | * 这节课开始接触着色器,用着色器 绘制一个普通的顶点Point 1.学会写简单的着色器 2.了解如何加载着色器 3.学会如何在java代码中动态给着色器的属性赋值
21 | */
22 |
23 | public class MainActivity extends AppCompatActivity implements ViewListener {
24 |
25 | GLSurfaceView view;
26 |
27 | @Override
28 | protected void onCreate(Bundle savedInstanceState) {
29 |
30 | super.onCreate(savedInstanceState);
31 | // checkPermission();
32 | requestCameraPermission();
33 | view = new GLSurfaceView(this);
34 |
35 | //第一步 检验是否支持opengl 2.0
36 | final boolean isSuppotES2 = isSupportES2();
37 | //第二步创建渲染器
38 | final PreviewGLRender render = new PreviewGLRender(this);
39 | render.setListener(this);
40 | if (isSuppotES2) {
41 | //设定egl版本
42 | view.setEGLContextClientVersion(2);
43 | //设置渲染器,设置完这一步之后相当于开启了 另一条渲染线程
44 | view.setRenderer(render);
45 | //设置渲染模式 一直渲染
46 | view.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
47 | } else {
48 | Toast.makeText(this, "该手机不支持opengl es 2.0", Toast.LENGTH_LONG).show();
49 | return;
50 | }
51 | setContentView(view);
52 | }
53 |
54 | void checkPermission() {
55 | final List permissionsList = new ArrayList<>();
56 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
57 | if ((checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED))
58 | permissionsList.add(Manifest.permission.CAMERA);
59 | }
60 | }
61 |
62 |
63 |
64 | private static final int REQUEST_PERMISSION_CAMERA_CODE = 1;
65 | @TargetApi(Build.VERSION_CODES.M)
66 | private void requestCameraPermission() {
67 | requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_PERMISSION_CAMERA_CODE);
68 | }
69 |
70 | @Override
71 | public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
72 | super.onRequestPermissionsResult(requestCode, permissions, grantResults);
73 | if (requestCode == REQUEST_PERMISSION_CAMERA_CODE) {
74 | int grantResult = grantResults[0];
75 | boolean granted = grantResult == PackageManager.PERMISSION_GRANTED;
76 | }
77 | }
78 |
79 |
80 |
81 | @Override
82 | protected void onResume() {
83 | super.onResume();
84 | view.onResume();
85 | }
86 |
87 | @Override
88 | protected void onPause() {
89 | super.onPause();
90 | view.onPause();
91 | }
92 |
93 | /**
94 | * 检验是否支持opengl 2.0
95 | */
96 | private boolean isSupportES2() {
97 | return ((ActivityManager) getSystemService(Context.ACTIVITY_SERVICE))
98 | .getDeviceConfigurationInfo().reqGlEsVersion >= 0x20000;
99 | }
100 |
101 | @Override
102 | public void requestRender() {
103 | view.requestRender();
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/lesson5/src/main/java/com/opengl/youyang/lesson5/PreviewGLRender.java:
--------------------------------------------------------------------------------
1 | package com.opengl.youyang.lesson5;
2 |
3 | import android.annotation.TargetApi;
4 | import android.content.Context;
5 | import android.graphics.SurfaceTexture;
6 | import android.hardware.Camera;
7 | import android.opengl.GLES20;
8 | import android.opengl.GLSurfaceView;
9 | import android.os.Build;
10 |
11 | import java.io.IOException;
12 | import java.nio.ByteBuffer;
13 | import java.nio.ByteOrder;
14 | import java.nio.FloatBuffer;
15 |
16 | import javax.microedition.khronos.egl.EGLConfig;
17 | import javax.microedition.khronos.opengles.GL10;
18 |
19 | /**
20 | * Created by youyang on 16/5/24.
21 | */
22 | @TargetApi(Build.VERSION_CODES.HONEYCOMB)
23 | public class PreviewGLRender implements GLSurfaceView.Renderer, SurfaceTexture.OnFrameAvailableListener {
24 |
25 | private FloatBuffer mFloatBuffer;
26 |
27 | private ViewListener mViewListener;
28 |
29 | private Context mContext;
30 | private FloatBuffer mTextureBuffer;
31 | Camera mCamera;
32 | SurfaceTexture mSurfaceTexture;
33 | private ViewListener mListener;
34 |
35 | public PreviewGLRender(Context context) {
36 | mContext = context;
37 | }
38 |
39 | // float[] mVertex = new float[]{
40 | // 0f,0f
41 | // } ;
42 |
43 | float aPoint = 0.8f;
44 | float[] mVertex = new float[]{
45 | -aPoint, aPoint,
46 | -aPoint, -aPoint,
47 | aPoint, -aPoint,
48 |
49 | aPoint, -aPoint,
50 | aPoint, aPoint,
51 | -aPoint, aPoint
52 |
53 | };
54 |
55 | float[] mTextureCoord = new float[]{
56 |
57 | 0f, 1f, //1
58 | 1f, 1f, //2
59 | 1f, 0f, //3
60 |
61 | 1f, 0f, //3
62 | 0f, 0f, //0
63 | 0f, 1f //1
64 |
65 | };
66 |
67 | private ColorShaderProgram mColorShaderProgram;
68 |
69 | @TargetApi(Build.VERSION_CODES.HONEYCOMB)
70 | @Override
71 | public void onSurfaceCreated(GL10 gl, EGLConfig config) {
72 |
73 |
74 | mCamera = Camera.open();
75 |
76 | GLES20.glClearColor(0.0f, 0.5f, 0.3f, 0.4f);
77 |
78 | mColorShaderProgram = new ColorShaderProgram(mContext);
79 |
80 | mFloatBuffer = ByteBuffer.allocateDirect(mVertex.length * 4).order(ByteOrder.nativeOrder())
81 | .asFloatBuffer().put(mVertex);
82 | mTextureBuffer = ByteBuffer.allocateDirect(mTextureCoord.length * 4).order(ByteOrder.nativeOrder())
83 | .asFloatBuffer().put(mTextureCoord);
84 | mFloatBuffer.position(0);
85 | mTextureBuffer.position(0);
86 |
87 | mColorShaderProgram.useProgram();
88 |
89 | mSurfaceTexture = new SurfaceTexture(TextureHelper.loadTexture());
90 | mColorShaderProgram.setUniforms();
91 |
92 | mSurfaceTexture.setOnFrameAvailableListener(this);
93 | try {
94 | mCamera.setPreviewTexture(mSurfaceTexture);
95 | } catch (IOException e) {
96 | e.printStackTrace();
97 | }
98 | mCamera.startPreview();
99 |
100 |
101 | GLES20.glVertexAttribPointer(mColorShaderProgram.getPositionAttributionLocation(), 2, GLES20.GL_FLOAT, false, 2 * 4, mFloatBuffer);
102 | GLES20.glEnableVertexAttribArray(mColorShaderProgram.getPositionAttributionLocation());
103 | // mFloatBuffer.position(0);
104 | GLES20.glEnableVertexAttribArray(mColorShaderProgram.getTextureCoordAttributionLocation());
105 | GLES20.glVertexAttribPointer(mColorShaderProgram.getTextureCoordAttributionLocation(), 2, GLES20.GL_FLOAT, false, 2 * 4, mTextureBuffer);
106 | }
107 |
108 |
109 | @Override
110 | public void onFrameAvailable(SurfaceTexture surfaceTexture) {
111 | mListener.requestRender();
112 | }
113 |
114 |
115 | @Override
116 | public void onSurfaceChanged(GL10 gl, int width, int height) {
117 | //设置显示区域大小和位置
118 | GLES20.glViewport(0, 0, width, height);
119 | }
120 |
121 | @Override
122 | public void onDrawFrame(GL10 gl) {
123 | GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
124 |
125 | mSurfaceTexture.updateTexImage();
126 | GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, 6);
127 | // 最终的绘制方法
128 | // GLES20.glDrawArrays(GLES20.GL_POINTS,0,1);
129 | // GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP,0,6);
130 | }
131 |
132 | public void setListener(ViewListener listener) {
133 | mListener = listener;
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/lesson5/src/main/java/com/opengl/youyang/lesson5/ShaderHelper.java:
--------------------------------------------------------------------------------
1 | package com.opengl.youyang.lesson5;
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 | /**
13 | * 编译顶点着色器
14 | * @param shaderCode
15 | * @return
16 | */
17 | public static int compileVertexShader(String shaderCode){
18 | return compileShader(GLES20.GL_VERTEX_SHADER,shaderCode);
19 | }
20 |
21 | /**
22 | * 编译片元着色器
23 | * @param shaderCode
24 | * @return
25 | */
26 | public static int compileFragmentShader(String shaderCode){
27 | return compileShader(GLES20.GL_FRAGMENT_SHADER,shaderCode);
28 | }
29 |
30 | private static int compileShader(int type ,String shaderCode){
31 | //创建着色器 获取着色器对象的id
32 | final int shaderObjectId=GLES20.glCreateShader(type);
33 | if(shaderObjectId==0){
34 | if(LogConfig.ON){
35 | Log.w(TAG,"无法创建新的shader");
36 | }
37 | return 0;
38 | }
39 | //上传和编译着色器的源码
40 | GLES20.glShaderSource(shaderObjectId, shaderCode);
41 | GLES20.glCompileShader(shaderObjectId);
42 |
43 | final int[] compileStatus=new int[1];
44 | GLES20.glGetShaderiv(shaderObjectId,GLES20.GL_COMPILE_STATUS,compileStatus,0);
45 | if(LogConfig.ON){
46 | Log.v(TAG,"编译源码的结果是:"+GLES20.glGetShaderInfoLog(shaderObjectId));
47 |
48 | }
49 |
50 | if(compileStatus[0]==0){
51 | GLES20.glDeleteShader(shaderObjectId);
52 | return 0;
53 | }
54 |
55 | return shaderObjectId;
56 | }
57 |
58 | public static int linkProgram(int vertexShaderId ,int fragmentShaderId){
59 | final int programObjectId=GLES20.glCreateProgram();
60 | if(programObjectId==0){
61 | if(LogConfig.ON){
62 | Log.w(TAG,"无法创建新的程序");
63 | }
64 | return 0;
65 | }
66 | //绑定顶点着色器和片元着色器
67 | GLES20.glAttachShader(programObjectId,vertexShaderId);
68 | GLES20.glAttachShader(programObjectId, fragmentShaderId);
69 |
70 | GLES20.glLinkProgram(programObjectId);
71 | final int[] linkStatus =new int[1];
72 | GLES20.glGetProgramiv(programObjectId, GLES20.GL_LINK_STATUS, linkStatus, 0);
73 | if(LogConfig.ON){
74 | Log.v(TAG,"程序连接结果是:"+GLES20.glGetProgramInfoLog(programObjectId));
75 | }
76 |
77 | if(linkStatus[0]==0){
78 | GLES20.glDeleteProgram(programObjectId);
79 | if(LogConfig.ON){
80 | Log.w(TAG,"连接程序失败");
81 | }
82 | return 0;
83 | }
84 | return programObjectId;
85 | }
86 |
87 |
88 | /**
89 | * 检验当前的程序是否低效 无法运行
90 | * @param programPbjectId
91 | * @return
92 | */
93 | public static boolean validateProgram(int programPbjectId){
94 | GLES20.glValidateProgram(programPbjectId);
95 | final int [] validateStatus=new int[1];
96 | GLES20.glGetProgramiv(programPbjectId,GLES20.GL_VALIDATE_STATUS,validateStatus,0);
97 | Log.v(TAG,"更新程序状态:"+validateStatus[0]+"\nLog"+GLES20.glGetProgramInfoLog(programPbjectId));
98 | return validateStatus[0]!=0;
99 | }
100 |
101 |
102 | /**
103 | * 链接顶点着色器和片段着色器,返回程序id
104 | * @param vertexShaderSource
105 | * @param fragmentShaderSource
106 | * @return
107 | */
108 | public static int buildProgram(String vertexShaderSource,String fragmentShaderSource){
109 | int program;
110 | int vertexShader=compileVertexShader(vertexShaderSource);
111 | int fragmentShader=compileFragmentShader(fragmentShaderSource);
112 | program=linkProgram(vertexShader,fragmentShader);
113 |
114 | if (LogConfig.ON){
115 | validateProgram(program);
116 | }
117 | return program;
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/lesson5/src/main/java/com/opengl/youyang/lesson5/ShaderProgram.java:
--------------------------------------------------------------------------------
1 | package com.opengl.youyang.lesson5;
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 = "sTexture";
12 |
13 | //attribute常量
14 | protected static final String A_POSITION = "a_Position";
15 |
16 | protected static final String A_TEXTURECOORD = "aTextureCoord";
17 |
18 | protected final int mProgram;
19 |
20 | protected ShaderProgram(Context context, int vertexShaderResourceId, int fragmentShaderResourceId) {
21 | mProgram = ShaderHelper.buildProgram(TextResourceReader.readTextResourceFromRaw(context,
22 | vertexShaderResourceId), TextResourceReader.readTextResourceFromRaw(context,
23 | fragmentShaderResourceId));
24 | }
25 |
26 | public void useProgram(){
27 | GLES20.glUseProgram(mProgram);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/lesson5/src/main/java/com/opengl/youyang/lesson5/TextResourceReader.java:
--------------------------------------------------------------------------------
1 | package com.opengl.youyang.lesson5;
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 |
--------------------------------------------------------------------------------
/lesson5/src/main/java/com/opengl/youyang/lesson5/TextureHelper.java:
--------------------------------------------------------------------------------
1 | package com.opengl.youyang.lesson5;
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.GLES11Ext;
8 | import android.opengl.GLES20;
9 | import android.opengl.GLUtils;
10 | import android.util.Log;
11 |
12 | /**
13 | * Created by youyang on 15-4-17.
14 | */
15 | public class TextureHelper {
16 | public static final String TAG = "TextureHelper";
17 |
18 | public static int loadTexture() {
19 | final int[] textureObjectIds = new int[1];
20 |
21 | GLES20.glGenTextures(1, textureObjectIds, 0);
22 | GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
23 |
24 |
25 | GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureObjectIds[0]);
26 |
27 | GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
28 | GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
29 |
30 | GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
31 | GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
32 |
33 |
34 | // GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
35 | // GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
36 | // GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
37 | // GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
38 | // GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
39 | // GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
40 | // GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
41 | // GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
42 | //解除绑定
43 | // GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0);
44 |
45 |
46 | return textureObjectIds[0];
47 | }
48 |
49 | /**
50 | * Calculates the next highest power of two for a given integer.
51 | */
52 | private static int getNextHighestPO2(int n) {
53 | n -= 1;
54 | n = n | (n >> 1);
55 | n = n | (n >> 2);
56 | n = n | (n >> 4);
57 | n = n | (n >> 8);
58 | n = n | (n >> 16);
59 | n = n | (n >> 32);
60 | return n + 1;
61 | }
62 |
63 | /**
64 | * Generates nearest power of two sized Bitmap for give Bitmap. Returns this new Bitmap using
65 | * default return statement + original texture coordinates are stored into RectF.
66 | */
67 | private static Bitmap getTexture(Bitmap bitmap) {
68 | // Bitmap original size.
69 | int w = bitmap.getWidth();
70 | int h = bitmap.getHeight();
71 | // Bitmap size expanded to next power of two. This is done due to
72 | // the requirement on many devices, texture width and height should
73 | // be power of two.
74 | int newW = getNextHighestPO2(w);
75 | int newH = getNextHighestPO2(h);
76 |
77 | // TODO: Is there another way to create a bigger Bitmap and copy
78 | // original Bitmap to it more efficiently? Immutable bitmap anyone?
79 | Bitmap bitmapTex = Bitmap.createBitmap(newW, newH, bitmap.getConfig());
80 | Canvas c = new Canvas(bitmapTex);
81 | c.drawBitmap(bitmap, 0, 0, null);
82 |
83 | // Calculate final texture coordinates.
84 | float texX = (float) w / newW;
85 | float texY = (float) h / newH;
86 | return bitmapTex;
87 | }
88 |
89 | public static int loadCubeMap(Context context, int[] cubeResource) {
90 | final int[] textureObjectIds = new int[1];
91 | GLES20.glGenTextures(1, textureObjectIds, 0);
92 | if (textureObjectIds[0] == 0) {
93 | if (LogConfig.ON) {
94 | Log.w(TAG, "无法生成一个纹理对象");
95 | }
96 | return 0;
97 | }
98 | final BitmapFactory.Options options = new BitmapFactory.Options();
99 | options.inScaled = false;
100 | final Bitmap[] cubeBitmaps = new Bitmap[6];
101 |
102 | for (int i = 0; i < 6; i++) {
103 | cubeBitmaps[i] = BitmapFactory.decodeResource(context.getResources(), cubeResource[i], options);
104 |
105 | if (cubeBitmaps[i] == null) {
106 | if (LogConfig.ON) {
107 | Log.w(TAG, "ResourceId:" + cubeResource[i] + "无法加载纹理");
108 | }
109 | GLES20.glDeleteTextures(1, textureObjectIds, 0);
110 | return 0;
111 | }
112 | }
113 |
114 | GLES20.glBindTexture(GLES20.GL_TEXTURE_CUBE_MAP, textureObjectIds[0]);
115 | GLES20.glTexParameteri(GLES20.GL_TEXTURE_CUBE_MAP, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
116 | GLES20.glTexParameteri(GLES20.GL_TEXTURE_CUBE_MAP, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
117 |
118 | GLUtils.texImage2D(GLES20.GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, cubeBitmaps[0], 0);
119 | GLUtils.texImage2D(GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, cubeBitmaps[1], 0);
120 |
121 | GLUtils.texImage2D(GLES20.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, cubeBitmaps[2], 0);
122 | GLUtils.texImage2D(GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, cubeBitmaps[3], 0);
123 |
124 | GLUtils.texImage2D(GLES20.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, cubeBitmaps[4], 0);
125 | GLUtils.texImage2D(GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, cubeBitmaps[5], 0);
126 |
127 | GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
128 |
129 | for (Bitmap bitmap : cubeBitmaps) {
130 | bitmap.recycle();
131 | }
132 |
133 | return textureObjectIds[0];
134 |
135 | }
136 |
137 | }
138 |
--------------------------------------------------------------------------------
/lesson5/src/main/java/com/opengl/youyang/lesson5/ViewListener.java:
--------------------------------------------------------------------------------
1 | package com.opengl.youyang.lesson5;
2 |
3 | /**
4 | * Created by youyang on 16/8/19.
5 | */
6 | public interface ViewListener {
7 | void requestRender();
8 | }
9 |
--------------------------------------------------------------------------------
/lesson5/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
17 |
18 |
--------------------------------------------------------------------------------
/lesson5/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/lesson5/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/lesson5/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/lesson5/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/lesson5/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/lesson5/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/lesson5/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/lesson5/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/lesson5/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/lesson5/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/lesson5/src/main/res/raw/point_fragment_shader.glsl:
--------------------------------------------------------------------------------
1 | #extension GL_OES_EGL_image_external : require
2 | precision mediump float;
3 | varying vec2 vTextureCoord;
4 | uniform samplerExternalOES sTexture;
5 | void main() {
6 | vec2 offset0 = vec2(-1.0,-1.0);
7 | vec2 offset1 = vec2(0.0,-1.0);
8 | vec2 offset2 = vec2(1.0,-1.0);
9 | vec2 offset3 = vec2(-1.0,0.0);
10 | vec2 offset4 = vec2(0.0,0.0);
11 | vec2 offset5 = vec2(1.0,0.0);
12 | vec2 offset6 = vec2(-1.0,1.0);
13 | vec2 offset7 = vec2(0.0,1.0);
14 | vec2 offset8 = vec2(1.0,1.0);
15 |
16 | // const float scaleFactor = 1.0/9.0;//调整亮度
17 | const float scaleFactor = 1.9;//调整亮度
18 |
19 | //边缘检测
20 | float kernelValue0 = 0.0;
21 | float kernelValue1 = 1.0;
22 | float kernelValue2 = 0.0;
23 | float kernelValue3 = 1.0;
24 | float kernelValue4 = -4.0;
25 | float kernelValue5 = 1.0;
26 | float kernelValue6 = 0.0;
27 | float kernelValue7 = 1.0;
28 | float kernelValue8 = 0.0;
29 |
30 | //浮雕效果
31 | // float kernelValue0 = 2.0;
32 | // float kernelValue1 = 0.0;
33 | // float kernelValue2 = 2.0;
34 | // float kernelValue3 = 0.0;
35 | // float kernelValue4 = 0.0;
36 | // float kernelValue5 = 0.0;
37 | // float kernelValue6 = 3.0;
38 | // float kernelValue7 = 0.0;
39 | // float kernelValue8 = -6.0;
40 |
41 | vec4 sum;
42 |
43 | vec4 cTemp0,cTemp1,cTemp2,cTemp3,cTemp4,cTemp5,cTemp6,cTemp7,cTemp8;
44 |
45 | cTemp0 = texture2D(sTexture, vTextureCoord.st + offset0.xy/512.0);
46 | cTemp1 = texture2D(sTexture, vTextureCoord.st + offset1.xy/512.0);
47 | cTemp2 = texture2D(sTexture, vTextureCoord.st + offset2.xy/512.0);
48 | cTemp3 = texture2D(sTexture, vTextureCoord.st + offset3.xy/512.0);
49 | cTemp4 = texture2D(sTexture, vTextureCoord.st + offset4.xy/512.0);
50 | cTemp5 = texture2D(sTexture, vTextureCoord.st + offset5.xy/512.0);
51 | cTemp6 = texture2D(sTexture, vTextureCoord.st + offset6.xy/512.0);
52 | cTemp7 = texture2D(sTexture, vTextureCoord.st + offset7.xy/512.0);
53 | cTemp8 = texture2D(sTexture, vTextureCoord.st + offset8.xy/512.0);
54 |
55 | //颜色求和
56 | sum = kernelValue0*cTemp0 + kernelValue1*cTemp1 +
57 | kernelValue2*cTemp2 + kernelValue3*cTemp3 + kernelValue4*cTemp4 +
58 | kernelValue5*cTemp5 + kernelValue6*cTemp6 + kernelValue7*cTemp7 + kernelValue8*cTemp8;
59 |
60 | //灰度化
61 | // float hd = (sum.r + sum.g +sum.b)/3.0;
62 |
63 | // gl_FragColor = vec4(hd) * scaleFactor;
64 | gl_FragColor = sum * scaleFactor;
65 | }
66 |
--------------------------------------------------------------------------------
/lesson5/src/main/res/raw/point_vertext_shader.glsl:
--------------------------------------------------------------------------------
1 | attribute vec2 a_Position;
2 | attribute vec2 aTextureCoord;
3 | varying vec2 vTextureCoord;
4 |
5 | void main() {
6 | gl_Position = vec4(a_Position,0.0,1.0);
7 | vTextureCoord = aTextureCoord;
8 | }
9 |
--------------------------------------------------------------------------------
/lesson5/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/lesson5/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/lesson5/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/lesson5/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Lesson5
3 |
4 |
--------------------------------------------------------------------------------
/lesson5/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/lesson5/src/test/java/com/opengl/youyang/lesson5/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.opengl.youyang.lesson5;
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 view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------
/lesson6.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lord19871207/OpenGLLessons/20f2733e7c6a288d4a0c2171694c373a0c457402/lesson6.gif
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':Lesson1', ':Lesson2', ':Lesson4', ':Lesson5', ':Lesson3', ':Lesson6'
2 |
--------------------------------------------------------------------------------