有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java OpenGL纹理不遵循几何体

我正在与OpenGL ES 1复杂性的跳跃作斗争。x到2.0。我试图将纹理应用于矩形平面,然后能够缩放和平移该平面,同时保持纹理正确映射

我的问题是:我做错了什么?在平移和缩放平面时,我将如何对平面进行纹理处理

我将发布渲染器类、对象用于绘制自身的类以及顶点和片段着色器:

GL渲染器:

package com.detour.raw;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import 安卓.content.Context;
import 安卓.graphics.Bitmap;
import 安卓.opengl.GLES20;
import 安卓.opengl.GLSurfaceView;
import 安卓.opengl.Matrix;

public class GameRenderer implements GLSurfaceView.Renderer{

private static final String TAG = "GameRenderer";
Context mContext;
Bitmap bitmap;

private float red = 0.5f;
private float green = 0.5f;
private float blue = 0.5f;

Shader shader;
int program;
FPSCounter fps;
Sprite sprite;
Sprite sprite2;
int x = 0;

private int muMVPMatrixHandle;

private float[] mMVPMatrix = new float[16];
private float[] mProjMatrix = new float[16];
private float[] mMVMatrix = new float[16];
//private float[] mVMatrix = new float[16];
//private float[] mMMatrix = new float[16];
//private float[] mVPMatrix = new float[16];
//private float[] mIMatrix = new float[16];



public GameRenderer(Context context){
    mContext = context;

    //create objects/sprites
    sprite = new Sprite(mContext);
    sprite2 = new Sprite(mContext);
    fps = new FPSCounter();
}

@Override
public void onDrawFrame(GL10 gl) {

    GLES20.glClearColor(red, green, blue, 1.0f);
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

    GLES20.glUseProgram(program);
    //Matrix.setIdentityM(mIMatrix, 0);

    //Matrix.multiplyMM(mMVMatrix, 0, mVMatrix, 0, mMMatrix, 0);
    Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVMatrix , 0);

    GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);

    sprite.draw();
    /*if(x>3){
        x=0;
    }
    if(x%2==0){
        sprite.draw();
    }else{
        sprite2.draw();
    }
    x++;*/

    //fps.calculate();
    //fps.draw(gl);
}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {

    GLES20.glViewport(0, 0, width, height);
    float ratio = ((float)(width))/((float)(height));
    Matrix.orthoM(mProjMatrix, 0, -ratio, ratio, -1, 1, 0.5f, 10);
    Matrix.setLookAtM(mMVMatrix, 0, 0, 0, 1.0f, 0.0f, 0f, 0f, 0f, 1.0f, 0.0f);
}

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    // TODO Auto-generated method stub

    /*int error = GLES20.glGetError();
    Log.d(LOG_TAG, ""+error);*/

    shader = new Shader(R.raw.sprite_vs, R.raw.sprite_fs, mContext);
    program = shader.getProgram();

    muMVPMatrixHandle = GLES20.glGetUniformLocation(program, "u_MVPMatrix");

    GLES20.glEnable(GLES20.GL_TEXTURE_2D);
    GLES20.glEnable(GLES20.GL_DEPTH_TEST);
    GLES20.glClearDepthf(1.0f);
    GLES20.glDepthFunc(GLES20.GL_LEQUAL);
    GLES20.glDepthMask(true);
    GLES20.glEnable(GLES20.GL_CULL_FACE);
    GLES20.glCullFace(GLES20.GL_BACK);
    GLES20.glClearColor(red, green, blue, 1.0f);


    sprite.loadGLTexture(R.drawable.raw1a, program);
    sprite2.loadGLTexture(R.drawable.raw2, program);

    System.gc();
}

}

可提取类别:

package com.detour.raw;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

import 安卓.content.Context;
import 安卓.graphics.Bitmap;
import 安卓.graphics.BitmapFactory;
import 安卓.opengl.GLES20;
import 安卓.opengl.GLUtils;

