无法让 opengl ES 在 Android 上绘制任何 2D 内容

发布于 2025-01-04 05:49:28 字数 3069 浏览 0 评论 0原文

这是我为了让 2D 绘图工作而编写的代码。活动、视图和渲染器均以正确的方式设置。我得到一个全黑的屏幕,但上面没有多边形。什么也没画。这快要把我逼疯了……

public class OpenGLActivity extends Activity {

    private GLSurfaceView surfaceView;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(
                WindowManager.LayoutParams.FLAG_FULLSCREEN, 
                WindowManager.LayoutParams.FLAG_FULLSCREEN
                );

        this.surfaceView = new OpenGLSurfaceView(this);
        setContentView(this.surfaceView);
    }

    @Override
    protected void onPause() {
        super.onPause();
        surfaceView.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        surfaceView.onResume();
    }
}

public class OpenGLSurfaceView extends GLSurfaceView {

    private OpenGLSurfaceRenderer renderer;

    public OpenGLSurfaceView(Context context) {
        super(context);
        this.renderer = new OpenGLSurfaceRenderer();
        setRenderer(renderer);
    }

}

public class OpenGLSurfaceRenderer implements Renderer {

    private FloatBuffer vertexBuffer;
    private float[] vertices = {
            0.0f, 1.0f, 0.0f,
            0.0f, 0.0f, 0.0f,
            1.0f, 1.0f, 0.0f,
            1.0f, 0.0f, 0.0f,
            0.0f, 10.0f, 0.0f,
            0.0f, 0.0f, 0.0f,
            10.0f, 10.0f, 0.0f,
            10.0f, 0.0f, 0.0f
    };

    public OpenGLSurfaceRenderer() {
        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * (Float.SIZE >> 3));
        vertexBuffer = byteBuffer.asFloatBuffer();
        vertexBuffer.put(vertices);
        vertexBuffer.position(0);
    }

    public void onSurfaceCreated(GL10 gl, EGLConfig config) {

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

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

        gl.glDisable(GL10.GL_DITHER);
        gl.glDisable(GL10.GL_LIGHTING);

        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    }

    public void onDrawFrame(GL10 gl) {

        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);

        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

        gl.glTranslatef(0.0f, 0.0f, 0.5f);
        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
    }

    public void onSurfaceChanged(GL10 gl, int width, int height) {

        gl.glViewport(0, 0, width, height);

        // Clear the projection matrix
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();

        // Set up orthographic projection mode (2D drawing)
        gl.glOrthof(0, width, height, 0, 0, 1);

        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
    }

}

This is the code I wrote in order to get 2D drawing to work. The activity and the view and renderer are setup the correct way. I get a completely black screen, but with no polygons on it. Nothing is drawn. This is about to drive me crazy...

public class OpenGLActivity extends Activity {

    private GLSurfaceView surfaceView;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(
                WindowManager.LayoutParams.FLAG_FULLSCREEN, 
                WindowManager.LayoutParams.FLAG_FULLSCREEN
                );

        this.surfaceView = new OpenGLSurfaceView(this);
        setContentView(this.surfaceView);
    }

    @Override
    protected void onPause() {
        super.onPause();
        surfaceView.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        surfaceView.onResume();
    }
}

public class OpenGLSurfaceView extends GLSurfaceView {

    private OpenGLSurfaceRenderer renderer;

    public OpenGLSurfaceView(Context context) {
        super(context);
        this.renderer = new OpenGLSurfaceRenderer();
        setRenderer(renderer);
    }

}

public class OpenGLSurfaceRenderer implements Renderer {

    private FloatBuffer vertexBuffer;
    private float[] vertices = {
            0.0f, 1.0f, 0.0f,
            0.0f, 0.0f, 0.0f,
            1.0f, 1.0f, 0.0f,
            1.0f, 0.0f, 0.0f,
            0.0f, 10.0f, 0.0f,
            0.0f, 0.0f, 0.0f,
            10.0f, 10.0f, 0.0f,
            10.0f, 0.0f, 0.0f
    };

    public OpenGLSurfaceRenderer() {
        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * (Float.SIZE >> 3));
        vertexBuffer = byteBuffer.asFloatBuffer();
        vertexBuffer.put(vertices);
        vertexBuffer.position(0);
    }

    public void onSurfaceCreated(GL10 gl, EGLConfig config) {

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

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

        gl.glDisable(GL10.GL_DITHER);
        gl.glDisable(GL10.GL_LIGHTING);

        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    }

    public void onDrawFrame(GL10 gl) {

        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);

        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

        gl.glTranslatef(0.0f, 0.0f, 0.5f);
        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
    }

    public void onSurfaceChanged(GL10 gl, int width, int height) {

        gl.glViewport(0, 0, width, height);

        // Clear the projection matrix
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();

        // Set up orthographic projection mode (2D drawing)
        gl.glOrthof(0, width, height, 0, 0, 1);

        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

软的没边 2025-01-11 05:49:28

我看到四个问题:

  1. glDrawArrays() 的最后一个参数应该是 8,而不是 4。这是您提供的顶点数,而不是三角形带中的三角形数。

  2. 您的正交投影使您的世界单位相当于像素。前 4 个顶点描述 1 像素宽的三角形。也许您在屏幕的左下角看到了一个白色像素?

  3. 每一帧都沿 Z 轴推进模型投影。 2 帧后,它将脱离视锥体。

  4. 最重要的是,您没有在 ByteBuffer 上设置正确的顺序。将此行插入到您的 OpenGlRenderer() 构造函数中:

    公共 OpenGLSurfaceRenderer() {
    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
    byteBuffer.order(ByteOrder.nativeOrder()); <------
    vertexBuffer = byteBuffer.asFloatBuffer();
    vertexBuffer.put(顶点);
    vertexBuffer.position(0);
    最重要

I see four problems:

  1. The last parameter to glDrawArrays() should be 8, not 4. It's the number of vertices you are providing, not the number of triangles in your triangle strip.

  2. Your orthographic projection makes your world units equivalent to pixels. Your first 4 vertexes describe triangles that are 1-pixel wide. Maybe you are getting a single white pixel in the bottom left corner of the screen?

  3. You advance the model projection along the Z-axis every frame. After 2 frames it will be out of the view frustrum.

  4. Most importantly, you do not set the right ordering on your ByteBuffer. Insert this line into your OpenGlRenderer() constructor:

    public OpenGLSurfaceRenderer() {
    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
    byteBuffer.order(ByteOrder.nativeOrder()); <------
    vertexBuffer = byteBuffer.asFloatBuffer();
    vertexBuffer.put(vertices);
    vertexBuffer.position(0);
    }

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文