OpenGL纹理使用

1.纹理坐标(UV纹理坐标)
1.1可以通过调整纹理坐标或者通过拉伸或压扁纹理本身来适应被绘制的形状
1.2计算机图像默认坐标
这里写图片描述
2.opengl纹理过滤模式
参考:http://blog.csdn.net/pizi0475/article/details/49740879
3.纹理绘制
纹理不会被直接绘制,它们要被绑定到纹理单元,然后把这些纹理单元传递给着色器。通过在纹理单元中把纹理切来窃取,我们还可以在场景中绘制不同的纹理,但是过分的切换可能使性能下降,我们也能同时使用多个纹理单元绘制几个纹理。
4.主要代码

//片段着色器/res/raw/texture_fragment_shader.glsl
precision mediump float;

uniform sampler2D u_TextureUnit;
varying vec2 v_TextureCoordinates;

void main()
{
    gl_FragColor = texture2D(u_TextureUnit, v_TextureCoordinates);
}
//顶点着色器/res/raw/texture_vertex_shader.glsl
uniform mat4 u_Matrix;

attribute vec4 a_Position;
attribute vec2 a_TextureCoordinates;

varying vec2 v_TextureCoordinates;

void main()
{
    v_TextureCoordinates = a_TextureCoordinates;
    gl_Position = u_Matrix * a_Position;
}
package com.example.firstopengl.util;

import static android.opengl.GLES20.GL_LINEAR;
import static android.opengl.GLES20.GL_LINEAR_MIPMAP_LINEAR;
import static android.opengl.GLES20.GL_TEXTURE_2D;
import static android.opengl.GLES20.GL_TEXTURE_MAG_FILTER;
import static android.opengl.GLES20.GL_TEXTURE_MIN_FILTER;
import static android.opengl.GLES20.glBindTexture;
import static android.opengl.GLES20.glDeleteTextures;
import static android.opengl.GLES20.glGenTextures;
import static android.opengl.GLES20.glGenerateMipmap;
import static android.opengl.GLES20.glTexParameteri;
import static android.opengl.GLUtils.texImage2D;

import com.example.firstopengl.LoggerConfig;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;

public class TextureHelper {
    private static final String TAG = "TestureHelper";
    /**
     * 加载纹理
     * @param context    
     * @param resourceId  资源id
     * @return            纹理数据
     */
    public static int loadTexture(Context context, int resourceId){     
        final int[] textureObjectIds = new int[1];
        glGenTextures(1, textureObjectIds, 0);

        if(textureObjectIds[0] == 0){
            if(LoggerConfig.ON){
                Log.w(TAG, "不能创建纹理对象");
            }
            return 0;
        }
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inScaled = false;//图像原始数据

        final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resourceId, options);

        if(bitmap==null){
            if(LoggerConfig.ON){
                Log.w(TAG, "资源不能被加载");
            }
            glDeleteTextures(1, textureObjectIds, 0);
            return 0;
        }
        //绑定纹理,才可进行对纹理操作
        glBindTexture(GL_TEXTURE_2D, textureObjectIds[0]);
        //opengl纹理过滤模式 http://blog.csdn.net/pizi0475/article/details/49740879
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);   
        //加载位图数据到纹理
        texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);
        bitmap.recycle();
        //生成MIP贴图
        glGenerateMipmap(GL_TEXTURE_2D);
        //解除纹理绑定
        glBindTexture(GL_TEXTURE_2D, 0);

        return textureObjectIds[0];
    }
}
package com.example.firstopengl.programs;

import static android.opengl.GLES20.GL_TEXTURE0;
import static android.opengl.GLES20.GL_TEXTURE_2D;
import static android.opengl.GLES20.glActiveTexture;
import static android.opengl.GLES20.glBindTexture;
import static android.opengl.GLES20.glGetAttribLocation;
import static android.opengl.GLES20.glGetUniformLocation;
import static android.opengl.GLES20.glUniform1i;
import static android.opengl.GLES20.glUniformMatrix4fv;

import com.example.firstopengl.R;

import android.content.Context;

public class TextureShaderProgram extends ShaderProgram{
    //Uniform locations
    private final int uMatrixLocation;
    private final int uTextureUnitLocation;

    //Attribute locations
    private final int aPositionLocation;
    private final int aTextureCoordinatesLocation;

