gpt4 book ai didi

java - OpenGL 纹理不遵循几何

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:59:02 26 4
gpt4 key购买 nike

我正在努力应对从 OpenGL ES 1.x 到 2.0 的复杂性跃升。我正在尝试将纹理应用于矩形平面,然后能够在保持纹理正确映射的同时缩放和平移该平面。

我的问题是:我哪里做错了,我如何才能在平移和缩放平面时对平面进行纹理处理?

我将发布我的渲染器类,对象将用来绘制自身的类,以及我的顶点和 fragment 着色器:

GL 渲染器:

package com.detour.raw;

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

import android.content.Context;
import android.graphics.Bitmap;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.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 android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLES20;
import android.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();
}

}

fragment 着色器:

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;),我得到了正确大小的正方形,但纹理不是可见/正方形是完全白色的。

我还尝试为可渲染 (RenderVisible) 类制作方法,使移动和缩放我的 Sprite 变得简单。我该怎么做?

最佳答案

你的纹理坐标是你的顶点坐标的函数,这就是这种行为的原因,要修复它,只需改变你的顶点着色器:

v_texcoord = a_texcoord;

所以你使用你的常量纹理坐标。还要记得启用纹理坐标顶点属性:

GLES20.glEnableVertexAttribArray(texCoordHandle);

关于java - OpenGL 纹理不遵循几何,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6840243/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com