LWJGL 3、VAO 和 Shader 不渲染
LWJGL 3, VAO and Shader not rendering
我正在使用 LWJGL 3 和带有 VAO 的着色器。我当前的实现在使用着色器时不绘制 VAO。然而,当不使用着色器时 VAO 将绘制,但 VAO 将是白色的。我的问题是我在着色器设置中缺少什么阻止我在使用着色器时看到 VAO?
主要Class.
着色器和 VAO 设置在 gameStart() 方法中。
public class Test {
/** Window Properties **/
private int
HEIGHT = 800,
WIDTH = 1200,
RESIZABLE = GL11.GL_FALSE,
REFRESH_RATE = 60;
private String TITLE = "test";
// The window handler
private long window;
// callback reference instances
private GLFWErrorCallback errorCallback;
private GLFWKeyCallback keyCallback;
private void preWindowSetup() {
// Setup an error callback
GLFW.glfwSetErrorCallback(errorCallback = errorCallbackPrint(System.err));
// Initialize GLFW
if (GLFW.glfwInit() != GL11.GL_TRUE)
exit();
}
private void windowSetup() {
// Configure Window Properties
glfwDefaultWindowHints();
GLFW.glfwWindowHint(GLFW_VISIBLE, GL_FALSE); // Keep the window hidden
glfwWindowHint(GLFW_RESIZABLE, RESIZABLE); // Do not allow resizing
glfwWindowHint(GLFW_REFRESH_RATE, REFRESH_RATE); // Refresh rate
// Create the window
window = glfwCreateWindow(WIDTH, HEIGHT, TITLE, NULL, NULL);
if ( window == NULL )
exit();
// Get the resolution of the primary monitor
ByteBuffer vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
// Center our window
glfwSetWindowPos(
window,
(GLFWvidmode.width(vidmode) - WIDTH) / 2,
(GLFWvidmode.height(vidmode) - HEIGHT) / 2
);
}
private void callbackSetup() {
// Setup a key callback. It will be called every time a key is pressed, repeated or released.
glfwSetKeyCallback(window, keyCallback = new GLFWKeyCallback() {
@Override
public void invoke(long window, int key, int scancode, int action, int mods) {//TODO Dispatch key events
if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE)
Tasker.executeASyncTask("GLFW_MAIN_THREAD");
}
});
}
public void initGL() {
preWindowSetup();
windowSetup();
callbackSetup();
glfwMakeContextCurrent(window); // Make the OpenGL context current
glfwShowWindow(window); // Make the window visible
GLContext.createFromCurrent(); // Bind lwjgl with GLFW
// Initialize openGl
GL11.glViewport(0, 0, WIDTH, HEIGHT);
GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, WIDTH, 0, HEIGHT, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
// Enable alpha transparency (for overlay image)
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glDepthFunc(GL11.GL_LEQUAL);
GL11.glShadeModel(GL11.GL_SMOOTH);
}
public void gameStart() {
System.out.println("LWJGL Version: ["+Sys.getVersion()+"]");
System.out.println("OpenGL Version: ["+GL11.glGetString(GL11.GL_VERSION)+"]");
// ===============================================================================================
// =================== Shader Setup =====================
String vertPath = "src/test/java/org/ajgl/test/graphics/shaders/VertexShaderTest.glsl";
String fragPath = "src/test/java/org/ajgl/test/graphics/shaders/FragmentShaderTest.glsl";
int sahderVert = GL20.glCreateShader(GL20.GL_VERTEX_SHADER);
GL20.glShaderSource(sahderVert, Shader.loadShader(vertPath));
GL20.glCompileShader(sahderVert);
int sahderFrag = GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER);
GL20.glShaderSource(sahderFrag, Shader.loadShader(fragPath));
GL20.glCompileShader(sahderFrag);
// =================== Shader Setup =====================
// =================== Shader Check =====================
int status = GL20.glGetShaderi(sahderVert, GL20.GL_COMPILE_STATUS);
if (status != GL11.GL_TRUE) {
throw new RuntimeException(GL20.glGetShaderInfoLog(sahderVert));
}
int statusN = GL20.glGetShaderi(sahderFrag, GL20.GL_COMPILE_STATUS);
if (statusN != GL11.GL_TRUE) {
throw new RuntimeException(GL20.glGetShaderInfoLog(sahderFrag));
}
// =================== Shader Check =====================
// =================== Shader Program ===================
int programID = GL20.glCreateProgram();
GL20.glAttachShader(programID, sahderVert);
GL20.glAttachShader(programID, sahderFrag);
GL20.glBindAttribLocation(programID, 0, "position");
GL20.glBindAttribLocation(programID, 1, "color");
GL20.glLinkProgram(programID);
// =================== Shader Program ===================
// =============== Shader Program Check =================
int statusP = GL20.glGetProgrami(programID, GL20.GL_LINK_STATUS);
if (statusP != GL11.GL_TRUE) {
throw new RuntimeException(GL20.glGetProgramInfoLog(programID));
}
// =============== Shader Program Check =================
// =================== VAO Setup ========================
FloatBuffer vertexBufferVAO = BufferUtils.createFloatBuffer(9);
vertexBufferVAO.put(new float[]{600,10,0, 550,50,0, 500,10,0});
vertexBufferVAO.flip();
FloatBuffer colorBufferVAO = BufferUtils.createFloatBuffer(9);
colorBufferVAO.put(new float[]{1,0,0, 0,1,0, 0,0,1});
colorBufferVAO.flip();
int vaoID = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vaoID);
{
int vertHandle = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vertHandle);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vertexBufferVAO, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);
int colorHandle = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, colorHandle);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, colorBufferVAO, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(1, 3, GL11.GL_FLOAT, false, 0, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
GL30.glBindVertexArray(0);
// =================== VAO Setup ========================
// ===============================================================================================
while ( glfwWindowShouldClose(window) == GL_FALSE ) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Run Cycles
input();
GL20.glUseProgram(programID);
GL30.glBindVertexArray(vaoID);
{
GL20.glEnableVertexAttribArray(0);
GL20.glEnableVertexAttribArray(1);
GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, 3);
GL20.glDisableVertexAttribArray(0);
GL20.glDisableVertexAttribArray(1);
}
GL30.glBindVertexArray(0);
GL20.glUseProgram(0);
// Display Buffer swap
glfwSwapBuffers(window);
}
// Release window and window call backs
glfwDestroyWindow(window);
keyCallback.release();
exit();
}
private void input() {
glfwPollEvents();
Tasker.executeASyncTask("GLFW_MAIN_THREAD");
}
public void exit() {
// Terminate GLFW and release the GLFWerrorfun
glfwTerminate();
errorCallback.release();
System.exit(1);
}
public static void main(String[] args) {
Test test = new Test();
test.initGL();
test.gameStart();
}
}
着色器 class.
public class Shader {
public static CharSequence loadShader(String path) {
StringBuilder shaderSource = new StringBuilder();
int shaderID = 0;
try {
BufferedReader reader = new BufferedReader(new FileReader(path));
String line;
while ((line = reader.readLine()) != null) {
shaderSource.append(line).append("\n");
}
reader.close();
} catch (IOException e) {
System.err.println("Could not read file.");
e.printStackTrace();
System.exit(-1);
}
return shaderSource;
}
}
顶点和片段着色器。
// Vertex Shader
#version 400
in vec3 position;
in vec3 color;
out vec3 Color;
void main()
{
Color = color;
gl_Position = vec4(position, 1.0);
}
// Fragment shader
#version 400
in vec3 Color;
out vec4 fragColor;
void main()
{
fragColor = vec4(Color, 1.0);
}
我使用此站点找到了问题的解决方案 here。问题是我没有使用 link 中所说的设备坐标。相反,我使用的是笛卡尔坐标系。
修复。
FloatBuffer vertexBufferVAO = BufferUtils.createFloatBuffer(9);
**vertexBufferVAO.put(new float[]{{-0.95f,-0.95f,0, -0.5f,-0.95f,0, -0.95f,-0.5f,0});
vertexBufferVAO.flip();
我正在使用 LWJGL 3 和带有 VAO 的着色器。我当前的实现在使用着色器时不绘制 VAO。然而,当不使用着色器时 VAO 将绘制,但 VAO 将是白色的。我的问题是我在着色器设置中缺少什么阻止我在使用着色器时看到 VAO?
主要Class.
着色器和 VAO 设置在 gameStart() 方法中。
public class Test {
/** Window Properties **/
private int
HEIGHT = 800,
WIDTH = 1200,
RESIZABLE = GL11.GL_FALSE,
REFRESH_RATE = 60;
private String TITLE = "test";
// The window handler
private long window;
// callback reference instances
private GLFWErrorCallback errorCallback;
private GLFWKeyCallback keyCallback;
private void preWindowSetup() {
// Setup an error callback
GLFW.glfwSetErrorCallback(errorCallback = errorCallbackPrint(System.err));
// Initialize GLFW
if (GLFW.glfwInit() != GL11.GL_TRUE)
exit();
}
private void windowSetup() {
// Configure Window Properties
glfwDefaultWindowHints();
GLFW.glfwWindowHint(GLFW_VISIBLE, GL_FALSE); // Keep the window hidden
glfwWindowHint(GLFW_RESIZABLE, RESIZABLE); // Do not allow resizing
glfwWindowHint(GLFW_REFRESH_RATE, REFRESH_RATE); // Refresh rate
// Create the window
window = glfwCreateWindow(WIDTH, HEIGHT, TITLE, NULL, NULL);
if ( window == NULL )
exit();
// Get the resolution of the primary monitor
ByteBuffer vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
// Center our window
glfwSetWindowPos(
window,
(GLFWvidmode.width(vidmode) - WIDTH) / 2,
(GLFWvidmode.height(vidmode) - HEIGHT) / 2
);
}
private void callbackSetup() {
// Setup a key callback. It will be called every time a key is pressed, repeated or released.
glfwSetKeyCallback(window, keyCallback = new GLFWKeyCallback() {
@Override
public void invoke(long window, int key, int scancode, int action, int mods) {//TODO Dispatch key events
if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE)
Tasker.executeASyncTask("GLFW_MAIN_THREAD");
}
});
}
public void initGL() {
preWindowSetup();
windowSetup();
callbackSetup();
glfwMakeContextCurrent(window); // Make the OpenGL context current
glfwShowWindow(window); // Make the window visible
GLContext.createFromCurrent(); // Bind lwjgl with GLFW
// Initialize openGl
GL11.glViewport(0, 0, WIDTH, HEIGHT);
GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, WIDTH, 0, HEIGHT, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
// Enable alpha transparency (for overlay image)
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glDepthFunc(GL11.GL_LEQUAL);
GL11.glShadeModel(GL11.GL_SMOOTH);
}
public void gameStart() {
System.out.println("LWJGL Version: ["+Sys.getVersion()+"]");
System.out.println("OpenGL Version: ["+GL11.glGetString(GL11.GL_VERSION)+"]");
// ===============================================================================================
// =================== Shader Setup =====================
String vertPath = "src/test/java/org/ajgl/test/graphics/shaders/VertexShaderTest.glsl";
String fragPath = "src/test/java/org/ajgl/test/graphics/shaders/FragmentShaderTest.glsl";
int sahderVert = GL20.glCreateShader(GL20.GL_VERTEX_SHADER);
GL20.glShaderSource(sahderVert, Shader.loadShader(vertPath));
GL20.glCompileShader(sahderVert);
int sahderFrag = GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER);
GL20.glShaderSource(sahderFrag, Shader.loadShader(fragPath));
GL20.glCompileShader(sahderFrag);
// =================== Shader Setup =====================
// =================== Shader Check =====================
int status = GL20.glGetShaderi(sahderVert, GL20.GL_COMPILE_STATUS);
if (status != GL11.GL_TRUE) {
throw new RuntimeException(GL20.glGetShaderInfoLog(sahderVert));
}
int statusN = GL20.glGetShaderi(sahderFrag, GL20.GL_COMPILE_STATUS);
if (statusN != GL11.GL_TRUE) {
throw new RuntimeException(GL20.glGetShaderInfoLog(sahderFrag));
}
// =================== Shader Check =====================
// =================== Shader Program ===================
int programID = GL20.glCreateProgram();
GL20.glAttachShader(programID, sahderVert);
GL20.glAttachShader(programID, sahderFrag);
GL20.glBindAttribLocation(programID, 0, "position");
GL20.glBindAttribLocation(programID, 1, "color");
GL20.glLinkProgram(programID);
// =================== Shader Program ===================
// =============== Shader Program Check =================
int statusP = GL20.glGetProgrami(programID, GL20.GL_LINK_STATUS);
if (statusP != GL11.GL_TRUE) {
throw new RuntimeException(GL20.glGetProgramInfoLog(programID));
}
// =============== Shader Program Check =================
// =================== VAO Setup ========================
FloatBuffer vertexBufferVAO = BufferUtils.createFloatBuffer(9);
vertexBufferVAO.put(new float[]{600,10,0, 550,50,0, 500,10,0});
vertexBufferVAO.flip();
FloatBuffer colorBufferVAO = BufferUtils.createFloatBuffer(9);
colorBufferVAO.put(new float[]{1,0,0, 0,1,0, 0,0,1});
colorBufferVAO.flip();
int vaoID = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vaoID);
{
int vertHandle = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vertHandle);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vertexBufferVAO, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, 0);
int colorHandle = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, colorHandle);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, colorBufferVAO, GL15.GL_STATIC_DRAW);
GL20.glVertexAttribPointer(1, 3, GL11.GL_FLOAT, false, 0, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
GL30.glBindVertexArray(0);
// =================== VAO Setup ========================
// ===============================================================================================
while ( glfwWindowShouldClose(window) == GL_FALSE ) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Run Cycles
input();
GL20.glUseProgram(programID);
GL30.glBindVertexArray(vaoID);
{
GL20.glEnableVertexAttribArray(0);
GL20.glEnableVertexAttribArray(1);
GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, 3);
GL20.glDisableVertexAttribArray(0);
GL20.glDisableVertexAttribArray(1);
}
GL30.glBindVertexArray(0);
GL20.glUseProgram(0);
// Display Buffer swap
glfwSwapBuffers(window);
}
// Release window and window call backs
glfwDestroyWindow(window);
keyCallback.release();
exit();
}
private void input() {
glfwPollEvents();
Tasker.executeASyncTask("GLFW_MAIN_THREAD");
}
public void exit() {
// Terminate GLFW and release the GLFWerrorfun
glfwTerminate();
errorCallback.release();
System.exit(1);
}
public static void main(String[] args) {
Test test = new Test();
test.initGL();
test.gameStart();
}
}
着色器 class.
public class Shader {
public static CharSequence loadShader(String path) {
StringBuilder shaderSource = new StringBuilder();
int shaderID = 0;
try {
BufferedReader reader = new BufferedReader(new FileReader(path));
String line;
while ((line = reader.readLine()) != null) {
shaderSource.append(line).append("\n");
}
reader.close();
} catch (IOException e) {
System.err.println("Could not read file.");
e.printStackTrace();
System.exit(-1);
}
return shaderSource;
}
}
顶点和片段着色器。
// Vertex Shader
#version 400
in vec3 position;
in vec3 color;
out vec3 Color;
void main()
{
Color = color;
gl_Position = vec4(position, 1.0);
}
// Fragment shader
#version 400
in vec3 Color;
out vec4 fragColor;
void main()
{
fragColor = vec4(Color, 1.0);
}
我使用此站点找到了问题的解决方案 here。问题是我没有使用 link 中所说的设备坐标。相反,我使用的是笛卡尔坐标系。
修复。
FloatBuffer vertexBufferVAO = BufferUtils.createFloatBuffer(9);
**vertexBufferVAO.put(new float[]{{-0.95f,-0.95f,0, -0.5f,-0.95f,0, -0.95f,-0.5f,0});
vertexBufferVAO.flip();