How to fix this OpenGL error? “unexpected tokens following preprocessor directive - expected a newline”

梦想的初衷 提交于 2020-02-25 05:41:51

问题


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

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?

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 class which extends JFrame and implements GLEventListener. It contains the 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;

    }

}   

Main class invoking this JFrame class:

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);

    }

}

Vertex shader GLSL source:

#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

What is wrong?

The output of the program:


回答1:


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

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;
} 

Notice the + "\n" change.



来源:https://stackoverflow.com/questions/60098830/how-to-fix-this-opengl-error-unexpected-tokens-following-preprocessor-directiv

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!