如何在TextureView Android中绘制立方体[关闭]
Posted
技术标签:
【中文标题】如何在TextureView Android中绘制立方体[关闭]【英文标题】:How to draw cube in TextureView Android [closed] 【发布时间】:2015-01-07 09:52:45 【问题描述】:我是 opengl ES 的新手,我想在 TextureView 上渲染 open gl 视图。
这里是立方体绘图的示例 open-gl 示例https://gist.github.com/ybakos/4151696 但 当我尝试使用 TextureView 绘制同一个立方体时,
我无法绘制那个立方体。 指导我如何使用 TextureView 绘制 opengl 立方体。
这里是示例代码::
public class DemoGraphicGlctivity extends Activity implements TextureView.SurfaceTextureListener
private RenderThread mRenderThread;
private TextureView mTextureView;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
mTextureView = new TextureView(this);
mTextureView.setSurfaceTextureListener(this);
setContentView(mTextureView, new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, 400));
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height)
mRenderThread = new RenderThread(getResources(), surface, DemoGraphicGlctivity.this);
mRenderThread.start();
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height)
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface)
mRenderThread.finish();
try
mRenderThread.join();
catch (InterruptedException e)
Log.e(RenderThread.LOG_TAG, "Could not wait for render thread");
return true;
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface)
private static class RenderThread extends Thread
private static final String LOG_TAG = "GLTextureView";
static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
static final int EGL_OPENGL_ES2_BIT = 4;
private volatile boolean mFinished;
private final Resources mResources;
private final SurfaceTexture mSurface;
private EGL10 mEgl;
private EGLDisplay mEglDisplay;
private EGLConfig mEglConfig;
private EGLContext mEglContext;
private EGLSurface mEglSurface;
private GL mGL;
Context context;
RenderThread(Resources resources, SurfaceTexture surface, Context mContext)
mResources = resources;
mSurface = surface;
context = mContext;
@Override
public void run()
initGL();
// vertices
FloatBuffer vertexBuffer = ByteBuffer
.allocateDirect(CubeConstant.vertices.length * 4)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
vertexBuffer.put(CubeConstant.vertices);
vertexBuffer.position(0);
// texture map
FloatBuffer textureBuffer = ByteBuffer
.allocateDirect(CubeConstant.texture.length * 4)
.order(ByteOrder.nativeOrder()).asFloatBuffer();
textureBuffer.put(CubeConstant.texture);
textureBuffer.position(0);
// indices
ByteBuffer indexBuffer = ByteBuffer.allocateDirect(CubeConstant.indices.length);
indexBuffer.put(CubeConstant.indices);
indexBuffer.position(0);
int texture = loadTexture(R.drawable.receipt_bg);
//int program = buildProgram(sSimpleVS, sSimpleFS);
int program = ShaderHelper
.linkProgram(ShaderHelper
.compileVertexShader(TextResourceReader
.readTextFileFromResource(context,
R.raw.cube_vertex)), ShaderHelper
.compileFragmentShader(TextResourceReader
.readTextFileFromResource(context,
R.raw.cube_fragment)));
int aPositionLocation = glGetAttribLocation(program, "a_Position");
checkGlError();
int aTextureCoordinatesLocation = glGetAttribLocation(program, "a_TextureCoordinates");
checkGlError();
glBindTexture(GL_TEXTURE_2D, texture);
checkGlError();
glUseProgram(program);
checkGlError();
glVertexAttribPointer(aPositionLocation, 3 , GL_FLOAT, false , 0, vertexBuffer);
checkGlError();
vertexBuffer.position(0);
glVertexAttribPointer(aPositionLocation, 3 , GL_FLOAT, false , 0, vertexBuffer);
glEnableVertexAttribArray(aPositionLocation);
textureBuffer.position(0);
glVertexAttribPointer(aTextureCoordinatesLocation, 2, GL_FLOAT, false, 0, textureBuffer);
glEnableVertexAttribArray(aTextureCoordinatesLocation);
checkGlError();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
checkGlError();
while (!mFinished)
checkCurrent();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
checkGlError();
glBindTexture(GL_TEXTURE_2D, texture);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, indexBuffer);
if (!mEgl.eglSwapBuffers(mEglDisplay, mEglSurface))
throw new RuntimeException("Cannot swap buffers");
checkEglError();
try
Thread.sleep(2000);
catch (InterruptedException e)
// Ignore
finishGL();
private int loadTexture(int resource)
int[] textures = new int[1];
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, textures, 0);
checkGlError();
int texture = textures[0];
glBindTexture(GL_TEXTURE_2D, texture);
checkGlError();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
Bitmap bitmap = BitmapFactory.decodeResource(mResources, resource);
GLUtils.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bitmap, GL_UNSIGNED_BYTE, 0);
checkGlError();
bitmap.recycle();
return texture;
private void checkEglError()
int error = mEgl.eglGetError();
if (error != EGL10.EGL_SUCCESS)
Log.w(LOG_TAG, "EGL error = 0x" + Integer.toHexString(error));
private static void checkGlError()
int error = glGetError();
if (error != GL_NO_ERROR)
Log.w(LOG_TAG, "GL error = 0x" + Integer.toHexString(error));
private void finishGL()
mEgl.eglDestroyContext(mEglDisplay, mEglContext);
mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
private void checkCurrent()
if (!mEglContext.equals(mEgl.eglGetCurrentContext()) ||
!mEglSurface.equals(mEgl.eglGetCurrentSurface(EGL10.EGL_DRAW)))
if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext))
throw new RuntimeException("eglMakeCurrent failed "
+ GLUtils.getEGLErrorString(mEgl.eglGetError()));
private void initGL()
mEgl = (EGL10) EGLContext.getEGL();
mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
if (mEglDisplay == EGL10.EGL_NO_DISPLAY)
throw new RuntimeException("eglGetDisplay failed "
+ GLUtils.getEGLErrorString(mEgl.eglGetError()));
int[] version = new int[2];
if (!mEgl.eglInitialize(mEglDisplay, version))
throw new RuntimeException("eglInitialize failed " +
GLUtils.getEGLErrorString(mEgl.eglGetError()));
mEglConfig = chooseEglConfig();
if (mEglConfig == null)
throw new RuntimeException("eglConfig not initialized");
mEglContext = createContext(mEgl, mEglDisplay, mEglConfig);
mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, mEglConfig, mSurface, null);
if (mEglSurface == null || mEglSurface == EGL10.EGL_NO_SURFACE)
int error = mEgl.eglGetError();
if (error == EGL10.EGL_BAD_NATIVE_WINDOW)
Log.e(LOG_TAG, "createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
return;
throw new RuntimeException("createWindowSurface failed "
+ GLUtils.getEGLErrorString(error));
if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext))
throw new RuntimeException("eglMakeCurrent failed "
+ GLUtils.getEGLErrorString(mEgl.eglGetError()));
mGL = mEglContext.getGL();
EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig)
int[] attrib_list = EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE ;
return egl.eglCreateContext(eglDisplay, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
private EGLConfig chooseEglConfig()
int[] configsCount = new int[1];
EGLConfig[] configs = new EGLConfig[1];
int[] configSpec = getConfig();
if (!mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, configsCount))
throw new IllegalArgumentException("eglChooseConfig failed " +
GLUtils.getEGLErrorString(mEgl.eglGetError()));
else if (configsCount[0] > 0)
return configs[0];
return null;
private static int[] getConfig()
return new int[]
EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL10.EGL_RED_SIZE, 8,
EGL10.EGL_GREEN_SIZE, 8,
EGL10.EGL_BLUE_SIZE, 8,
EGL10.EGL_ALPHA_SIZE, 8,
EGL10.EGL_DEPTH_SIZE, 0,
EGL10.EGL_STENCIL_SIZE, 0,
EGL10.EGL_NONE
;
void finish()
mFinished = true;
请让我知道我哪里出错了......
【问题讨论】:
我遇到了同样的问题。我想用纹理视图绘制一个立方体。请提供上述问题的解决方案 【参考方案1】:我知道的不多,但我认为你必须对此有罗马人的说明: 创建 OpenGL 上下文
-
生成 OpenGL 纹理名称。
使用纹理名称创建 SurfaceTexture。
将 SurfaceTexture 传递给相机。
收听更新。
在 SurfaceTexture 更新时,使用 OpenGL 绘制纹理
你想要的着色器。
【讨论】:
以上是关于如何在TextureView Android中绘制立方体[关闭]的主要内容,如果未能解决你的问题,请参考以下文章
使用 lockCanvas() 的 Android TextureView 硬件加速
android: View, SurfaceView, GLSurfaceView, TextureView 区别与联系