Android GLSurfaceView glTexImage2D glDrawTexiOES

标签 android opengl-es textures android-ndk texture2d

我正在尝试使用 GLSurfaceView 和 Native C 代码在 Android 上使用 OpenGL ES 渲染 640x480 RGB565 图像。

最初,我在使用 glTexImage2D 时遇到了 0x0501 错误,我可以通过更改图像尺寸来解决该错误。

但是现在,在“drawFrame”调用中,当我执行 glDrawTexiOES 重新渲染纹理时,我在日志上收到以下错误:

drawtex.c:89:DrawTexture:未启用纹理

我已经在执行 glEnable(GL_TEXTURE_2D),还有什么我应该做的吗?

是否有完整的示例显示 GLSurfaceView 以及使用纹理的 native 代码?

提前致谢!

最佳答案

我也遇到了同样的问题,您可以像这样制作自定义渲染器: 或者(通过直接子类化 SurfaceView 来实现有点复杂)


import java.nio.ByteBuffer;
import java.nio.ByteOrder;

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

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.util.Log;

import com.TIEmulator.JNI.NLib;

class EmulatorRenderer implements GLSurfaceView.Renderer, NLib.EventsInterface {

    public static interface RenderCb {
        public boolean dismissStartupDialog();

        public void updateStartupDialog(String msg);
    }

    private static int mViewHeight;
    private static int mViewWidth;
    private static BitmapFactory.Options sBitmapOptions = new BitmapFactory.Options();

    private static int TEX_BUF_HEIGHT = 128;
    private static int TEX_BUF_WIDTH = 256;

    private final ByteBuffer byteBuffer = ByteBuffer.allocateDirect(4
            * EmulatorRenderer.TEX_BUF_HEIGHT * EmulatorRenderer.TEX_BUF_WIDTH);
    private boolean emulation_running = false;

    private Context mContext = null;
    private final int[] mCropWorkspace;
    private final GLSurfaceView mGLView;
    protected int mTex = -1;

    protected int[] mtexBuf = new int[1];
    private final int[] mTextureNameWorkspace;

    public EmulatorRenderer(final Context ctx, final GLSurfaceView v) {
        // Pre-allocate and store these objects so we can use them at runtime
        // without allocating memory mid-frame.
        mTextureNameWorkspace = new int[1];
        mCropWorkspace = new int[4];

        byteBuffer.order(ByteOrder.BIG_ENDIAN);

        // Set our bitmaps to 16-bit, 565 format.
        EmulatorRenderer.sBitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565;
        mGLView = v;
        mContext = ctx;

        try {
            NLib.setListener(this);
        } catch (final RuntimeException exc) {
            exc.printStackTrace();
            callFinishOnce();
            return;
        }
        if (!NLib.TryLoadLib()) {
            callFinishOnce();
            return;
        }
        Log.v(this.getClass().toString(),">>>>>>>>>>>>>>>>>>>>>>> init successfull! <<<<<<<<<<<<<<<<<<<<<<");
    }

    private void callFinishOnce() {
        if (mContext != null) {
            ((Activity) mContext).finish();
            mContext = null;
        }
    }

    @Override
    protected void finalize() throws Throwable {
        NLib.stopEmu();
        super.finalize();
    }

    protected int loadBB(final GL10 gl) {
        int textureName = -1;
        if (mContext != null && gl != null) {
            gl.glGenTextures(1, mTextureNameWorkspace, 0);

            textureName = mTextureNameWorkspace[0];
            gl.glBindTexture(GL10.GL_TEXTURE_2D, textureName);

            gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
                    GL10.GL_NEAREST);
            gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
                    GL10.GL_NEAREST);// GL10.GL_LINEAR);

            gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
                    GL10.GL_CLAMP_TO_EDGE);
            gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
                    GL10.GL_CLAMP_TO_EDGE);

            gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
                    GL10.GL_REPLACE);

            mCropWorkspace[0] = 0; // u
            // mCropWorkspace[1] = EMU_HEIGHT; // v
            mCropWorkspace[1] = 0; // v

            mCropWorkspace[2] = NLib.getWidth(); // w
            // mCropWorkspace[3] = -EMU_HEIGHT; // h -EMU_HEIGHT;
            mCropWorkspace[3] = NLib.getHeight(); // h -EMU_HEIGHT;
            byteBuffer.order(ByteOrder.BIG_ENDIAN);

            final int error = gl.glGetError();
            if (error != GL10.GL_NO_ERROR) {
                Log.e("SpriteMethodTest", "Texture Load GLError: " + error);
            }
        }
        return textureName;
    }

    public void onDrawFrame(final GL10 gl) {
        // Log.v(this.toString(),"onDrawFrame called");
        gl.glActiveTexture(mTex);
        gl.glClientActiveTexture(mTex);

        byteBuffer.position(0);

        // this two lines bind and create the texture!
        gl.glBindTexture(GL10.GL_TEXTURE_2D, mTex);
        ((GL11) gl).glTexParameteriv(GL10.GL_TEXTURE_2D,
                GL11Ext.GL_TEXTURE_CROP_RECT_OES, mCropWorkspace, 0);

        gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA,
                EmulatorRenderer.TEX_BUF_WIDTH,
                EmulatorRenderer.TEX_BUF_HEIGHT, 0, GL10.GL_RGBA,
                GL10.GL_UNSIGNED_BYTE, byteBuffer);

        ((GL11Ext) gl).glDrawTexiOES(0, 0, 0, EmulatorRenderer.mViewWidth,
                EmulatorRenderer.mViewHeight);

        /** gl.glEnable(GL10.GL_DEPTH_TEST); gl.glDepthFunc(GL10.GL_LEQUAL);
         */
    }

    public void OnFatalError(final String text) {
        Log.d(toString(), "FATAL ERROR CALLBACK raised: " + text
                + " ===> Activity calls finish()");
    }

    public void onFinish() {
        onPause();
    }
