首页 > 解决方案 > 当我想在 OpenGL 中的 3d 立方体的一个面上显示纹理时出现问题

问题描述

今天,我试图在一个 3d 立方体的一个面上显示两个纹理。我达到了我的目标。问题出在其他面上,它们也显示出奇怪的纹理。

我检查了纹理的坐标,只显示了主面。

private float textureCord[] = {
        // Mapping coordinates for the vertices
        // Front face
        1.2f, 1.2f,
        1.2f, -0.2f,
        -0.2f, -0.2f,
        -0.2f, 1.2f
};

其次,我添加这些行是为了防止重复。

            GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);

它有帮助,但仍然无法正常工作。

结果

任何帮助将不胜感激,谢谢

立方类:

public class Cubo {

private Context context;
private final String vertexShaderCode =
        "uniform mat4 uMVPMatrix;" +
                "attribute vec4 vPosition;" +
                "attribute vec4 aColor;" +
                "varying vec4 vColor;" +
                "attribute vec2 a_TexCoordinate0;" +
                "varying vec2 v_TexCoordinate0;" +
                "attribute vec2 a_TexCoordinate1;" +
                "varying vec2 v_TexCoordinate1;" +
                "void main() {" +
                "  vColor=aColor;" +
                "  gl_Position = uMVPMatrix * vPosition;" +
                "  v_TexCoordinate0 = a_TexCoordinate0;" +
                "  v_TexCoordinate1 = a_TexCoordinate1;" +
                "}";

private final String fragmentShaderCode =
        "precision mediump float;" +
                "uniform sampler2D u_Texture0;" +
                "uniform sampler2D u_Texture1;" +
                "uniform vec4 aColor;" +
                "varying vec2 v_TexCoordinate0;" +
                "varying vec2 v_TexCoordinate1;" +
                "void main() {" +
                "   vec4 base = texture2D(u_Texture0, v_TexCoordinate0);" +
                "   vec4 overlay = texture2D(u_Texture1, v_TexCoordinate1);" +
                "   mediump float ra = (overlay.a) * overlay.r + (1.0 - overlay.a) * base.r;" +
                "   mediump float ga = (overlay.a) * overlay.g + (1.0 - overlay.a) * base.g;" +
                "   mediump float ba = (overlay.a) * overlay.b + (1.0 - overlay.a) * base.b;" +
                "   vec3 textureColor = vec3(ra, ga, ba);" +
                "   float textureAlpha = max(base.a, overlay.a);" +
                "   gl_FragColor = vec4(mix(aColor.rgb, textureColor, textureAlpha), 1.0);" +
                "}";

private final FloatBuffer vertexBuffer;
private final ShortBuffer drawListBuffer;
private FloatBuffer mTextureBuffer;
private final int mProgram;
private int mPositionHandle;
private int mColorHandle;
private int mMVPMatrixHandle;
private final int mTextureCoordinateDataSize = 2;


static final int COORDS_PER_VERTEX = 3;
static float cubeCoords[] = {
        -0.5f, 0.5f, 0.5f,   // top left
        -0.5f, -0.5f, 0.5f,   // bottom left
        0.5f, -0.5f, 0.5f,   // bottom right
        0.5f, 0.5f, 0.5f,  // top right
        -0.5f, 0.5f, -0.5f,   // top left back
        -0.5f, -0.5f, -0.5f,   // bottom left back
        0.5f, -0.5f, -0.5f,   // bottom right back
        0.5f, 0.5f, -0.5f  // top right back
};

private final short drawOrder[] = {0, 1, 2, 0, 2, 3,
        3, 2, 6, 3, 6, 7,
        0, 3, 7, 0, 7, 4,
        1, 5, 6, 1, 6, 2,
        4, 5, 1, 4, 1, 0,
        7, 6, 5, 7, 5, 4};

private final int vertexStride = COORDS_PER_VERTEX * 4;


float color[] = {0.63671875f, 0.76953125f, 0.22265625f, 0.0f};

private float textureCord[] = {
        // Mapping coordinates for the vertices
        // Front face
        1.2f, 1.2f,
        1.2f, -0.2f,
        -0.2f, -0.2f,
        -0.2f, 1.2f
};

private int[] textures = new int[2];

private int[] bitmapsId = {
        R.drawable.horizontal,
        R.drawable.casilla27
};


public Cubo(Context context) {
    this.context = context;
    ByteBuffer bb = ByteBuffer.allocateDirect(
            cubeCoords.length * 4);
    bb.order(ByteOrder.nativeOrder());
    vertexBuffer = bb.asFloatBuffer();
    vertexBuffer.put(cubeCoords);
    vertexBuffer.position(0);

    ByteBuffer dlb = ByteBuffer.allocateDirect(
            drawOrder.length * 2);
    dlb.order(ByteOrder.nativeOrder());
    drawListBuffer = dlb.asShortBuffer();
    drawListBuffer.put(drawOrder);
    drawListBuffer.position(0);

    ByteBuffer byteBuf = ByteBuffer.allocateDirect(textureCord.length * 4);
    byteBuf.order(ByteOrder.nativeOrder());
    mTextureBuffer = byteBuf.asFloatBuffer();
    mTextureBuffer.put(textureCord);
    mTextureBuffer.position(0);

    int vertexShader = MyGLRenderer.loadShader(
            GLES20.GL_VERTEX_SHADER,
            vertexShaderCode);
    int fragmentShader = MyGLRenderer.loadShader(
            GLES20.GL_FRAGMENT_SHADER,
            fragmentShaderCode);

    mProgram = GLES20.glCreateProgram();             // create empty OpenGL Program
    GLES20.glAttachShader(mProgram, vertexShader);   // add the vertex shader to program
    GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
    GLES20.glLinkProgram(mProgram);                  // create OpenGL program executables
}

public void draw(float[] mvpMatrix) {
    GLES20.glUseProgram(mProgram);
    mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
    GLES20.glEnableVertexAttribArray(mPositionHandle);
    GLES20.glVertexAttribPointer(
            mPositionHandle, COORDS_PER_VERTEX,
            GLES20.GL_FLOAT, false,
            vertexStride, vertexBuffer);
    mColorHandle = GLES20.glGetAttribLocation(mProgram, "aColor");
    GLES20.glUniform4fv(mColorHandle, 1, color, 0);
    mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
    //---------------textura-------------------
    for (int i = 0; i < textures.length; i++) {
        int mTextureUniformHandle = GLES20.glGetUniformLocation(mProgram, "u_Texture" + i);
        int mTextureCoordinateHandle = GLES20.glGetAttribLocation(mProgram, "a_TexCoordinate" + i);
        GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle);
        GLES20.glVertexAttribPointer(mTextureCoordinateHandle, mTextureCoordinateDataSize, GLES20.GL_FLOAT, false,
                0, mTextureBuffer);
        GLES20.glActiveTexture(i == 0 ? GLES20.GL_TEXTURE0 : GLES20.GL_TEXTURE1);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[i]);
        GLES20.glUniform1i(mTextureUniformHandle, i);
    }
    //------------------------------------------
    GLES20.glDrawElements(
            GLES20.GL_TRIANGLES, drawOrder.length,
            GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
    GLES20.glDisableVertexAttribArray(mPositionHandle);
}

