gpt4 book ai didi

java - 当我尝试使用着色器时,OpenGL 向我发送堆栈下溢错误 (Java)

转载 作者:行者123 更新时间:2023-12-01 17:35:59 27 4
gpt4 key购买 nike

我正在 Java 中使用 lwjgl 3 开发游戏,它工作正常,但当我想使用着色器时,OpenGL 发送 STACK_UNDERFLOW 错误 (1284)。

我使用 3 个缓冲区:顶点缓冲区、颜色缓冲区、索引缓冲区;

我的旧代码:

private int vbo;
private int cbo;
private int ibo;
private FloatBuffer buffer;
private FloatBuffer colorBuffer;
private IntBuffer indexBuffer;

private IcoSphere sphere;
int radius = 200;

@Override
public void init() {
sphere = new IcoSphere(9, radius);
sphere.generate();
generateBuffer();
}

private void generateBuffer() {
buffer = BufferUtils.createFloatBuffer(sphere.getVertexCount() * 3);
colorBuffer = BufferUtils.createFloatBuffer(sphere.getFacesCount() * 4 * 4);
indexBuffer = BufferUtils.createIntBuffer(sphere.getFacesCount());

Random r = new Random();
OpenSimplexNoise noise = new OpenSimplexNoise();

ArrayList<Vector3f> vertex = sphere.getVertex();
float[] v = new float[vertex.size() * 3];
for (int i = 0; i < vertex.size(); i++) {
vertex.get(i).normalize();
vertex.get(i).mul(sphere.getRadius() + (float) noise.eval(
vertex.get(i).x * 8,
vertex.get(i).y * 8,
vertex.get(i).z * 8
) * 12);
v[i * 3 + 0] = vertex.get(i).x;
v[i * 3 + 1] = vertex.get(i).y;
v[i * 3 + 2] = vertex.get(i).z;
}
buffer.put(sphere.getVertexArray());

indexBuffer.put(sphere.getIndexArray());

for (int i = 0; i < sphere.getFacesCount(); i++) {
colorBuffer.put(new float[] {
r.nextFloat(), r.nextFloat(), r.nextFloat(), 1,
r.nextFloat(), r.nextFloat(), r.nextFloat(), 1,
r.nextFloat(), r.nextFloat(), r.nextFloat(), 1
});
}

buffer.flip();
colorBuffer.flip();
indexBuffer.flip();

createBuffer();
}

private void createBuffer() {
vbo = glGenBuffers();
cbo = glGenBuffers();
ibo = glGenBuffers();

glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW);

glBindBuffer(GL_ARRAY_BUFFER, cbo);
glBufferData(GL_ARRAY_BUFFER, colorBuffer, GL_STATIC_DRAW);

glBindBuffer(GL_ARRAY_BUFFER, 0);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexBuffer, GL_STATIC_DRAW);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}

@Override
public void update() {

}

@Override
public void render() {
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);

glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexPointer(3, GL_FLOAT, 0, 0);

glBindBuffer(GL_ARRAY_BUFFER, cbo);
glColorPointer(4, GL_FLOAT, 0, 0);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);

glDrawElements(GL_TRIANGLES, sphere.getFacesCount() * 3, GL_UNSIGNED_INT, 0);

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}

添加着色器后我的新代码:

GlUtils.glCall(() -> ..); 用于捕获 opengl 错误。

private int vbo;
private int cbo;
private int ibo;
private FloatBuffer buffer;
private FloatBuffer colorBuffer;
private IntBuffer indexBuffer;

private IcoSphere sphere;
int radius = 200;

@Override
public void init() {
sphere = new IcoSphere(9, radius);
sphere.generate();
generateBuffer();
}

private void generateBuffer() {
buffer = BufferUtils.createFloatBuffer(sphere.getVertexCount() * 3);
colorBuffer = BufferUtils.createFloatBuffer(sphere.getFacesCount() * 4 * 4);
indexBuffer = BufferUtils.createIntBuffer(sphere.getFacesCount());

Random r = new Random();
OpenSimplexNoise noise = new OpenSimplexNoise();

ArrayList<Vector3f> vertex = sphere.getVertex();
float[] v = new float[vertex.size() * 3];
for (int i = 0; i < vertex.size(); i++) {
vertex.get(i).normalize();
vertex.get(i).mul(sphere.getRadius() + (float) noise.eval(
vertex.get(i).x * 8,
vertex.get(i).y * 8,
vertex.get(i).z * 8
) * 12);
v[i * 3 + 0] = vertex.get(i).x;
v[i * 3 + 1] = vertex.get(i).y;
v[i * 3 + 2] = vertex.get(i).z;
}
buffer.put(sphere.getVertexArray());

indexBuffer.put(sphere.getIndexArray());

for (int i = 0; i < sphere.getFacesCount(); i++) {
colorBuffer.put(new float[] {
r.nextFloat(), r.nextFloat(), r.nextFloat(), 1,
r.nextFloat(), r.nextFloat(), r.nextFloat(), 1,
r.nextFloat(), r.nextFloat(), r.nextFloat(), 1
});
}

buffer.flip();
colorBuffer.flip();
indexBuffer.flip();

createBuffer();
}

private void createBuffer() {

vbo = glGenBuffers();
cbo = glGenBuffers();
ibo = glGenBuffers();

GlUtils.glCall(() -> glBindBuffer(GL_ARRAY_BUFFER, vbo));
GlUtils.glCall(() -> glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW));
GlUtils.glCall(() -> glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0));

GlUtils.glCall(() -> glBindBuffer(GL_ARRAY_BUFFER, cbo));
GlUtils.glCall(() -> glBufferData(GL_ARRAY_BUFFER, colorBuffer, GL_STATIC_DRAW));
GlUtils.glCall(() -> glVertexAttribPointer(1, 4, GL_FLOAT, false, 0, 0));

GlUtils.glCall(() -> glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo));
GlUtils.glCall(() -> glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexBuffer, GL_STATIC_DRAW));

GlUtils.glCall(() -> glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
GlUtils.glCall(() -> glBindBuffer(GL_ARRAY_BUFFER, 0));

}

@Override
public void update() {

}

@Override
public void render() {
Shader.MAIN.bind();

GlUtils.glCall(() -> glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0));

GlUtils.glCall(() -> glEnableVertexAttribArray(0));
GlUtils.glCall(() -> glEnableVertexAttribArray(1));


GlUtils.glCall(() -> glDrawElements(GL_TRIANGLES, indexBuffer));

GlUtils.glCall(() -> glDisableVertexAttribArray(0));
GlUtils.glCall(() -> glDisableVertexAttribArray(1));

Shader.MAIN.unbind();
}

我的着色器:

碎片

#version 410

out vec4 vertColor;

void main(){
gl_FragColor = vertColor;
}

垂直

#version 410

layout (location=0) in vec3 position;

void main()
{
gl_Position = vec4(position, 1.0);
}

最佳答案

当您使用着色器程序时,您可以使用客户端功能以与之前相同的方式绘制网格。
您所要做的就是使用 glEnableVertexAttribArrayglVertexAttribPointer 而不是 glEnableClientStateglVertexPointerglColorPointer:

创建缓冲区:

vbo = glGenBuffers();
cbo = glGenBuffers();
ibo = glGenBuffers();

glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW);

glBindBuffer(GL_ARRAY_BUFFER, cbo);
glBufferData(GL_ARRAY_BUFFER, colorBuffer, GL_STATIC_DRAW);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexBuffer, GL_STATIC_DRAW);

绘制网格

glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);

glBindBuffer(GL_ARRAY_BUFFER, cbo);
glVertexAttribPointer(1, 4, GL_FLOAT, false, 0, 0);

glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glDrawElements(GL_TRIANGLES, sphere.getFacesCount() * 3, GL_UNSIGNED_INT, 0);

glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);

你实际做的是使用默认 Vertex Array Object (0) 为规范。请注意,默认 VAO (0) 仅在兼容性配置文件 OpenGL Context 中有效。 .

<小时/>

可以通过使用名为 Vertex Array Object 来改进这一点。请注意,您必须在核心配置文件 OpenGL Context 中使用命名的 VAO :

private int vao;
vao = glGenVertexArrays();
vbo = glGenBuffers();
cbo = glGenBuffers();
ibo = glGenBuffers();

glBindVertexArray(vao);

glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);

glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);

glBindBuffer(GL_ARRAY_BUFFER, cbo);
glBufferData(GL_ARRAY_BUFFER, colorBuffer, GL_STATIC_DRAW);
glVertexAttribPointer(1, 4, GL_FLOAT, false, 0, 0);

glBindBuffer(GL_ARRAY_BUFFER, 0);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexBuffer, GL_STATIC_DRAW);

glBindVertexArray(0);

顶点数组规范在顶点数组对象中声明。因此不需要glDisableVertexAttribArray
此外Index buffers (GL_ELEMENT_ARRAY_BUFFER) 也在 VAO 中说明。 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 会破坏绑定(bind)。

现在,在绘制网格时绑定(bind) VAO 就足够了:

glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, sphere.getFacesCount() * 3, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
<小时/>

您有 2 个颜色属性,顶点坐标和颜色。这 2 个属性是 Vertex Shader 的输入。顶点坐标用于设置gl_Position。颜色必须传递到 Fragment Shader 。它是顶点着色器的输出和片段着色器的输入。在片段着色器中,颜色被写入输出fragColor。片段着色器的输出写入frambuffer:

顶点着色器:

layout (location=0) in vec3 position;
layout (location=1) in vec4 color;

out vec4 vertColor;

void main()
{
vertColor = color;
gl_Position = vec4(position, 1.0);
}

片段着色器:

#version 410

in vec4 vertColor;
out vec4 fragColor;

void main()
{
fragColor = vertColor;
}

关于java - 当我尝试使用着色器时,OpenGL 向我发送堆栈下溢错误 (Java),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61040867/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com