OpenGL ES 紋理以及紋理的映射

文章目錄

    • 開啟紋理
    • 創建紋理
    • 綁定紋理
    • 生成紋理
    • 紋理坐標
    • 圖像配置
      • 線性插值
      • 重復效果
      • 限制拉伸
    • 完整代碼

在 Android OpenGL ES 中使用紋理(Texture)可以顯著提升圖形渲染的質量和效率。以下是使用紋理的主要好處:

  1. 增強視覺真實感
    紋理可以將復雜的圖像細節(如皮膚、木紋、磚石等)映射到簡單的幾何模型上,避免為每個細節創建復雜的幾何體,從而用較低的計算成本實現高度真實的視覺效果。

  2. 減少內存占用
    通過紋理復用,可以避免為相似的物體重復定義頂點數據。
    使用同一張紋理圖渲染多個相同的物體(如樹木、建筑)
    利用紋理壓縮技術(如 ETC、ASTC)進一步減少內存占用

  3. 提高渲染性能
    紋理在 GPU 中以高度優化的方式存儲和處理,比動態生成的圖形更高效。例如:
    使用預渲染的紋理代替實時計算(如陰影、光照效果)
    利用 Mipmapping 技術優化遠處物體的紋理采樣

  4. 實現復雜特效
    紋理不僅可以用于靜態圖像,還能實現各種高級特效:
    環境映射(Environment Mapping):模擬反射效果(如鏡面、金屬表面)
    法線貼圖(Normal Mapping):通過紋理模擬表面細節,增加立體感
    程序紋理(Procedural Textures):動態生成紋理(如火焰、煙霧)
    多重紋理(Multi-texturing):疊加多個紋理創建復合效果(如地形 + 植被)

  5. 簡化模型復雜度
    使用紋理可以將細節從幾何模型轉移到紋理圖像中,從而:
    減少頂點數量,降低 GPU 處理負擔
    簡化模型設計流程,提高開發效率
    支持更復雜的視覺效果,而不增加渲染負擔

  6. 跨平臺兼容性
    OpenGL ES 紋理機制在不同設備上具有良好的一致性,使得:
    紋理資源可以在不同 Android 設備間復用
    便于將應用移植到其他支持 OpenGL ES 的平臺

  7. 靈活的紋理控制
    通過調整紋理參數,可以實現豐富的視覺變化:
    過濾模式(Filtering):控制紋理縮放時的質量(如線性插值、最近鄰采樣)
    環繞模式(Wrapping):定義紋理坐標超出 [0,1] 范圍時的行為(重復、鏡像等)
    紋理混合(Blending):將紋理與顏色或其他紋理組合

開啟紋理

為了使用紋理,需要開啟一些開關啟動一些功能。

  • 打開2D貼圖
激活 OpenGL ES 上下文的 2D 紋理功能
允許后續的紋理操作(如綁定紋理、設置紋理參數)生效
確保在繪制時使用紋理坐標對紋理進行采樣gl.glEnable(GL10.GL_TEXTURE_2D)
  • 打開混色
在 Android OpenGL ES 中,gl.glEnable(GL10.GL_BLEND) 
用于啟用顏色混合功能,這是實現半透明效果、粒子系統、紋理疊加等視覺效果的關鍵技術。gl.glEnable(GL10.GL_BLEND) 
  • 設置混色

下面方法是 Android OpenGL ES 中用于設置標準透明度混合(Alpha Blending)的核心方法。
這個設置允許你實現半透明效果,讓新繪制的物體能夠以透明方式與背景融合。gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA)
  • OpenGL 支持的混色方案如下
因子描述
GL_ZERO因子 = (0, 0, 0, 0)
GL_ONE因子 = (1, 1, 1, 1)
GL_SRC_COLOR因子 = (Rs, Gs, Bs, As) (源顏色)
GL_ONE_MINUS_SRC_COLOR因子 = (1-Rs, 1-Gs, 1-Bs, 1-As) (1 - 源顏色)
GL_DST_COLOR因子 = (Rd, Gd, Bd, Ad) (目標顏色)
GL_ONE_MINUS_DST_COLOR因子 = (1-Rd, 1-Gd, 1-Bd, 1-Ad) (1 - 目標顏色)
GL_SRC_ALPHA因子 = (As, As, As, As) (源 Alpha 值)
GL_ONE_MINUS_SRC_ALPHA因子 = (1-As, 1-As, 1-As, 1-As) (1 - 源 Alpha 值)
GL_DST_ALPHA因子 = (Ad, Ad, Ad, Ad) (目標 Alpha 值)
GL_ONE_MINUS_DST_ALPHA因子 = (1-Ad, 1-Ad, 1-Ad, 1-Ad) (1 - 目標 Alpha 值)

