一个VBO中的多个立方体

时间:2014-01-08 02:58:25

标签: java opengl 3d lwjgl

所以,我已经弄明白了如何实现这一目标。我的阵列似乎搞砸了。这个问题很难解释,所以我会提供一些图片和代码。

编辑:问题是for循环和x1,y1,z1变量由浮点数控制

public void create() {
    setup();
    render();
}

private void makeCube() {
    texture = glGenBuffers();
    cube = glGenBuffers();

    FloatBuffer cubeBuffer;
    FloatBuffer textureBuffer;

    ArrayList<Float> cubeList = new ArrayList<>();
    ArrayList<Float> textureList = new ArrayList<>();

    float[] cubeFloat;
    float[] textureFloat;

    for (float x1 = 0; x1 < tileSize * width; x1 += tileSize) {
        for (float y1 = 0; y1 < tileSize * height; y1 += tileSize) {
            for (float z1 = -tileSize * depth; z1 < 0; z1 += tileSize) {
                float highX = x1 + tileSize;
                float highY = y1 + tileSize;
                float highZ = z1 + tileSize;

                float[] cubeData = new float[]{
                    /*Front Face*/
                    x1, y1, z1,
                    highX, y1, z1,
                    highX, highY, z1,
                    x1, highY, z1,
                    /*Back Face*/
                    x1, y1, highZ,
                    highX, y1, highZ,
                    highX, highY, highZ,
                    x1, highY, highZ,
                    /*Left Face*/
                    x1, y1, z1,
                    x1, y1, highZ,
                    x1, highY, highZ,
                    x1, highY, z1,
                    /*Right Face*/
                    highX, y1, z1,
                    highX, y1, highZ,
                    highX, highY, highZ,
                    highX, highY, z1,
                    /*Bottom Face*/
                    x1, y1, z1,
                    x1, y1, highZ,
                    highX, y1, highZ,
                    highX, y1, z1,
                    /*Top Face*/
                    x1, highY, z1,
                    x1, highY, highZ,
                    highX, highY, highZ,
                    highX, highY, z1};

                for (float f : cubeData) {
                    cubeList.add(f);
                }
            }
        }
    }

    cubeFloat = compileFloat(cubeList);

    for (int i = 0; i < (width * height * depth); i++) {
        float[] textureData = new float[]{
            0, 0,
            1, 0,
            1, 1,
            0, 1,
            0, 0,
            1, 0,
            1, 1,
            0, 1,
            0, 0,
            1, 0,
            1, 1,
            0, 1,
            0, 0,
            1, 0,
            1, 1,
            0, 1,
            0, 0,
            1, 0,
            1, 1,
            0, 1,
            0, 0,
            1, 0,
            1, 1,
            0, 1};

        for (Float f : textureData) {
            textureList.add(f);
        }
    }

    textureFloat = compileFloat(textureList);

    textureBuffer = asFloatBuffer(textureFloat);
    glBindBuffer(GL_ARRAY_BUFFER, texture);
    glBufferData(GL_ARRAY_BUFFER, textureBuffer, GL_DYNAMIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    cubeBuffer = asFloatBuffer(cubeFloat);
    glBindBuffer(GL_ARRAY_BUFFER, cube);
    glBufferData(GL_ARRAY_BUFFER, cubeBuffer, GL_DYNAMIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

private float[] compileFloat(ArrayList<Float> list) {
    float[] f = new float[list.size()];

    for (int i = 0; i < list.size(); i++) {
        f[i] = list.get(i);
    }

    return f;
}

private void renderCube() {
    textures.get(0).bind();

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    glBindBuffer(GL_ARRAY_BUFFER, cube);
    glVertexPointer(3, GL_FLOAT, 0, 0);

    glBindBuffer(GL_ARRAY_BUFFER, texture);
    glTexCoordPointer(2, GL_FLOAT, 0, 0);

    glDrawArrays(GL_QUADS, 0, 24 * (width * height * depth));

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}

private void render() {
    while (!Display.isCloseRequested()) {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glLoadIdentity();
        camera();

        renderCube();

        Display.update();
        Display.sync(30);
    }

    Display.destroy();
    System.exit(0);
}

private void setup() {
    try {
        Display.setDisplayMode(new DisplayMode(frameWidth, frameHeight));
        Display.setTitle("3D Project");
        Display.setVSyncEnabled(vSync);
        Display.create();
    } catch (LWJGLException ex) {
        Logger.getLogger(Camera.class.getName()).log(Level.SEVERE, null, ex);
    }

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(fov, (float) Display.getWidth() / (float) Display.getHeight(), zNear, zFar);
    //glOrtho(0, Display.getWidth(), Display.getHeight(), 0, -1, 1);
    glMatrixMode(GL_MODELVIEW);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_TEXTURE_2D);

    glLoadIdentity();

    loadTextures();

    makeCube();

}

制作一个3x3x1阵列会产生这样的结果:

3x3x1

尽管制作2x2x1阵列的效果非常好。 2x2x1

所以我认为这是错误的,我不知道如何解决它。 (这应该是5x5x1。 Problem

1 个答案:

答案 0 :(得分:2)

感谢您解释tileSize使用的值。值 0.1 不能以任何精度浮点表示,它会退化为base-2中的重复分数,就像每个人都熟悉1/3在base-10中所做的那样。现在,如果你继续添加这个不完全 0.1 的数字,最终结果会与你期望的结果略有不同。

通常,最好避免循环控制的浮点表达式。您可能认为,因为编译器很乐意接受浮点常量,例如 0.1 ,一切都很好,并且它可以准确地表示该数字,但是如果您不理解浮点数学的机制那么奇怪的事情可能会发生。

如果您感到好奇,可以找到我提到的问题的更详细解释here