lwjgl glDrawArrays给出了无效的操作错误

时间:2013-07-23 06:51:17

标签: java macos opengl lwjgl

在学习如何通过lwjgl使用OpenGL 3.2时,我遵循了here的教程。我一直在方法调用glDrawArrays上得到无效的操作错误。如果我从教程中复制源代码,甚至会发生此错误。

我的操作系统是Mac OS X 10.8.3,快速搜索后无法显示任何内容。

我的代码(来自教程的改编代码):

渲染方法:

public void render() {

    GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);             
    // Bind to the VAO that has all the information about the quad vertices 
    GL30.glBindVertexArray(vaoId);  
    GL20.glEnableVertexAttribArray(0);
    this.exitOnGLError("Error before DrawArrays");  
    // Draw the vertices    
    GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, vertexCount);    
    this.exitOnGLError("Error in DrawArrays");  
    // Put everything back to default (deselect)    
    GL20.glDisableVertexAttribArray(0); 
    GL30.glBindVertexArray(0);              
    this.exitOnGLError("Error in render");
}   

其余代码:

import java.nio.FloatBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.ContextAttribs;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import org.lwjgl.opengl.PixelFormat;
import org.lwjgl.util.glu.GLU;

public class TestOpenGL {

// Entry point for the application  
public static void main(String[] args) {    
    new TestOpenGL();   
}

// Setup variables  
private final String WINDOW_TITLE = "The Quad: glDrawArrays";   
private final int WIDTH = 320;  
private final int HEIGHT = 240;

// Quad variables   
private int vaoId = 0;  
private int vboId = 0;  
private int vertexCount = 0;

public TestOpenGL() {   
    // Initialize OpenGL (Display)      
    this.setupOpenGL();     
    this.setupQuad();

    while (!Display.isCloseRequested()) {       
        // Do a single loop (logic/render)
        render();
        // Force a maximum FPS of about 60          
        Display.sync(60);           
        // Let the CPU synchronize with the GPU if GPU is tagging behind            
        Display.update();       
    }       
    // Destroy OpenGL (Display)     
    this.destroyOpenGL();       
}

public void setupOpenGL() {     
    // Setup an OpenGL context with API version 3.2     
    try {       
        PixelFormat pixelFormat = new PixelFormat();        
        ContextAttribs contextAtrributes = new ContextAttribs(3, 2)         
        .withForwardCompatible(true)            
        .withProfileCore(true);

        Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));         
        Display.setTitle(WINDOW_TITLE);         
        Display.create(pixelFormat, contextAtrributes);

        System.out.println(GL11.glGetString(GL11.GL_VERSION));      
        GL11.glViewport(0, 0, WIDTH, HEIGHT);

    } catch (LWJGLException e) {        
        e.printStackTrace();        
        System.exit(-1);    
    }

    // Setup an XNA like background color       
    GL11.glClearColor(0.4f, 0.6f, 0.9f, 0f);    

    // Map the internal OpenGL coordinate system to the entire screen       
    GL11.glViewport(0, 0, WIDTH, HEIGHT);               
    this.exitOnGLError("Error in setupOpenGL"); 
}

public void setupQuad() {       
    // OpenGL expects vertices to be defined counter clockwise by default       
    float[] vertices = {    
        // Left bottom triangle     
        -0.5f, 0.5f, 0f,        
        -0.5f, -0.5f, 0f,       
        0.5f, -0.5f, 0f,

        // Right top triangle       
        0.5f, -0.5f, 0f,    
        0.5f, 0.5f, 0f, 
        -0.5f, 0.5f, 0f     
    };

    // Sending data to OpenGL requires the usage of (flipped) byte buffers

    FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(vertices.length);    
    verticesBuffer.put(vertices);       
    verticesBuffer.flip();       

    vertexCount = 6;         

    // Create a new Vertex Array Object in memory and select it (bind)      
    // A VAO can have up to 16 attributes (VBO's) assigned to it by default
    vaoId = GL30.glGenVertexArrays();
    GL30.glBindVertexArray(vaoId);

    // Create a new Vertex Buffer Object in memory and select it (bind)     
    // A VBO is a collection of Vectors which in this case resemble the location of each vertex.        
    vboId = GL15.glGenBuffers();

    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboId);
    GL15.glBufferData(GL15.GL_ARRAY_BUFFER, verticesBuffer, GL15.GL_STATIC_DRAW);
    // Put the VBO in the attributes list at index 0
    GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);

    // Deselect (bind to 0) the VBO     
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);

    // Deselect (bind to 0) the VAO     
    GL30.glBindVertexArray(0);

    this.exitOnGLError("Error in setupQuad");

}

public void destroyOpenGL() {      

    // Disable the VBO index from the VAO attributes list       
    GL20.glDisableVertexAttribArray(0);

    // Delete the VBO       
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
    GL15.glDeleteBuffers(vboId);     

    // Delete the VAO   
    GL30.glBindVertexArray(0);      
    GL30.glDeleteVertexArrays(vaoId);    

    Display.destroy();
}

public void exitOnGLError(String errorMessage) {    
    int errorValue = GL11.glGetError();         
    if (errorValue != GL11.GL_NO_ERROR) {   
        String errorString = GLU.gluErrorString(errorValue);    
        System.err.println("ERROR - " + errorMessage + ": " + errorString);         
        if (Display.isCreated())
            Display.destroy();      
        System.exit(-1);        
    }
}
}

输出

3.2 INTEL-8.10.44
ERROR - Error in DrawArrays: Invalid operation

1 个答案:

答案 0 :(得分:3)

您的代码似乎不是完全使用着色器。当您请求向前兼容的OpenGL上下文时,不支持固定功能管道,因此需要着色器。您必须使用着色器来处理顶点或使用兼容性上下文,以便让OpenGl进行顶点和片段处理。