中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

柳州市黨風(fēng)廉政建設(shè)網(wǎng)站專注網(wǎng)站建設(shè)服務(wù)機(jī)構(gòu)

柳州市黨風(fēng)廉政建設(shè)網(wǎng)站,專注網(wǎng)站建設(shè)服務(wù)機(jī)構(gòu),門戶網(wǎng)站怎樣做,北京交友網(wǎng)站排行榜1 前言 本文通過一個立方體貼圖的例子,講解三維紋理貼圖(子網(wǎng)格貼圖)的應(yīng)用,案例中使用 6 張不同的圖片給立方體貼圖,圖片如下。 讀者如果對 Filament 不太熟悉,請回顧以下內(nèi)容。 Filament環(huán)境搭建繪制三角…

1 前言

????????本文通過一個立方體貼圖的例子,講解三維紋理貼圖(子網(wǎng)格貼圖)的應(yīng)用,案例中使用 6 張不同的圖片給立方體貼圖,圖片如下。

????????讀者如果對 Filament 不太熟悉,請回顧以下內(nèi)容。

  • Filament環(huán)境搭建
  • 繪制三角形
  • 繪制矩形
  • 繪制圓形
  • 繪制立方體
  • 紋理貼圖

2 立方體貼圖

????????本文項(xiàng)目結(jié)構(gòu)如下,完整代碼資源 →?Filament立方體貼圖(6張圖)。

2.1 基礎(chǔ)類

????????為方便讀者將注意力聚焦在 Filament 的輸入上,輕松配置復(fù)雜的環(huán)境依賴邏輯,筆者仿照 OpenGL ES 的寫法,抽出了 FLSurfaceView、BaseModel、Mesh、MaterialUtils 和 TextureUtils 類。FLSurfaceView 與 GLSurfaceView 的功能類似,承載了渲染環(huán)境配置;BaseModel 用于管理模型的網(wǎng)格和材質(zhì);Mesh 用于管理模型的頂點(diǎn)屬性;MaterialUtils 和 TextureUtils 中分別提供了一些材質(zhì)和紋理相關(guān)的工具。

????????build.gradle