通過合理選擇混色方案,你可以在 Android OpenGL ES 應用中實現從簡單半透明到復雜特效的各種視覺效果。

創建紋理

	// 存儲紋理IDprivate val texture = IntArray(1)// 用于生成紋理ID是臨時存儲val textureArray = IntArray(1)// 生成紋理ID,存儲到textureArray 中。gl.glGenTextures(1, textureArray, 0)// 保存ID到成員變量,后續使用texture[0] = textureArray[0]

生成紋理:glGenTextures 是 OpenGL 的核心函數,用于創建紋理對象
第一個參數 1:表示生成 1 個紋理
第二個參數 textureArray:存儲生成的紋理 ID
第三個參數 0:表示從數組的第 0 個位置開始存儲

綁定紋理

  • 紋理綁定的基本概念

      紋理綁定是指將一個紋理對象(通過 glGenTextures 生成)關聯到當前 OpenGL 上下文的過程。綁定后,所有對紋理的操作(如設置參數、上傳數據)都將作用于這個紋理對象。OpenGL ES 使用紋理單元(Texture Unit)機制來支持同時使用多個紋理。每個紋理單元可以綁定一個紋理對象,通過 glActiveTexture 切換當前使用的紋理單元。
    

紋理綁定本質

  • 將一個紋理對象(由 textureId 標識)關聯到當前的紋理目標(如 GL_TEXTURE_2D)
  • 狀態覆蓋:每次調用 glBindTexture 都會覆蓋之前的綁定狀態
  • 最終生效:在繪制時,OpenGL 使用的是最后一次綁定的紋理
  • 綁定紋理函數
gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[0])

第一個參數:紋理目標:指定紋理的類型,常見的有:
GL_TEXTURE_2D:二維紋理(最常用)
GL_TEXTURE_CUBE_MAP:立方體貼圖(用于天空盒、反射等)
GL_TEXTURE_3D:三維紋理(OpenGL ES 3.0+ 支持)

第二個參數:紋理 ID:通過 glGenTextures 生成的唯一標識符,代表一個紋理對象

  • 為什么需要綁定紋理?
    OpenGL 使用狀態機模型,所有操作都作用于當前綁定的對象。

綁定紋理的主要目的是:

  • 設置紋理參數:在綁定時設置過濾模式、環繞模式等
  • 上傳紋理數據:將圖像數據(如 Bitmap)加載到紋理中
  • 在繪制時使用紋理:確保正確的紋理被應用到幾何體上

生成紋理

GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, mBitmapTexture, 0)

該方法參數如下:

public static void texImage2D(int target,     // 紋理目標類型int level,      // Mipmap 級別Bitmap bitmap,  // 源 Bitmap 對象int border      // 邊框寬度(必須為 0)
)
  • 對bitmap的尺寸要求

2 的冪尺寸:傳統 OpenGL ES 1.x 和部分設備要求紋理尺寸必須是 2 的冪(如 64×64、256×512)。若使用非 2 的冪(NPOT)紋理,可能需要額外設置紋理參數.
OpenGL ES 2.0+ 支持:現代設備通常支持任意尺寸(需檢查 GL_MAX_TEXTURE_SIZE),但為兼容性建議使用 2 的冪尺寸。

紋理坐標

在 OpenGL ES 中,紋理坐標(Texture Coordinates)用于將 2D 圖像(紋理)映射到 3D 模型的表面。理解紋理坐標的工作原理對實現正確的紋理映射至關重要。

  • 坐標系范圍:紋理坐標使用標準化的 (s, t) 坐標系統,范圍從 (0, 0) 到 (1, 1)。

    • s:水平方向(類似屏幕的 X 軸)。
    • t:垂直方向(類似屏幕的 Y 軸)。
  • 原點位置:(0, 0) 位于紋理的左下角,(1, 1) 位于右上角。

  • 與屏幕坐標的差異:屏幕坐標通常以左上角為原點,而 OpenGL 紋理坐標以左下角為原點,這可能導致紋理顯示時上下顛倒(需特別處理)。

  • 紋理坐標與頂點坐標的映射

    • 紋理坐標需要與頂點坐標一一對應,以確定紋理如何被拉伸或扭曲到模型表面。以下是常見形狀的映射示例:
      圖中是一個正方形,對應原點為中心點,長度為1,對應的紋理坐標,可見左下角頂點坐標(-1,-1,0) 對應的紋理坐標的(0,0)
頂點坐標                 紋理坐標
(-1, 1, 0) ------------ (0, 1)|                       ||                       ||                       |
(-1,-1, 0) ------------ (0, 0)------------(1,-1, 0)   (1, 0)|||------------(1, 1, 0)   (1, 1)

對應代碼如下:

// 頂點坐標(x, y, z)
float[] vertices = {-1f,  1f, 0f,  // 左上-1f, -1f, 0f,  // 左下1f, -1f, 0f,  // 右下1f,  1f, 0f   // 右上
};// 紋理坐標(s, t)
float[] texCoords = {0f, 1f,  // 左上0f, 0f,  // 左下1f, 0f,  // 右下1f, 1f   // 右上
};

圖像配置

線性插值

在 OpenGL ES 中,紋理的線性插值(Linear Interpolation) 是一種紋理過濾技術,用于在紋理被縮放時生成平滑的視覺效果。與最近鄰采樣(GL_NEAREST)相比,線性插值通過計算相鄰紋理像素(紋素)的加權平均值來減少鋸齒和馬賽克現象,尤其適用于紋理被縮小或旋轉的場景。

  • 最近鄰采樣(Nearest Neighbor):

    • 直接選擇離采樣點最近的單個紋素值。
    • 優點:性能高,適合像素藝術風格。
    • 缺點:紋理縮放時會產生明顯鋸齒或馬賽克。
  • 線性插值(Bilinear Filtering):

    • 在水平和垂直方向各取 2×2 個紋素,計算采樣點周圍紋素的加權平均值。
    • 優點:平滑過渡,減少鋸齒。
    • 缺點:模糊化(尤其在大幅縮小時),性能略低于最近鄰。
  • 啟用線性插值

    • 通過 glTexParameteri() 設置紋理過濾模式:
// 綁定紋理后設置過濾模式
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);// 設置縮小過濾為線性插值(紋理被縮小時)
gl.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);// 設置放大過濾為線性插值(紋理被放大時)
gl.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
**GL_LINEAR 代表OpenGL采用簡單的線性插值方式調整圖像。**

為了將圖標貼到正方體的一個面,繪制時根據面來設置紋理,最后會貼出全部代碼。增加紋理部分如下:

private fun setTexture(gl: GL10) {gl.glEnable(GL10.GL_TEXTURE_2D)gl.glEnable(GL10.GL_BLEND)gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA)val textureArray = IntArray(1)gl.glGenTextures(1, textureArray, 0)texture[0] = textureArray[0]// 綁定紋理gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[0])// 當需要縮小時采用線性插值方式gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR)// 當需要放大時采用線性插值的方式gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR)GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, mBitmapTexture, 0)}

繪制時采用紋理的代碼如下(只針對其中一個面):

				// 目標面啟用紋理gl.glEnable(GL10.GL_TEXTURE_2D)gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[0])gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY)gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textCoordsSquare)
public void glTexCoordPointer(int size,        // 每個紋理坐標的分量數int type,        // 數據類型int stride,      // 相鄰兩個紋理坐標之間的字節偏移量java.nio.Buffer pointer  // 數據緩沖區
)
  • size(每個紋理坐標的分量數)取值:必須為 2、3 或 4。

    • 2表示 (s, t) 坐標(最常用)。
    • 3表示 (s, t, r) 坐標(用于 3D 紋理,OpenGL ES 中較少使用)。
    • 4表示 (s, t, r, q) 坐標(用于齊次坐標,OpenGL ES 中極少使用)。
  • pointer(數據緩沖區)

    • 類型:java.nio.Buffer(通常為 FloatBuffer)。
    • 含義:存儲紋理坐標數據的緩沖區,必須為直接緩沖區(Direct Buffer)。

繪制效果如下:Android的Logo。

在這里插入圖片描述

備注:如果一個四邊形的圖片通過紋理的方式貼到三角形上,則選取正方形的三個角的紋理點,對應三角形坐標點。選取的三角形部分會繪制到對應三角形上。

重復效果

先將紋理坐標超過 1.0

// 紋理坐標(左下角為(0,0),右上角為(1,1))private val textureCoords = floatArrayOf(0.0f, 2f,  // 左下 V02f, 2f,  // 右下 V12f, 0.0f,  // 右上 V20.0f, 0.0f   // 左上 V3)

然后增加設置重復設置

		// 設置紋理環繞模式(重復)gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT)gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT)

效果如下:

在這里插入圖片描述
GL_REPEAT:紋理會在超出部分重復平鋪。例如,紋理坐標為 1.5 時,會使用 0.5 處的紋理數據,從而實現紋理在整個表面上重復鋪設的效果,常用于制作無縫紋理背景。

限制拉伸

OpenGLES可以設置簡單地將紋理坐標超過1.0的值限制為1.0,任何低于0.0的值限制為0.0。這實際會引起邊沿像素重復。
將重復設置修改為限制拉伸設置

        gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE)gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE)

效果如下:只顯示了左上角一個圖標。
在這里插入圖片描述

完整代碼

class SquareWithTextureRenderer(private val context: Context) : GLSurfaceView.Renderer {private val vertexBuffer: FloatBufferprivate val indexBuffer: ShortBufferprivate val textureCoordsBuffer: FloatBufferprivate val normalsBuffer: FloatBufferprivate val texture: IntArrayprivate val mBitmapTexture: Bitmapprivate var angle = 0f// 正方形的4個頂點坐標(中心在原點,邊長為1)private val vertices = floatArrayOf(-0.5f, -0.5f, 0.0f,  // 左下 V00.5f, -0.5f, 0.0f,   // 右下 V10.5f, 0.5f, 0.0f,    // 右上 V2-0.5f, 0.5f, 0.0f    // 左上 V3)// 兩個三角形組成正方形的頂點索引private val indices = shortArrayOf(0, 1, 2,  // 第一個三角形2, 3, 0   // 第二個三角形)// 正方形頂點的法線(全部朝向屏幕外,即Z軸正方向)private val normals = floatArrayOf(0.0f, 0.0f, 1.0f,  // 所有頂點法線相同0.0f, 0.0f, 1.0f,0.0f, 0.0f, 1.0f,0.0f, 0.0f, 1.0f)// 紋理坐標(左下角為(0,0),右上角為(1,1))private val textureCoords = floatArrayOf(0.0f, 2f,  // 左下 V02f, 2f,  // 右下 V12f, 0.0f,  // 右上 V20.0f, 0.0f   // 左上 V3)init {// 初始化頂點緩沖區val vbb = ByteBuffer.allocateDirect(vertices.size * 4)vbb.order(ByteOrder.nativeOrder())vertexBuffer = vbb.asFloatBuffer()vertexBuffer.put(vertices)vertexBuffer.position(0)// 初始化索引緩沖區val ibb = ByteBuffer.allocateDirect(indices.size * 2)ibb.order(ByteOrder.nativeOrder())indexBuffer = ibb.asShortBuffer()indexBuffer.put(indices)indexBuffer.position(0)// 初始化紋理坐標緩沖區val tcb = ByteBuffer.allocateDirect(textureCoords.size * 4)tcb.order(ByteOrder.nativeOrder())textureCoordsBuffer = tcb.asFloatBuffer()textureCoordsBuffer.put(textureCoords)textureCoordsBuffer.position(0)// 初始化法線緩沖區val nb = ByteBuffer.allocateDirect(normals.size * 4)nb.order(ByteOrder.nativeOrder())normalsBuffer = nb.asFloatBuffer()normalsBuffer.put(normals)normalsBuffer.position(0)// 加載紋理圖片texture = IntArray(1)mBitmapTexture = BitmapFactory.decodeResource(context.resources, R.drawable.ic_l)}override fun onSurfaceCreated(gl: GL10, config: EGLConfig) {gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f)gl.glEnable(GL10.GL_DEPTH_TEST)gl.glEnableClientState(GL10.GL_VERTEX_ARRAY)gl.glEnableClientState(GL10.GL_NORMAL_ARRAY)setupLight(gl)setMaterial(gl)setTexture(gl)}private fun setTexture(gl: GL10) {gl.glEnable(GL10.GL_TEXTURE_2D)gl.glEnable(GL10.GL_BLEND)gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA)val textureArray = IntArray(1)gl.glGenTextures(1, textureArray, 0)texture[0] = textureArray[0]// 綁定紋理gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[0])// 設置紋理過濾gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR)gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR)// 設置紋理環繞模式
//        gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT)
//        gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT)gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE)gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE)// 加載紋理GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, mBitmapTexture, 0)mBitmapTexture.recycle() // 紋理加載后回收Bitmap}override fun onSurfaceChanged(gl: GL10, width: Int, height: Int) {gl.glViewport(0, 0, width, height)gl.glMatrixMode(GL10.GL_PROJECTION)gl.glLoadIdentity()val aspectRatio = width.toFloat() / heightGLU.gluPerspective(gl, 45.0f, aspectRatio, 0.1f, 1000.0f)gl.glMatrixMode(GL10.GL_MODELVIEW)gl.glLoadIdentity()}override fun onDrawFrame(gl: GL10) {gl.glClear(GL10.GL_COLOR_BUFFER_BIT or GL10.GL_DEPTH_BUFFER_BIT)gl.glLoadIdentity()gl.glShadeModel(GL10.GL_SMOOTH)gl.glTranslatef(0.0f, 0f, -3.0f) // 拉近正方形,使其更清晰
//        gl.glRotatef(angle, 0.0f, 0.0f, 1.0f) // 繞Z軸旋轉//        angle += 1.0f // 旋轉角度遞增// 設置頂點、法線和紋理坐標gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer)gl.glNormalPointer(GL10.GL_FLOAT, 0, normalsBuffer)gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY)gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureCoordsBuffer)// 啟用紋理gl.glEnable(GL10.GL_TEXTURE_2D)gl.glBindTexture(GL10.GL_TEXTURE_2D, texture[0])// 繪制正方形(兩個三角形)gl.glDrawElements(GL10.GL_TRIANGLES, indices.size,GL10.GL_UNSIGNED_SHORT, indexBuffer)// 禁用紋理和緩沖區gl.glDisable(GL10.GL_TEXTURE_2D)gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY)}/*** 設置光效*/private fun setupLight(gl: GL10) {// 啟用光照gl.glEnable(GL10.GL_LIGHTING)gl.glEnable(GL10.GL_LIGHT0)gl.glEnable(GL10.GL_SPECULAR)// 設置環境光val ambientLight = floatArrayOf(0.2f, 0.2f, 0.2f, 1.0f)gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, ambientLight, 0)// 設置漫反射光val diffuseLight = floatArrayOf(0.8f, 0.8f, 0.8f, 1.0f)gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, diffuseLight, 0)// 設置高光val specularLight = floatArrayOf(1.0f, 1.0f, 1.0f, 1.0f)gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_SPECULAR, specularLight, 0)// 設置光源位置(位于正方形前方)val lightPosition = floatArrayOf(0.0f, 0.0f, 1.0f, 0.0f)gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPosition, 0)}private fun setMaterial(gl: GL10) {// 環境元素val ambientLight = floatArrayOf(0f, 0.1f, 0.9f, 1.0f)gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, ambientLight, 0)// 散射元素val diffuseLight = floatArrayOf(0.9f, 0f, 0.1f, 1.0f)gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE, diffuseLight, 0)// 高光元素val specularLight = floatArrayOf(0.9f, 0.9f, 0f, 1.0f)gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_SPECULAR, specularLight, 0)// 反光度gl.glMaterialf(GL10.GL_FRONT_AND_BACK, GL10.GL_SHININESS, 25F)// 自發光val emissionLight = floatArrayOf(0.0f, 0.4f, 0f, 1.0f)gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_EMISSION, emissionLight, 0)}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/90385.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/90385.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/90385.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

從金字塔到個性化路徑:AI 正在重新定義學習方式

幾十年來,我們的教育系統始終遵循著一條熟悉的路線: 從小學、初中、高中,再到大學和研究生。這條標準化的路徑(K-12 到研究所)結構清晰,卻也緩慢。但在當今這個信息爆炸、知識快速更新、個性化需求高漲的時…

產品經理崗位職責拆解

以下是產品經理崗位職責的詳細分解表,涵蓋工作內容、核心動作及輸出成果:崗位職責具體工作內容輸出成果1. 日常版本迭代管理需求分析及PRD產出協調資源推動產品上線- 收集業務/用戶需求,分析可行性及優先級- 撰寫PRD文檔,明確功能…

后端微服務基礎架構Spring Cloud

版本關系 版本發布說明-阿里云Spring Cloud Alibaba官網 選擇 創建項目 創建父項目 什么都不動&#xff0c;創建即可 1) 刪掉沒用的文件 保留 2) pom中加入 打包方式 <packaging>pom</packaging> 3) 刪掉src 4) pom.xml中刪除沒用的 5)更改pom.xml中 spring…

數據分析框架和方法

一、核心分析框架 (The Big Picture Frameworks)??描述性分析 (What Happened?)????目的&#xff1a;?? 了解過去發生了什么&#xff0c;描述現狀&#xff0c;監控業務健康。??核心工作&#xff1a;?? 匯總、聚合、計算基礎指標 (KPI)&#xff0c;生成報表和儀表盤…

電路研究9.3.10——合宙Air780EP中的AT開發指南:阿里云應用指南

這個好像也用不到&#xff0c;不過可以先貼出來。簡單看了一下也沒深入分析&#xff0c;直接扒過來了&#xff0c;感覺涉及到了上位機的學習了。我這下位機的可能用不到&#xff0c;就是貼過來好了。 應用概述 使用 AT 方式連接阿里云分為一機一密和一型一密&#xff0c;其中一…

[Backlog] 核心協調器 | 終端用戶界面(TUI)實現 | 多分支任務沖突解決 | 測試驗證體系

第8章 核心協調器 歡迎回到Backlog.md&#xff01; 在上一章文件系統操作中&#xff0c;我們深入了解了數據物理存儲層面的讀寫機制。本章將聚焦系統的神經中樞——核心協調器。 核心協調器的本質&#xff08;中央決策引擎&#xff09; 如果將Backlog.md視為項目管理團隊&a…

車載以太網-TC8測試-UT(Upper Tester)

目錄 一、技術原理:指令體系與協議適配1. **指令格式與傳輸機制**2. **協議棧交互邏輯**3. **規范遵循與版本演進**二、測試應用:TC8測試場景與案例1. **TCP協議棧深度驗證**2. **ARP協議健壯性測試**3. **SOME/IP服務動態管理**三、實現挑戰與解決方案1. **實時性要求**2. *…

扣子Coze純前端部署多Agents

純前端網頁搭建&#xff0c;無需任何后端代碼&#xff0c;方便快捷&#xff01; 就像公司前臺的多功能控制臺&#xff0c;員工可以通過按鈕快速呼叫不同的AI助手。具備多設備適配、智能對話等基礎能力。 支持添加多個智能體 配置方式 添加智能體信息&#xff0c;data-bot為智…

STM32中I2C協議詳解

前言 在嵌入式系統中&#xff0c;設備間的短距離通信協議中&#xff0c;I2C&#xff08;Inter-Integrated Circuit&#xff0c;集成電路互連&#xff09;以其信號線少、布線簡單、支持多從機等特點&#xff0c;被廣泛應用于傳感器、EEPROM、OLED屏等中低速外設的通信場景。與SP…

解鎖Spring Boot多項目共享Redis:優雅Key命名結構指南

引言Redis 基礎與 Spring Boot 集成Redis 簡介Redis&#xff0c;即 Remote Dictionary Server&#xff0c;是一個開源的基于內存的數據結構存儲系統&#xff0c;可用作數據庫、緩存和消息中間件 。它具備諸多顯著特性&#xff0c;使其在現代軟件開發中占據重要地位。Redis 的讀…

《重構項目》基于Apollo架構設計的項目重構方案(多種地圖、多階段、多任務、狀態機管理)

1. 項目結構設計project/ ├── config/ # 配置文件&#xff08;定義 Scenario、Stage、Task 的映射&#xff09; ├── src/ │ ├── base/ # 抽象基類定義 │ │ ├── scenario_base.h/.cpp │ │ ├── stage_base.h/.cpp…

動手學深度學習13.6. 目標檢測數據集-筆記練習(PyTorch)

以下內容為結合李沐老師的課程和教材補充的學習筆記&#xff0c;以及對課后練習的一些思考&#xff0c;自留回顧&#xff0c;也供同學之人交流參考。 本節課程地址&#xff1a;數據集_嗶哩嗶哩_bilibili 本節教材地址&#xff1a;13.6. 目標檢測數據集 — 動手學深度學習 2.0…

Unity3D游戲內存優化指南

前言 Unity3D 游戲的內存控制是保證游戲流暢運行&#xff08;尤其在移動端和主機平臺&#xff09;和避免崩潰的關鍵挑戰。以下是核心策略和常見問題的解決方案&#xff1a; 對惹&#xff0c;這里有一個游戲開發交流小組&#xff0c;希望大家可以點擊進來一起交流一下開發經驗…

git學習:首次創建倉庫

文章目錄前言&#xff1a;1、首次創建倉庫并上傳數據1.1 創建倉庫&#xff0c;1.2 命令上傳1.3 首次代碼上傳至倉庫的步驟&#xff1a;2、分支操作2.1 分支的刪除2.2 切換分支2.3 查看分支2.4 同步其他分支的修改3、查看電腦的配置文件4、遠程倉庫命令 git remote5、其他后語前…

C++并行計算:OpenMP與MPI全解析

在高性能計算領域&#xff0c;充分利用硬件資源的并行計算技術已成為剛需。從單節點多核到跨節點集群&#xff0c;開發者需要掌握不同的并行編程模型。本文將系統講解兩種主流并行技術&#xff1a;OpenMP&#xff08;共享內存多核并行&#xff09;與MPI&#xff08;分布式內存集…

TCP 動態選路協議全面研究:OSPF、BGP 與 IS-IS 的比較與應用分析

一、引言&#xff1a;動態選路協議概述 在現代計算機網絡中&#xff0c;路由選擇是數據傳輸的核心功能&#xff0c;它決定了數據包從源到目的地的路徑選擇。隨著網絡規模的不斷擴大和復雜性的增加&#xff0c;靜態路由已經無法滿足網絡動態變化的需求&#xff0c;動態路由協議…

OpenCV 圖像哈希類cv::img_hash::AverageHash

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 cv::img_hash::AverageHash是OpenCV中用于圖像哈希&#xff08;Image Hashing&#xff09;的一個類&#xff0c;屬于opencv_img_hash模塊。它實現了…

【Python-網絡爬蟲】爬蟲的基礎概念介紹

目錄 一、爬蟲的介紹 1.1 爬蟲的概念 1.2 爬蟲的作用 1. 搜索引擎數據索引 2. 商業數據采集與分析 3. 輿情監控與社交分析 4. 學術研究與數據挖掘 5. 信息聚合與服務優化 二、爬蟲的分類 三、爬蟲的基本流程 3.1 基本流程 3.2 Robots協議 一、爬蟲的介紹 1.1 爬蟲的…

力扣-31.下一個排列

題目鏈接 31.下一個排列 class Solution {public void nextPermutation(int[] nums) {//1.從右往左找第一個非逆序的數aint left nums.length - 2; //這里是為了找不到順序對的時候正好停在-1while (left > 0 && nums[left] > nums[left 1]) { //一定要取等號…

Python爬蟲實戰:研究python-nameparser庫相關技術

1. 引言 在當今數字化時代,姓名作為個人身份的重要標識,在許多領域都有著廣泛的應用需求。例如,在客戶關系管理系統中,準確解析姓名可以幫助企業更好地了解客戶背景;在學術研究中,分析作者姓名分布有助于發現研究團隊的地域特征;在社交網絡分析中,姓名信息可以輔助進行…