在 OpenGL ES 2D 正交 (Ortho) 模式下绘图时出现问题

发布于 2024-11-06 11:21:39 字数 10635 浏览 1 评论 0原文

几天来我一直在拼命想解决这个问题,在搜索了 Stack Overflow 和网络之后,我还没有找到任何对我有用的例子。我终于得到了看起来很接近的代码,所以也许你们(和女孩们?)可以帮助我解决这个问题。

我的第一个问题是,我试图通过将屏幕抓取作为纹理来实现运动模糊,然后以透明度在下一帧上绘制纹理 - 或者使用更多帧以获得更多模糊。 (如果有人感兴趣,这是我遵循的指南:http://www.codeproject.com /KB/openGL/MotionBlur.aspx

我已经将屏幕保存为纹理工作正常。我遇到的问题是在屏幕顶部以正交模式绘制。经过一番绞尽脑汁,我终于得到了一个基本的方形绘图,但我对 OpenGL ES 缺乏理解和一个​​易于理解的示例现在阻碍了我。我需要获取我保存的纹理,并将其绘制到我绘制的正方形中。我所做的一切似乎都不起作用。

另外,我的第二个问题是将更复杂的 3D 模型绘制到正交模式中。我似乎无法找到任何模型来绘制。我正在使用(稍微定制的)min3d 框架(http://code.google.com/p/min3d/),并且我尝试在正交模式下绘制 Object3d,就像在透视模式下绘制它们一样。据我了解,他们应该画一样的,只是没有深度。但我似乎根本没有看到他们。

这是我正在使用的代码。我尝试了很多不同的东西,这是我得到的最接近的东西(实际上是在屏幕上画一些可以看到的东西)。我仍然不知道如何在正交视图中获得正确的 3D 模型图。我确信我正在做一些严重错误的事情,并且可能完全误解了 OpenGL 绘图的一些基本方面。如果我需要发布任何其他代码,请告诉我。

// Gets called once, before all drawing occurs
//
private void reset()
{
    // Reset TextureManager
    Shared.textureManager().reset();

    // Do OpenGL settings which we are using as defaults, or which we will not be changing on-draw

    // Explicit depth settings
    _gl.glEnable(GL10.GL_DEPTH_TEST);                                   
    _gl.glClearDepthf(1.0f);
    _gl.glDepthFunc(GL10.GL_LESS);                                      
    _gl.glDepthRangef(0,1f);                                            
    _gl.glDepthMask(true);                                              

    // Alpha enabled
    _gl.glEnable(GL10.GL_BLEND);                                        
    _gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);    

    // "Transparency is best implemented using glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) 
    // with primitives sorted from farthest to nearest."

    // Texture
    _gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST); // (OpenGL default is GL_NEAREST_MIPMAP)
    _gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); // (is OpenGL default)

    // CCW frontfaces only, by default
    _gl.glFrontFace(GL10.GL_CCW);
    _gl.glCullFace(GL10.GL_BACK);
    _gl.glEnable(GL10.GL_CULL_FACE);

    // Disable lights by default
    for (int i = GL10.GL_LIGHT0; i < GL10.GL_LIGHT0 + NUM_GLLIGHTS; i++) {
        _gl.glDisable(i);
    }

    //
    // Scene object init only happens here, when we get GL for the first time
    // 
}

// Called every frame
//
protected void drawScene()
{   
    if(_scene.fogEnabled() == true) {
        _gl.glFogf(GL10.GL_FOG_MODE, _scene.fogType().glValue());
        _gl.glFogf(GL10.GL_FOG_START, _scene.fogNear());
        _gl.glFogf(GL10.GL_FOG_END, _scene.fogFar());
        _gl.glFogfv(GL10.GL_FOG_COLOR, _scene.fogColor().toFloatBuffer() );
        _gl.glEnable(GL10.GL_FOG);
    } else {
        _gl.glDisable(GL10.GL_FOG);
    }

    // Sync all of the object drawing so that updates in the mover
    // thread can be synced if necessary
    synchronized(Renderer.SYNC)
    {
        for (int i = 0; i < _scene.children().size(); i++)
        {
            Object3d o = _scene.children().get(i);
            if(o.animationEnabled())
            {
                ((AnimationObject3d)o).update();
            }
            drawObject(o);
        }
    }

    //
    //
    //
    // Draw the blur

    // Set Up An Ortho View
    _switchToOrtho();

    _drawMotionBlur();

    // Switch back to the previous view
    _switchToPerspective();

    _saveScreenToTexture("blur", 512);
}

