问题描述
我正在尝试使用着色器完成我的第一个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错误? “预处理指令后的意外令牌-预期换行"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!