问题描述
我试图通过经由openGL的过滤器运行它,然后在一个GLSurfaceView显示它来过滤从相机硬件传来的流。当openGL的去渲染帧时,LogCat中反复吐出一个错误:
0x502是一个通用的openGL的错误,并没有真正帮助我跟踪问题。这是一个怎样的code工作(或至少应工作在我的头上看到)的顺序,我已经复制低于我的code。我希望别人能看到我的问题是。
MainActivity.java
公共类MainActivity扩展活动实现SurfaceTexture.OnFrameAvailableListener
{
私人相机mCamera;
私人MyGLSurfaceView glSurfaceView;
私人表面表面纹理;
MyGL20Renderer渲染器;
@覆盖
公共无效的onCreate(包savedInstanceState)
{
super.onCreate(savedInstanceState);
glSurfaceView =新MyGLSurfaceView(本);
渲染= glSurfaceView.getRenderer();
的setContentView(glSurfaceView);
}
公共无效startCamera(INT纹理)
{
表面=新的表面纹理(纹理);
surface.setOnFrameAvailableListener(本);
renderer.setSurface(面);
mCamera = Camera.open();
尝试
{
mCamera.set previewTexture(面);
mCamera.start preVIEW();
}
赶上(IOException异常IOE)
{
Log.w(MainActivity,CAM发射失败);
}
}
公共无效onFrameAvailable(表面纹理表面纹理)
{
glSurfaceView.requestRender();
}
@覆盖
公共无效的onPause()
{
mCamera.stop preVIEW();
mCamera.release();
System.exit(0);
}
MyGLSurfaceView.java
类MyGLSurfaceView扩展GLSurfaceView
{
MyGL20Renderer渲染器;
公共MyGLSurfaceView(上下文的背景下)
{
超(上下文);
setEGLContextClientVersion(2);
渲染器=新MyGL20Renderer((MainActivity)上下文);
setRenderer(渲染);
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
公共MyGL20Renderer getRenderer()
{
返回渲染器;
}
}
MyGL20Renderer.java
公共类MyGL20Renderer实现GLSurfaceView.Renderer
{
DirectVideo mDirectVideo;
INT质感;
私人表面表面纹理;
MainActivity代表;
公共MyGL20Renderer(MainActivity _delegate)
{
委托= _delegate;
}
公共无效onSurfaceCreated(GL10未使用的,EGLConfig配置)
{
mDirectVideo =新DirectVideo(纹理);
质地= createTexture();
GLES20.glClearColor(0.5F,0.5F,0.5F,1.0F);
delegate.startCamera(纹理);
}
公共无效onDrawFrame(GL10未使用)
{
浮动[] MTX =新的浮动[16];
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
surface.updateTexImage();
surface.getTransformMatrix(MTX);
mDirectVideo.draw();
}
公共无效onSurfaceChanged(GL10未使用的,诠释的宽度,高度INT)
{
GLES20.glViewport(0,0,宽度,高度);
}
静态公众诠释loadShader(整型,字符串着色器code)
{
INT着色器= GLES20.glCreateShader(类型);
GLES20.glShaderSource(着色,着色器code);
GLES20.glCompileShader(着色);
返回着色器;
}
静态私人诠释createTexture()
{
INT []质地=新INT [1];
GLES20.glGenTextures(1,纹理,0);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,纹理[0]);
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_LINEAR);
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
GL10.GL_TEXTURE_WRAP_S,GL10.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
GL10.GL_TEXTURE_WRAP_T,GL10.GL_CLAMP_TO_EDGE);
返回质地[0];
}
公共无效setSurface(表面纹理_surface)
{
表面= _surface;
}
}
DirectVideo.java
公共类DirectVideo {
私人最终字符串vertexShader code =
#extension GL_OES_EGL_image_external:需要的\ n+
属性vec4地位; +
属性vec4 inputTextureCoordinate; +
不同的TextureCoordinate VEC2; +
无效的主要()+
{+
GL_POSITION =地位;+
的TextureCoordinate = inputTextureCoordinate.xy; +
};
私人最终字符串fragmentShader code =
#extension GL_OES_EGL_image_external:需要的\ n+
precision mediump浮动; +
统一vec4 vColor; +
无效的主要(){+
gl_FragColor = vColor; +
};
私人FloatBuffer vertexBuffer,textureVerticesBuffer;
私人ShortBuffer drawListBuffer;
私人最终诠释mProgram;
私人诠释mPositionHandle;
私人诠释mColorHandle;
私人诠释mTextureCoordHandle;
//此数组中每个顶点的坐标数量
静态最终诠释COORDS_PER_VERTEX = 2;
静浮squareVertices逆时针顺序[] = {//:
-1.0F,1.0F,
-1.0F,-1.0F,
1.0F,-1.0F,
1.0F,1.0F
};
私人短DRAWORDER [] = {0,1,2,0,2,3}; //为了绘制顶点
静浮textureVertices逆时针顺序[] = {//:
1.0F,1.0F,
1.0F,0.0,
0.0,1.0F,
0.0,0.0
};
私人最终诠释vertexStride = COORDS_PER_VERTEX * 4;每个顶点// 4字节
私人诠释质感;
公共DirectVideo(INT _texture)
{
纹理= _texture;
ByteBuffer的BB = ByteBuffer.allocateDirect(squareVertices.length * 4);
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(squareVertices);
vertexBuffer.position(0);
ByteBuffer的DLB = ByteBuffer.allocateDirect(drawOrder.length * 2);
dlb.order(ByteOrder.nativeOrder());
drawListBuffer = dlb.asShortBuffer();
drawListBuffer.put(DRAWORDER);
drawListBuffer.position(0);
ByteBuffer的BB2 = ByteBuffer.allocateDirect(textureVertices.length * 4);
bb2.order(ByteOrder.nativeOrder());
textureVerticesBuffer = bb2.asFloatBuffer();
textureVerticesBuffer.put(textureVertices);
textureVerticesBuffer.position(0);
INT vertexShader = MyGL20Renderer.loadShader(GLES20.GL_VERTEX_SHADER,vertexShader code);
INT fragmentShader = MyGL20Renderer.loadShader(GLES20.GL_FRAGMENT_SHADER,fragmentShader code);
mProgram = GLES20.glCreateProgram(); //创建空的OpenGL ES项目
GLES20.glAttachShader(mProgram,vertexShader); //添加顶点着色器程序
GLES20.glAttachShader(mProgram,fragmentShader); //添加片段着色器进行编程
GLES20.glLinkProgram(mProgram);
}
公共无效平局()
{
GLES20.glUseProgram(mProgram);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,质地);
mPositionHandle = GLES20.glGetAttribLocation(mProgram,位置);
GLES20.glEnableVertexAttribArray(mPositionHandle);
GLES20.glVertexAttribPointer(mPositionHandle,COORDS_PER_VERTEX,GLES20.GL_FLOAT,假的,vertexStride,vertexBuffer);
mTextureCoordHandle = GLES20.glGetAttribLocation(mPrograminputTextureCoordinate);
GLES20.glEnableVertexAttribArray(mTextureCoordHandle);
GLES20.glVertexAttribPointer(mTextureCoordHandle,COORDS_PER_VERTEX,GLES20.GL_FLOAT,假的,vertexStride,textureVerticesBuffer);
mColorHandle = GLES20.glGetUniformLocation(mProgramvColor);
GLES20.glDrawElements(GLES20.GL_TRIANGLES,drawOrder.length,
GLES20.GL_UNSIGNED_SHORT,drawListBuffer);
//禁用顶点数组
GLES20.glDisableVertexAttribArray(mPositionHandle);
GLES20.glDisableVertexAttribArray(mTextureCoordHandle);
}
}
mDirectVideo =新DirectVideo(纹理);
质地= createTexture();
应
纹理= createTexture();
mDirectVideo =新DirectVideo(纹理);
着色
私有最终字符串vertexShader code =
属性vec4地位; +
属性VEC2 inputTextureCoordinate; +
不同的TextureCoordinate VEC2; +
无效的主要()+
{+
GL_POSITION =地位;+
的TextureCoordinate = inputTextureCoordinate; +
};
私人最终字符串fragmentShader code =
#extension GL_OES_EGL_image_external:需要的\ n+
precision mediump浮动; +
不同的TextureCoordinate VEC2; \ N+
统一samplerExternalOES s_texture; \ N+
无效的主要(){+
gl_FragColor =的Texture2D(s_texture,的TextureCoordinate); \ N+
};
mColorHandle = GLES20.glGetUniformLocation(mProgram,vColor);
应
mColorHandle = GLES20.glGetAttribLocation(mProgram,s_texture);
从DirectVideo draw.glVertexAttribPointer删除初始化的东西等放入一些初始化函数。
公共无效平局()
{
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,质地);
GLES20.glDrawElements(GLES20.GL_TRIANGLES,drawOrder.length,
GLES20.GL_UNSIGNED_SHORT,drawListBuffer);
}
I am trying to filter the stream coming from the camera hardware by running it through an openGL filter, then displaying it in a GLSurfaceView. When openGL goes to render the frame, the LogCat repeatedly spits out an error:
0x502 is a generic openGL error, and doesn't really help me track down the problem. This is a sequence of how the code works (or atleast should be working as seen in my head), and I've copied my code below that. I am hoping that somebody else can see what my problem is.
MainActivity.java
public class MainActivity extends Activity implements SurfaceTexture.OnFrameAvailableListener
{
private Camera mCamera;
private MyGLSurfaceView glSurfaceView;
private SurfaceTexture surface;
MyGL20Renderer renderer;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
glSurfaceView = new MyGLSurfaceView(this);
renderer = glSurfaceView.getRenderer();
setContentView(glSurfaceView);
}
public void startCamera(int texture)
{
surface = new SurfaceTexture(texture);
surface.setOnFrameAvailableListener(this);
renderer.setSurface(surface);
mCamera = Camera.open();
try
{
mCamera.setPreviewTexture(surface);
mCamera.startPreview();
}
catch (IOException ioe)
{
Log.w("MainActivity","CAM LAUNCH FAILED");
}
}
public void onFrameAvailable(SurfaceTexture surfaceTexture)
{
glSurfaceView.requestRender();
}
@Override
public void onPause()
{
mCamera.stopPreview();
mCamera.release();
System.exit(0);
}
MyGLSurfaceView.java
class MyGLSurfaceView extends GLSurfaceView
{
MyGL20Renderer renderer;
public MyGLSurfaceView(Context context)
{
super(context);
setEGLContextClientVersion(2);
renderer = new MyGL20Renderer((MainActivity)context);
setRenderer(renderer);
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
public MyGL20Renderer getRenderer()
{
return renderer;
}
}
MyGL20Renderer.java
public class MyGL20Renderer implements GLSurfaceView.Renderer
{
DirectVideo mDirectVideo;
int texture;
private SurfaceTexture surface;
MainActivity delegate;
public MyGL20Renderer(MainActivity _delegate)
{
delegate = _delegate;
}
public void onSurfaceCreated(GL10 unused, EGLConfig config)
{
mDirectVideo = new DirectVideo(texture);
texture = createTexture();
GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
delegate.startCamera(texture);
}
public void onDrawFrame(GL10 unused)
{
float[] mtx = new float[16];
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
surface.updateTexImage();
surface.getTransformMatrix(mtx);
mDirectVideo.draw();
}
public void onSurfaceChanged(GL10 unused, int width, int height)
{
GLES20.glViewport(0, 0, width, height);
}
static public int loadShader(int type, String shaderCode)
{
int shader = GLES20.glCreateShader(type);
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
return shader;
}
static private int createTexture()
{
int[] texture = new int[1];
GLES20.glGenTextures(1,texture, 0);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, texture[0]);
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_LINEAR);
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES,
GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
return texture[0];
}
public void setSurface(SurfaceTexture _surface)
{
surface = _surface;
}
}
DirectVideo.java
public class DirectVideo {
private final String vertexShaderCode =
"#extension GL_OES_EGL_image_external : require\n"+
"attribute vec4 position;" +
"attribute vec4 inputTextureCoordinate;" +
"varying vec2 textureCoordinate;" +
"void main()" +
"{"+
"gl_Position = position;"+
"textureCoordinate = inputTextureCoordinate.xy;" +
"}";
private final String fragmentShaderCode =
"#extension GL_OES_EGL_image_external : require\n"+
"precision mediump float;" +
"uniform vec4 vColor;" +
"void main() {" +
" gl_FragColor = vColor;" +
"}";
private FloatBuffer vertexBuffer, textureVerticesBuffer;
private ShortBuffer drawListBuffer;
private final int mProgram;
private int mPositionHandle;
private int mColorHandle;
private int mTextureCoordHandle;
// number of coordinates per vertex in this array
static final int COORDS_PER_VERTEX = 2;
static float squareVertices[] = { // in counterclockwise order:
-1.0f, 1.0f,
-1.0f, -1.0f,
1.0f, -1.0f,
1.0f, 1.0f
};
private short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices
static float textureVertices[] = { // in counterclockwise order:
1.0f, 1.0f,
1.0f, 0.0f,
0.0f, 1.0f,
0.0f, 0.0f
};
private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex
private int texture;
public DirectVideo(int _texture)
{
texture = _texture;
ByteBuffer bb = ByteBuffer.allocateDirect(squareVertices.length * 4);
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(squareVertices);
vertexBuffer.position(0);
ByteBuffer dlb = ByteBuffer.allocateDirect(drawOrder.length * 2);
dlb.order(ByteOrder.nativeOrder());
drawListBuffer = dlb.asShortBuffer();
drawListBuffer.put(drawOrder);
drawListBuffer.position(0);
ByteBuffer bb2 = ByteBuffer.allocateDirect(textureVertices.length * 4);
bb2.order(ByteOrder.nativeOrder());
textureVerticesBuffer = bb2.asFloatBuffer();
textureVerticesBuffer.put(textureVertices);
textureVerticesBuffer.position(0);
int vertexShader = MyGL20Renderer.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int fragmentShader = MyGL20Renderer.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
mProgram = GLES20.glCreateProgram(); // create empty OpenGL ES Program
GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader to program
GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
GLES20.glLinkProgram(mProgram);
}
public void draw()
{
GLES20.glUseProgram(mProgram);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, texture);
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "position");
GLES20.glEnableVertexAttribArray(mPositionHandle);
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false,vertexStride, vertexBuffer);
mTextureCoordHandle = GLES20.glGetAttribLocation(mProgram, "inputTextureCoordinate");
GLES20.glEnableVertexAttribArray(mTextureCoordHandle);
GLES20.glVertexAttribPointer(mTextureCoordHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false,vertexStride, textureVerticesBuffer);
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length,
GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
// Disable vertex array
GLES20.glDisableVertexAttribArray(mPositionHandle);
GLES20.glDisableVertexAttribArray(mTextureCoordHandle);
}
}
mDirectVideo = new DirectVideo(texture);
texture = createTexture();
should be
texture = createTexture();
mDirectVideo = new DirectVideo(texture);
Shader
private final String vertexShaderCode =
"attribute vec4 position;" +
"attribute vec2 inputTextureCoordinate;" +
"varying vec2 textureCoordinate;" +
"void main()" +
"{"+
"gl_Position = position;"+
"textureCoordinate = inputTextureCoordinate;" +
"}";
private final String fragmentShaderCode =
"#extension GL_OES_EGL_image_external : require\n"+
"precision mediump float;" +
"varying vec2 textureCoordinate; \n" +
"uniform samplerExternalOES s_texture; \n" +
"void main() {" +
" gl_FragColor = texture2D( s_texture, textureCoordinate );\n" +
"}";
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
should be
mColorHandle = GLES20.glGetAttribLocation(mProgram, "s_texture");
remove initialization stuff from DirectVideo draw.glVertexAttribPointer etc. Put it in some init function.
public void draw()
{
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, texture);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length,
GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
}
这篇关于修改使用表面纹理和OpenGL摄像机输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!