private void _switchToOrtho()
{
    // Set Up An Ortho View
    _gl.glDisable(GL10.GL_DEPTH_TEST);
    _gl.glMatrixMode(GL10.GL_PROJECTION); // Select Projection
    _gl.glPushMatrix(); // Push The Matrix
    _gl.glLoadIdentity(); // Reset The Matrix
    _gl.glOrthof(0f, 480f, 0f, 800f, -1f, 1f);
    //_gl.glOrthof(0f, 480f, 0f, 800f, -100f, 100f);
    _gl.glMatrixMode(GL10.GL_MODELVIEW); // Select Modelview Matrix
    _gl.glPushMatrix(); // Push The Matrix
    _gl.glLoadIdentity(); // Reset The Matrix
}

private void _switchToPerspective()
{
    // Switch back to the previous view
    _gl.glEnable(GL10.GL_DEPTH_TEST);
    _gl.glMatrixMode(GL10.GL_PROJECTION);
    _gl.glPopMatrix();
    _gl.glMatrixMode(GL10.GL_MODELVIEW);
    _gl.glPopMatrix(); // Pop The Matrix
}

private void _saveScreenToTexture(String $textureId, int $size)
{
    // Save the screen as a texture
    _gl.glViewport(0, 0, $size, $size);
    _gl.glBindTexture(GL10.GL_TEXTURE_2D, _textureManager.getGlTextureId($textureId));
    _gl.glCopyTexImage2D(GL10.GL_TEXTURE_2D,0,GL10.GL_RGB,0,0,512,512,0);
    _gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
    _gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
    _gl.glViewport(0, 0, 480, 800);
}

private void _drawMotionBlur()
{
    // Vertices
    float squareVertices[] = {
        -3f, 0f,     // Bottom Left
        475f, 0f,     // Bottom Right
        475f, 800f, // Top Right
        -3f, 800f  // Top Left
    };

    ByteBuffer vbb = ByteBuffer.allocateDirect(squareVertices.length * 4);
    vbb.order(ByteOrder.nativeOrder());
    FloatBuffer vertexBuffer = vbb.asFloatBuffer();
    vertexBuffer.put(squareVertices);
    vertexBuffer.position(0);

    //
    //
    // Textures
    FloatBuffer textureBuffer;  // buffer holding the texture coordinates
    float texture[] = {         
            // Mapping coordinates for the vertices
            0.0f, 1.0f,     // top left     (V2)
            0.0f, 0.0f,     // bottom left  (V1)
            1.0f, 1.0f,     // top right    (V4)
            1.0f, 0.0f      // bottom right (V3)
    };
    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(squareVertices.length * 4);
    byteBuffer.order(ByteOrder.nativeOrder());
    byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
    byteBuffer.order(ByteOrder.nativeOrder());
    textureBuffer = byteBuffer.asFloatBuffer();
    textureBuffer.put(texture);
    textureBuffer.position(0);
    //
    //
    //

    _gl.glLineWidth(3.0f);
    _gl.glTranslatef(5.0f, 0.0f, 0.0f);
    _gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertexBuffer);
    _gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

    _gl.glDrawArrays(GL10.GL_LINE_LOOP, 0, 4);
    //_gl.glTranslatef(100.0f, 0.0f, 0.0f);
    //_gl.glDrawArrays(GL10.GL_LINE_LOOP, 0, 4);
    //_gl.glTranslatef(100.0f, 0.0f, 0.0f);
    //_gl.glDrawArrays(GL10.GL_LINE_LOOP, 0, 4);


    _gl.glEnable(GL10.GL_TEXTURE_2D);
    _gl.glEnable(GL10.GL_BLEND);
    _gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    _gl.glLoadIdentity();

    //
    //
    //
    _gl.glBindTexture(GL10.GL_TEXTURE_2D, _textureManager.getGlTextureId("blur"));
    _gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
    _gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
    //
    //
    //

    _gl.glDisable(GL10.GL_BLEND);
    _gl.glDisable(GL10.GL_TEXTURE_2D);
    _gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}

