简体   繁体   English

glVertexAttribPointer的JOGL错误

[英]JOGL error with glVertexAttribPointer

I am tring the code below (using VAO(Vertex Buffer Object) and glDrawArraysInstanced method) 我正在尝试下面的代码(使用VAO(顶点缓冲区对象)和glDrawArraysInstanced方法)

If I set useVao = false, it is ok. 如果我设置useVao = false,就可以。 But when I set it to true, I've got the following exception: 但是,当我将其设置为true时,将出现以下异常:

javax.media.opengl.GLException: Thread[AWT-EventQueue-0,6,main] glGetError() returned the following error codes after a call to glVertexAttribPointer( GLArrayDataWrapper[mgl_MultiTexCoord, index -1, location 1, isVertexAttribute true, dataType 0x1406, bufferClazz class java.nio.FloatBuffer, elements 4, components 2, stride 20b 5c, mappedElementCount 0, buffer java.nio.DirectFloatBufferU[pos=0 lim=20 cap=40], vboEnabled true, vboName 1, vboUsage 0x88e4, vboTarget 0x8892, vboOffset 12, alive true]): GL_INVALID_OPERATION ( 1282 0x502), javax.media.opengl.GLException:线程[AWT-EventQueue-0,6,main] glGetError()在调用glVertexAttribPointer(GLArrayDataWrapper [mgl_MultiTexCoord,index -1,location 1,isVertexAttribute true,dataType 0x1406)后返回了以下错误代码,bufferClazz类java.nio.FloatBuffer,元素4,组件2,跨度20b 5c,mappedElementCount 0,缓冲区java.nio.DirectFloatBufferU [pos = 0 lim = 20 cap = 40],vboEnabled true,vboName 1,vboUsage 0x88e4,vboTarget 0x8892,vboOffset 12,alive true]):GL_INVALID_OPERATION(1282 0x502),

I think the last argument (0, and Buffers.SIZEOF_FLOAT * 3) for glVertexAttribPointer() is suspicious but I can't correct it. 我认为glVertexAttribPointer()的最后一个参数(0和Buffers.SIZEOF_FLOAT * 3)可疑,但我无法纠正。

My trials: 我的试验:

  1. change the variable arg0 to 0. 将变量arg0更改为0。
  2. change the variable stride to 0. 将变量跨度更改为0。
  3. change the variable stride to 0, and arg0 to 0. 将变量stride更改为0,并将arg0更改为0。

And I'm not sure if I can use the VAO and glDrawArraysInstanced method at the same time. 而且我不确定是否可以同时使用VAO和glDrawArraysInstanced方法。

Any suggestions? 有什么建议么?

package demos.triangle;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.nio.FloatBuffer;

import javax.media.opengl.DebugGL3;
import javax.media.opengl.GL3;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLJPanel;
import javax.media.opengl.fixedfunc.GLMatrixFunc;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

import com.jogamp.common.nio.Buffers;
import com.jogamp.opengl.util.FPSAnimator;
import com.jogamp.opengl.util.PMVMatrix;

public class MultTriangleVAOInstancedExperiment implements GLEventListener {
    private final JFrame frame;
    private final FPSAnimator animator;
    private final GLJPanel panel;
    private final Dimension dim = new Dimension(1024, 768);
    private double t0 = System.currentTimeMillis();
    private float theta;

    private int shaderProgram;
    private int vertShader;
    private int fragShader;
    private int modelViewProjectionMatrixLocation;
    private int transformMatrixLocation;

    private static final int locPos = 1;
    private static final int locCol = 2;
    private static final boolean useVao = false;
//  private static final boolean useVao = true;

    private int[] vbo;
    private int[] vao;

