写一个OpenGL ES 纹理从上到下循环流动的Android demo
时间: 2024-05-04 08:16:32 浏览: 282
好的,我理解了你的问题,以下是 OpenGL ES 纹理从上到下循环流动的 Android demo:
1. 首先,我们需要在 Android Studio 中创建一个新项目。
2. 在项目中创建一个名为“texture.glsl”的文件,并在其中添加以下代码:
vertexShaderCode:
```glsl
attribute vec4 position;
attribute vec2 textureCoordinate;
varying vec2 vTextureCoord;
void main() {
gl_Position = position;
vTextureCoord = textureCoordinate;
}
```
fragmentShaderCode:
```glsl
precision mediump float;
uniform sampler2D uTexture;
varying vec2 vTextureCoord;
uniform float uTime;
void main() {
vec2 uv = vec2(vTextureCoord.x, vTextureCoord.y + uTime);
if (uv.y > 1.0) {
uv.y -= 1.0;
}
vec4 textureColor = texture2D(uTexture, uv);
gl_FragColor = textureColor;
}
```
3. 接下来,在项目中创建一个名为“TextureRenderer.java”的类,并在其中添加以下代码:
```java
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;
import android.os.SystemClock;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
public class TextureRenderer implements GLSurfaceView.Renderer {
private Context context;
private int textureId;
private int program;
private int positionHandle;
private int textureCoordinateHandle;
private int uTextureHandle;
private int uTimeHandle;
private float[] vertices = {
-1f, -1f,
1f, -1f,
-1f, 1f,
1f, 1f
};
private float[] textureCoords = {
0f, 1f,
1f, 1f,
0f, 0f,
1f, 0f
};
private Bitmap bitmap;
public TextureRenderer(Context context) {
this.context = context;
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(0f, 0f, 0f, 1f);
createProgram();
createTexture();
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
GLES20.glViewport(0, 0, width, height);
}
@Override
public void onDrawFrame(GL10 gl) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glUseProgram(program);
long time = SystemClock.uptimeMillis();
float seconds = time / 1000f;
float timeValue = seconds % 1.0f;
GLES20.glUniform1f(uTimeHandle, timeValue);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
GLES20.glUniform1i(uTextureHandle, 0);
GLES20.glVertexAttribPointer(
positionHandle,
2,
GLES20.GL_FLOAT,
false,
0,
VertexArrayHelper.createFloatBuffer(vertices)
);
GLES20.glEnableVertexAttribArray(positionHandle);
GLES20.glVertexAttribPointer(
textureCoordinateHandle,
2,
GLES20.GL_FLOAT,
false,
0,
VertexArrayHelper.createFloatBuffer(textureCoords)
);
GLES20.glEnableVertexAttribArray(textureCoordinateHandle);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
GLES20.glDisableVertexAttribArray(positionHandle);
GLES20.glDisableVertexAttribArray(textureCoordinateHandle);
}
private void createProgram() {
String vertexShaderCode = AssetsHelper.loadShaderCode(context, "texture.glsl", "vertexShaderCode");
String fragmentShaderCode = AssetsHelper.loadShaderCode(context, "texture.glsl", "fragmentShaderCode");
program = GLES20.glCreateProgram();
int vertexShader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
GLES20.glShaderSource(vertexShader, vertexShaderCode);
GLES20.glCompileShader(vertexShader);
GLES20.glAttachShader(program, vertexShader);
int fragmentShader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
GLES20.glShaderSource(fragmentShader, fragmentShaderCode);
GLES20.glCompileShader(fragmentShader);
GLES20.glAttachShader(program, fragmentShader);
GLES20.glLinkProgram(program);
positionHandle = GLES20.glGetAttribLocation(program, "position");
textureCoordinateHandle = GLES20.glGetAttribLocation(program, "textureCoordinate");
uTextureHandle = GLES20.glGetUniformLocation(program, "uTexture");
uTimeHandle = GLES20.glGetUniformLocation(program, "uTime");
}
private void createTexture() {
bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.texture);
int[] textureIds = new int[1];
GLES20.glGenTextures(1, textureIds, 0);
textureId = textureIds[0];
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameteri(
GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_WRAP_S,
GLES20.GL_REPEAT
);
GLES20.glTexParameteri(
GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_WRAP_T,
GLES20.GL_REPEAT
);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
}
}
```
4. 最后,在 MainActivity 中,添加以下代码:
```java
public class MainActivity extends AppCompatActivity {
private GLSurfaceView glSurfaceView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
glSurfaceView = findViewById(R.id.gl_surface_view);
glSurfaceView.setEGLContextClientVersion(2);
glSurfaceView.setRenderer(new TextureRenderer(this));
glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
}
}
```
5. 运行应用程序,您将看到纹理从上到下循环流动的效果。
希望这个demo能够帮到你。
阅读全文