You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android OpenGL:为Square类添加Bitmap纹理及教程拓展咨询

How to Add Bitmap Texture to the Square Class in the Android OpenGL Tutorial

Great question! Let's walk through the step-by-step modifications needed to make your Square class use a Bitmap as a texture, plus cover the extension content available in the official tutorial.


1. Update the Square Class for Texture Support

First, modify your Square class to handle texture coordinates, texture IDs, and shader uniforms:

public class Square {
    // Existing variables (vertices, program handles, etc.)
    private FloatBuffer mVertexBuffer;
    private int mProgram;
    private int mPositionHandle;

    // New texture-related variables
    private int mTextureId;
    private int mTextureCoordinateHandle;
    private int mTextureUniformHandle;
    private FloatBuffer mTextureCoordinateBuffer;

    // Texture coordinate array (maps to square vertices)
    private final float[] mTextureCoordinates = {
        0.0f, 0.0f, // Bottom-left
        1.0f, 0.0f, // Bottom-right
        0.0f, 1.0f, // Top-left
        1.0f, 1.0f  // Top-right
    };

    public Square() {
        // Existing vertex buffer initialization...

        // Initialize texture coordinate buffer
        ByteBuffer byteBuf = ByteBuffer.allocateDirect(mTextureCoordinates.length * 4);
        byteBuf.order(ByteOrder.nativeOrder());
        mTextureCoordinateBuffer = byteBuf.asFloatBuffer();
        mTextureCoordinateBuffer.put(mTextureCoordinates);
        mTextureCoordinateBuffer.position(0);

        // Compile shaders (update this to use texture-enabled shaders)
        int vertexShader = loadShader(GLES32.GL_VERTEX_SHADER, vertexShaderCode);
        int fragmentShader = loadShader(GLES32.GL_FRAGMENT_SHADER, fragmentShaderCode);
        mProgram = GLES32.glCreateProgram();
        GLES32.glAttachShader(mProgram, vertexShader);
        GLES32.glAttachShader(mProgram, fragmentShader);
        GLES32.glLinkProgram(mProgram);

        // Get handles for texture attributes/uniforms
        mPositionHandle = GLES32.glGetAttribLocation(mProgram, "vPosition");
        mTextureCoordinateHandle = GLES32.glGetAttribLocation(mProgram, "a_TexCoordinate");
        mTextureUniformHandle = GLES32.glGetUniformLocation(mProgram, "u_Texture");
    }

    // Setter for texture ID (called from renderer)
    public void setTextureId(int textureId) {
        mTextureId = textureId;
    }

    public void draw() {
        GLES32.glUseProgram(mProgram);

        // Enable vertex position attribute
        GLES32.glVertexAttribPointer(mPositionHandle, 3, GLES32.GL_FLOAT, false, 0, mVertexBuffer);
        GLES32.glEnableVertexAttribArray(mPositionHandle);

        // Enable texture coordinate attribute
        GLES32.glVertexAttribPointer(mTextureCoordinateHandle, 2, GLES32.GL_FLOAT, false, 0, mTextureCoordinateBuffer);
        GLES32.glEnableVertexAttribArray(mTextureCoordinateHandle);

        // Activate and bind the texture
        GLES32.glActiveTexture(GLES32.GL_TEXTURE0);
        GLES32.glBindTexture(GLES32.GL_TEXTURE_2D, mTextureId);
        GLES32.glUniform1i(mTextureUniformHandle, 0); // Tell shader to use texture unit 0

        // Draw the square
        GLES32.glDrawArrays(GLES32.GL_TRIANGLE_STRIP, 0, 4);

        // Clean up
        GLES32.glDisableVertexAttribArray(mPositionHandle);
        GLES32.glDisableVertexAttribArray(mTextureCoordinateHandle);
    }

    // Existing loadShader method...

    // Updated shader code
    private final String vertexShaderCode = "#version 320 es\n" +
            "layout (location = 0) in vec4 vPosition;\n" +
            "layout (location = 1) in vec2 a_TexCoordinate;\n" +
            "out vec2 v_TexCoordinate;\n" +
            "void main() {\n" +
            "  gl_Position = vPosition;\n" +
            "  v_TexCoordinate = a_TexCoordinate;\n" +
            "}";

    private final String fragmentShaderCode = "#version 320 es\n" +
            "precision mediump float;\n" +
            "uniform sampler2D u_Texture;\n" +
            "in vec2 v_TexCoordinate;\n" +
            "out vec4 fragColor;\n" +
            "void main() {\n" +
            "  fragColor = texture(u_Texture, v_TexCoordinate);\n" +
            "}";
}

2. Load Bitmap as OpenGL Texture in MyGLRenderer

Add a method to convert a Bitmap into an OpenGL texture, then pass it to your Square instance:

public class MyGLRenderer implements GLSurfaceView.Renderer {
    private Square mSquare;
    private Context mContext;

    public MyGLRenderer(Context context) {
        mContext = context;
    }

    @Override
    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
        // Set background color
        GLES32.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

        mSquare = new Square();

        // Load your bitmap (replace with your image resource)
        Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.your_texture_image);
        int textureId = loadTextureFromBitmap(bitmap);
        mSquare.setTextureId(textureId);
    }

    // Helper method to load texture from Bitmap
    private int loadTextureFromBitmap(Bitmap bitmap) {
        int[] textureIds = new int[1];
        GLES32.glGenTextures(1, textureIds, 0);
        int textureId = textureIds[0];

        // Bind texture and set parameters
        GLES32.glBindTexture(GLES32.GL_TEXTURE_2D, textureId);
        GLES32.glTexParameteri(GLES32.GL_TEXTURE_2D, GLES32.GL_TEXTURE_MIN_FILTER, GLES32.GL_LINEAR);
        GLES32.glTexParameteri(GLES32.GL_TEXTURE_2D, GLES32.GL_TEXTURE_MAG_FILTER, GLES32.GL_LINEAR);
        GLES32.glTexParameteri(GLES32.GL_TEXTURE_2D, GLES32.GL_TEXTURE_WRAP_S, GLES32.GL_CLAMP_TO_EDGE);
        GLES32.glTexParameteri(GLES32.GL_TEXTURE_2D, GLES32.GL_TEXTURE_WRAP_T, GLES32.GL_CLAMP_TO_EDGE);

        // Load bitmap data into texture
        GLUtils.texImage2D(GLES32.GL_TEXTURE_2D, 0, bitmap, 0);
        bitmap.recycle(); // Free bitmap memory

        return textureId;
    }

    // Existing onDrawFrame and onSurfaceChanged methods...
}

Yes! The official Android OpenGL training series includes several advanced topics that build on the basic square example:

  • 3D Graphics: Learn to render 3D objects, use perspective projection, and implement camera controls.
  • Lighting & Materials: Add ambient, diffuse, and specular lighting to create realistic scene visuals.
  • Framebuffer Objects: Implement off-screen rendering for effects like shadows, reflections, or post-processing.
  • 3D Model Loading: Work with common 3D formats (e.g., OBJ) and load complex models into your app.
  • Performance Optimization: Tips for reducing draw calls, using vertex buffer objects (VBOs) efficiently, and optimizing shader code.

These topics are part of the same training pathway you're already following, so you can continue exploring there for deeper dives.

内容的提问来源于stack exchange,提问作者TinFellow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:58:44