动态移动VBO的问题

时间:2014-12-03 09:58:20

标签: java model 3d lwjgl vbo

我正在制作一款3D游戏,其玩家拥有跟随摄像头。在我开始使用真实模型之前,我使用了立方体,然后使用displaylist渲染它,​​一切都很顺利。但是,现在我正在导入包含更多顶点的完整3D模型,我查看了VBO。我有一个完整的结构设置我的VBO我可以看到最初绘制的模型,但它是在游戏世界的中心绘制。当我移动播放器时,模型不会按原样进行翻译。该模型没有移动它的位置。

这是我最初用来将播放器绘制为矩形(可以工作)的代码:

public static void drawRectPrism(float centerx, float centery, float centerz, float length, float height, float width, float rx, float ry, float rz)
{
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    {
        glTranslatef(centerx, centery, centerz);
        glRotatef(rx, 1, 0, 0);
        glRotatef(ry, 0, 1, 0);
        glRotatef(rz, 0, 0, 1);
        glTranslatef(-centerx, -centery, -centerz);
        glTranslatef(-length/2f, -height/2f, -width/2f);


        glBegin(GL_QUADS);
        {
            glColor3f(1.0f, 0, 0);
            glVertex3f(centerx, centery, centerz);
            glVertex3f(centerx + length, centery, centerz);
            glVertex3f(centerx + length, centery + height, centerz);
            glVertex3f(centerx, centery + height, centerz);

            glColor3f(0, 1.0f, 0);
            glVertex3f(centerx, centery, centerz + width);
            glVertex3f(centerx + length, centery, centerz + width);
            glVertex3f(centerx + length, centery + height, centerz + width);
            glVertex3f(centerx, centery + height, centerz + width);

            glColor3f(0, 0, 1.0f);
            glVertex3f(centerx, centery, centerz);
            glVertex3f(centerx, centery + height, centerz);
            glVertex3f(centerx, centery + height, centerz + width);
            glVertex3f(centerx, centery, centerz + width);          

            glColor3f(0, 1.0f, 1.0f);
            glVertex3f(centerx + length, centery, centerz);
            glVertex3f(centerx + length, centery + height, centerz);
            glVertex3f(centerx + length, centery + height, centerz + width);
            glVertex3f(centerx + length, centery, centerz + width); 

            glColor3f(1.0f, 1.0f, 0);
            glVertex3f(centerx, centery, centerz);
            glVertex3f(centerx + length, centery, centerz);
            glVertex3f(centerx + length, centery, centerz + width);
            glVertex3f(centerx, centery, centerz + width);

            glColor3f(1.0f, 0, 1.0f);
            glVertex3f(centerx, centery + height, centerz);
            glVertex3f(centerx + length, centery + height, centerz);
            glVertex3f(centerx + length, centery + height, centerz + width);
            glVertex3f(centerx, centery + height, centerz + width);         
        }
        glEnd();
    }
    glPopMatrix();
}   

我尝试了几种不同的方式比其他方式更好,可能实现了糟糕的编程结构,但我认为它应该仍然有效。

首次尝试:调整矩形代码以加载我的顶点和模型,而不是特定的矩形顶点:

public void translate(float x, float y, float z, float rx, float ry, float rz)
{

        File f = new File("graveDigga.obj");
        try{
            m = OBJLoader.loadModel(f);
        }
        catch(FileNotFoundException e)
        {
            e.printStackTrace();
            Display.destroy();
            System.exit(1);
        }
        catch(IOException e)
        {
            e.printStackTrace();
            Display.destroy();
            System.exit(1);
        }
        displayListChar = glGenLists(1);
        glNewList(displayListChar, GL_COMPILE);
        glMatrixMode(GL_MODELVIEW);
        glPushMatrix();
        {
            glTranslatef(x, y, z);
            glRotatef(rx, 1, 0, 0);
            glRotatef(ry, 0, 1, 0);
            glRotatef(rz, 0, 0, 1);
            //glTranslatef(-x, -y, -z);
            //glTranslatef(-length/2f, -height/2f, -width/2f);
            glBegin(GL_TRIANGLES);
            for(Face face : m.faces)
            {
                Vector2f t1 = m.textures.get((int) face.textures.x - 1);
                glTexCoord2f(t1.x +x ,1-(t1.y +y ));
                Vector3f n1 = m.normals.get((int) face.normal.x-1);
                glNormal3f(n1.x +x ,n1.y+y,n1.z +z);
                Vector3f v1 = m.vertices.get((int) face.vertex.x-1);
                glVertex3f(v1.x +x,v1.y+y,v1.z+z);
                Vector2f t2 = m.textures.get((int) face.textures.y - 1);
                glTexCoord2f(t2.x +x, 1 - (t2.y+y ));
                Vector3f n2 = m.normals.get((int) face.normal.y-1);
                glNormal3f(n2.x+x,n2.y+y ,n2.z+z);
                Vector3f v2 = m.vertices.get((int) face.vertex.y-1);
                glVertex3f(v2.x+x,v2.y+y ,v2.z+z);
                Vector2f t3 = m.textures.get((int) face.textures.z - 1);
                glTexCoord2f(t3.x +x, 1 - (t3.y +y));
                Vector3f n3 = m.normals.get((int) face.normal.z-1);
                glNormal3f(n3.x+x,n3.y+y,n3.z +z);
                Vector3f v3 = m.vertices.get((int) face.vertex.z-1);
                glVertex3f(v3.x+x,v3.y+y,v3.z +z);

            }
            glEnd();
        }
        glPopMatrix();

    //}
    //glPopMatrix();
    build();
}

