如何修复此OpenGL错误

如何修复此OpenGL错误

本文介绍了如何修复此OpenGL错误? “预处理指令后的意外令牌-预期换行"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用着色器完成我的第一个JOGL OpenGL程序.

I am trying to complete my first JOGL OpenGL program using shaders.

我只是从一个简单的Vertex着色器开始,它会导致编译错误.着色器预计会收到vec2(0.5, 0.5),它基本上是(x,y)坐标,并且会生成适当的vec4(x-1.0,y-1.0,0.0,1.0)像素.

I am just starting with a simple Vertex shader which does a compilation error. The shader is expected to receive a vec2(0.5, 0.5) which is basically (x,y) coordinates and it generates a proper vec4(x-1.0,y-1.0,0.0,1.0) pixel.

该程序实际上显示像素,但未使用着色器,因为该着色器会导致编译错误.如何获得有关失败原因的更多信息?

The program actually displays the pixel, but it is not using the shader as the shader gives compilation error. How can I get more information on what is failing?

在JOGL API代码中没有指定要使用3.30的地方,不确定是否相关.

Nowhere in the JOGL API code is specified that specifically 3.30 wants to be used, not sure if that is relevant or not.

Java类,该类扩展了JFrame并实现了GLEventListener.它包含GLCanvas:

package openglexample1;

import com.jogamp.common.nio.Buffers;
import static com.jogamp.opengl.GL.GL_NO_ERROR;
import com.jogamp.opengl.GL3;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLContext;
import com.jogamp.opengl.GLEventListener;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.awt.GLCanvas;
import com.jogamp.opengl.glu.GLU;
import java.io.IOException;
import java.nio.FloatBuffer;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Vector;
import java.util.stream.Stream;
import javax.swing.JFrame;

public class WindowD extends JFrame implements GLEventListener {

    /**
     * @return the glcanvas
     */
    public GLCanvas getGlcanvas() {
        return glcanvas;
    }

    //getting the capabilities object of GL3 profile
    final private GLProfile profile;
    final private GLCapabilities capabilities;
    final private GLCanvas glcanvas;

    // GL PROGAM
    private int glProgram;

    // VAO AND VBOs
    private int vao[] = new int[1];    // VAO GROUPS VBOs, ONLY ONE USED
    private int vbo[] = new int[2];    // 2 VBOs FOR 2 SQUARES

    public WindowD() {

        // OpenGL CAPABILITIES
        profile = GLProfile.get(GLProfile.GL3);
        capabilities = new GLCapabilities(profile);

        // CANVAS
        glcanvas = new GLCanvas(capabilities);
        glcanvas.addGLEventListener(this);
        glcanvas.setSize(400, 400);

        // JFRAME
        this.getContentPane().add(glcanvas);
        this.setSize(this.getContentPane().getPreferredSize());

    }

    @Override
    public void display(GLAutoDrawable drawable) {

        GL3 gl = drawable.getGL().getGL3();

        // USE PROGRAM
        gl.glUseProgram(glProgram);

        // USE VBOs
        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo[0]);
        gl.glVertexAttribPointer(0, 2, gl.GL_FLOAT, false, 0, 0); // associate 0th vertex attribute with active buffer
        gl.glEnableVertexAttribArray(0); // enable the 0th vertex attribute

        // DRAW POINT
        gl.glDrawArrays(GL3.GL_POINTS, 0, 1);


    }

    @Override
    public void init(GLAutoDrawable drawable) {

        GL3 gl = drawable.getGL().getGL3();

        // CREATE PROGRAM
        glProgram = gl.glCreateProgram();

        // CREATE VERTEX SHADER
        int vertexShader = gl.glCreateShader(GL3.GL_VERTEX_SHADER);

        // COMPILATION STATUS
        int[ ] vertCompiled = new int[1];

        // LOAD SOURCE CODE
        String[] vertexShaderSource = readShader("VertexShader1.glsl");
        gl.glShaderSource(vertexShader, vertexShaderSource.length, vertexShaderSource, null, 0);
        checkOpenGLError(); // can use returned boolean
        gl.glGetShaderiv(vertexShader, GL3.GL_COMPILE_STATUS, vertCompiled, 0);
        gl.glCompileShader(vertexShader);
        if (vertCompiled[0] == 1)
        {
            System.out.println(". . . vertex compilation success.");
        } else {
            System.out.println(". . . vertex compilation failed.");
            printShaderLog(vertexShader);
        }

        // ATTACH VERTEX SHADER TO PROGRAM, LINK AND DELETE SHADERS
        gl.glAttachShader(glProgram, vertexShader);
        gl.glLinkProgram(glProgram);
        gl.glDeleteShader(vertexShader);

        // CREATE VAO
        gl.glGenVertexArrays(1, vao, 0);
        gl.glBindVertexArray(vao[0]);

        // COORDINATES SQUARES
        float[] coordinatesSquare1 = new float[]{0.5f, 0.5f};
        //float[] coordinatesSquare2 = new float[]{-0.5f, -0.5f};

        // CREATE VBOs
        gl.glGenBuffers(1, vbo, 0);

        // POPULATE VBO 1 FOR SQUARE 1
        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo[0]);
        FloatBuffer bufferSquare1 = Buffers.newDirectFloatBuffer(coordinatesSquare1);
        gl.glBufferData(gl.GL_ARRAY_BUFFER, bufferSquare1.limit()*4, bufferSquare1, gl.GL_STATIC_DRAW);

    }

    @Override
    public void dispose(GLAutoDrawable drawable) {
    }

    @Override
    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
        System.out.println("reshape");
        this.display(drawable);

    }

    private String[] readShader(String filename) {

        Vector<String> lines = new Vector<String>();

        try (Stream<String> stream = Files.lines(Paths.get(filename))) {
            stream.forEach(x -> lines.add(x));
        } catch (IOException e) {
            e.printStackTrace();
        }

        // CONVERT VECTOR TO ARRAY
        Object[] objArray = lines.toArray();
        String[] array = Arrays.copyOf(objArray, objArray.length, String[].class);

        return array;
    }

    private void printShaderLog(int shader) {

        GL3 gl = (GL3) GLContext.getCurrentGL();

        int[ ] len = new int[1];
        int[ ] chWrittn = new int[1];
        byte[ ] log = null;

        // determine the length of the shader compilation log
        gl.glGetShaderiv(shader, GL3.GL_INFO_LOG_LENGTH, len, 0);
        if (len[0] > 0)
        {
            log = new byte[len[0]];
            gl.glGetShaderInfoLog(shader, len[0], chWrittn, 0, log, 0);
            System.out.println("Shader Info Log: ");
            for (int i = 0; i < log.length; i++)
            {
                System.out.print((char) log[i]);
            }
        }
    }

    void printProgramLog(int prog) {

        GL3 gl = (GL3) GLContext.getCurrentGL();

        int[ ] len = new int[1];
        int[ ] chWrittn = new int[1];
        byte[ ] log = null;

        // determine the length of the program linking log
        gl.glGetProgramiv(prog,GL3.GL_INFO_LOG_LENGTH,len, 0);
        if (len[0] > 0)
        {
            log = new byte[len[0]];
            gl.glGetProgramInfoLog(prog, len[0], chWrittn, 0,log, 0);
            System.out.println("Program Info Log: ");
            for (int i = 0; i < log.length; i++)
            {
                System.out.print((char) log[i]);
            }
        }
    }

    boolean checkOpenGLError() {

        GL3 gl = (GL3) GLContext.getCurrentGL();

        boolean foundError = false;
        GLU glu = new GLU();
        int glErr = gl.glGetError();
        while (glErr != GL_NO_ERROR) {
            System.err.println("glError: " + glu.gluErrorString(glErr));
            foundError = true;
            glErr = gl.glGetError();
        }
        return foundError;

    }

}


调用该JFrame类的主类:

package openglexample1;

import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.swing.WindowConstants;

public class OpenGLExample3 {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

      // TEST WINDOW
      WindowD basicFrame3 = new WindowD();
      basicFrame3.setTitle("WindowD");
      basicFrame3.setLocation(400,400);
      basicFrame3.setVisible(true);
      basicFrame3.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

    }

}


顶点着色器GLSL来源:

#version 330 core

layout (location = 0) in vec2 squareCenterPosition;

void main()
{
    gl_Position = vec4(squareCenterPosition.x - 1.0, squareCenterPosition.y -1.0, 0.0, 1.0);
}


如此处所示,该程序绘制了像素,但由于得到以下消息,因此未使用着色器:


As shown here, the program draws the pixel, but it is not using the shader as I get the following message:

run:
. . . vertex compilation failed.
Shader Info Log:
ERROR: 2:1: '#version' :  syntax error
ERROR: 2:1: '#version' :  syntax error
ERROR: 2:1: '' : syntax error: unexpected tokens following preprocessor directive - expected a newline

怎么了?

程序的输出:

推荐答案

源代码行不使用\n提交给API.

The source code lines were being submitted to the API without \n.

这是正确的readShader例程:

This is the right readShader routine:

private String[] readShader(String filename) {

    Vector<String> lines = new Vector<String>();

    try (Stream<String> stream = Files.lines(Paths.get(filename))) {
        stream.forEach(x -> lines.add(x + "\n"));
    } catch (IOException e) {
        e.printStackTrace();
    }

    // CONVERT VECTOR TO ARRAY
    Object[] objArray = lines.toArray();
    String[] array = Arrays.copyOf(objArray, objArray.length, String[].class);

    return array;
}

请注意+ "\n"更改.

这篇关于如何修复此OpenGL错误? “预处理指令后的意外令牌-预期换行"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-19 08:33