...
android {...aaptOptions { // 在應(yīng)用程序打包過程中不壓縮的文件noCompress 'filamat', 'ktx'}
}dependencies {implementation fileTree(dir: '../libs', include: ['*.aar'])...
}

????????說明:在項(xiàng)目根目錄下的 libs 目錄中,需要放入以下 aar 文件,它們源自Filament環(huán)境搭建中編譯生成的 aar。

????????FLSurfaceView.java

package com.zhyan8.multitexture.filament;import android.content.Context;
import android.graphics.Point;
import android.view.Choreographer;
import android.view.Surface;
import android.view.SurfaceView;import com.google.android.filament.Camera;
import com.google.android.filament.Engine;
import com.google.android.filament.EntityManager;
import com.google.android.filament.Filament;
import com.google.android.filament.Renderer;
import com.google.android.filament.Scene;
import com.google.android.filament.Skybox;
import com.google.android.filament.SwapChain;
import com.google.android.filament.View;
import com.google.android.filament.Viewport;
import com.google.android.filament.android.DisplayHelper;
import com.google.android.filament.android.FilamentHelper;
import com.google.android.filament.android.UiHelper;import java.util.ArrayList;/** Filament中待渲染的SurfaceView* 功能可以類比OpenGL ES中的GLSurfaceView* 用于創(chuàng)建Filament的渲染環(huán)境*/
public class FLSurfaceView extends SurfaceView {public static int RENDERMODE_WHEN_DIRTY = 0; // 用戶請求渲染才渲染一幀public static int RENDERMODE_CONTINUOUSLY = 1; // 持續(xù)渲染protected int mRenderMode = RENDERMODE_CONTINUOUSLY; // 渲染模式protected Choreographer mChoreographer; // 消息控制protected DisplayHelper mDisplayHelper; // 管理Display(可以監(jiān)聽分辨率或刷新率的變化)protected UiHelper mUiHelper; // 管理SurfaceView、TextureView、SurfaceHolderprotected Engine mEngine; // 引擎(跟蹤用戶創(chuàng)建的資源, 管理渲染線程和硬件渲染器)protected Renderer mRenderer; // 渲染器(用于操作系統(tǒng)窗口, 生成繪制命令, 管理幀延時)protected Scene mScene; // 場景(管理渲染對象、燈光)protected View mView; // 存儲渲染數(shù)據(jù)(View是Renderer操作的對象)protected Camera mCamera; // 相機(jī)(視角管理)protected Point mDesiredSize; // 渲染分辨率protected float[] mSkyboxColor; // 背景顏色protected SwapChain mSwapChain; // 操作系統(tǒng)的本地可渲染表面(native renderable surface, 通常是一個window或view)protected FrameCallback mFrameCallback = new FrameCallback(); // 幀回調(diào)protected ArrayList<RenderCallback> mRenderCallbacks; // 每一幀渲染前的回調(diào)(一般用于處理模型變換、相機(jī)變換等)static {Filament.init();}public FLSurfaceView(Context context) {super(context);mChoreographer = Choreographer.getInstance();mDisplayHelper = new DisplayHelper(context);mRenderCallbacks = new ArrayList<>();}public void init() { // 初始化setupSurfaceView();setupFilament();setupView();setupScene();}public void setRenderMode(int renderMode) { // 設(shè)置渲染模式mRenderMode = renderMode;}public void addRenderCallback(RenderCallback renderCallback) { // 添加渲染回調(diào)if (renderCallback != null) {mRenderCallbacks.add(renderCallback);}}public void requestRender() { // 請求渲染mChoreographer.postFrameCallback(mFrameCallback);}public void onResume() { // 恢復(fù)mChoreographer.postFrameCallback(mFrameCallback);}public void onPause() { // 暫停mChoreographer.removeFrameCallback(mFrameCallback);}public void onDestroy() { // 銷毀Filament環(huán)境mChoreographer.removeFrameCallback(mFrameCallback);mRenderCallbacks.clear();mUiHelper.detach();mEngine.destroyRenderer(mRenderer);mEngine.destroyView(mView);mEngine.destroyScene(mScene);mEngine.destroyCameraComponent(mCamera.getEntity());EntityManager entityManager = EntityManager.get();entityManager.destroy(mCamera.getEntity());mEngine.destroy();}protected void setupScene() { // 設(shè)置Scene參數(shù)}protected void onResized(int width, int height) { // Surface尺寸變化時回調(diào)double zoom = 1;double aspect = (double) width / (double) height;mCamera.setProjection(Camera.Projection.ORTHO,-aspect * zoom, aspect * zoom, -zoom, zoom, 0, 1000);}private void setupSurfaceView() { // 設(shè)置SurfaceViewmUiHelper = new UiHelper(UiHelper.ContextErrorPolicy.DONT_CHECK);mUiHelper.setRenderCallback(new SurfaceCallback());if (mDesiredSize != null) {mUiHelper.setDesiredSize(mDesiredSize.x, mDesiredSize.y);}mUiHelper.attachTo(this);}private void setupFilament() { // 設(shè)置Filament參數(shù)mEngine = Engine.create();// mEngine = (new Engine.Builder()).featureLevel(Engine.FeatureLevel.FEATURE_LEVEL_0).build();mRenderer = mEngine.createRenderer();mScene = mEngine.createScene();mView = mEngine.createView();mCamera = mEngine.createCamera(mEngine.getEntityManager().create());}private void setupView() { // 設(shè)置View參數(shù)float[] color = mSkyboxColor != null ? mSkyboxColor : new float[] {0, 0, 0, 1};Skybox skybox = (new Skybox.Builder()).color(color).build(mEngine);mScene.setSkybox(skybox);if (mEngine.getActiveFeatureLevel() == Engine.FeatureLevel.FEATURE_LEVEL_0) {mView.setPostProcessingEnabled(false); // FEATURE_LEVEL_0不支持post-processing}mView.setCamera(mCamera);mView.setScene(mScene);}/** 幀回調(diào)*/private class FrameCallback implements Choreographer.FrameCallback {@Overridepublic void doFrame(long frameTimeNanos) { // 渲染每幀數(shù)據(jù)if (mRenderMode == RENDERMODE_CONTINUOUSLY) {mChoreographer.postFrameCallback(this); // 請求下一幀}mRenderCallbacks.forEach(callback -> callback.onCall());if (mUiHelper.isReadyToRender()) {if (mRenderer.beginFrame(mSwapChain, frameTimeNanos)) {mRenderer.render(mView);mRenderer.endFrame();}}}}/** Surface回調(diào)*/private class SurfaceCallback implements UiHelper.RendererCallback {@Overridepublic void onNativeWindowChanged(Surface surface) { // Native窗口改變時回調(diào)if (mSwapChain != null) {mEngine.destroySwapChain(mSwapChain);}long flags = mUiHelper.getSwapChainFlags();if (mEngine.getActiveFeatureLevel() == Engine.FeatureLevel.FEATURE_LEVEL_0) {if (SwapChain.isSRGBSwapChainSupported(mEngine)) {flags = flags | SwapChain.CONFIG_SRGB_COLORSPACE;}}mSwapChain = mEngine.createSwapChain(surface, flags);mDisplayHelper.attach(mRenderer, getDisplay());}@Overridepublic void onDetachedFromSurface() { // 解綁Surface時回調(diào)mDisplayHelper.detach();if (mSwapChain != null) {mEngine.destroySwapChain(mSwapChain);mEngine.flushAndWait();mSwapChain = null;}}@Overridepublic void onResized(int width, int height) { // Surface尺寸變化時回調(diào)mView.setViewport(new Viewport(0, 0, width, height));FilamentHelper.synchronizePendingFrames(mEngine);FLSurfaceView.this.onResized(width, height);}}/** 每一幀渲染前的回調(diào)* 一般用于處理模型變換、相機(jī)變換等*/public static interface RenderCallback {void onCall();}
}

????????BaseModel.java

package com.zhyan8.multitexture.filament;import android.content.Context;import com.google.android.filament.Box;
import com.google.android.filament.Engine;
import com.google.android.filament.EntityManager;
import com.google.android.filament.Material;
import com.google.android.filament.MaterialInstance;
import com.google.android.filament.RenderableManager;
import com.google.android.filament.RenderableManager.PrimitiveType;
import com.google.android.filament.Texture;
import com.google.android.filament.TransformManager;import com.zhyan8.multitexture.filament.Mesh.SubMesh;
import com.zhyan8.multitexture.filament.utils.MaterialUtils;
import com.zhyan8.multitexture.filament.utils.TextureUtils;/** 模型基類* 管理模型的網(wǎng)格、材質(zhì)、渲染id*/
public class BaseModel {private static String TAG = "BaseModel";protected Context mContext; // 上下文protected Engine mEngine; // Filament引擎protected TransformManager mTransformManager; // 模型變換管理器protected Mesh mMesh; // 模型網(wǎng)格protected SubMesh[] mSubMeshes; // 子網(wǎng)格protected Material[] mMaterials; // 模型材質(zhì)protected MaterialInstance[] mMaterialInstances; // 模型材質(zhì)實(shí)例protected Texture[] mTextures; // 紋理protected int mRenderable; // 渲染idprotected int mTransformComponent; // 模型變換組件的idprotected Box mBox; // 渲染區(qū)域protected FLSurfaceView.RenderCallback mRenderCallback; // 每一幀渲染前的回調(diào)(一般用于處理模型變換、相機(jī)變換等)public BaseModel(Context context, Engine engine) {mContext = context;mEngine = engine;mTransformManager = mEngine.getTransformManager();}public int getRenderable() { // 獲取渲染idreturn mRenderable;}public FLSurfaceView.RenderCallback getRenderCallback() { // 獲取渲染回調(diào)return mRenderCallback;}public void destroy() { // 銷毀模型mEngine.destroyEntity(mRenderable);if (mMesh != null) {mMesh.destroy();}if (mTextures != null) {for (int i = 0; i < mTextures.length; i++) {mEngine.destroyTexture(mTextures[i]);}}if (mMaterialInstances != null) {for (int i = 0; i < mMaterialInstances.length; i++) {mEngine.destroyMaterialInstance(mMaterialInstances[i]);}}if (mMaterials != null) {for (int i = 0; i < mMaterials.length; i++) {mEngine.destroyMaterial(mMaterials[i]);}}EntityManager entityManager = EntityManager.get();entityManager.destroy(mRenderable);}protected int getRenderable(PrimitiveType primitiveType, int vertexCount) { // 獲取渲染idint renderable = EntityManager.get().create();if (mSubMeshes == null) {mSubMeshes = new SubMesh[] {new SubMesh(0, 0, vertexCount - 1, vertexCount)};}RenderableManager.Builder builder = new RenderableManager.Builder(mSubMeshes.length).boundingBox(mBox);for (int i = 0; i < mSubMeshes.length; i++) {builder.geometry(i, primitiveType, mMesh.getVertexBuffer(), mMesh.getIndexBuffer(),mSubMeshes[i].offset, mSubMeshes[i].minIndex, mSubMeshes[i].maxIndex, mSubMeshes[i].indexCount).material(i, mMaterialInstances[i]);}builder.build(mEngine, renderable);return renderable;}protected Material[] loadMaterials(String materialPath) { // 加載材質(zhì)Material material = MaterialUtils.loadMaterial(mContext, mEngine, materialPath);if (material != null) {return new Material[] {material};}return null;}protected Material[] loadMaterials(String[] materialPaths) { // 加載材質(zhì)Material[] materials = new Material[materialPaths.length];for (int i = 0; i < materials.length; i++) {materials[i] = MaterialUtils.loadMaterial(mContext, mEngine, materialPaths[i]);}return materials;}protected MaterialInstance[] getMaterialInstance(Material[] materials) { // 獲取材質(zhì)實(shí)例MaterialInstance[] materialInstances = new MaterialInstance[materials.length];for (int i = 0; i < materials.length; i++) {materialInstances[i] = materials[i].createInstance();}return materialInstances;}protected MaterialInstance[] getMaterialInstance(Material material, int count) { // 獲取材質(zhì)實(shí)例MaterialInstance[] materialInstances = new MaterialInstance[count];for (int i = 0; i < count; i++) {materialInstances[i] = material.createInstance();}return materialInstances;}protected Texture[] loadTextures(String texturePath) { // 加載紋理Texture texture = TextureUtils.getTexture(mContext, mEngine, texturePath);if (texture != null) {return new Texture[] {texture};}return null;}protected Texture[] loadTextures(String[] texturePaths) { // 加載紋理Texture[] textures = new Texture[texturePaths.length];for (int i = 0; i < textures.length; i++) {textures[i] = TextureUtils.getTexture(mContext, mEngine, texturePaths[i]);}return textures;}
}

????????Mesh.java

package com.zhyan8.multitexture.filament;import com.google.android.filament.Engine;
import com.google.android.filament.IndexBuffer;
import com.google.android.filament.VertexBuffer;
import com.google.android.filament.VertexBuffer.AttributeType;
import com.google.android.filament.VertexBuffer.VertexAttribute;import java.nio.ByteBuffer;
import java.nio.ByteOrder;/** 網(wǎng)格* 用于管理模型的頂點(diǎn)屬性和頂點(diǎn)索引*/
public class Mesh {private Engine mEngine; // Filament引擎private VertexBuffer mVertexBuffer; // 頂點(diǎn)屬性緩存private IndexBuffer mIndexBuffer; // 頂點(diǎn)索引緩存public Mesh(Engine engine) {mEngine = engine;}public Mesh(Engine engine, float[] vertices, short[] indices) {mEngine = engine;setVertices(vertices);setIndices(indices);}public Mesh(Engine engine, VertexPosCol[] vertices, short[] indices) {mEngine = engine;setVertices(vertices);setIndices(indices);}public Mesh(Engine engine, VertexPosUV[] vertices, short[] indices) {mEngine = engine;setVertices(vertices);setIndices(indices);}public void setVertices(float[] vertices) { // 設(shè)置頂點(diǎn)屬性mVertexBuffer = getVertexBuffer(vertices);}public void setVertices(VertexPosCol[] vertices) { // 設(shè)置頂點(diǎn)屬性mVertexBuffer = getVertexBuffer(vertices);}public void setVertices(VertexPosUV[] vertices) { // 設(shè)置頂點(diǎn)屬性mVertexBuffer = getVertexBuffer(vertices);}public void setIndices(short[] indices) { // 設(shè)置頂點(diǎn)索引mIndexBuffer = getIndexBuffer(indices);}public VertexBuffer getVertexBuffer() { // 獲取頂點(diǎn)屬性緩存return mVertexBuffer;}public IndexBuffer getIndexBuffer() { // 獲取頂點(diǎn)索引緩存return mIndexBuffer;}public void destroy() {mEngine.destroyVertexBuffer(mVertexBuffer);mEngine.destroyIndexBuffer(mIndexBuffer);}private VertexBuffer getVertexBuffer(float[] values) { // 獲取頂點(diǎn)屬性緩存ByteBuffer vertexData = getByteBuffer(values);int vertexCount = values.length / 3;int vertexSize = Float.BYTES * 3;VertexBuffer vertexBuffer = new VertexBuffer.Builder().bufferCount(1).vertexCount(vertexCount).attribute(VertexBuffer.VertexAttribute.POSITION, 0, VertexBuffer.AttributeType.FLOAT3, 0, vertexSize).build(mEngine);vertexBuffer.setBufferAt(mEngine, 0, vertexData);return vertexBuffer;}private VertexBuffer getVertexBuffer(VertexPosCol[] values) { // 獲取頂點(diǎn)屬性緩存ByteBuffer vertexData = getByteBuffer(values);int vertexCount = values.length;int vertexSize = VertexPosCol.BYTES;VertexBuffer vertexBuffer = new VertexBuffer.Builder().bufferCount(1).vertexCount(vertexCount).attribute(VertexAttribute.POSITION, 0, AttributeType.FLOAT3, 0, vertexSize).attribute(VertexAttribute.COLOR,    0, AttributeType.UBYTE4, 3 * Float.BYTES, vertexSize).normalized(VertexBuffer.VertexAttribute.COLOR).build(mEngine);vertexBuffer.setBufferAt(mEngine, 0, vertexData);return vertexBuffer;}private VertexBuffer getVertexBuffer(VertexPosUV[] values) { // 獲取頂點(diǎn)屬性緩存ByteBuffer vertexData = getByteBuffer(values);int vertexCount = values.length;int vertexSize = VertexPosUV.BYTES;VertexBuffer vertexBuffer = new VertexBuffer.Builder().bufferCount(1).vertexCount(vertexCount).attribute(VertexBuffer.VertexAttribute.POSITION, 0, VertexBuffer.AttributeType.FLOAT3, 0, vertexSize).attribute(VertexBuffer.VertexAttribute.UV0,    0, VertexBuffer.AttributeType.FLOAT2, 3 * Float.BYTES, vertexSize).build(mEngine);vertexBuffer.setBufferAt(mEngine, 0, vertexData);return vertexBuffer;}private IndexBuffer getIndexBuffer(short[] values) { // 獲取頂點(diǎn)索引緩存ByteBuffer indexData = getByteBuffer(values);int indexCount = values.length;IndexBuffer indexBuffer = new IndexBuffer.Builder().indexCount(indexCount).bufferType(IndexBuffer.Builder.IndexType.USHORT).build(mEngine);indexBuffer.setBuffer(mEngine, indexData);return indexBuffer;}private ByteBuffer getByteBuffer(float[] values) { // float數(shù)組轉(zhuǎn)換為ByteBufferByteBuffer byteBuffer = ByteBuffer.allocate(values.length * Float.BYTES);byteBuffer.order(ByteOrder.nativeOrder());for (int i = 0; i < values.length; i++) {byteBuffer.putFloat(values[i]);}byteBuffer.flip();return byteBuffer;}private ByteBuffer getByteBuffer(short[] values) { // short數(shù)組轉(zhuǎn)換為ByteBufferByteBuffer byteBuffer = ByteBuffer.allocate(values.length * Short.BYTES);byteBuffer.order(ByteOrder.nativeOrder());for (int i = 0; i < values.length; i++) {byteBuffer.putShort(values[i]);}byteBuffer.flip();return byteBuffer;}private ByteBuffer getByteBuffer(VertexPosCol[] values) { // VertexPosCol數(shù)組轉(zhuǎn)換為ByteBufferByteBuffer byteBuffer = ByteBuffer.allocate(values.length * VertexPosCol.BYTES);byteBuffer.order(ByteOrder.nativeOrder());for (int i = 0; i < values.length; i++) {values[i].put(byteBuffer);}byteBuffer.flip();return byteBuffer;}private ByteBuffer getByteBuffer(VertexPosUV[] values) { // VertexPosUV數(shù)組轉(zhuǎn)換為ByteBufferByteBuffer byteBuffer = ByteBuffer.allocate(values.length * VertexPosUV.BYTES);byteBuffer.order(ByteOrder.nativeOrder());for (int i = 0; i < values.length; i++) {values[i].put(byteBuffer);}byteBuffer.flip();return byteBuffer;}/** 子網(wǎng)格*/public static class SubMesh {public int offset;public int minIndex;public int maxIndex;public int indexCount;public SubMesh() {}public SubMesh(int offset, int minIndex, int maxIndex, int indexCount) {this.offset = offset;this.minIndex = minIndex;this.maxIndex = maxIndex;this.indexCount = indexCount;}}/** 頂點(diǎn)數(shù)據(jù)(位置+顏色)* 包含頂點(diǎn)位置和顏色*/public static class VertexPosCol {public static int BYTES = 16;public float x;public float y;public float z;public int color;public VertexPosCol() {}public VertexPosCol(float x, float y, float z, int color) {this.x = x;this.y = y;this.z = z;this.color = color;}public ByteBuffer put(ByteBuffer buffer) { // VertexPosCol轉(zhuǎn)換為ByteBufferbuffer.putFloat(x);buffer.putFloat(y);buffer.putFloat(z);buffer.putInt(color);return buffer;}}/** 頂點(diǎn)數(shù)據(jù)(位置+紋理坐標(biāo))* 包含頂點(diǎn)位置和紋理坐標(biāo)*/public static class VertexPosUV {public static int BYTES = 20;public float x;public float y;public float z;public float u;public float v;public VertexPosUV() {}public VertexPosUV(float x, float y, float z, float u, float v) {this.x = x;this.y = y;this.z = z;this.u = u;this.v = v;}public ByteBuffer put(ByteBuffer buffer) { // VertexPosUV轉(zhuǎn)換為ByteBufferbuffer.putFloat(x);buffer.putFloat(y);buffer.putFloat(z);buffer.putFloat(u);buffer.putFloat(v);return buffer;}}
}

? ? ? ? MaterialUtils.java

package com.zhyan8.multitexture.filament.utils;import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;import com.google.android.filament.Engine;
import com.google.android.filament.Material;import java.io.FileInputStream;
import java.io.IOException;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;/** 材質(zhì)工具類*/
public class MaterialUtils {private static String TAG = "MaterialUtils";public static Material loadMaterial(Context context, Engine engine, String materialPath) { // 加載材質(zhì)Buffer buffer = readUncompressedAsset(context, materialPath);if (buffer != null) {Material material = (new Material.Builder()).payload(buffer, buffer.remaining()).build(engine);material.compile(Material.CompilerPriorityQueue.HIGH,Material.UserVariantFilterBit.ALL,new Handler(Looper.getMainLooper()),() -> Log.i(TAG, "Material " + material.getName() + " compiled."));engine.flush();return material;}return null;}private static Buffer readUncompressedAsset(Context context, String assetPath) { // 加載資源ReadableByteChannel src = null;FileInputStream fis = null;ByteBuffer dist = null;try {AssetFileDescriptor fd = context.getAssets().openFd(assetPath);fis = fd.createInputStream();dist = ByteBuffer.allocate((int) fd.getLength());src = Channels.newChannel(fis);src.read(dist);} catch (IOException e) {e.printStackTrace();} finally {if (src != null) {try {src.close();} catch (IOException e) {e.printStackTrace();}}if (fis != null) {try {fis.close();} catch (IOException e) {e.printStackTrace();}}}if (dist != null) {return dist.rewind();}return null;}
}

????????TextureUtils.java

package com.zhyan8.multitexture.filament.utils;import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.util.Log;import com.google.android.filament.Engine;
import com.google.android.filament.Texture;
import com.google.android.filament.android.TextureHelper;import java.io.IOException;
import java.io.InputStream;/** 紋理工具類*/
public class TextureUtils {private static String TAG = "TextureUtils";public static Texture getTexture(Context context, Engine engine, String texturePath) { // 獲取TextureBitmap bitmap = loadBitmapFromAsset(context, texturePath);if (bitmap != null) {return generateTexture(engine, bitmap);}return null;}public static Texture getTexture(Context context, Engine engine, int resourceId) { // 獲取TextureBitmap bitmap = loadBitmapFromDrawable(context, resourceId);if (bitmap != null) {return generateTexture(engine, bitmap);}return null;}private static Texture generateTexture(Engine engine, Bitmap bitmap) { // 生成TextureTexture texture = new Texture.Builder().width(bitmap.getWidth()).height(bitmap.getHeight()).sampler(Texture.Sampler.SAMPLER_2D).format(Texture.InternalFormat.SRGB8_A8).levels(0xff).build(engine);TextureHelper.setBitmap(engine, texture, 0, bitmap, new Handler(), () ->Log.i(TAG, "getTexture, Bitmap is released."));texture.generateMipmaps(engine);return texture;}private static Bitmap loadBitmapFromAsset(Context context, String assetPath) { // 從asset中加載bitmapInputStream inputStream = null;Bitmap bitmap = null;try {inputStream = context.getAssets().open(assetPath);bitmap = BitmapFactory.decodeStream(inputStream);} catch (IOException e) {e.printStackTrace();} finally {if (inputStream != null) {try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}}return bitmap;}private static Bitmap loadBitmapFromDrawable(Context context, int resourceId) { // 從drawable中加載bitmapBitmapFactory.Options options = new BitmapFactory.Options();options.inPremultiplied = true;Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resourceId, options);return bitmap;}
}

2.2 業(yè)務(wù)類

????????MainActivity.java

package com.zhyan8.multitexture;import android.os.Bundle;import androidx.appcompat.app.AppCompatActivity;import com.zhyan8.multitexture.filament.FLSurfaceView;public class MainActivity extends AppCompatActivity {private FLSurfaceView mFLSurfaceView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);mFLSurfaceView = new MyFLSurfaceView(this);setContentView(mFLSurfaceView);mFLSurfaceView.init();mFLSurfaceView.setRenderMode(FLSurfaceView.RENDERMODE_CONTINUOUSLY);}@Overridepublic void onResume() {super.onResume();mFLSurfaceView.onResume();}@Overridepublic void onPause() {super.onPause();mFLSurfaceView.onPause();}@Overridepublic void onDestroy() {super.onDestroy();mFLSurfaceView.onDestroy();}
}

????????MyFLSurfaceView.java

package com.zhyan8.multitexture;import android.content.Context;import com.google.android.filament.Camera;
import com.zhyan8.multitexture.filament.BaseModel;
import com.zhyan8.multitexture.filament.FLSurfaceView;public class MyFLSurfaceView extends FLSurfaceView {private BaseModel mMyModel;public MyFLSurfaceView(Context context) {super(context);}public void init() {mSkyboxColor = new float[] {0.35f, 0.35f, 0.35f, 1};super.init();}@Overridepublic void onDestroy() {mMyModel.destroy();super.onDestroy();}@Overrideprotected void setupScene() { // 設(shè)置Scene參數(shù)mMyModel = new Cube(getContext(), mEngine);mScene.addEntity(mMyModel.getRenderable());addRenderCallback(mMyModel.getRenderCallback());}@Overrideprotected void onResized(int width, int height) {double zoom = 0.25;double aspect = (double) width / (double) height;mCamera.setProjection(Camera.Projection.PERSPECTIVE,-aspect * zoom, aspect * zoom, -zoom, zoom, 0.3, 100);float[] eye = new float[] {1, 1, 1.5f};float[] center = new float[] {0, 0, 0};float[] up = new float[] {0, 1, 0};mCamera.lookAt(eye[0], eye[1], eye[2],center[0], center[1], center[2], up[0], up[1], up[2]);}
}

????????Cube.java

package com.zhyan8.multitexture;import android.content.Context;
import android.opengl.Matrix;import com.google.android.filament.Box;
import com.google.android.filament.Engine;
import com.google.android.filament.RenderableManager.PrimitiveType;
import com.google.android.filament.TextureSampler;
import com.zhyan8.multitexture.filament.BaseModel;
import com.zhyan8.multitexture.filament.Mesh;
import com.zhyan8.multitexture.filament.Mesh.SubMesh;
import com.zhyan8.multitexture.filament.Mesh.VertexPosUV;public class Cube extends BaseModel {private String materialPaths = "materials/square.filamat";private String[] texturePaths = new String[] {"textures/a1.jpg", "textures/a2.jpg", "textures/a3.jpg","textures/a4.jpg", "textures/a6.jpg", "textures/a5.jpg"};private VertexPosUV[] mVertices; // 頂點(diǎn)坐標(biāo)private short[] mIndices; // 頂點(diǎn)索引private float[] mModelMatrix; // 模型變換矩陣private float[] mRotateAxis; // 旋轉(zhuǎn)軸private float mRotateAgree = 0; // 旋轉(zhuǎn)角度public Cube(Context context, Engine engine) {super(context, engine);init();}private void init() {mBox = new Box(0.0f, 0.0f, 0.0f, 2.0f, 2.0f, 2.0f);mVertices = getVertices(0.5f);mIndices = getIndices();mMesh = new Mesh(mEngine, mVertices, mIndices);mSubMeshes = getSubMesh();mTextures = loadTextures(texturePaths);mMaterials = loadMaterials(materialPaths);mMaterialInstances = getMaterialInstance(mMaterials[0], mTextures.length);TextureSampler textureSampler = new TextureSampler();for (int i = 0; i < mMaterialInstances.length; i++) {mMaterialInstances[i].setParameter("mainTex", mTextures[i], textureSampler);}mRenderable = getRenderable(PrimitiveType.TRIANGLES, mIndices.length);mTransformComponent = mTransformManager.getInstance(mRenderable);mRenderCallback = () -> renderCallback();mModelMatrix = new float[16];mRotateAxis = new float[] { 0.5f, 1f, 1f };}private void renderCallback() {mRotateAgree = (mRotateAgree + 1) % 360;mRotateAxis[0] = mRotateAgree / 180f - 1;mRotateAxis[1] = (float) Math.sin(mRotateAgree / 180f * Math.PI * 0.7f);mRotateAxis[2] = (float) Math.cos(mRotateAgree / 180f * Math.PI * 0.5f);Matrix.setRotateM(mModelMatrix, 0, mRotateAgree, mRotateAxis[0], mRotateAxis[1], mRotateAxis[2]);mTransformManager.setTransform(mTransformComponent, mModelMatrix);}private VertexPosUV[] getVertices(float r) {VertexPosUV[] vertices = new VertexPosUV[] {// 前面new VertexPosUV(r, r, r, 0f, 1f), // 0new VertexPosUV(-r, r, r, 1f, 1f), // 1new VertexPosUV(-r, -r, r, 1f, 0f), // 2new VertexPosUV(r, -r, r, 0f, 0f), // 3// 后面new VertexPosUV(r, r, -r, 0f, 1f), // 4new VertexPosUV(-r, r, -r, 1f, 1f), // 5new VertexPosUV(-r, -r, -r, 1f, 0f), // 6new VertexPosUV(r, -r, -r, 0f, 0f), // 7// 上面new VertexPosUV(r, r, r, 0f, 1f), // 8new VertexPosUV(r, r, -r, 1f, 1f), // 9new VertexPosUV(-r, r, -r, 1f, 0f), // 10new VertexPosUV(-r, r, r, 0f, 0f), // 11// 下面new VertexPosUV(r, -r, r, 0f, 1f), // 12new VertexPosUV(r, -r, -r, 1f, 1f), // 13new VertexPosUV(-r, -r, -r, 1f, 0f), // 14new VertexPosUV(-r, -r, r, 0f, 0f), // 15// 右面new VertexPosUV(r, r, r, 0f, 1f), // 16new VertexPosUV(r, r, -r, 1f, 1f), // 17new VertexPosUV(r, -r, -r, 1f, 0f), // 18new VertexPosUV(r, -r, r, 0f, 0f), // 19// 左面new VertexPosUV(-r, r, r, 0f, 1f), // 20new VertexPosUV(-r, r, -r, 1f, 1f), // 21new VertexPosUV(-r, -r, -r, 1f, 0f), // 22new VertexPosUV(-r, -r, r, 0f, 0f) // 23};return vertices;}private short[] getIndices() {short[] indices = new short[] {0, 1, 2, 0, 2, 3, // 前面4, 6, 5, 4, 7, 6, // 上面8, 9, 10, 8, 10, 11, // 右面12, 14, 13, 12, 15, 14, // 后面16, 18, 17, 16, 19, 18, // 下面20, 21, 22, 20, 22, 23 // 左面};return indices;}private SubMesh[] getSubMesh() {int subMeshCount = 6;int vertexCount = 6;SubMesh[] subMeshes = new SubMesh[subMeshCount];for (int i = 0; i < subMeshCount; i++) {int offset = i * vertexCount;int minIndex = offset;int maxIndex = minIndex + vertexCount - 1;subMeshes[i] = new SubMesh(offset, minIndex, maxIndex, vertexCount);}return subMeshes;}
}

????????square.mat

material {name : square,shadingModel : unlit, // 禁用所有l(wèi)ighting// 自定義變量參數(shù)parameters : [{type : sampler2d,name : mainTex}],// 頂點(diǎn)著色器入?yún)aterialVertexInputs中需要的頂點(diǎn)屬性requires : [uv0]
}fragment {void material(inout MaterialInputs material) {prepareMaterial(material); // 在方法返回前必須回調(diào)該函數(shù)material.baseColor = texture(materialParams_mainTex, getUV0());}
}

????????transform.bat

@echo off
setlocal enabledelayedexpansion
set "srcFolder=../src/main/materials"
set "distFolder=../src/main/assets/materials"for %%f in ("%srcFolder%\*.mat") do (set "matfile=%%~nf"matc -p mobile -a opengl -o "!matfile!.filamat" "%%f"move "!matfile!.filamat" "%distFolder%\!matfile!.filamat"
)echo Processing complete.
pause

????????說明:需要將 matc.exe 文件與 transform.bat 文件放在同一個目錄下面,matc.exe 源自Filament環(huán)境搭建中編譯生成的 exe 文件。雙擊 transform.bat 文件,會自動將 /src/main/materials/ 下面的所有 mat 文件全部轉(zhuǎn)換為 filamat 文件,并移到 /src/main/assets/materials/ 目錄下面。

? ? ? ? 運(yùn)行效果如下。
?

http://www.risenshineclean.com/news/30013.html

相關(guān)文章:

  • 青海報社網(wǎng)站建設(shè)公司百度在線問答
  • 做的網(wǎng)站怎么放視頻如何做網(wǎng)站的教程
  • 網(wǎng)站建設(shè)一點(diǎn)通口碑營銷是什么
  • 企業(yè)移動網(wǎng)站建設(shè)商百度賬號登陸
  • 小程序設(shè)計開發(fā)國內(nèi)seo公司排名
  • 免費(fèi)做電腦網(wǎng)站網(wǎng)站視頻
  • 零基礎(chǔ)怎么開網(wǎng)店seo短視頻網(wǎng)頁入口引流下載
  • wordpress多賬號權(quán)限天津seo優(yōu)化
  • 網(wǎng)站建設(shè)用哪種語言最好深圳網(wǎng)絡(luò)營銷怎么推廣
  • 什么叫網(wǎng)站建設(shè)手機(jī)怎么建網(wǎng)站
  • 網(wǎng)站架設(shè)客服QQ百度熱搜 百度指數(shù)
  • 教育企業(yè)重慶網(wǎng)站建設(shè)動態(tài)網(wǎng)站設(shè)計畢業(yè)論文
  • 鄂爾多斯網(wǎng)站建設(shè)百度提交網(wǎng)站入口
  • 城鄉(xiāng)建設(shè)網(wǎng)站報建需要什么網(wǎng)絡(luò)產(chǎn)品及其推廣方法
  • 搭建網(wǎng)站找什么公司銷售網(wǎng)站排名
  • 網(wǎng)站建設(shè) 關(guān)于我們百度 seo 工具
  • 專業(yè)網(wǎng)站建設(shè)好不好越秀seo搜索引擎優(yōu)化
  • 滄州哪里可以做網(wǎng)站中山seo排名
  • 網(wǎng)站url改版百度推廣年費(fèi)多少錢
  • 家庭寬帶 做網(wǎng)站在哪里查關(guān)鍵詞排名
  • 網(wǎng)站群建設(shè)報價seo優(yōu)化就業(yè)前景
  • 東營做網(wǎng)站建設(shè)的公司友鏈網(wǎng)站
  • it運(yùn)維培訓(xùn)怎么做優(yōu)化關(guān)鍵詞
  • c 新手一個人做網(wǎng)站湖北seo公司
  • 民權(quán)平臺網(wǎng)站建設(shè)銷售人員培訓(xùn)課程有哪些
  • 關(guān)鍵詞優(yōu)化排名用哪個軟件比較好南京百度seo排名優(yōu)化
  • 網(wǎng)站建設(shè) 從用戶角度開始網(wǎng)站建設(shè)及推廣優(yōu)化
  • 網(wǎng)站優(yōu)化公司 網(wǎng)絡(luò)服務(wù)產(chǎn)品運(yùn)營推廣方案
  • 成都都江堰網(wǎng)站建設(shè)廣告媒體資源平臺
  • 重慶網(wǎng)站服務(wù)器建設(shè)推薦萬網(wǎng)