2013-01-20 79 views
2

我开始学习OpenGL。我可以加载.obj模型并用elementBuffer绘制它。但是我一直在试图尝试两种不同的模型。我想绘制的模型位于实体类中。 我能找到的大部分教程只显示如何加载和绘制一个sinlge模型。没有解释(以我能找到/理解的方式)如何处理多个模型。在OpenGL中绘制多个对象

这里是我的所有代码:

public static void main(String[] args) throws LWJGLException, IOException 
{ 
    PixelFormat pixelFormat = new PixelFormat(); 
    ContextAttribs contextAtrributes = new ContextAttribs(3, 2); 
    contextAtrributes.withForwardCompatible(true); 
    contextAtrributes.withProfileCore(true); 

    Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT)); 
    Display.setTitle("Textured quad!"); 
    Display.create(pixelFormat, contextAtrributes); 

    Mouse.create(); 
    Mouse.setGrabbed(true); 
    Keyboard.create(); 

    glEnable(GL_DEPTH_TEST); 
    glEnable(GL_CULL_FACE); 

    entity = new Entity("planeTex.obj"); 
    entity2 = new Entity("modelTex2.obj"); 

    Shaders.load(); 
    Textures.load(); 
    Camera.create(new Vector3f(0, 1, -0.75f), new Vector3f(-50, 0, 20), HEIGHT, WIDTH); 

    while (!Display.isCloseRequested()) 
    { 

     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

     entity.draw(); 
     entity2.draw(); 

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

} 

public class Entity 
{ 
    private int vao, vbo, ebo; 
    private int elementSize; 

    public Entity(String name) 
    { 
     vao = glGenVertexArrays(); 
     glBindVertexArray(vao); 
     vbo = glGenBuffers(); 
     *Load vertex data into buffer* 
     glBindBuffer(GL_ARRAY_BUFFER, vbo); 
     glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW); 
     ebo = glGenBuffers(); 
     *load data into elementBuffer* 
     *Set elementSize to the element count* 
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); 
     glBufferData(GL_ELEMENT_ARRAY_BUFFER, elementBuffer, GL_STATIC_DRAW); 
    } 

    public void draw() 
    { 
     glBindVertexArray(vao); 
     glBindBuffer(GL_ARRAY_BUFFER, vbo); 
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); 

     glDrawElements(GL_TRIANGLES, elementSize, GL_UNSIGNED_INT, 0); 
    } 
} 

public class Shaders 
{ 

public static int vertexShader, fragmentShader; 
public static int shaderProgram; 
public static int uniTrans; 

    public static void load() 
    { 
     vertexShader = glCreateShader(GL_VERTEX_SHADER); 
     glShaderSource(vertexShader, loadFile("vertex.shader")); 
     glCompileShader(vertexShader); 

     fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); 
     glShaderSource(fragmentShader, loadFile("fragment.shader")); 
     glCompileShader(fragmentShader); 


     shaderProgram = glCreateProgram(); 
     glAttachShader(shaderProgram, vertexShader); 
     glAttachShader(shaderProgram, fragmentShader); 
     glBindFragDataLocation(shaderProgram, 0, "outColor"); 
     glLinkProgram(shaderProgram); 
     glUseProgram(shaderProgram); 


     // Specify the layout of the vertex data 
     int posAttrib = glGetAttribLocation(shaderProgram, "position"); 
     glEnableVertexAttribArray(posAttrib); 
     glVertexAttribPointer(posAttrib, 3, GL_FLOAT, false, (Float.SIZE/8) * 8, 0); 

     int colAttrib = glGetAttribLocation(shaderProgram, "color"); 
     glEnableVertexAttribArray(colAttrib); 
     glVertexAttribPointer(colAttrib, 3, GL_FLOAT, false, (Float.SIZE/8) * 8, (Float.SIZE/8) * 3); 

     int texAttrib = glGetAttribLocation(shaderProgram, "texcoord"); 
     glEnableVertexAttribArray(texAttrib); 
     glVertexAttribPointer(texAttrib, 2, GL_FLOAT, false, (Float.SIZE/8) * 8, (Float.SIZE/8) * 6); 

     uniTrans = glGetUniformLocation(Shaders.shaderProgram, "model"); 
    } 
} 

的结果是,只有创建的最后实体对象将被绘制。不管画图顺序如​​何。

+0

“vao,vbo和ebo都是全局整数” - 你的意思是静态变量吗?那么这就是问题所在。 – kerim

+0

@kerim,它们不是静态的。我更新了问题以准确显示课程的外观。 –

+0

另一个说明 - 你不需要在'draw'的'glBindVertexArray'后面调用'glBindBuffer'。您已经在构造函数中将这些缓冲区与VAO关联。 – kerim

回答

0

好,我通过将该块固定它 //指定顶点数据的布局 INT posAttrib = glGetAttribLocation(Shaders.shaderProgram, “位置”); glEnableVertexAttribArray(posAttrib); glVertexAttribPointer(posAttrib,3,GL_FLOAT,false,(Float.SIZE/8)* 8,0);

int colAttrib = glGetAttribLocation(Shaders.shaderProgram, "color"); 
    glEnableVertexAttribArray(colAttrib); 
    glVertexAttribPointer(colAttrib, 3, GL_FLOAT, false, (Float.SIZE/8) * 8, (Float.SIZE/8) * 3); 

    int texAttrib = glGetAttribLocation(Shaders.shaderProgram, "texcoord"); 
    glEnableVertexAttribArray(texAttrib); 
    glVertexAttribPointer(texAttrib, 2, GL_FLOAT, false, (Float.SIZE/8) * 8, (Float.SIZE/8) * 6); 

在实体类中,在glDrawElements方法之前绘制循环。配售块其他地方将导致崩溃的程序:

否则就简单地画什么都没有“当数组缓冲区对象是残疾人无法使用补偿”。我得到了NicolBolas的感觉,我应该把它放在Entity的构造函数中,但正如我所说的那样,它在任何地方都不起作用。