我是最新版本的OpenGL的新手,我正在尝试按照本教程学习它:http://open.gl/drawing
然而,我正在使用最新版本的LWJGL,并尽力将其OpenGL用于本教程。仍然,应该绘制的白色三角形不是。
这是我的代码:
package experiments;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL30.*;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
public class Exp1 {
//Shader
private int shaderProgram;
private int vertShader;
private int fragShader;
//Vertex Buffer Object
private int vbo;
//Vertex Array Object
private int vao;
//Triangle
private float vertices[] = {
0.0f, 0.5f, // Vertex 1 (X, Y)
0.5f, -0.5f, // Vertex 2 (X, Y)
-0.5f, -0.5f // Vertex 3 (X, Y)
};
public Exp1() throws IOException {
setUpDisplay();
}
private void createShader() throws IOException
{
this.shaderProgram = glCreateProgram();
this.vertShader = glCreateShader(GL_VERTEX_SHADER);
this.fragShader = glCreateShader(GL_FRAGMENT_SHADER);
//set source and compile
glShaderSource(vertShader, fileToString("src/experiments/shader.vert"));
glCompileShader(vertShader);
if(glGetShaderi(vertShader, GL_COMPILE_STATUS) == GL_FALSE) System.err.print("Vertex Shader wasn't able to be compiled correctly");
glShaderSource(fragShader, fileToString("src/experiments/shader.frag"));
glCompileShader(fragShader);
if(glGetShaderi(fragShader, GL_COMPILE_STATUS) == GL_FALSE) System.err.print("Fragment Shader wasn't able to be compiled correctly");
//attach shaders to shader program
glAttachShader(shaderProgram, vertShader);
glAttachShader(shaderProgram, fragShader);
glLinkProgram(shaderProgram);
glValidateProgram(shaderProgram);
}
private void start() throws IOException
{
this.vao = glGenVertexArrays();
glBindVertexArray(vao);
this.vbo = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo);
FloatBuffer fBuffer= ByteBuffer.allocateDirect(vertices.length * 4).asFloatBuffer();
fBuffer.put(vertices);
glBufferData(GL_ARRAY_BUFFER, fBuffer, GL_STATIC_DRAW);
createShader();
glUseProgram(shaderProgram);
int posAttrib = glGetAttribLocation(shaderProgram, "position");
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, false, 0, 0);
glEnableVertexAttribArray(posAttrib);
while(!Display.isCloseRequested())
{
render();
Display.update();
Display.sync(60);
}
glDeleteProgram(shaderProgram);
glDeleteShader(vertShader);
glDeleteShader(fragShader);
Display.destroy();
System.exit(0);
}
private void render()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
private String fileToString(String path) throws IOException
{
StringBuilder builder = new StringBuilder();
BufferedReader reader = new BufferedReader(new FileReader(path));
String line;
while((line = reader.readLine()) != null)
builder.append(line).append('\n');
reader.close();
return builder.toString();
}
private void setUpDisplay()
{
try
{
Display.setDisplayMode(new DisplayMode(640, 480));
Display.setTitle("Shader Demo");
Display.create();
}
catch (LWJGLException e) {
System.out.println("Display Fail");
e.printStackTrace();
Display.destroy();
System.exit(1);
}
}
public static void main(String[] args) throws IOException {
Exp1 demo = new Exp1();
demo.start();
}
}
我的着色器与教程完全相同,但是为了更容易阅读,它们会发布它们:
.frag
#version 150
out vec4 outColor;
void main()
{
outColor = vec4(1.0, 1.0, 1.0, 1.0);
}
.vert
#version 150
in vec2 position;
void main()
{
gl_Position = vec4(position, 0.0, 1.0);
}
代码运行但都是黑色的。有什么想法吗?
答案 0 :(得分:3)
我发现了问题:
FloatBuffer fBuffer= ByteBuffer.allocateDirect(vertices.length * 4).asFloatBuffer();
fBuffer.put(vertices);
glBufferData(GL_ARRAY_BUFFER, fBuffer, GL_STATIC_DRAW);
这段代码错了。正确的方法是:
//Create vertice buffer
FloatBuffer verticeBuffer= BufferUtils.createFloatBuffer(vertices.length);
verticeBuffer.put(vertices).flip();
//Send vertice buffer to VBO
glBufferData(GL_ARRAY_BUFFER, verticeBuffer, GL_STATIC_DRAW);
以下是整个代码,以防对任何人有用,我尽量使其尽可能可读:)
package experiments;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL30.*;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.nio.FloatBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
public class Exp1 {
//Shader
private int shaderProgram;
private int vertShader;
private int fragShader;
//Vertex Buffer Object
private int vbo;
//Vertex Array Object
private int vao;
//Triangle
private float vertices[] = {
0.0f, 0.5f, // Vertex 1 (X, Y)
0.5f, -0.5f, // Vertex 2 (X, Y)
-0.5f, -0.5f // Vertex 3 (X, Y)
};
private int posAttrib;
public Exp1() throws IOException {
setUpDisplay();
}
private void start() throws IOException
{
setUpDraw();
while(!Display.isCloseRequested())
{
render();
Display.update();
Display.sync(60);
}
glDeleteProgram(shaderProgram);
glDeleteShader(vertShader);
glDeleteShader(fragShader);
glDeleteBuffers(vbo);
glDeleteVertexArrays(vao);
Display.destroy();
System.exit(0);
}
private void setUpDraw() throws IOException{
// Create a new VAO in memory and bind it (A VAO can have up to 16 attributes (VBO's) assigned to it by default)
this.vao = glGenVertexArrays();
glBindVertexArray(vao);
//Create a new VBO in memory and bind it (A VBO is a collection of Vectors which in this case resemble the location of each vertex)
this.vbo = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo);
//Create new shader and use it
createShader();
glUseProgram(shaderProgram);
//Create vertice buffer
FloatBuffer verticeBuffer= BufferUtils.createFloatBuffer(vertices.length);
verticeBuffer.put(vertices).flip();
//Send vertice buffer to VBO
glBufferData(GL_ARRAY_BUFFER, verticeBuffer, GL_STATIC_DRAW);
//Put the VBO in the attributes list at index posAttrib
posAttrib = glGetAttribLocation(shaderProgram, "position");
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, false, 0, 0);
//Unbind VBO and VAO
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
private void createShader() throws IOException
{
//create
this.shaderProgram = glCreateProgram();
this.vertShader = glCreateShader(GL_VERTEX_SHADER);
this.fragShader = glCreateShader(GL_FRAGMENT_SHADER);
//set source and compile
glShaderSource(vertShader, fileToString("src/experiments/shader.vert"));
glCompileShader(vertShader);
if(glGetShaderi(vertShader, GL_COMPILE_STATUS) == GL_FALSE) System.err.print("Vertex Shader wasn't able to be compiled correctly");
glShaderSource(fragShader, fileToString("src/experiments/shader.frag"));
glCompileShader(fragShader);
if(glGetShaderi(fragShader, GL_COMPILE_STATUS) == GL_FALSE) System.err.print("Fragment Shader wasn't able to be compiled correctly");
//attach shaders to shader program
glAttachShader(shaderProgram, vertShader);
glAttachShader(shaderProgram, fragShader);
glLinkProgram(shaderProgram);
glValidateProgram(shaderProgram);
}
private void render()
{
//Clear screen
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
//Bind our VAO which already has the quad info and enable attribute list in posAttrib index
glBindVertexArray(vao);
glEnableVertexAttribArray(posAttrib);
//Draw the vertices
glDrawArrays(GL_TRIANGLES, 0, 3);
//Unbind back to defaults
glDisableVertexAttribArray(posAttrib);
glBindVertexArray(0);
}
private String fileToString(String path) throws IOException
{
StringBuilder builder = new StringBuilder();
BufferedReader reader = new BufferedReader(new FileReader(path));
String line;
while((line = reader.readLine()) != null)
builder.append(line).append('\n');
reader.close();
return builder.toString();
}
private void setUpDisplay()
{
try
{
Display.setDisplayMode(new DisplayMode(640, 480));
Display.setTitle("Shader Demo");
Display.create();
}
catch (LWJGLException e) {
System.out.println("Display Fail");
e.printStackTrace();
Display.destroy();
System.exit(1);
}
}
public static void main(String[] args) throws IOException {
Exp1 demo = new Exp1();
demo.start();
}
}
答案 1 :(得分:0)
您正在检查着色器编译日志,因此着色器应该没问题。开始调试这些的一个好方法是开始在很多地方插入glGetError()
个调用。如果您获得非零返回值(0 == GL_NO_ERROR
),您就会发现早期gl*
来电出现问题。目前,例如,您正在调用glValidateProgram
,如果程序未成功链接,则会生成错误,但您必须自己使用glGetError()
检查错误。
编辑:由于您正在使用LWJGL,您还可以使用lwjgl.opengl.Util中的错误检查方法。