public class RenderVisible implements Renderable{

Context mContext;
Bitmap bitmap;

private int vertexHandle;
private int texCoordHandle;
private int textureHandle;

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

private float textureCoordinates[] = {
        0.0f, 0.0f,
        0.0f, 1.0f,
        1.0f, 1.0f,
        1.0f, 0.0f
        };

private float vertices[] = {
        -1.0f,  1.0f,// 0.0f,
        -1.0f, -1.0f,// 0.0f,
         1.0f, -1.0f,// 0.0f,
         1.0f,  1.0f// 0.0f,
         };

private short[] indices = {
        0, 1, 2,
        0, 2, 3};

private FloatBuffer vertexBuffer;
private FloatBuffer textureBuffer;
private ShortBuffer indexBuffer;


public RenderVisible(Context context){

    mContext = context;

    ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
    vbb.order(ByteOrder.nativeOrder());
    vertexBuffer = vbb.asFloatBuffer();
    vertexBuffer.put(vertices);
    vertexBuffer.position(0);

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

    ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
    ibb.order(ByteOrder.nativeOrder());
    indexBuffer = ibb.asShortBuffer();
    indexBuffer.put(indices);
    indexBuffer.position(0);

}

@Override
public void draw() {

    GLES20.glEnableVertexAttribArray(vertexHandle);
    GLES20.glVertexAttribPointer(vertexHandle, 2, GLES20.GL_FLOAT, false, 0, vertexBuffer);
    GLES20.glVertexAttribPointer(texCoordHandle, 2, GLES20.GL_FLOAT, false, 0, textureBuffer);
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
    GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.length, GLES20.GL_UNSIGNED_SHORT, indexBuffer);

}

@Override
public void loadGLTexture(int id, int program) {

    vertexHandle = GLES20.glGetAttribLocation(program, "a_position");
    texCoordHandle = GLES20.glGetAttribLocation(program, "a_texcoord");
    textureHandle = GLES20.glGetUniformLocation(program, "u_texture");

    bitmap = BitmapFactory.decodeResource(mContext.getResources(), id);
    /*InputStream is = mContext.getResources().openRawResource(id);
    try {
        bitmap = BitmapFactory.decodeStream(is);
    } finally {
        try {
            is.close();
            is = null;
        } catch (IOException e) {
        }
    }*/

    GLES20.glGenTextures(1, textures, 0);
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
    GLES20.glUniform1i(textureHandle, 0);

    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);

    //GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, FRAME_WIDTH, FRAME_HEIGHT, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, byteBuf);//(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);

    bitmap.recycle();
}

}

片段着色器:

precision mediump float;

uniform sampler2D u_texture;

varying vec2 v_texcoord;

void main()
{
    gl_FragColor = texture2D(u_texture, v_texcoord);
}

顶点着色器:

attribute vec2 a_position;
attribute vec2 a_texcoord;

uniform mat4 u_MVPMatrix;

varying vec2 v_texcoord;

void main()
{
    gl_Position = vec4(a_position, 0.0, 1.0) * u_MVPMatrix;
    v_texcoord = a_position * vec2(0.5, -0.5) + vec2(0.5);
}

当我像这样运行程序时,我得到了预期的结果:

enter image description here

当我更改可渲染对象的顶点时(在本例中,所有顶点都将每个值除以2),平面的形状将发生更改,但纹理不会以我所期望的方式随之移动。我不知道为什么(解释一下就好了)

enter image description here

当我修复平面的顶点并更改顶点着色器以接受我给它的纹理坐标(v_texcoord = a_texcoord;)时,我得到了正确大小的正方形,但纹理不可见/正方形是完全白色的

我还尝试为renderable(RenderVisible)类创建方法,以简化精灵的移动和缩放。我该怎么做


共 (1) 个答案

  1. # 1 楼答案

    纹理坐标是顶点坐标的函数,这就是这种行为的原因,要解决它,只需更改顶点着色器:

    v_texcoord = a_texcoord;
    

    所以你使用恒定的纹理坐标。还要记住启用纹理坐标顶点属性:

    GLES20.glEnableVertexAttribArray(texCoordHandle);