/*
* JNI interface
*
*/
    @Override
    public void OnBufferUpdate() {
        mGLView.requestRender();
    }
    // TODO Auto-generated method stub

    @Override
    public void OnWarning(String msg) {
        // TODO Auto-generated method stub

    }
    public void onPause() {
        mGLView.onPause();
        // Log.v("onPause", "NILib.stopEmulate()");
        emulation_running = false;
        //startupDialogDismiss = false;
        NLib.stopEmu();
    }

    public void onResume() {
        // Log.v(this.toString(),"EmulatorRenderer:onResume called");
        NLib.startEmu(byteBuffer);

        mGLView.onResume();
        //callFinishOnce();
        emulation_running = true;
    }

    public void onSurfaceChanged(final GL10 gl, final int w, final int h) {
        EmulatorRenderer.mViewWidth = w;
        EmulatorRenderer.mViewHeight = h;
        Log.v(toString(), "onSurfaceChanged: ==> New View Size: [" + w + ","
                + h + "]");
    }

    public void onSurfaceCreated(final GL10 gl, final EGLConfig config) {

        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);

        gl.glClearColor(0.5f, 0.5f, 0.5f, 1);
        gl.glShadeModel(GL10.GL_FLAT);
        gl.glDisable(GL10.GL_DEPTH_TEST);
        gl.glEnable(GL10.GL_TEXTURE_2D);

        /*
         * By default, OpenGL enables features that improve quality but reduce
         * performance. One might want to tweak that especially on software
         * renderer.
         */
        gl.glDisable(GL10.GL_DITHER);
        gl.glDisable(GL10.GL_LIGHTING);
        gl.glDisable(GL10.GL_BLEND);
        gl.glDisable(GL10.GL_DEPTH_TEST);
        gl.glHint(GL10.GL_LINE_SMOOTH_HINT, GL10.GL_NICEST); // Set Line
        // Antialiasing
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

        // create the one and only texture here...
        mTex = loadBB(gl);
    }

    public void OnTIEmuStopped() {
        System.out.println("OnTIEmuStopped callback called! ");
        callFinishOnce();
    }

    /* Called when the size of the window changes. */
    public void sizeChanged(final GL10 gl, final int w, final int h) {
        // Log.v(this.toString(),"sizeChanged: ==> new Viewport: ["+w+","+h+"]");

        gl.glViewport(0, 0, w, h);
        /*
         * Set our projection matrix. This doesn't have to be done each time we
         * draw, but usually a new projection needs to be set when the viewport
         * is resized.
         */
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();

        // Set up the orthographic projection
        // gl.glOrthof(0.0f, w, 0.0f, h, 0.0f, 1.0f);
        gl.glOrthof(0.0f, w, 0.0f, 0.0f, h, 1.0f);

        gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
        gl.glColor4x(0x10000, 0x10000, 0x10000, 0x10000);
        gl.glEnable(GL10.GL_TEXTURE_2D);

        gl.glMatrixMode(GL10.GL_MODELVIEW);
    }
}

关于Android GLSurfaceView glTexImage2D glDrawTexiOES,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2761425/

相关文章:

android - 第二个 float 操作按钮的位置未锁定在布局中

android - 如何在带有参数和 header 的android Volley库中使用POST请求?

opengl-es - OpenGL ES :Purpose of calling glClear on every frame

opencv - 如何使用cuda tex2D访问像素的每个 channel

Android Material 设计过渡

android - 对于GcmListenerService 是onMessageReceived 后台吗?

opengl-es - 这个着色器中的 "uniform samplerXX iChannel0..3"是什么?

java - 游戏循环速度不稳定

c++ - 关于direct3d关于D3DXCreateTextureFromFileEx的方法

c++ - OpenGL 导入 PNG 变暗