如何修复此 OpenGL 错误? "unexpected tokens following preprocessor directive - expected a newline"
How to fix this OpenGL error? "unexpected tokens following preprocessor directive - expected a newline"
我正在尝试使用着色器完成我的第一个 JOGL OpenGL 程序。
我刚开始使用一个简单的顶点着色器,它会出现编译错误。着色器预计会收到一个 vec2(0.5, 0.5)
,它基本上是 (x,y) 坐标,它会生成一个适当的 vec4(x-1.0,y-1.0,0.0,1.0)
像素。
程序实际显示了像素,但它没有使用着色器,因为着色器给出了编译错误。我怎样才能获得有关失败原因的更多信息?
JOGL API 代码中没有指定要使用 3.30,不确定是否相关。
Java class 扩展 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;
}
}
Main class 调用此 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);
}
}
顶点着色器 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);
}
如此处所示,程序绘制了像素,但它没有使用着色器,因为我收到以下消息:
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
怎么了?
程序的输出:
源代码行被提交到 API 而没有 \n
。
这是正确的 readShader 例程:
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"
变化。
我正在尝试使用着色器完成我的第一个 JOGL OpenGL 程序。
我刚开始使用一个简单的顶点着色器,它会出现编译错误。着色器预计会收到一个 vec2(0.5, 0.5)
,它基本上是 (x,y) 坐标,它会生成一个适当的 vec4(x-1.0,y-1.0,0.0,1.0)
像素。
程序实际显示了像素,但它没有使用着色器,因为着色器给出了编译错误。我怎样才能获得有关失败原因的更多信息?
JOGL API 代码中没有指定要使用 3.30,不确定是否相关。
Java class 扩展 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;
}
}
Main class 调用此 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);
}
}
顶点着色器 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);
}
如此处所示,程序绘制了像素,但它没有使用着色器,因为我收到以下消息:
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
怎么了?
程序的输出:
源代码行被提交到 API 而没有 \n
。
这是正确的 readShader 例程:
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"
变化。