我接下来尝试通过从这些数据创建一个VBO来显示模型,并在我的游戏循环中调用一个rander方法。在调用render之前,我将通过代码尝试转换VBO的位置,但没有发生任何事情。

glMatrixMode(GL_MODELVIEW);
            glPushMatrix();
            {
                //glLoadIdentity();
                glTranslatef(x,y,z);
                glRotatef(rx, 1, 0, 0);
                glRotatef(ry, 0, 1, 0);
                glRotatef(rz, 0, 0, 1);
                glTranslatef(-x,-y,-z);
                glDrawArrays(GL_TRIANGLES, 0, m.faces.size() * 3);

}

我不确定我是否应该使用着色器,但是我的一部分质疑为什么难以在世界空间中移动3D模型?是否存在一种易于实施的临时方式?

1 个答案:

答案 0 :(得分:1)

考虑到你是一个有1个代表的新人,有一个upvote。写得很好的问题:)。

  

我不确定我是否应该使用着色器,但是我的一部分质疑为什么难以在世界空间中移动3D模型?有一种混乱的方式,更容易实施临时基础吗?

一个简单的glTranslatef()调用应该足以移动一个对象,简单的glRotatef()调用将旋转该对象。

例如,使用glRotatef(90,1,0,0)会返回以下结果: enter image description here 没有线的草,草根本没有旋转: enter image description here

与船相同。使用glRotatef(40,-1,0,0)返回以下结果: enter image description here 没有线的轮子它只是平坦的: enter image description here

显然那只是球场。 glRotatef(AmountToRotate,PITCH,YAW,ROLL)可以将船侧倾,或者绕船旋转。

足够旋转。

为了渲染草,我只是用它:

public void render(){
    Main.TerrainDemo.shader.start();
    glPushMatrix();
    glDisable(GL_LIGHTING);
    glTranslatef(location.x * TerrainDemo.scale, location.y, location.z * TerrainDemo.scale);
    TexturedModel texturedModel = TerrainDemo.texModel;
    RawModel model = texturedModel.getRawModel();
    GL30.glBindVertexArray(model.getVaoID());
    GL20.glEnableVertexAttribArray(0);
    GL20.glEnableVertexAttribArray(1);
    GL13.glActiveTexture(GL13.GL_TEXTURE0);
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, texturedModel.getTexture().getID());
    glScalef(10f, 10f, 10f);
    glColor4f(0, 0, 0, 0.5f);
    glDrawElements(GL_TRIANGLES, model.getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
    GL20.glDisableVertexAttribArray(0);
    GL20.glDisableVertexAttribArray(1);
    GL30.glBindVertexArray(0);
    glEnable(GL_LIGHTING);
    glPopMatrix();
    Main.TerrainDemo.shader.stop();
}

要切断你可能无法识别/理解的代码,我基本上只是说glTranslatef(location.x * TerrainDemo.scale,location.y,location.z * TerrainDemo.scale)是唯一的东西。设置位置。翻译后,我简单地设置比例(大小),然后绘制它。

如果我删除了glTranslatef()行,那么所有草只会在同一位置渲染: enter image description here

所以回答你的问题: 使用类似这样的东西(Psuedocode)

PUSH MATRIX HERE (glPushMatrix) SO TO NOT SAVE THE CURRENT TRANSLATION
USE GLTRANSLATEF ON LOCATION OF CURRENT OBJECT
RENDER/DRAW OBJECT
POP THE MATRIX

不幸的是,查看你的代码我无法找到实际上导致它不能绘制的具体问题,这意味着我不能只说“有xxx代码并且它会起作用”,但我希望它有助于如何移动/旋转对象。

我正在使用VBO就像渲染草地,船只和树木一样(虽然我使用地形显示列表因为我很懒)。 如果你想进一步讨论,我的Skype是joehot200。