编辑:这是一个更简单的示例,它全部在一个函数中,不包括任何将屏幕保存到纹理的内容。这只是绘制一个 3D 场景,切换到 Ortho,绘制一个带有纹理的正方形,然后切换回透视。

// Called every frame
//
protected void drawScene()
{   
    // Draw the 3d models in perspective mode
    // This part works (uses min3d) and draws a 3d scene
    //
    for (int i = 0; i < _scene.children().size(); i++)
    {
        Object3d o = _scene.children().get(i);
        if(o.animationEnabled())
        {
            ((AnimationObject3d)o).update();
        }
        drawObject(o);
    }

    // Set Up The Ortho View to draw a square with a texture
    // over the 3d scene
    //
    _gl.glDisable(GL10.GL_DEPTH_TEST);
    _gl.glMatrixMode(GL10.GL_PROJECTION); // Select Projection
    _gl.glPushMatrix(); // Push The Matrix
    _gl.glLoadIdentity(); // Reset The Matrix
    _gl.glOrthof(0f, 480f, 0f, 800f, -1f, 1f);
    _gl.glMatrixMode(GL10.GL_MODELVIEW); // Select Modelview Matrix
    _gl.glPushMatrix(); // Push The Matrix
    _gl.glLoadIdentity(); // Reset The Matrix


    // Draw A Square With A Texture
    // (Assume that the texture "blur" is already created properly --
    // it is as I can use it when drawing my 3d scene if I apply it
    // to one of the min3d objects)
    //
    float squareVertices[] = {
        -3f, 0f,     // Bottom Left
        475f, 0f,     // Bottom Right
        475f, 800f, // Top Right
        -3f, 800f  // Top Left
    };

    ByteBuffer vbb = ByteBuffer.allocateDirect(squareVertices.length * 4);
    vbb.order(ByteOrder.nativeOrder());
    FloatBuffer vertexBuffer = vbb.asFloatBuffer();
    vertexBuffer.put(squareVertices);
    vertexBuffer.position(0);

    FloatBuffer textureBuffer;  // buffer holding the texture coordinates
    float texture[] = {         
            // Mapping coordinates for the vertices
            0.0f, 1.0f,     // top left     (V2)
            0.0f, 0.0f,     // bottom left  (V1)
            1.0f, 1.0f,     // top right    (V4)
            1.0f, 0.0f      // bottom right (V3)
    };
    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(squareVertices.length * 4);
    byteBuffer.order(ByteOrder.nativeOrder());
    byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
    byteBuffer.order(ByteOrder.nativeOrder());
    textureBuffer = byteBuffer.asFloatBuffer();
    textureBuffer.put(texture);
    textureBuffer.position(0);

    _gl.glLineWidth(3.0f);
    _gl.glTranslatef(5.0f, 0.0f, 0.0f);
    _gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertexBuffer);
    _gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

    _gl.glDrawArrays(GL10.GL_LINE_LOOP, 0, 4);

    _gl.glEnable(GL10.GL_TEXTURE_2D);
    _gl.glEnable(GL10.GL_BLEND);
    _gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    _gl.glLoadIdentity();

    _gl.glBindTexture(GL10.GL_TEXTURE_2D, _textureManager.getGlTextureId("blur"));
    _gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
    _gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);

    _gl.glDisable(GL10.GL_BLEND);
    _gl.glDisable(GL10.GL_TEXTURE_2D);
    _gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

    // Switch Back To The Perspective Mode
    //
    _gl.glEnable(GL10.GL_DEPTH_TEST);
    _gl.glMatrixMode(GL10.GL_PROJECTION);
    _gl.glPopMatrix();
    _gl.glMatrixMode(GL10.GL_MODELVIEW);
    _gl.glPopMatrix(); // Pop The Matrix
}

