1 前言
本文将介绍基于 SurfaceControlViewHost 实现跨进程渲染普通 View 和 GlSurfaceView,力求用最简单的 Demo,介绍 SurfaceControlViewHost 的应用,方便读者轻松扣出核心代码应用到自己的业务中。
核心代码片段如下。
1)服务端- public SurfaceControlViewHost.SurfacePackage getSurfacePackage(int displayId, IBinder hostToken, int width, int height) {
- // 创建SurfaceControlViewHost
- Display display = mContext.getSystemService(DisplayManager.class).getDisplay(displayId);
- mSurfaceControlViewHost = new SurfaceControlViewHost(mContext, display, hostToken);
- // 创建要渲染的View
- mView = new CustomView(mContext);
- // 将View附加到SurfaceControlViewHost
- mSurfaceControlViewHost.setView(mView, width, height);
- SurfacePackage surfacePackage = mSurfaceControlViewHost.getSurfacePackage();
- return surfacePackage;
- }
复制代码 2)客户端- IBinder hostToken = mSurfaceView.getHostToken();
- SurfaceControlViewHost.SurfacePackage surfacePackage = mRemoteRender.getSurfacePackage(0, hostToken, 1000, 2000);
- mSurfaceView.setChildSurfacePackage(surfacePackage);
复制代码 本文案例项目结构如下,完整资源见 → 基于SurfaceControlViewHost实现跨进程渲染。
2 AIDL 配置
Android 跨进程通信可以使用 AIDL 或 messenger,它们本质都是 Binder,本文使用 AIDL 实现跨进程通信。
1)aidl 文件- // IRemoteRender.aidl
- package com.zhyan8.remoterender;
- import android.view.SurfaceControlViewHost.SurfacePackage;
- import android.os.IBinder;
- interface IRemoteRender {
- SurfacePackage getSurfacePackage(int displayId, IBinder hostToken, int width, int height);
- }
复制代码 2)gradle 配置- sourceSets {
- main {
- <queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>aidl.srcDirs = ['src/main/aidl']
- }
- }
- buildFeatures.aidl true
复制代码 3)manifest 配置
客户端配置如下。- <queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>
复制代码 服务端配置如下。- <queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>
复制代码 3 客户端
MainActivity.java- package com.zhyan8.client;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.ServiceConnection;import android.os.Bundle;import android.os.IBinder;import android.os.RemoteException;import android.util.Log;import android.view.SurfaceControlViewHost.SurfacePackage;import android.view.SurfaceView;import android.view.View;import androidx.appcompat.app.AppCompatActivity;import com.zhyan8.remoterender.IRemoteRender;public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private IRemoteRender mRemoteRender; private IBinder mService; private SurfaceView mSurfaceView; @Override protected void onCreate(Bundle savedInstanceState) {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>super.onCreate(savedInstanceState);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>setContentView(R.layout.activity_main);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>mSurfaceView = findViewById(R.id.surface_view);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>startService(); } public void onClickDraw(View view) {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>try {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> IBinder hostToken = mSurfaceView.getHostToken();<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> SurfacePackage surfacePackage = mRemoteRender.getSurfacePackage(0, hostToken, 1000, 2000);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> mSurfaceView.setChildSurfacePackage(surfacePackage);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>} catch (RemoteException e) {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> e.printStackTrace();<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>} } @Override protected void onDestroy() {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>super.onDestroy();<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>unbindService(mConnection); } private void startService() {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>Log.d(TAG, "startService");<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>Intent intent = new Intent("com.zhyan8.remoterender.IRemoteRender");<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>//intent.setPackage("com.zhyan8.service"); // 渲染普通View的服务<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>intent.setPackage("com.zhyan8.glservice"); // 基于OpenGL ES渲染的服务<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>bindService(intent, mConnection, Context.BIND_AUTO_CREATE); } private void clearBind() {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>Log.d(TAG, "clearBind");<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>if (mService != null) {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> mService.unlinkToDeath(mDeathRecipient, 0);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>}<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>mRemoteRender = null;<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>mService = null; } private ServiceConnection mConnection = new ServiceConnection() {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>@Override<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>public void onServiceConnected(ComponentName name, IBinder service) {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> Log.d(TAG, "onServiceConnected");<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> mRemoteRender = IRemoteRender.Stub.asInterface(service);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> mService = service;<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> try {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>mService.linkToDeath(mDeathRecipient, 0);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> } catch (RemoteException e) {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>Log.e(TAG, "e=" + e.getMessage());<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> }<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>}<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>@Override<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>public void onServiceDisconnected(ComponentName name) {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> Log.d(TAG, "onServiceDisconnected");<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> clearBind();<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>} }; private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>@Override<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>public void binderDied() {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> Log.d(TAG, "binderDied");<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> clearBind();<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>} };}
复制代码 activity_main.xml- <queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>
复制代码 4 跨进程渲染普通 View
RemoteRenderService.java- package com.zhyan8.service;import android.app.Service;import android.content.Context;import android.content.Intent;import android.hardware.display.DisplayManager;import android.os.Handler;import android.os.IBinder;import android.os.Looper;import android.util.Log;import android.view.Display;import android.view.SurfaceControlViewHost;import android.view.SurfaceControlViewHost.SurfacePackage;import android.view.ViewGroup;import android.widget.ImageView;import com.zhyan8.remoterender.IRemoteRender;import java.util.concurrent.CountDownLatch;public class RemoteRenderService extends Service { private static final String TAG = "RemoteRenderService"; private SurfaceControlViewHost mSurfaceControlViewHost; private ImageView mImageView; private Handler mHandler = new Handler(Looper.getMainLooper()); @Override public void onCreate() {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>super.onCreate();<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>Log.i(TAG, "onCreate"); } @Override public IBinder onBind(Intent intent) {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>Log.i(TAG, "onBind");<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>return mBinder; } @Override public void onDestroy() {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>super.onDestroy();<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>Log.i(TAG, "onDestroy");<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>if (mSurfaceControlViewHost != null) {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> mSurfaceControlViewHost.release();<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>} } private final IRemoteRender.Stub mBinder = new IRemoteRender.Stub() {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>@Override<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>public SurfacePackage getSurfacePackage(int displayId, IBinder hostToken, int width, int height) {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> Log.i(TAG, "getSurfacePackage, displayId=" + displayId + ", hostToken=" + hostToken + ", width=" + width + ", height=" + height);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> final SurfacePackage[] result = new SurfaceControlViewHost.SurfacePackage[1];<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> final CountDownLatch latch = new CountDownLatch(1);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> mHandler.post( () -> {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>// 创建SurfaceControlViewHost<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>Context context = getBaseContext();<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>Display display = context.getSystemService(DisplayManager.class).getDisplay(displayId);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>mSurfaceControlViewHost = new SurfaceControlViewHost(context, display, hostToken);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>// 创建要渲染的内容<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>mImageView = new ImageView(RemoteRenderService.this);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>mImageView.setLayoutParams(new ViewGroup.LayoutParams(width, height));<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>mImageView.setScaleType(ImageView.ScaleType.FIT_XY);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>mImageView.setImageResource(R.drawable.girl);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>// 将视图附加到SurfaceControlViewHost<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>mSurfaceControlViewHost.setView(mImageView, width, height);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>result[0] = mSurfaceControlViewHost.getSurfacePackage();<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>latch.countDown();<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> });<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> try {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>latch.await(); // 等待主线程完成操作<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>return result[0];<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> } catch (InterruptedException e) {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>Log.i(TAG, "getSurfacePackage, e=" + e.getMessage());<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> }<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> return null;<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>} };}
复制代码 运行效果如下。
5 跨进程渲染 GLSurfaceView
RemoteGLRenderService.java- package com.zhyan8.glservice;import android.app.Service;import android.content.Context;import android.content.Intent;import android.hardware.display.DisplayManager;import android.opengl.GLSurfaceView;import android.os.Handler;import android.os.IBinder;import android.os.Looper;import android.util.Log;import android.view.Display;import android.view.SurfaceControlViewHost;import android.view.SurfaceControlViewHost.SurfacePackage;import android.view.ViewGroup;import com.zhyan8.remoterender.IRemoteRender;import java.util.concurrent.CountDownLatch;public class RemoteGLRenderService extends Service { private static final String TAG = "RemoteGLRenderService"; private SurfaceControlViewHost mSurfaceControlViewHost; private GLSurfaceView mGLSurfaceView; private Handler mHandler = new Handler(Looper.getMainLooper()); @Override public void onCreate() {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>super.onCreate();<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>Log.i(TAG, "onCreate"); } @Override public IBinder onBind(Intent intent) {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>Log.i(TAG, "onBind");<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>return mBinder; } @Override public void onDestroy() {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>Log.i(TAG, "onDestroy");<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>super.onDestroy();<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>if (mSurfaceControlViewHost != null) {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> mSurfaceControlViewHost.release();<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>} } private final IRemoteRender.Stub mBinder = new IRemoteRender.Stub() {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>@Override<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>public SurfacePackage getSurfacePackage(int displayId, IBinder hostToken, int width, int height) {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> Log.i(TAG, "getSurfacePackage, displayId=" + displayId + ", hostToken=" + hostToken + ", width=" + width + ", height=" + height);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> final SurfacePackage[] result = new SurfaceControlViewHost.SurfacePackage[1];<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> final CountDownLatch latch = new CountDownLatch(1);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> mHandler.post( () -> {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>// 创建SurfaceControlViewHost<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>Context context = getBaseContext();<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>Display display = context.getSystemService(DisplayManager.class).getDisplay(displayId);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>mSurfaceControlViewHost = new SurfaceControlViewHost(context, display, hostToken);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>// 创建要渲染的内容<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>mGLSurfaceView = new GLSurfaceView(RemoteGLRenderService.this);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>mGLSurfaceView.setEGLContextClientVersion(3);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>mGLSurfaceView.setLayoutParams(new ViewGroup.LayoutParams(width, height));<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>mGLSurfaceView.setRenderer(new MyGLRenderer(RemoteGLRenderService.this));<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>// 将视图附加到SurfaceControlViewHost<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>mSurfaceControlViewHost.setView(mGLSurfaceView, width, height);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>result[0] = mSurfaceControlViewHost.getSurfacePackage();<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>latch.countDown();<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> });<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> try {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>latch.await(); // 等待主线程完成操作<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>return result[0];<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> } catch (InterruptedException e) {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>Log.i(TAG, "getSurfacePackage, e=" + e.getMessage());<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> }<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> return null;<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>} };}
复制代码 MyGLRenderer.java- package com.zhyan8.glservice;import android.opengl.GLES30;import android.opengl.GLSurfaceView;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;import android.content.Context;import java.nio.FloatBuffer;public class MyGLRenderer implements GLSurfaceView.Renderer { private FloatBuffer vertexBuffer; private FloatBuffer textureBuffer; private MyGLUtils mGLUtils; private int mTextureId; private int mTimeLocation; private long mStartTime = 0L; private long mRunTime = 0L; public MyGLRenderer(Context context) {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>mGLUtils = new MyGLUtils(context);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>getFloatBuffer();<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>mStartTime = System.currentTimeMillis(); } @Override public void onSurfaceCreated(GL10 gl, EGLConfig eglConfig) {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>//设置背景颜色<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>GLES30.glClearColor(0.1f, 0.2f, 0.3f, 0.4f);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>//编译着色器<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>final int vertexShaderId = mGLUtils.compileShader(GLES30.GL_VERTEX_SHADER, R.raw.vertex_shader);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>final int fragmentShaderId = mGLUtils.compileShader(GLES30.GL_FRAGMENT_SHADER, R.raw.fragment_shader);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>//链接程序片段<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>int programId = mGLUtils.linkProgram(vertexShaderId, fragmentShaderId);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>GLES30.glUseProgram(programId);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>mTextureId = mGLUtils.loadTexture(R.drawable.girl);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>mTimeLocation = GLES30.glGetUniformLocation(programId, "u_time"); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>//设置视图窗口<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>GLES30.glViewport(0, 0, width, height); } @Override public void onDrawFrame(GL10 gl) {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>mRunTime = System.currentTimeMillis() - mStartTime;<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>//将颜色缓冲区设置为预设的颜色<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>GLES30.glUniform1f(mTimeLocation, mRunTime / 1000f);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>//启用顶点的数组句柄<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>GLES30.glEnableVertexAttribArray(0);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>GLES30.glEnableVertexAttribArray(1);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>//准备顶点坐标和纹理坐标<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>GLES30.glVertexAttribPointer(0, 3, GLES30.GL_FLOAT, false, 0, vertexBuffer);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>GLES30.glVertexAttribPointer(1, 2, GLES30.GL_FLOAT, false, 0, textureBuffer);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>//激活纹理<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>GLES30.glActiveTexture(GLES30.GL_TEXTURE);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>//绑定纹理<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, mTextureId);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>//绘制贴图<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>GLES30.glDrawArrays(GLES30.GL_TRIANGLE_FAN, 0, 4);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>//禁止顶点数组句柄<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>GLES30.glDisableVertexAttribArray(0);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>GLES30.glDisableVertexAttribArray(1); } private void getFloatBuffer() {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>float[] vertex = new float[] {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>1f, 1f, 0f, //V0<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>-1f, 1f, 0f, //V1<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>-1f, -1f, 0f, //V2<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>1f, -1f, 0f //V3<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>};<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>float[] texture = {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>1f, 0f, //V0<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>0f, 0f, //V1<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>0f, 1.0f, //V2<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>1f, 1.0f //V3<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>};<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>vertexBuffer = mGLUtils.getFloatBuffer(vertex);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>textureBuffer = mGLUtils.getFloatBuffer(texture); }}
复制代码 MyGLUtils.java- package com.zhyan8.glservice;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.opengl.GLES30;import android.opengl.GLUtils;import android.opengl.Matrix;import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.FloatBuffer;public class MyGLUtils { private Context mContext; private Bitmap mBitmap; public MyGLUtils(Context context) {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>mContext = context; } public FloatBuffer getFloatBuffer(float[] floatArr) {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>FloatBuffer fb = ByteBuffer.allocateDirect(floatArr.length * Float.BYTES)<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>.order(ByteOrder.nativeOrder())<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>.asFloatBuffer();<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>fb.put(floatArr);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>fb.position(0);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>return fb; } //通过代码片段编译着色器 public int compileShader(int type, String shaderCode){<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>int shader = GLES30.glCreateShader(type);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>GLES30.glShaderSource(shader, shaderCode);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>GLES30.glCompileShader(shader);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>return shader; } //通过外部资源编译着色器 public int compileShader(int type, int shaderId){<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>String shaderCode = readShaderFromResource(shaderId);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>return compileShader(type, shaderCode); } //链接到着色器 public int linkProgram(int vertexShaderId, int fragmentShaderId) {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>final int programId = GLES30.glCreateProgram();<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>//将顶点着色器加入到程序<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>GLES30.glAttachShader(programId, vertexShaderId);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>//将片元着色器加入到程序<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>GLES30.glAttachShader(programId, fragmentShaderId);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>//链接着色器程序<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>GLES30.glLinkProgram(programId);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>return programId; } //从shader文件读出字符串 private String readShaderFromResource(int shaderId) {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>InputStream is = mContext.getResources().openRawResource(shaderId);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>BufferedReader br = new BufferedReader(new InputStreamReader(is));<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>String line;<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>StringBuilder sb = new StringBuilder();<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>try {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> while ((line = br.readLine()) != null) {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>sb.append(line);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries><queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>sb.append("\n");<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> }<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> br.close();<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>} catch (Exception e) {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries> e.printStackTrace();<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>}<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>return sb.toString(); } //加载纹理贴图 public int loadTexture(int resourceId) {<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>BitmapFactory.Options options = new BitmapFactory.Options();<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>options.inScaled = false;<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>mBitmap = BitmapFactory.decodeResource(mContext.getResources(), resourceId, options);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>final int[] textureIds = new int[1];<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>// 生成纹理id<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>GLES30.glGenTextures(1, textureIds, 0);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>// 绑定纹理到OpenGL<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, textureIds[0]);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_LINEAR_MIPMAP_LINEAR);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_LINEAR);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>// 加载bitmap到纹理中<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>GLUtils.texImage2D(GLES30.GL_TEXTURE_2D, 0, mBitmap, 0);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>// 生成MIP贴图<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>GLES30.glGenerateMipmap(GLES30.GL_TEXTURE_2D);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>// 取消绑定纹理<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, 0);<queries>
- <package android:name="com.zhyan8.service" />
- <package android:name="com.zhyan8.glservice" />
- </queries>return textureIds[0]; }}
复制代码 vertex_shader.glsl- attribute vec4 aPosition;
- attribute vec2 aTextureCoord;
- varying vec2 vTexCoord;
- void main() {
- gl_Position = aPosition;
- vTexCoord = aTextureCoord;
- }
复制代码 fragment_shader.glsl- precision mediump float;
- uniform sampler2D uTextureUnit;
- varying vec2 vTexCoord;
- uniform float u_time;
- void main() {
- vec3 color = texture2D(uTextureUnit, vTexCoord).rgb;
- color.x += sin(u_time * 1.3 + 0.4) * 0.2;
- color.y += cos(u_time * 1.7 + 7.1) * 0.2;
- color.z += (sin(u_time) + cos(u_time)) * 0.2;
- gl_FragColor = vec4(color, 1.0);
- }
复制代码 运行效果如下。
声明:本文转自【Android】基于SurfaceControlViewHost实现跨进程渲染。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |