【发布时间】:2021-07-25 03:53:37
【问题描述】:
我尝试使用 lwjgl 绘制一个简单的三角形
这是我的 3D 对象类:
public class ThreeDObject {
float[] vertices;
float[] color;
int vao;
int vvbo; //vertex vbo
int cvbo; //color vbo
int vtexNumber;
boolean isSetUp = false;
String fragmentShader;
String vertexShader;
int frag;
int vert;
int program;
public ThreeDObject( float[] vertices, float[] color) {
this.vertices = vertices;
this.color = color;
this.vtexNumber = this.vertices.length / 3;
setupVAO();
this.vertexShader = defaultVert;
this.fragmentShader = defaultFrag;
setupShaders();
System.out.println(Arrays.toString(this.vertices));
}
public void setupVAO() {
FloatBuffer vb = BufferUtils.createFloatBuffer(vertices.length);
vb.put(vertices).flip();
FloatBuffer cb = BufferUtils.createFloatBuffer(color.length);
cb.put(color).flip();
if(hasEBO()) {
IntBuffer ob = BufferUtils.createIntBuffer(order.length);
ob.put(order).flip();
}
vao = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vao);
vvbo = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vvbo);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vb, GL15.GL_STATIC_DRAW);
GL30.glVertexAttribPointer(0, 3, GL30.GL_FLOAT, false, 0, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GL20.glEnableVertexAttribArray(0);
GL30.glVertexAttribPointer(0, 3, GL30.GL_FLOAT, false, 0, 0);
cvbo = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, cvbo);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, cb, GL15.GL_STATIC_DRAW);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GL20.glEnableVertexAttribArray(1);
GL30.glVertexAttribPointer(1, 3, GL30.GL_FLOAT, false, 0, 0);
GL30.glBindVertexArray(0);
isSetUp = true;
}
public void setupShaders() {
GL30.glBindVertexArray(vao);
program = GL20.glCreateProgram();
vert = GL20.glCreateShader(GL20.GL_VERTEX_SHADER);
GL20.glShaderSource(vert, vertexShader);
frag = GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER);
GL20.glShaderSource(frag, fragmentShader);
GL20.glCompileShader(vert);
if(GL20.glGetShaderi(vert, GL20.GL_COMPILE_STATUS) == GL20.GL_FALSE) {
System.out.println("Couldn't comile vertex shader");
System.out.println(GL30.glGetShaderInfoLog(vert));
}
GL20.glCompileShader(frag);
if(GL20.glGetShaderi(frag, GL20.GL_COMPILE_STATUS) == GL20.GL_FALSE) {
System.out.println("Couldn't comile fragment shader");
System.out.println(GL30.glGetShaderInfoLog(frag));
}
GL20.glAttachShader(program, vert);
GL20.glAttachShader(program, frag);;
GL20.glValidateProgram(program);
if(GL20.glGetProgrami(program, GL20.GL_VALIDATE_STATUS) != GL20.GL_TRUE) {
System.out.println("Can't validate shader");
System.out.println(GL20.glGetProgramInfoLog(program));
}
GL30.glBindVertexArray(0);
}
public void draw() {
GL20.glUseProgram(program);
GL30.glBindVertexArray(vao);
GL15.glDrawArrays(GL15.GL_TRIANGLES, 0, vtexNumber);
GL30.glBindVertexArray(0);
}
}
我的构造函数是:
t = new ThreeDObject(new float[] {
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
-1.0f, -1.0f, 0.0f
}, new float[] {
1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f
});
(构造函数是故意错误的)。
我删除了一些未使用的代码,如果找不到错误请告诉我
我得到的只是一个白色三角形被绘制到屏幕上。
我尝试了所有我能找到的解决方案,如果你能帮助我,我会很高兴的。
编辑:我更改了一些代码,但仍然得到相同的结果。
在控制台上我得到了这个:
Can't validate shader
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0]
这是顶点着色器:
#version 330
out vec4 outColor;
layout (location = 0) in vec3 inPosition;
layout (location = 1) in vec3 inColor;
void main() {
gl_Position = vec4(inPosition,1.0);
outColor = vec4(inColor, 1.0);
}
这是片段着色器:
#version 330
in vec3 outColor;
out vec4 finalColor;
void main() {
finalColor = vec4(1.0,0.0,0.0,1.0);
}
结果是这个三角形:
链接着色器时的结果:
编辑 2:
我改了代码
我现在正在链接着色器:
GL20.glAttachShader(program, frag);
GL20.glLinkProgram(program);
if(GL20.glGetProgrami(program, GL20.GL_LINK_STATUS) != GL20.GL_TRUE) {
System.out.println("Can't link shader");
System.out.println(GL20.glGetProgramInfoLog(program));
}
GL20.glValidateProgram(program);
我也改了这一行:
GL15.glDrawArrays(GL15.GL_TRIANGLES, 0, vtexNumber);
GL30.glBindVertexArray(0);
GL20.glUseProgram(0);
并更改了顶点和片段着色器:
Vertex:
#version 330
out vec3 vertColor;
layout (location = 0) in vec3 inPosition;
layout (location = 1) in vec3 inColor;
void main() {
gl_Position = vec4(inPosition,1.0);
vertColor = inColor;
}
Fragment:
#version 330
in vec3 vertColor;
out vec4 FragColor;
void main() {
FragColor = vec4(vertColor,1.0);
}
但我仍然得到奇怪的结果:
我得到一个黑色三角形覆盖了一半的窗口,我尝试移动相机但没有任何变化。
【问题讨论】:
-
你为什么
glEnableClientState?如果您使用的是着色器程序,则不需要固定的函数属性。 -
@Rabbid76 我编辑了帖子和代码以添加更多细节,但我仍然得到相同的结果。
-
你在哪里链接着色器程序? (
glLinkProgram)。此外,第一个和第二个顶点坐标是相同的。 -
@Rabbid76 当我链接着色器时,我得到了一个更奇怪的结果:屏幕全是红色,我编程让屏幕在我按下一个键时改变颜色,当我按下那个键时没有任何反应,第一个和第二个故意相同,即使使用了错误的三角形,它仍然显示相同的东西
-
当我使用这个链接着色器时:
GL20.glAttachShader(program, frag); GL20.glLinkProgram(program); if(GL20.GL_LINK_STATUS != GL20.GL_TRUE) { System.out.println("Can't link shader"); System.out.println(GL20.glGetProgramInfoLog(program)); } GL20.glValidateProgram(program);我在控制台中得到相同的结果并在窗口中得到这个结果:结果在帖子中