public void loadTexture() {
    GLES20.glGenTextures(2, textures, 0);
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inScaled = false;
    for (int i = 0; i < textures.length; i++) {
        final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), bitmapsId[i], options);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[i]);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
        bitmap.recycle();
    }
}

}

渲染器:

public class MyGLRenderer implements GLSurfaceView.Renderer {


private Cubo cubo;
private Context context;
private final float[] mMVPMatrix = new float[16];
private final float[] mProjectionMatrix = new float[16];
private final float[] mViewMatrix = new float[16];
private final float[] mRotationMatrix_x = new float[16];
private final float[] mRotationMatrix_y = new float[16];
private final float[] mRotationMatrix = new float[16];

private float mXAngle;
private float mYAngle;

public MyGLRenderer(Context context) {
    this.context = context;
}

@Override
public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
    GLES20.glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
    GLES20.glClearDepthf(1.0f);
    GLES20.glEnable(GL10.GL_DEPTH_TEST);
    cubo = new Cubo(context);
    cubo.loadTexture();
}

@Override
public void onSurfaceChanged(GL10 gl10, int i, int i1) {
    GLES20.glViewport(0, 0, i, i1);
    float ratio = (float) i / i1;
    Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
}

@Override
public void onDrawFrame(GL10 gl10) {
    float[] scratch = new float[16];
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
    Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -4, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
    Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);
    Matrix.setRotateM(mRotationMatrix_x, 0, mYAngle, 1.0f, 0, 0);
    Matrix.setRotateM(mRotationMatrix_y, 0, mXAngle, 0, 1.0f,  0);
    Matrix.multiplyMM(mRotationMatrix, 0, mRotationMatrix_y, 0, mRotationMatrix_x, 0);
    Matrix.multiplyMM(scratch, 0, mMVPMatrix, 0, mRotationMatrix, 0);
    cubo.draw(scratch);
}


public static int loadShader(int type, String shaderCode) {
    int shader = GLES20.glCreateShader(type);
    GLES20.glShaderSource(shader, shaderCode);
    GLES20.glCompileShader(shader);
    return shader;
}

public float getmXAngle() {
    return mXAngle;
}

public void setmXAngle(float mXAngle) {
    this.mXAngle = mXAngle;
}

public float getmYAngle() {
    return mYAngle;
}

public void setmYAngle(float mYAngle) {
    this.mYAngle = mYAngle;
}

标签: javaandroidopengl-es

解决方案


推荐阅读