2

在学习如何通过 lwjgl 使用 OpenGL 3.2 时,我按照这里的教程进行操作。我在方法调用 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
4

1 回答 1

3

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

于 2013-08-20T00:58:41.473 回答