    public static void main(String[] s){
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new MultTriangleVAOInstancedExperiment();
            }
        });
    }

    public MultTriangleVAOInstancedExperiment() {
        frame = new JFrame(this.getClass().getSimpleName());
        frame.setLayout(new BorderLayout());
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                animator.stop();
                System.exit(0);
            }
        });

        GLProfile profile = GLProfile.get(GLProfile.GL3);
            panel = new GLJPanel(new GLCapabilities(profile));
        panel.addGLEventListener(this);
        panel.setPreferredSize(dim);
        frame.add(panel, BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);
        animator = new FPSAnimator(panel, 60, true);
        animator.start();
    }

    @Override
    public void init(GLAutoDrawable drawable) {
        GL3 gl = drawable.getGL().getGL3();
        drawable.setGL(new DebugGL3(gl));

        gl.glClearColor(1, 1, 1, 1);
        gl.glClearDepth(1.0f);

        System.err.println("Chosen GLCapabilities: " + drawable.getChosenGLCapabilities());
        System.err.println("INIT GL IS: " + gl.getClass().getName());
        System.err.println("GL_VENDOR: " + gl.glGetString(GL3.GL_VENDOR));
        System.err.println("GL_RENDERER: " + gl.glGetString(GL3.GL_RENDERER));
        System.err.println("GL_VERSION: " + gl.glGetString(GL3.GL_VERSION));

        vertShader = gl.glCreateShader(GL3.GL_VERTEX_SHADER);
        fragShader = gl.glCreateShader(GL3.GL_FRAGMENT_SHADER);

        String[] vlines = new String[] { vertexShaderString };
        int[] vlengths = new int[] { vlines[0].length() };
        gl.glShaderSource(vertShader, vlines.length, vlines, vlengths, 0);
        gl.glCompileShader(vertShader);

        int[] compiled = new int[1];
        gl.glGetShaderiv(vertShader, GL3.GL_COMPILE_STATUS, compiled, 0);
        if(compiled[0] != 0) {
            System.out.println("Vertex shader compiled");
        } else {
            int[] logLength = new int[1];
            gl.glGetShaderiv(vertShader, GL3.GL_INFO_LOG_LENGTH, logLength, 0);

            byte[] log = new byte[logLength[0]];
            gl.glGetShaderInfoLog(vertShader, logLength[0], (int[])null, 0, log, 0);

            System.err.println("Error compiling the vertex shader: " + new String(log));
            System.exit(1);
        }

        String[] flines = new String[] { fragmentShaderString };
        int[] flengths = new int[] { flines[0].length() };
        gl.glShaderSource(fragShader, flines.length, flines, flengths, 0);
        gl.glCompileShader(fragShader);

        gl.glGetShaderiv(fragShader, GL3.GL_COMPILE_STATUS, compiled, 0);
        if(compiled[0] != 0){
            System.out.println("Fragment shader compiled.");
        } else {
            int[] logLength = new int[1];
            gl.glGetShaderiv(fragShader, GL3.GL_INFO_LOG_LENGTH, logLength, 0);

            byte[] log = new byte[logLength[0]];
            gl.glGetShaderInfoLog(fragShader, logLength[0], (int[])null, 0, log, 0);

            System.err.println("Error compiling the fragment shader: " + new String(log));
            System.exit(1);
        }

        shaderProgram = gl.glCreateProgram();
        gl.glAttachShader(shaderProgram, vertShader);
        gl.glAttachShader(shaderProgram, fragShader);

        gl.glBindAttribLocation(shaderProgram, locPos, "VertexPosition");
        gl.glBindAttribLocation(shaderProgram, locCol, "VertexColor");

        gl.glLinkProgram(shaderProgram);

        modelViewProjectionMatrixLocation = gl.glGetUniformLocation(shaderProgram, "uniform_Projection");
        System.out.println("modelViewProjectionMatrixLocation:" + modelViewProjectionMatrixLocation);
        transformMatrixLocation = gl.glGetUniformLocation(shaderProgram, "uniform_Transform");
        System.out.println("transformMatrixLocation:" + transformMatrixLocation);

        FloatBuffer interleavedBuffer = Buffers.newDirectFloatBuffer(vertices.length + colors.length);
        for(int i = 0; i < vertices.length/3; i++) {
            for(int j = 0; j < 3; j++) {
                interleavedBuffer.put(vertices[i*3 + j]);
            }
            for(int j = 0; j < 4; j++) {
                interleavedBuffer.put(colors[i*4 + j]);
            }
        }
        interleavedBuffer.flip();

        vao = new int[1];
        gl.glGenVertexArrays(1, vao , 0); // was 2
        gl.glBindVertexArray(vao[0]);
        vbo = new int[1];
        gl.glGenBuffers(1, vbo, 0); //was 2
        gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, vbo[0]);
        gl.glBufferData(GL3.GL_ARRAY_BUFFER, interleavedBuffer.limit() * Buffers.SIZEOF_FLOAT, interleavedBuffer, GL3.GL_STATIC_DRAW);

        gl.glEnableVertexAttribArray(locPos);
        gl.glEnableVertexAttribArray(locCol);

            // 
        int stride = Buffers.SIZEOF_FLOAT * (3+4);

        long arg0 = Buffers.SIZEOF_FLOAT * 3;

            //suspicious 
        gl.glVertexAttribPointer( locPos, 3, GL3.GL_FLOAT, false, stride, 0);
        gl.glVertexAttribPointer( locCol, 4, GL3.GL_FLOAT, false, stride, arg0); 

        if(!useVao) { //added
          gl.glDisableVertexAttribArray(locPos);
          gl.glDisableVertexAttribArray(locCol);
        }
    }

    @Override
    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
        System.out.println("Window resized to width=" + width + " height=" + height);
        GL3 gl = drawable.getGL().getGL3();
        gl.glViewport(0, 0, width, height);
    }

    @Override
    public void display(GLAutoDrawable drawable) {
        double t1 = System.currentTimeMillis();
        theta += (t1-t0)*0.005f;
        t0 = t1;

        GL3 gl = drawable.getGL().getGL3();
        gl.glClear(GL3.GL_COLOR_BUFFER_BIT | GL3.GL_DEPTH_BUFFER_BIT);

        gl.glUseProgram(shaderProgram);

        float[] instanceTransform0 = new float[16];
        float[] instanceTransform1 = new float[16];
        //I use PMVMatrix class in order to calculate model-view matrix.
        PMVMatrix mat0 = new PMVMatrix();
        mat0.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
        mat0.glLoadIdentity();
        mat0.glTranslatef(0.25f, 0f, 0f);
        mat0.glRotatef(15f*theta, 0.0f, 0.0f, 1.0f);
        mat0.glScalef(0.8f, 0.8f, 1f);
        mat0.glGetFloatv(GLMatrixFunc.GL_MODELVIEW, instanceTransform0, 0);

        PMVMatrix mat1 = new PMVMatrix();
        mat1.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
        mat1.glLoadIdentity();
        mat1.glTranslatef(-0.25f, 0f, 0f);
        mat1.glRotatef(10f*theta, 0.0f, 0.0f, 1.0f);
        mat1.glScalef(0.5f, 0.5f, 1f);
        mat1.glGetFloatv(GLMatrixFunc.GL_MODELVIEW, instanceTransform1, 0);

        //concatnate 2 float arrays.
        float[] instanceTransformConcatnated = concatnateArrays(instanceTransform0, instanceTransform1);

        gl.glUniformMatrix4fv(transformMatrixLocation, instanceTransformConcatnated.length, false, instanceTransformConcatnated , 0);

        if(useVao) {
            gl.glBindVertexArray(vao[0]);
        } else {
            gl.glEnableVertexAttribArray(locPos);
            gl.glEnableVertexAttribArray(locCol);
        }
        gl.glDrawArraysInstanced(GL3.GL_TRIANGLES, 0, 3, 2);
        if(useVao) {
            //EDIT: after removing the next line, the exception disappears.
            //gl.glBindVertexArray(0);
        } else {
            gl.glDisableVertexAttribArray(locPos);
            gl.glDisableVertexAttribArray(locCol);
        }
        gl.glUseProgram(0);
    }

    @Override
    public void dispose(GLAutoDrawable drawable){
        GL3 gl = drawable.getGL().getGL3();
        gl.glUseProgram(0);
        gl.glDeleteBuffers(2, vbo, 0);
        gl.glDetachShader(shaderProgram, vertShader);
        gl.glDeleteShader(vertShader);
        gl.glDetachShader(shaderProgram, fragShader);
        gl.glDeleteShader(fragShader);
        gl.glDeleteProgram(shaderProgram);
    }

    private float[] concatnateArrays(float[] arg0, float[] arg1) {
        float[] result = new float[arg0.length + arg1.length];
        System.arraycopy(arg0, 0, result, 0, arg0.length);
        System.arraycopy(arg1, 0, result, arg0.length, arg1.length);
        return result;
    }

    private final String vertexShaderString =
            "#version 330 \n" +
                    "\n" +
                    "uniform mat4 uniform_Projection; \n" + //not used
                    "uniform mat4 uniform_Transform[2]; \n" +
                    "in vec4  VertexPosition; \n" +
                    "in vec4  VertexColor; \n" +
                    "out vec4 tmpColor; \n" +
                    "void main(void) \n" +
                    "{ \n" +
                    "  tmpColor = VertexColor; \n" +
                    //"  gl_Position = uniform_Projection * VertexPosition; \n" +
                    "  gl_Position = uniform_Transform[gl_InstanceID] * VertexPosition; \n" +
                    "} ";

    private final String fragmentShaderString =
            "#version 330\n" +
                    "\n" +
                    "in vec4    tmpColor; \n" +
                    "out vec4   outColor; \n" +
                    "void main (void) \n" +
                    "{ \n" +
                    "  outColor = tmpColor; \n" +
                    "} ";

    private final float[] vertices = {
            1.0f, 0.0f, 0,
            -0.5f, 0.866f, 0,
            -0.5f, -0.866f, 0
    };

    private final float[] colors = {
            1.0f, 0.0f, 0.0f, 1.0f,
            0.0f, 1.0f, 0.0f, 1.0f,
            0f, 0f, 1.0f, 1f
    };

}

The specific exception message is unclear to me, but here is one problem you definitely have: At the end of your init() method, you call glDisableVertexAttribArray() for your two vertex attributes. 特定的异常消息对我来说尚不清楚,但是您肯定有一个问题:在init()方法的最后,您为两个顶点属性调用glDisableVertexAttribArray() At this point, your VAO is bound. 至此,您的VAO已绑定。 The attribute enable/disable state is part of the VAO state. 属性启用/禁用状态是VAO状态的一部分。 So when you later call glBindVertexArray() in your display() method, the vertex attributes will be disabled, and you make your glDrawArraysInstanced() call without any enabled attributes. 因此,当您以后在display()方法中调用glBindVertexArray()时,顶点属性将被禁用,并且您调用glDrawArraysInstanced()将不启用任何属性。

To fix this, you should make the glDisableVertexAttribArray() calls at the end of init() conditional: 要解决此问题,您应该在init()结尾的条件下进行glDisableVertexAttribArray()调用:

if (!useVao) {
    gl.glDisableVertexAttribArray(locPos);
    gl.glDisableVertexAttribArray(locCol);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM