基于GLES20实现纹理右上角定位与逐帧旋转的技术咨询
Let's break this down step by step—you've got two main goals, plus a bug to fix where both your camera feed and overlay texture are rotating together. Here's how to sort it all out:
Right now, your vertex coordinates are set to fill the entire screen. To pin the texture to the top-right, you need to define a smaller quad in normalized device coordinates (NDC, where (-1,-1) is bottom-left and (1,1) is top-right) and use that instead of full-screen vertices.
Example Vertex Coordinates for Top-Right Quad
Let's make a quad that takes up the top-right 1/4 of the screen (adjust the values to resize it as needed):
// Top-right quad vertices (NDC) private static final float[] TOP_RIGHT_VERTICES = { 0.5f, 1.0f, // Top-left corner of the quad (top-right of screen) 0.5f, 0.5f, // Bottom-left corner of the quad 1.0f, 1.0f, // Top-right corner of the quad 1.0f, 0.5f // Bottom-right corner of the quad }; // Keep your original texture coordinates to display the bitmap correctly private static final float[] TEXTURE_COORDS = { 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f };
When drawing, bind these top-right vertices instead of your full-screen ones. Also, make sure to draw the camera feed first (using full-screen vertices) before drawing the overlay texture—this ensures the texture sits on top.
The problem with your current setup is that you're applying the rotation matrix to everything (camera + texture). We need to isolate the rotation to only the overlay texture by using separate shader programs or toggling matrix usage per draw call.
Step 1: Use Separate Shader Programs
- Keep your original
DEFAULT_VERTEX_SHADER(no matrix) for the camera feed. - Keep your modified vertex shader (with
uMVPMatrix) exclusively for the texture overlay.
Step 2: Rotate Around the Texture's Center
By default, OpenGL rotates around the NDC origin (0,0). To make the texture spin around its own center, we need to translate the quad to the origin, rotate it, then translate it back to the top-right position.
Updated Draw Code
private float rotation = 0.0f; private float[] mvpMatrix = new float[16]; private int textureMVPMatrixHandle; // Get this in your setup via glGetUniformLocation @Override public void onDraw() { super.onDraw(); // 1. Draw camera feed first (full screen, no rotation) switchToCameraShader(); // Activate camera's shader program bindFullScreenVertices(); // Bind your original full-screen vertices drawCameraFeed(); // Execute draw call for camera // 2. Draw rotating top-right texture if (bitmap == null || bitmap.isRecycled()) return; switchToTextureShader(); // Activate texture's shader program bindTopRightVertices(); // Bind the top-right quad vertices we defined // Update rotation matrix (spin around texture's center) Matrix.setIdentityM(mvpMatrix, 0); // Calculate texture quad center in NDC: (0.75f, 0.75f) for our 1/4 screen quad Matrix.translateM(mvpMatrix, 0, 0.75f, 0.75f, 0.0f); // Move to origin Matrix.rotateM(mvpMatrix, 0, rotation, 0.0f, 0.0f, 1.0f); // Rotate Matrix.translateM(mvpMatrix, 0, -0.75f, -0.75f, 0.0f); // Move back to top-right rotation += 1.0f; // Increment rotation each frame if (rotation >= 360f) rotation = 0f; // Reset to avoid overflow // Pass matrix to texture shader GLES20.glUniformMatrix4fv(textureMVPMatrixHandle, 1, false, mvpMatrix, 0); // Bind and draw the texture int offsetDepthMapUniform = getHandle("oTexture"); GLES20.glActiveTexture(GLES20.GL_TEXTURE3); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]); GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, bitmap, 0); GLES20.glUniform1i(offsetDepthMapUniform, 3); drawTextureQuad(); // Execute draw call for the texture releaseBitmap(); }
- Shader Isolation: Using separate shader programs ensures your camera feed doesn't inherit the texture's rotation matrix.
- NDC Precision: Double-check your vertex coordinates to make sure the texture lands exactly where you want it. Adjust the
0.5fvalues inTOP_RIGHT_VERTICESto resize the quad. - Matrix Order: OpenGL applies matrix operations in reverse order, so translate → rotate → translate back gives you a rotation around the texture's center.
内容的提问来源于stack exchange,提问作者XtremePlayer

