【问题标题】:Problem with GL_TRIANGLESGL_TRIANGLES 的问题
【发布时间】:2011-09-12 23:44:26
【问题描述】:

我正在开发一个根据用户输入绘制多边形的程序。 我在使用 GL_TRIANGLE 绘制三角形时遇到问题。我使用下面的相同代码来绘制正方形,效果很好。但是,如果我只想画一个三角形,它就行不通了。

谁能帮帮我?

公共类三角形扩展形状{

private FloatBuffer vertexBuffer;
private FloatBuffer _colorBuffer;
private ShortBuffer indexBuffer;

private float vertices[] = {
        -0.5f, -0.5f, 0.5f, // 0
           0.5f, -0.5f, 0.5f, // 1
           0f, -0.5f, -0.5f, // 2

    }; 

private short[] indices = { 0, 2, 1 };

float[] colors = {1f, 1f, 0f, 1f };



public Triangle() {

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


    ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
    ibb.order(ByteOrder.nativeOrder());
    indexBuffer = ibb.asShortBuffer();
    indexBuffer.put(indices);
    indexBuffer.position(0);

    ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length * 4);
    cbb.order(ByteOrder.nativeOrder());
    _colorBuffer = cbb.asFloatBuffer();
    _colorBuffer.put(colors);
    _colorBuffer.position(0);
}


public void draw(GL10 gl) {

    gl.glFrontFace(GL10.GL_CCW); 
    gl.glEnable(GL10.GL_CULL_FACE); 
    gl.glCullFace(GL10.GL_BACK); 


    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
            gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

    gl.glVertexPointer(3, GL10.GL_FLOAT, 0,  vertexBuffer);
    gl.glColorPointer(4, GL10.GL_FLOAT, 0, _colorBuffer);
    gl.glDrawElements(GL10.GL_TRIANGLES, indices.length,GL10.GL_UNSIGNED_SHORT, indexBuffer);

    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glDisable(GL10.GL_CULL_FACE); 
}

}

编辑:

我从这里调用我的三角形课程,也许我在这里犯了错误

公共类 OpenGLRenderer 实现 Renderer { 字符串名称; 数组列表 myArr ; 私人浮动角度,x,y,z;

public OpenGLRenderer(String nm ) {
      name =nm;
      myArr = new ArrayList<Shape>();
     x=0;
    y=0;
    z=-3;

}


@Override
public void onDrawFrame(GL10 gl) {
    //clear the screen and depth buffer

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

    gl.glTranslatef(x, y, z);

     for (Shape t : myArr)
     {
         if (t instanceof Rectangle)
     { 
            // gl.glTranslatef(0, 0, -4);

             ((Rectangle )t).draw(gl);
             }
         if (t instanceof Square)
         { //gl.glTranslatef(0, 1, 0);
             ((Square )t).draw(gl);}
         if (t instanceof Pyramid){
             ((Pyramid)t).draw(gl);

        if (t instanceof Triangle){
            ((Triangle)t).draw(gl);

        }
        if (t instanceof Line){
            ((Line)t).draw(gl);
        }
         }

     }//for

}

public String getName() {
    return name;
}


public void setName(String name) {
    this.name = name;
}


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


    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

    gl.glViewport(0, 0, width, height);
    gl.glMatrixMode(GL10.GL_PROJECTION);
    gl.glLoadIdentity(); //reset the projection matrix
    GLU.gluPerspective(gl, 45.0f, (float)width/(float)height,
            0.1f, 100.0f); //calculate the aspect ratio of window
    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glLoadIdentity();


}

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    //set the bg as black
    gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
    gl.glShadeModel(GL10.GL_SMOOTH);
    //depth buffer setup
    gl.glClearDepthf(1.0f);
    gl.glEnable(GL10.GL_DEPTH_TEST);
    gl.glDepthFunc(GL10.GL_LEQUAL);
    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); 


}

public void addshape(Shape s) {y=y+0.1f; myArr.add(s); } }

【问题讨论】:

  • 可能与您绘制它的方式有关。尝试禁用面部剔除,然后看看是否有任何显示?
  • 我检查了我的顶点,它看起来对我来说是正确的。
  • 我已经禁用了面部剔除,但没有任何改变
  • 不要忘记在你的颜色数组上禁用ClientState。怀疑这是问题所在,但这肯定是一种好习惯。

标签: android opengl-es


【解决方案1】:

在我看来,您的 colors 数组中没有足够的颜色。这可能会导致一个不可见的三角形,具体取决于您的_colorBuffer 中的初始垃圾值。

(编辑)尝试:

float[] colors = {
    1f, 1f, 0f, 1f,
    1f, 1f, 0f, 1f,
    1f, 1f, 0f, 1f
};