编辑2:感谢Christian的回答,我删除了第二个glVertexPointer_gl.glBlendFunc (GL10.GL_ONE, GL10.GL_ONE);(我删除了它们也来自上面的示例代码,因此不会混淆问题)。我现在有了纹理渲染,但仅限于构成正方形的三角形之一。所以我在屏幕左侧看到一个应用了纹理的三角形。为什么它不应用于正方形的两半?我认为这是因为我只有以下调用之一: gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); 所以我实际上只绘制了一个三角形。

I've been beating my head against the desk trying to figure this out for days now, and after scouring Stack Overflow and the web, I haven't found any examples that have worked for me. I've finally got code that's seems close, so maybe you guys (and gals?) can help me figure this out.

My first problem is that I'm trying to implement a motion blur by taking a screen grab as a texture, then drawing the texture over the next frame with transparency -- or use more frames for more blur. (If anyone's interested, this is the guide I followed: http://www.codeproject.com/KB/openGL/MotionBlur.aspx)

I've got the screen saving as a texture working fine. The issue I'm having is drawing in Ortho mode on top of the screen. After much head banging, I finally got a basic square drawing, but my lack of OpenGL ES understanding and an easy to follow example are holding me back now. I need to take the texture I saved, and draw it into the square I drew. Nothing I've been doing seems to work.

Also, my second problem, is drawing more complex 3d models into Ortho mode. I can't seem to get any models to draw. I'm using the (slightly customized) min3d framework (http://code.google.com/p/min3d/), and I'm trying to draw Object3d's in Ortho mode just like I draw them in Perspective mode. As I understand it, they should draw the same, they should just not have depth. Yet I don't seem to see them at all.

Here's the code I'm working with. I've tried a ton of different things and this is the closest I've gotten (actually drawing something on the screen that can be seen). I still have no idea how to get a proper 3d model drawing in the ortho view. I'm sure I'm doing something horribly wrong and probably completely misunderstanding some basic aspects of OpenGL drawing. Let me know if there's any other code I need to post.

// Gets called once, before all drawing occurs
//
private void reset()
{
    // Reset TextureManager
    Shared.textureManager().reset();

    // Do OpenGL settings which we are using as defaults, or which we will not be changing on-draw

    // Explicit depth settings
    _gl.glEnable(GL10.GL_DEPTH_TEST);                                   
    _gl.glClearDepthf(1.0f);
    _gl.glDepthFunc(GL10.GL_LESS);                                      
    _gl.glDepthRangef(0,1f);                                            
    _gl.glDepthMask(true);                                              

    // Alpha enabled
    _gl.glEnable(GL10.GL_BLEND);                                        
    _gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);    

    // "Transparency is best implemented using glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) 
    // with primitives sorted from farthest to nearest."

    // Texture
    _gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST); // (OpenGL default is GL_NEAREST_MIPMAP)
    _gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); // (is OpenGL default)

    // CCW frontfaces only, by default
    _gl.glFrontFace(GL10.GL_CCW);
    _gl.glCullFace(GL10.GL_BACK);
    _gl.glEnable(GL10.GL_CULL_FACE);

    // Disable lights by default
    for (int i = GL10.GL_LIGHT0; i < GL10.GL_LIGHT0 + NUM_GLLIGHTS; i++) {
        _gl.glDisable(i);
    }

    //
    // Scene object init only happens here, when we get GL for the first time
    // 
}

