Я разрабатываю игру с lwjgl 3 в java, и она работала нормально, но когда я хочу использовать шейдеры, 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();
}
Мои шейдеры:
Frag
#version 410
out vec4 vertColor;
void main(){
gl_FragColor = vertColor;
}
Vert
#version 410
layout (location=0) in vec3 position;
void main()
{
gl_Position = vec4(position, 1.0);
}