【讨论】:

  • 你能推荐其他的着色方式吗?因为我已经尝试过其他绘制三角形的方法
  • 我改了但没有生效
【解决方案2】:

首先,Martin 关于colors 数组是正确的。每个顶点都需要有一个颜色(在你的情况下是 4 个值)(所以总共有 12 个值)。

接下来,此时您的三角形位于 xz 平面内,并且由于您没有对模型视图矩阵进行任何更改(沿 z 轴平移除外),您应该只看到一条线,如果有的话,(想想从侧面看的一张纸)。

但你真正的问题是你的绘制循环。我猜您不仅是 OpenGL 的新手,而且对 Java 和一般的面向对象编程也是如此。这整个设计完全是垃圾。这就是虚拟函数在面向对象代码中的用途。只需让每个形状实现其正确的draw 方法。所以你唯一需要做的就是

for (Shape t : myArr)
    t.draw(gl);

鉴于Shape 有一个抽象的draw 方法,其他子类实现了该方法。但这更多是设计缺陷。实际的错误是,ifs 的大括号坏了。目前只绘制三角形,如果tPyramidTriangle 的一个实例,那么draw 永远不会为三角形(以及线条)调用。

【讨论】:

  • 感谢您的回复。我按照你和马丁的建议改变了我的颜色阵列,但我无法得到解决方案。另一方面,您的回答确实帮助我完成了我的项目。我把我的循环改成你的了,效果很好。
  • @sldbuffy “找不到解决方案”是什么意思?你不理解它或者你没有应用它,它仍然不起作用。
  • 我理解并应用了它。正如您所预测的那样,我的线类现在可以工作,但我的三角形仍然无法工作。我使用了你的 for 循环,它也解决了我的其他问题。
  • 我重新应用了您的解决方案,现在一切正常,感谢您的帮助
【解决方案3】:

这里我的三角代码来自一个有效的项目。看起来您的索引和颜色数组不同

package com.martynhaigh.Vortex;

import android.view.animation.Transformation;

import javax.microedition.khronos.opengles.GL10;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

public class Triangle {

    private ShortBuffer _indexBuffer;
    private FloatBuffer _vertexBuffer;
    private FloatBuffer _colorBuffer;
    static float _xAngle, _yAngle;
    private int _nrOfVertices; 

    Triangle() {
        float[] coords = {
                -0.5f, -0.5f, 0f, // (x1, y1, z1)
                0.5f, -0.5f, 0f, // (x2, y2, z2)
                0f, 0.5f, 0f // (x3, y3, z3)
        }; // 9

        _nrOfVertices = coords.length / 3;

        float[] colors = {
                1f, 0f, 0f, 1f, // point 1
                0f, 1f, 0f, 1f, // point 2
                0f, 0f, 1f, 1f // point 3
        }; // 12

        short[] indices = {0, 1, 2}; // 3

        // float has 4 bytes, coordinate * 4 bytes
        ByteBuffer vbb = ByteBuffer.allocateDirect(coords.length * 4); //36
        vbb.order(ByteOrder.nativeOrder());
        _vertexBuffer = vbb.asFloatBuffer();

        // short has 2 bytes, indices * 2 bytes
        ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2); // 6
        ibb.order(ByteOrder.nativeOrder());
        _indexBuffer = ibb.asShortBuffer();

        // float has 4 bytes, colors (RGBA) * 4 bytes
        ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length * 4); // 48
        cbb.order(ByteOrder.nativeOrder());
        _colorBuffer = cbb.asFloatBuffer();

        _vertexBuffer.put(coords);
        _indexBuffer.put(indices);
        _colorBuffer.put(colors);

        _vertexBuffer.position(0);
        _indexBuffer.position(0);
        _colorBuffer.position(0);
    }

    public void onDraw(GL10 gl) {
        // set rotation
        gl.glRotatef(_xAngle, 1f, 0f, 0f);
        gl.glRotatef(_yAngle, 0f, 1f, 0f);

        // set the color of our element
        //gl.glColor4f(0.5f, 0f, 0f, 0.5f);
        gl.glColorPointer(4, GL10.GL_FLOAT, 0, _colorBuffer);

        // define the vertices we want to draw
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, _vertexBuffer);

        // finally draw the vertices
        gl.glDrawElements(GL10.GL_TRIANGLES, _nrOfVertices, GL10.GL_UNSIGNED_SHORT, _indexBuffer);   
    }

    public void setXAngle(float angle) {
        _xAngle = angle;
    }

    public float getXAngle() {
        return _xAngle;
    }

    public void setYAngle(float angle) {
        _yAngle = angle;
    }

    public float getYAngle() {
        return _yAngle;
    }
}

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-15
  • 2012-09-17
  • 1970-01-01
  • 1970-01-01
  • 2012-04-07
  • 2014-08-20
相关资源
最近更新 更多