// Called every frame
//
protected void drawScene()
{   
    if(_scene.fogEnabled() == true) {
        _gl.glFogf(GL10.GL_FOG_MODE, _scene.fogType().glValue());
        _gl.glFogf(GL10.GL_FOG_START, _scene.fogNear());
        _gl.glFogf(GL10.GL_FOG_END, _scene.fogFar());
        _gl.glFogfv(GL10.GL_FOG_COLOR, _scene.fogColor().toFloatBuffer() );
        _gl.glEnable(GL10.GL_FOG);
    } else {
        _gl.glDisable(GL10.GL_FOG);
    }

    // Sync all of the object drawing so that updates in the mover
    // thread can be synced if necessary
    synchronized(Renderer.SYNC)
    {
        for (int i = 0; i < _scene.children().size(); i++)
        {
            Object3d o = _scene.children().get(i);
            if(o.animationEnabled())
            {
                ((AnimationObject3d)o).update();
            }
            drawObject(o);
        }
    }

    //
    //
    //
    // Draw the blur

    // Set Up An Ortho View
    _switchToOrtho();

    _drawMotionBlur();

    // Switch back to the previous view
    _switchToPerspective();

    _saveScreenToTexture("blur", 512);
}

private void _switchToOrtho()
{
    // Set Up An Ortho View
    _gl.glDisable(GL10.GL_DEPTH_TEST);
    _gl.glMatrixMode(GL10.GL_PROJECTION); // Select Projection
    _gl.glPushMatrix(); // Push The Matrix
    _gl.glLoadIdentity(); // Reset The Matrix
    _gl.glOrthof(0f, 480f, 0f, 800f, -1f, 1f);
    //_gl.glOrthof(0f, 480f, 0f, 800f, -100f, 100f);
    _gl.glMatrixMode(GL10.GL_MODELVIEW); // Select Modelview Matrix
    _gl.glPushMatrix(); // Push The Matrix
    _gl.glLoadIdentity(); // Reset The Matrix
}

private void _switchToPerspective()
{
    // Switch back to the previous view
    _gl.glEnable(GL10.GL_DEPTH_TEST);
    _gl.glMatrixMode(GL10.GL_PROJECTION);
    _gl.glPopMatrix();
    _gl.glMatrixMode(GL10.GL_MODELVIEW);
    _gl.glPopMatrix(); // Pop The Matrix
}

private void _saveScreenToTexture(String $textureId, int $size)
{
    // Save the screen as a texture
    _gl.glViewport(0, 0, $size, $size);
    _gl.glBindTexture(GL10.GL_TEXTURE_2D, _textureManager.getGlTextureId($textureId));
    _gl.glCopyTexImage2D(GL10.GL_TEXTURE_2D,0,GL10.GL_RGB,0,0,512,512,0);
    _gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
    _gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
    _gl.glViewport(0, 0, 480, 800);
}

private void _drawMotionBlur()
{
    // Vertices
    float squareVertices[] = {
        -3f, 0f,     // Bottom Left
        475f, 0f,     // Bottom Right
        475f, 800f, // Top Right
        -3f, 800f  // Top Left
    };

    ByteBuffer vbb = ByteBuffer.allocateDirect(squareVertices.length * 4);
    vbb.order(ByteOrder.nativeOrder());
    FloatBuffer vertexBuffer = vbb.asFloatBuffer();
    vertexBuffer.put(squareVertices);
    vertexBuffer.position(0);

    //
    //
    // Textures
    FloatBuffer textureBuffer;  // buffer holding the texture coordinates
    float texture[] = {         
            // Mapping coordinates for the vertices
            0.0f, 1.0f,     // top left     (V2)
            0.0f, 0.0f,     // bottom left  (V1)
            1.0f, 1.0f,     // top right    (V4)
            1.0f, 0.0f      // bottom right (V3)
    };
    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(squareVertices.length * 4);
    byteBuffer.order(ByteOrder.nativeOrder());
    byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
    byteBuffer.order(ByteOrder.nativeOrder());
    textureBuffer = byteBuffer.asFloatBuffer();
    textureBuffer.put(texture);
    textureBuffer.position(0);
    //
    //
    //

    _gl.glLineWidth(3.0f);
    _gl.glTranslatef(5.0f, 0.0f, 0.0f);
    _gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertexBuffer);
    _gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

    _gl.glDrawArrays(GL10.GL_LINE_LOOP, 0, 4);
    //_gl.glTranslatef(100.0f, 0.0f, 0.0f);
    //_gl.glDrawArrays(GL10.GL_LINE_LOOP, 0, 4);
    //_gl.glTranslatef(100.0f, 0.0f, 0.0f);
    //_gl.glDrawArrays(GL10.GL_LINE_LOOP, 0, 4);


    _gl.glEnable(GL10.GL_TEXTURE_2D);
    _gl.glEnable(GL10.GL_BLEND);
    _gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    _gl.glLoadIdentity();

    //
    //
    //
    _gl.glBindTexture(GL10.GL_TEXTURE_2D, _textureManager.getGlTextureId("blur"));
    _gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
    _gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
    //
    //
    //

    _gl.glDisable(GL10.GL_BLEND);
    _gl.glDisable(GL10.GL_TEXTURE_2D);
    _gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}

