android中用GLSurfaceview和opengl es2.0显示图片,图片无法正常显示
2016-12-30 14:25
417 查看
想用GLSurfaceView配合OPENGL es2.0编程实现把图片显示到手机界面中,照着网上的例子,自己在eclipse中敲了一遍,但是就是无法显示出图片(试过128*128的png和bmp),就显示出一个白色的界面。
网上找了下,没找到原因,求大神给看看。
代码如下:
package com.example.glsurfaceview_drawpicture;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import java.security.spec.MGF1ParameterSpec;
import java.util.TooManyListenersException;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLUtils;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
public class MainActivity extends Activity
implements Renderer{
final float[] vertexCoord = {
-0.5f,0.5f,0.0f,
-0.5f,-0.5f,0.0f,
0.5f,-0.5f,0.0f,
0.5f,0.5f,0.0f
};
final float[] textureCoord ={
1.0f,0.0f,
0.0f,0.0f,
1.0f,0.0f,
1.0f,1.0f
};
final short[] mdrawCoord = {0,1,2,0,2,3};
final String sVertexShader=
"uniform mat4 u_MVPMatrix;" +
"attribute vec4 a_position;"
+ "attribute vec2 a_texturecoord;"
+ "varying vec2 v_texturecoord;"
+ "void main()"
+ "{"
+ "gl_Position = a_position;"
+ "v_texturecoord = a_texturecoord;"
+ "}";
final String sFragmentShader =
"precision mediump float;"
+ "varying vec2 v_texturecoord;"
+ "uniform sampler2D u_samplerTexture;"
+ "void main()"
+ "{"
+ "gl_FragColor = texture2D(u_samplerTexture,v_texturecoord);"
+ "}";
GLSurfaceView mSurfaceView;
public int mprogramHandle;
public int mvertexShaderHandle;
public int mfragmentShaderHandle;
public int mAPositionIndex;
public int mATextureCoordIndex;
public int mUniformTextureIndex;
public FloatBuffer fb_position;
public FloatBuffer fb_texturecoord;
public ShortBuffer fb_drawCoord;
public int textureId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSurfaceView = new GLSurfaceView(this);
mSurfaceView.setEGLContextClientVersion(2);
mSurfaceView.setRenderer(this);
setContentView(mSurfaceView);
}
public int createShapeHandle(int handle,String shadercode,int type)
{
//创建渲染器容器
handle = GLES20.glCreateShader(type);
if(handle!=0){
//将渲染器代码放入容器中
GLES20.glShaderSource(handle, shadercode);
//编译
GLES20.glCompileShader(handle);
int status[] = new int[1];
//获取编译结果
GLES20.glGetShaderiv(handle, GLES20.GL_COMPILE_STATUS, status, 0);
if(status[0] == 0){
String ss = GLES20.glGetShaderInfoLog(handle);
Log.e("qcong_test",ss);
GLES20.glDeleteShader(handle);
handle =0;
}
}
if(handle == 0){
if(type == GLES20.GL_VERTEX_SHADER){
throw new RuntimeException("Fail to create Vertex Shader!");
}else if(type == GLES20.GL_FRAGMENT_SHADER){
throw new RuntimeException("Fail to create Fragement Shader!");
}
}else{
if(type == GLES20.GL_VERTEX_SHADER){
Log.e("qcong_test","Create vertex shader successful!");
}else if(type == GLES20.GL_FRAGMENT_SHADER){
Log.e("qcong_test","Create fragment shader successful!");
}
}
return handle;
}
public void createProgram()
{
//创建程序
mprogramHandle = GLES20.glCreateProgram();
if(mprogramHandle != 0){
//将渲染器容器绑定到程序中
GLES20.glAttachShader(mprogramHandle, mvertexShaderHandle);
GLES20.glAttachShader(mprogramHandle,mfragmentShaderHandle);
//链接程序
GLES20.glLinkProgram(mprogramHandle);
int status[] = new int[1];
//获取链接结果
GLES20.glGetProgramiv(mprogramHandle, GLES20.GL_LINK_STATUS, status, 0);
if(status[0] == 0){
GLES20.glDeleteProgram(mprogramHandle);
mprogramHandle =0;
}
}
if(mprogramHandle == 0){
throw new RuntimeException("Fail to create program!");
}else{
Log.e("qcong_test","Create program succussful!");
}
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
//激活2D纹理
GLES20.glEnable(GLES20.GL_TEXTURE_2D);
//创建缓存,存放数据
fb_position = ByteBuffer.allocateDirect(vertexCoord.length * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer();
fb_position.put(vertexCoord).position(0);
fb_texturecoord = ByteBuffer.allocateDirect(textureCoord.length * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer();
fb_texturecoord.put(textureCoord).position(0);
fb_drawCoord = ByteBuffer.allocateDirect(mdrawCoord.length * 2)
.order(ByteOrder.nativeOrder())
.asShortBuffer();
fb_drawCoord.put(mdrawCoord).position(0);
//建立渲染器容器
mvertexShaderHandle = createShapeHandle(mvertexShaderHandle,sVertexShader,GLES20.GL_VERTEX_SHADER);
mfragmentShaderHandle = createShapeHandle(mfragmentShaderHandle,sFragmentShader,GLES20.GL_FRAGMENT_SHADER);
if(mvertexShaderHandle == 0 || mfragmentShaderHandle == 0)
return;
//创建程序
createProgram();
//获取渲染器中变量的句柄
mAPositionIndex = GLES20.glGetAttribLocation(mprogramHandle, "a_position");
mATextureCoordIndex = GLES20.glGetAttribLocation(mprogramHandle, "a_textureCoord");
mUniformTextureIndex = GLES20.glGetUniformLocation(mprogramHandle, "u_samplerTexture");
GLES20.glUseProgram(mprogramHandle);
//启用顶点属性数组
GLES20.glEnableVertexAttribArray(mAPositionIndex);
GLES20.glEnableVertexAttribArray(mATextureCoordIndex);
//设置纹理采样器的值
GLES20.glUniform1i(mUniformTextureIndex, 0);
//绑定纹理单元(为上面的采样器绑定)
GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + 0);
textureId = loadTexture();
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
}
@Override
public void onDrawFrame(GL10 gl)
{
GLES20.glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
GLES20.glVertexAttribPointer(mAPositionIndex, 3, GLES20.GL_FLOAT, false, 12, fb_position);
GLES20.glVertexAttribPointer(mATextureCoordIndex, 2, GLES20.GL_FLOAT, false, 8, fb_texturecoord);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, mdrawCoord.length,GLES20.GL_UNSIGNED_SHORT,fb_drawCoord);
}
public int loadTexture()
{
int[] texture_ID = new int[1];
//创建纹理,得到ID
GLES20.glGenTextures(1, texture_ID, 0);
if(texture_ID[0]!=0){
Bitmap bitmap;
try {
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic129);//BitmapFactory.decodeStream(getAssets().open("ic128.png")); //BitmapFactory.decodeFile(path);
//将生成的纹理ID绑定到指定的纹理上
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture_ID[0]);
//设置纹理属性
GLES20.glTexPara
4000
meteri(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_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,
GLES20.GL_CLAMP_TO_EDGE);
//绑定纹理数据,传入指定图片
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
} catch (Exception e) {
e.printStackTrace();
}
}
return texture_ID[0];
}
@Override
protected void onResume() {
super.onResume();
mSurfaceView.onResume();
}
@Override
protected void onPause() {
super.onPause();
mSurfaceView.onPause();
}
}
网上找了下,没找到原因,求大神给看看。
代码如下:
package com.example.glsurfaceview_drawpicture;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import java.security.spec.MGF1ParameterSpec;
import java.util.TooManyListenersException;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLUtils;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
public class MainActivity extends Activity
implements Renderer{
final float[] vertexCoord = {
-0.5f,0.5f,0.0f,
-0.5f,-0.5f,0.0f,
0.5f,-0.5f,0.0f,
0.5f,0.5f,0.0f
};
final float[] textureCoord ={
1.0f,0.0f,
0.0f,0.0f,
1.0f,0.0f,
1.0f,1.0f
};
final short[] mdrawCoord = {0,1,2,0,2,3};
final String sVertexShader=
"uniform mat4 u_MVPMatrix;" +
"attribute vec4 a_position;"
+ "attribute vec2 a_texturecoord;"
+ "varying vec2 v_texturecoord;"
+ "void main()"
+ "{"
+ "gl_Position = a_position;"
+ "v_texturecoord = a_texturecoord;"
+ "}";
final String sFragmentShader =
"precision mediump float;"
+ "varying vec2 v_texturecoord;"
+ "uniform sampler2D u_samplerTexture;"
+ "void main()"
+ "{"
+ "gl_FragColor = texture2D(u_samplerTexture,v_texturecoord);"
+ "}";
GLSurfaceView mSurfaceView;
public int mprogramHandle;
public int mvertexShaderHandle;
public int mfragmentShaderHandle;
public int mAPositionIndex;
public int mATextureCoordIndex;
public int mUniformTextureIndex;
public FloatBuffer fb_position;
public FloatBuffer fb_texturecoord;
public ShortBuffer fb_drawCoord;
public int textureId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSurfaceView = new GLSurfaceView(this);
mSurfaceView.setEGLContextClientVersion(2);
mSurfaceView.setRenderer(this);
setContentView(mSurfaceView);
}
public int createShapeHandle(int handle,String shadercode,int type)
{
//创建渲染器容器
handle = GLES20.glCreateShader(type);
if(handle!=0){
//将渲染器代码放入容器中
GLES20.glShaderSource(handle, shadercode);
//编译
GLES20.glCompileShader(handle);
int status[] = new int[1];
//获取编译结果
GLES20.glGetShaderiv(handle, GLES20.GL_COMPILE_STATUS, status, 0);
if(status[0] == 0){
String ss = GLES20.glGetShaderInfoLog(handle);
Log.e("qcong_test",ss);
GLES20.glDeleteShader(handle);
handle =0;
}
}
if(handle == 0){
if(type == GLES20.GL_VERTEX_SHADER){
throw new RuntimeException("Fail to create Vertex Shader!");
}else if(type == GLES20.GL_FRAGMENT_SHADER){
throw new RuntimeException("Fail to create Fragement Shader!");
}
}else{
if(type == GLES20.GL_VERTEX_SHADER){
Log.e("qcong_test","Create vertex shader successful!");
}else if(type == GLES20.GL_FRAGMENT_SHADER){
Log.e("qcong_test","Create fragment shader successful!");
}
}
return handle;
}
public void createProgram()
{
//创建程序
mprogramHandle = GLES20.glCreateProgram();
if(mprogramHandle != 0){
//将渲染器容器绑定到程序中
GLES20.glAttachShader(mprogramHandle, mvertexShaderHandle);
GLES20.glAttachShader(mprogramHandle,mfragmentShaderHandle);
//链接程序
GLES20.glLinkProgram(mprogramHandle);
int status[] = new int[1];
//获取链接结果
GLES20.glGetProgramiv(mprogramHandle, GLES20.GL_LINK_STATUS, status, 0);
if(status[0] == 0){
GLES20.glDeleteProgram(mprogramHandle);
mprogramHandle =0;
}
}
if(mprogramHandle == 0){
throw new RuntimeException("Fail to create program!");
}else{
Log.e("qcong_test","Create program succussful!");
}
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
//激活2D纹理
GLES20.glEnable(GLES20.GL_TEXTURE_2D);
//创建缓存,存放数据
fb_position = ByteBuffer.allocateDirect(vertexCoord.length * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer();
fb_position.put(vertexCoord).position(0);
fb_texturecoord = ByteBuffer.allocateDirect(textureCoord.length * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer();
fb_texturecoord.put(textureCoord).position(0);
fb_drawCoord = ByteBuffer.allocateDirect(mdrawCoord.length * 2)
.order(ByteOrder.nativeOrder())
.asShortBuffer();
fb_drawCoord.put(mdrawCoord).position(0);
//建立渲染器容器
mvertexShaderHandle = createShapeHandle(mvertexShaderHandle,sVertexShader,GLES20.GL_VERTEX_SHADER);
mfragmentShaderHandle = createShapeHandle(mfragmentShaderHandle,sFragmentShader,GLES20.GL_FRAGMENT_SHADER);
if(mvertexShaderHandle == 0 || mfragmentShaderHandle == 0)
return;
//创建程序
createProgram();
//获取渲染器中变量的句柄
mAPositionIndex = GLES20.glGetAttribLocation(mprogramHandle, "a_position");
mATextureCoordIndex = GLES20.glGetAttribLocation(mprogramHandle, "a_textureCoord");
mUniformTextureIndex = GLES20.glGetUniformLocation(mprogramHandle, "u_samplerTexture");
GLES20.glUseProgram(mprogramHandle);
//启用顶点属性数组
GLES20.glEnableVertexAttribArray(mAPositionIndex);
GLES20.glEnableVertexAttribArray(mATextureCoordIndex);
//设置纹理采样器的值
GLES20.glUniform1i(mUniformTextureIndex, 0);
//绑定纹理单元(为上面的采样器绑定)
GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + 0);
textureId = loadTexture();
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
}
@Override
public void onDrawFrame(GL10 gl)
{
GLES20.glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
GLES20.glVertexAttribPointer(mAPositionIndex, 3, GLES20.GL_FLOAT, false, 12, fb_position);
GLES20.glVertexAttribPointer(mATextureCoordIndex, 2, GLES20.GL_FLOAT, false, 8, fb_texturecoord);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, mdrawCoord.length,GLES20.GL_UNSIGNED_SHORT,fb_drawCoord);
}
public int loadTexture()
{
int[] texture_ID = new int[1];
//创建纹理,得到ID
GLES20.glGenTextures(1, texture_ID, 0);
if(texture_ID[0]!=0){
Bitmap bitmap;
try {
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic129);//BitmapFactory.decodeStream(getAssets().open("ic128.png")); //BitmapFactory.decodeFile(path);
//将生成的纹理ID绑定到指定的纹理上
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture_ID[0]);
//设置纹理属性
GLES20.glTexPara
4000
meteri(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_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,
GLES20.GL_CLAMP_TO_EDGE);
//绑定纹理数据,传入指定图片
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
} catch (Exception e) {
e.printStackTrace();
}
}
return texture_ID[0];
}
@Override
protected void onResume() {
super.onResume();
mSurfaceView.onResume();
}
@Override
protected void onPause() {
super.onPause();
mSurfaceView.onPause();
}
}
相关文章推荐
- [Android]视频浮层效果使用SurfaceView无法正常显示的问题排查和解决方案
- [Android开发] 代码code设置9.png/9-patch 图片背景后,此view中的TextView等控件显示不正常(常见于listview中)
- 关于Android WebView显示html网页图片无法自适应(PS第一次写博客)
- [Android开发] 代码code设置9.png/9-patch 图片背景后,此view中的TextView等控件显示不正常(常见于listview中)
- [OpenGL]从零开始写一个Android平台下的全景视频播放器——1.4 用OpenGL ES 2.0显示一张图片(下)
- [Android开发] 代码code设置9.png/9-patch 图片背景后,此view中的TextView等控件显示不正常(常见于listview中)
- android imageview 图片不能正常显示 或不能自适应的解决方法
- Android Camera API 2使用OpenGL ES 2.0和GLSurfaceView对预览进行实时二次处理(黑白滤镜)
- [Android开发] 代码code设置9.png/9-patch 图片背景后,此view中的TextView等控件显示不正常(常见于listview中)
- [Android开发] 代码code设置9.png/9-patch 图片背景后,此view中的TextView等控件显示不正常(常见于listview中)
- Android代码code设置9.png/9-patch 图片背景后,此view中的控件显示不正常
- [Android开发] 代码code设置9.png/9-patch 图片背景后,此view中的TextView等控件显示不正常(常见于listview中)
- 由于TableView的Section的头部和尾部高度设置的不规范引起的部分Section中的图片无法正常显示
- Android webview Mixed Content无法显示图片解决
- [Android开发] 代码code设置9.png/9-patch 图片背景后,此view中的TextView等控件显示不正常(常见于listview中)
- 关于真机测试的android选择图片在ImageView上显示,调用setImageBitmap无法显示和闪退、控件消失
- android imageview 图片不能正常显示 或不能自适应的解决方法
- [Android]浮层视频效果,在另外一个Window使用SurfaceView无法正常显示的问题排查与解决
- Android webview加载https网页时http图片无法显示
- [Android开发] 代码code设置9.png/9-patch 图片背景后,此view中的TextView等控件显示不正常(常见于listview中)