    public TextureShaderProgram(Context context) {
        // TODO Auto-generated constructor stub
        super(context, R.raw.texture_vertex_shader, R.raw.texture_fragment_shader);

        uMatrixLocation = glGetUniformLocation(program, U_MATRIX);
        uTextureUnitLocation = glGetUniformLocation(program, U_TEXTURE_UNIT);

        aPositionLocation = glGetAttribLocation(program, A_POSITION);
        aTextureCoordinatesLocation = glGetAttribLocation(program, A_TEXTURE_COORDINATES);
    }

    /**
     * 设置着色器uniform变量
     * @param matrix
     * @param textureId
     */
    public void setUniforms(float[] matrix, int textureId){
        glUniformMatrix4fv(uMatrixLocation, 1, false, matrix, 0);
        //激活纹理单元0
        glActiveTexture(GL_TEXTURE0);
        //绑定纹理单元
        glBindTexture(GL_TEXTURE_2D, textureId);
        //传递纹理单元0
        glUniform1i(uTextureUnitLocation, 0);
    }

    public int getPositionAttributeLocation(){
        return aPositionLocation;
    }


    public int getTextureCoodinatesAttributeLocation() {
        return aTextureCoordinatesLocation;
    }

}
package com.example.firstopengl;

import static android.opengl.GLES20.GL_COLOR_BUFFER_BIT;
import static android.opengl.GLES20.glClear;
import static android.opengl.GLES20.glClearColor;
import static android.opengl.GLES20.glViewport;
import static android.opengl.Matrix.multiplyMM;
import static android.opengl.Matrix.perspectiveM;
import static android.opengl.Matrix.rotateM;
import static android.opengl.Matrix.setIdentityM;
import static android.opengl.Matrix.translateM;

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

import com.example.firstopengl.objs.Mallet;
import com.example.firstopengl.objs.Table;
import com.example.firstopengl.programs.ColorShaderProgram;
import com.example.firstopengl.programs.TextureShaderProgram;
import com.example.firstopengl.util.TextureHelper;

import android.content.Context;
import android.opengl.GLSurfaceView.Renderer;

public class MyRenderer implements Renderer {
    private final Context context;

    //投影矩阵
    private final float[] projectionMatrix = new float[16]; 
    //模型矩阵
    private final float[] modelMatrix = new float[16];
    //objs
    private Table table;
    private Mallet mallet;
    //着色器程序
    private TextureShaderProgram textureProgram;
    private ColorShaderProgram colorProgram;
    //纹理
    private int texture;

    public MyRenderer(Context context) {
        // TODO Auto-generated constructor stub
        this.context = context;
    }

    // 绘制每一帧时,GLSurfaceView调用(suface创建后)
    @Override
    public void onDrawFrame(GL10 gl) {
        // TODO Auto-generated method stub
        // 清除屏幕颜色
        glClear(GL_COLOR_BUFFER_BIT);

        //绘制table
        textureProgram.useProgram();
        textureProgram.setUniforms(projectionMatrix, texture);
        table.bindData(textureProgram);
        table.draw();

        //绘制mallet
        colorProgram.useProgram();
        colorProgram.setUniforms(projectionMatrix);
        mallet.bindData(colorProgram);
        mallet.draw();
    }

    // suface视图大小改变时,GLSurfaceView调用(suface创建后)
    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        //创建透视投影矩阵
        perspectiveM(projectionMatrix, 0, 45, (float)width/(float)height, 1f, 10f);
        //利用模型矩阵移动和旋转物体
        setIdentityM(modelMatrix, 0);
        translateM(modelMatrix, 0, 0f, 0f, -2.5f);
        rotateM(modelMatrix, 0, -60f, 1f, 0f, 0f);
        //透视投影矩阵与模型矩阵相乘赋值给projectionMatrix
        final float[] temp = new float[16];
        multiplyMM(temp, 0, projectionMatrix, 0, modelMatrix, 0);
        System.arraycopy(temp, 0, projectionMatrix, 0, temp.length);
    }

    // suface创建时,GLSurfaceView调用
    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        // TODO Auto-generated method stub
        // 清空屏幕的颜色
        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

        table = new Table();
        mallet = new Mallet();

        textureProgram = new TextureShaderProgram(context);
        colorProgram = new ColorShaderProgram(context);

        texture = TextureHelper.loadTexture(context, R.drawable.ic_launcher);
    }

}

5.源码:https://github.com/HQlin/ShaderOpenGL/commits/master

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值