EDIT: Here's a simpler example, it's all in the one function and doesn't include any of the saving the screen to a texture stuff. This is just drawing a 3d scene, switching to Ortho, drawing a square with a texture, then switching back to perspective.

// Called every frame
//
protected void drawScene()
{   
    // Draw the 3d models in perspective mode
    // This part works (uses min3d) and draws a 3d scene
    //
    for (int i = 0; i < _scene.children().size(); i++)
    {
        Object3d o = _scene.children().get(i);
        if(o.animationEnabled())
        {
            ((AnimationObject3d)o).update();
        }
        drawObject(o);
    }

    // Set Up The Ortho View to draw a square with a texture
    // over the 3d scene
    //
    _gl.glDisable(GL10.GL_DEPTH_TEST);
    _gl.glMatrixMode(GL10.GL_PROJECTION); // Select Projection
    _gl.glPushMatrix(); // Push The Matrix
    _gl.glLoadIdentity(); // Reset The Matrix
    _gl.glOrthof(0f, 480f, 0f, 800f, -1f, 1f);
    _gl.glMatrixMode(GL10.GL_MODELVIEW); // Select Modelview Matrix
    _gl.glPushMatrix(); // Push The Matrix
    _gl.glLoadIdentity(); // Reset The Matrix


    // Draw A Square With A Texture
    // (Assume that the texture "blur" is already created properly --
    // it is as I can use it when drawing my 3d scene if I apply it
    // to one of the min3d objects)
    //
    float squareVertices[] = {
        -3f, 0f,     // Bottom Left
        475f, 0f,     // Bottom Right
        475f, 800f, // Top Right
        -3f, 800f  // Top Left
    };

    ByteBuffer vbb = ByteBuffer.allocateDirect(squareVertices.length * 4);
    vbb.order(ByteOrder.nativeOrder());
    FloatBuffer vertexBuffer = vbb.asFloatBuffer();
    vertexBuffer.put(squareVertices);
    vertexBuffer.position(0);

    FloatBuffer textureBuffer;  // buffer holding the texture coordinates
    float texture[] = {         
            // Mapping coordinates for the vertices
            0.0f, 1.0f,     // top left     (V2)
            0.0f, 0.0f,     // bottom left  (V1)
            1.0f, 1.0f,     // top right    (V4)
            1.0f, 0.0f      // bottom right (V3)
    };
    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(squareVertices.length * 4);
    byteBuffer.order(ByteOrder.nativeOrder());
    byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
    byteBuffer.order(ByteOrder.nativeOrder());
    textureBuffer = byteBuffer.asFloatBuffer();
    textureBuffer.put(texture);
    textureBuffer.position(0);

    _gl.glLineWidth(3.0f);
    _gl.glTranslatef(5.0f, 0.0f, 0.0f);
    _gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertexBuffer);
    _gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

    _gl.glDrawArrays(GL10.GL_LINE_LOOP, 0, 4);

    _gl.glEnable(GL10.GL_TEXTURE_2D);
    _gl.glEnable(GL10.GL_BLEND);
    _gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    _gl.glLoadIdentity();

    _gl.glBindTexture(GL10.GL_TEXTURE_2D, _textureManager.getGlTextureId("blur"));
    _gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
    _gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);

    _gl.glDisable(GL10.GL_BLEND);
    _gl.glDisable(GL10.GL_TEXTURE_2D);
    _gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

    // Switch Back To The Perspective Mode
    //
    _gl.glEnable(GL10.GL_DEPTH_TEST);
    _gl.glMatrixMode(GL10.GL_PROJECTION);
    _gl.glPopMatrix();
    _gl.glMatrixMode(GL10.GL_MODELVIEW);
    _gl.glPopMatrix(); // Pop The Matrix
}

