我正在尝试使用数组缓冲区渲染三个点,但我无法渲染任何东西。
这是我的代码:
import java.nio.*;
import javax.media.opengl.*;
public class SimpleScene implements GLEventListener
{
private GL3 gl;
int myIdentityShader;
@Override
public void display(GLAutoDrawable drawable) {
gl.glClear(GL3.GL_COLOR_BUFFER_BIT);
gl.glUseProgram(myIdentityShader);
gl.glDrawArrays(GL3.GL_POINTS, 0, 3);
}
@Override
public void dispose(GLAutoDrawable drawable) {
gl.glDeleteProgram(myIdentityShader);
gl.glDeleteVertexArrays(1, vertexArrayObject, 0);
}
@Override
public void init(GLAutoDrawable drawable) {
gl = drawable.getGL().getGL3();
try {
myIdentityShader = createShaderProgram();
} catch (Exception e) {
e.printStackTrace();
return;
}
gl.glPointSize(30);
gl.glClearColor(0.7f, 0, 0, 1);
float[] floatData = {
0.25f, -0.25f, 0.5f, 1.0f,
-0.25f, -0.25f, 0.5f, 1.0f,
0.25f, 0.25f, 0.5f, 1.0f
};
FloatBuffer data = FloatBuffer.allocate(3 * 4);
for (int i=0;i<12;i++)
data.put(floatData[i]);
gl.glGenVertexArrays(1, vertexArrayObject, 0);
gl.glBindVertexArray(vertexArrayObject[0]);
int[] buffers = new int[1];
gl.glGenBuffers(1, buffers, 0);
gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, buffers[0]);
gl.glBufferData(GL3.GL_ARRAY_BUFFER, data.capacity(), data, GL3.GL_STATIC_DRAW);
gl.glVertexAttribPointer(2, 4, GL3.GL_FLOAT, false, 0, 0);
gl.glEnableVertexAttribArray(2);
}
@Override
public void reshape(GLAutoDrawable drawable, int arg1, int arg2, int arg3,
int arg4) {
// TODO Add reshape code
}
private String vertexShader = "#version 130 \n" +
"in vec4 position; \n" +
"void main(void) \n" +
"{ \n" +
" gl_Position = position; \n" +
"} \n";
private String fragmentShader = "#version 130 \n" +
"out vec4 vFragColor; \n" +
"void main(void) \n" +
"{ \n" +
" vFragColor = vec4(0.0, 0.8, 1.0, 1.0); \n" +
"} \n";
private int[] vertexArrayObject = new int[1];
private int createShaderProgram() throws Exception
{
int hVertexShader, hFragmentShader, hShaderProgram;
int[] successTest = new int[] {1};
hVertexShader = gl.glCreateShader(GL3.GL_VERTEX_SHADER);
hFragmentShader = gl.glCreateShader(GL3.GL_FRAGMENT_SHADER);
gl.glShaderSource(hVertexShader, 1, new String[] {vertexShader}, null);
gl.glShaderSource(hFragmentShader, 1, new String[] {fragmentShader}, null);
gl.glCompileShader(hVertexShader);
gl.glCompileShader(hFragmentShader);
gl.glGetShaderiv(hVertexShader, GL3.GL_COMPILE_STATUS, successTest, 0);
if (successTest[0] == 0)
{
byte[] infoLog = new byte[1024];
gl.glGetShaderInfoLog(hVertexShader, 1024, null, 0, infoLog, 0);
gl.glDeleteShader(hVertexShader);
gl.glDeleteShader(hFragmentShader);
throw new Exception("Vertex shader compilation failed with: " + new String(infoLog));
}
gl.glGetShaderiv(hFragmentShader, GL3.GL_COMPILE_STATUS, successTest, 0);
if (successTest[0] == 0)
{
byte[] infoLog = new byte[1024];
gl.glGetShaderInfoLog(hFragmentShader, 1024, null, 0, infoLog, 0);
gl.glDeleteShader(hVertexShader);
gl.glDeleteShader(hFragmentShader);
throw new Exception("Fragment shader compilation failed with: " + new String(infoLog));
}
hShaderProgram = gl.glCreateProgram();
gl.glAttachShader(hShaderProgram, hVertexShader);
gl.glAttachShader(hShaderProgram, hFragmentShader);
gl.glBindAttribLocation(hShaderProgram, 2, "position");
gl.glLinkProgram(hShaderProgram);
gl.glGetProgramiv(hShaderProgram, GL3.GL_LINK_STATUS, successTest, 0);
if (successTest[0] == 0)
{
byte[] infoLog = new byte[1024];
gl.glGetProgramInfoLog(hShaderProgram, 1024, null, 0, infoLog, 0);
gl.glDeleteProgram(hShaderProgram);
throw new Exception("Shader linking failed with: " + new String(infoLog);
}
gl.glDeleteShader(hVertexShader);
gl.glDeleteShader(hFragmentShader);
return hShaderProgram;
}
}
我绝对确定着色器和 createShaderProgram 方法是正确的。当我使用 glVertexAttrib4fv 时,所有三个点都被渲染在同一个位置(如预期的那样),但是当我使用 glVertexAttribPointer 时,没有任何东西被渲染并且没有错误(glGetError 返回 0)。
我发现如果属性索引为 0,glVertexAttrib4fv 不会发送坐标,从而导致所有点都呈现在屏幕的中心。glVertexAttribPointer 不会发生这种情况,因此会发送坐标。