【问题标题】:Problems dynamically moving VBO动态移动 VBO 的问题
【发布时间】:2014-12-03 09:58:19
【问题描述】:

我正在制作一个 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 方法来显示模型。在调用渲染之前,我会运行代码以尝试转换 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 模型很困难?有没有一种更容易临时实施的凌乱方式?

【问题讨论】:

    标签: java model 3d lwjgl vbo


    【解决方案1】:

    考虑到您是一个拥有 1 个代表的新人,请点赞。写得很好的问题:)。

    我不确定我是否应该为此使用着色器,但我的一部分人在质疑为什么在世界空间中移动 3D 模型很困难?有没有一种比较容易临时实现的凌乱方式?

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

    例如,使用 glRotatef(90, 1, 0, 0) 返回以下结果: 没有线,草根本不旋转:

    这艘船也是如此。使用 glRotatef(40, -1, 0, 0) 返回以下结果: 如果没有这条线,它只会返回平坦的:

    显然,这只是音调。 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() 行,所有的草都会在同一个位置渲染:

    所以回答你的问题: 使用这样的东西(伪代码)

    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。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多