EDIT2: Thanks to Christian's answer, I removed the second glVertexPointer and _gl.glBlendFunc (GL10.GL_ONE, GL10.GL_ONE); (I deleted them from the sample code above as well so it wouldn't confuse the question). I now have a texture rendering, but only in one of the triangles that make up the square. So I'm seeing a triangle in the left portion of the screen that has the texture applied. Why is it not being applied to both halves of the square? I think it's because I have only one of these calls: gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); so I'm literally only drawing one triangle.

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

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

发布评论

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

评论(1

冷默言语 2024-11-13 11:21:39

首先,将混合函数设置为(GL_ONE,GL_ONE),这只会将模糊纹理添加到帧缓冲区并使整个场景过亮。您可能想要使用 (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA),但是您必须确保您的模糊纹理具有正确的 alpha,方法是配置纹理环境以使用 alpha 的常量值(而不是纹理的)或将 GL_MODULATE 与(1,1,1,0.5) 彩色正方形。或者使用片段着色器。

其次,您在第二次调用 glVertexPointer 时指定大小 3,但您的数据是 2d 向量(第一次调用是正确的)。

glOrtho 不一定是 2D,它只是一个没有透视失真的相机(更远的物体不会变小)。 glOrtho 的参数指定视图坐标中的屏幕平面大小。因此,如果您的场景覆盖单位立方体中的世界,则 480x800 的正交就太大了(如果您绘制透视之外的其他对象,如正方形或 UI 元素,这没有问题,但是当您想要绘制相同的 3d比例必须匹配的物体)。另一件事是,在正交中,近距离和远距离仍然很重要,所有掉落的东西都会被剪掉。因此,如果您的相机位于 (0,0,0) 并且您沿 -z 方向查看,且 glOrtho 为 (0,480,0,800,-1,1),您将只能看到与 (0,0,-1) 相交的那些对象)-(480,800,1)-框。

因此请记住,glOrtho 和 glFrustum(或 gluPerspective)都定义了 3d 查看体积。在正交中它是一个盒子,在截锥体中它是一个截锥体(有顶金字塔)。如果这还不够清楚,请查阅一些有关转换和查看的更多介绍性文本。

First, you set the blend function to (GL_ONE, GL_ONE), which will just add the blur texture to the framebuffer and make the whole scene overbright. You probalby want to use (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA), but then you have to make sure your blur texture has the correct alpha, by configuring the texture environment to use a constant value for the alpha (instead of the texture's) or use GL_MODULATE with a (1,1,1,0.5) coloured square. Alternatively use a fragment shader.

Second, you specify a size 3 in the second call to glVertexPointer, but your data are 2d vectors (the first call is right).

glOrtho is not neccessarily 2D, its just a camera without perspective distortion (farther objects don't get smaller). The parameters to glOrtho specify your screen plane size in view coordinates. Thus if your scene covers the world in the unit cube, an ortho of 480x800 is just too large (this is no problem if you draw other objects than in perspective, as your square or UI elements, but when you want to draw your same 3d objects the scales have to match). Another thing is that in ortho the near and far distances still matter, everything that falls out is clipped away. So if your camera is at (0,0,0) and you view along -z with a glOrtho of (0,480,0,800,-1,1), you will only see those objects that intersect the (0,0,-1)-(480,800,1)-box.

So keep in mind, that glOrtho and glFrustum (or gluPerspective) all define a 3d viewing volume. In ortho its a box and in frustum its, guess a frustum (capped pyramid). consult some more introductory texts on transformations and viewing if this was not clear enough.

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