问题:我无法使三角形出现。我无法仅通过使用OpenGL 2.0来正确设置顶点属性
代码运行结果:红色窗口600 * 800,不带三角形。
目标:我尝试:
float
x 2(对于a
开始)int
x 3关联Java代码:
package prot20;
import static org.lwjgl.glfw.GLFW.GLFW_FALSE;
import static org.lwjgl.glfw.GLFW.GLFW_RESIZABLE;
import static org.lwjgl.glfw.GLFW.GLFW_TRUE;
import static org.lwjgl.glfw.GLFW.GLFW_VISIBLE;
import static org.lwjgl.glfw.GLFW.glfwCreateWindow;
import static org.lwjgl.glfw.GLFW.glfwDefaultWindowHints;
import static org.lwjgl.glfw.GLFW.glfwGetPrimaryMonitor;
import static org.lwjgl.glfw.GLFW.glfwInit;
import static org.lwjgl.glfw.GLFW.glfwMakeContextCurrent;
import static org.lwjgl.glfw.GLFW.glfwPollEvents;
import static org.lwjgl.glfw.GLFW.glfwShowWindow;
import static org.lwjgl.glfw.GLFW.glfwSwapBuffers;
import static org.lwjgl.glfw.GLFW.glfwSwapInterval;
import static org.lwjgl.glfw.GLFW.glfwWindowHint;
import static org.lwjgl.glfw.GLFW.glfwWindowShouldClose;
import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.GL_FLOAT;
import static org.lwjgl.opengl.GL11.GL_PROJECTION;
import static org.lwjgl.opengl.GL11.GL_TRIANGLES;
import static org.lwjgl.opengl.GL11.GL_UNSIGNED_INT;
import static org.lwjgl.opengl.GL11.glClear;
import static org.lwjgl.opengl.GL11.glClearColor;
import static org.lwjgl.opengl.GL11.glDrawElements;
import static org.lwjgl.opengl.GL11.glEnableClientState;
import static org.lwjgl.opengl.GL11.glGetString;
import static org.lwjgl.opengl.GL11.glLoadIdentity;
import static org.lwjgl.opengl.GL11.glMatrixMode;
import static org.lwjgl.opengl.GL11.glOrtho;
import static org.lwjgl.opengl.GL11.glViewport;
import static org.lwjgl.opengl.GL20.glUseProgram;
import static org.lwjgl.system.MemoryUtil.NULL;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL11;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import org.lwjgl.opengl.GLCapabilities;
public class prot20_2 {
private long window;
private int width = 800;
private int height = 600;
public static void main(String[] args) {
new prot20_2();
}
public prot20_2() {
if (!glfwInit()) {
throw new IllegalStateException("Unable to initialize GLFW");
}
glfwDefaultWindowHints();
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
long monitor = glfwGetPrimaryMonitor();
window = glfwCreateWindow(width, height, "Window20", NULL, NULL);
if (window == NULL) {
throw new AssertionError("Failed to create window");
}
glfwMakeContextCurrent(window);
glfwSwapInterval(0);
glfwShowWindow(window);
GLCapabilities c = GL.createCapabilities();
System.out.println(c.OpenGL20);
System.out.println(glGetString(GL11.GL_VERSION));
int program = util.createProgram(prot20_2.getSimpleVertexShaderCode(), prot20_2.getSimpleFragmentShaderCode());
float[] vertices = { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f };
int[] color = { 0, 128, 128, 128, 0, 128, 128, 128, 0 };
int[] indices = { 0, 1, 2 };
FloatBuffer vb = this.toBuffer(vertices);
IntBuffer ib = this.toBuffer(indices);
IntBuffer cb = this.toBuffer(color);
int vbo = glGenBuffers();
int ibo = glGenBuffers();
int cbo = glGenBuffers();
// Position
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, vb, GL_STATIC_DRAW);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
glBindAttribLocation(program, 0, "position");
glBindBuffer(GL_ARRAY_BUFFER, 0);
// Color
glBindBuffer(GL_ARRAY_BUFFER, cbo);
glBufferData(GL_ARRAY_BUFFER, cb, GL_STATIC_DRAW);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableVertexAttribArray(1);
glVertexAttribPointer(0, 3, GL_INT, false, 0, 0);
glBindAttribLocation(program, 1, "color");
glBindBuffer(GL_ARRAY_BUFFER, 0);
// indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, ib, GL_STATIC_DRAW);
glEnableClientState(GL_INDEX_ARRAY);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glUseProgram(program);
while (glfwWindowShouldClose(this.window) == false) {
glClearColor(1, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
float aspect = (float) width / height;
glLoadIdentity();
glOrtho(-aspect, aspect, -1, 1, -1, 1);
// glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0L);
glfwSwapBuffers(this.window);
glfwPollEvents();
}
glDeleteBuffers(vbo);
}
private FloatBuffer toBuffer(float[] f) {
FloatBuffer buffer = BufferUtils.createFloatBuffer(f.length);
buffer.put(f);
buffer.flip();
return buffer;
}
private IntBuffer toBuffer(int[] i) {
IntBuffer buffer = BufferUtils.createIntBuffer(i.length);
buffer.put(i);
buffer.flip();
return buffer;
}
public static String getSimpleFragmentShaderCode() {
StringBuilder sb = new StringBuilder();
sb.append("uniform vec3 color;\n");
sb.append("void main(void) {\n");
sb.append(" gl_FragColor = vec4(color.rgb, 1.0);");
sb.append("}\n");
return sb.toString();
}
public static String getSimpleVertexShaderCode() {
StringBuilder sb = new StringBuilder();
sb.append("uniform vec2 position;\n");
sb.append("void main(void) {\n");
sb.append(" gl_Position = vec4(position.xy,0.0,0.0);\n");
sb.append("}\n");
return sb.toString();
}
}
我一直在寻找文档和示例,但要么找到没有属性,颜色,索引或着色器的琐碎示例,要么使用opengl 3+找到复杂的代码。我发现很难找到一个涵盖以下方面的好示例:opengl 2.1,包括着色器,索引,属性,颜色和纹理。
答案 0 :(得分:2)
如果要绘制具有与每个顶点坐标关联的颜色的三角形,则需要具有2个属性的顶点着色器。一种用于顶点坐标,另一种用于颜色。颜色属性必须通过varying
变量从Vertex Shader传递到Fragment Shader。
请注意,attribute
和varying
已过时,但必须在GLSL 1.10版(与OpenGL 2.0版相对应)中使用。在“现代” OpenGL中,使用Type Qualifiers (GLSL) in
和out
:
顶点着色器
#version 110
attribute vec2 in_pos;
attribute vec3 in_col;
varying vec3 v_volor;
void main()
{
v_color = in_col;
gl_Position = vec4(in_pos.xy, 0.0, 1.0);
}
片段着色器
varying vec3 v_color;
void main()
{
gl_FragColor = vec4(v_color.rgb, 1.0);
}
程序链接后,必须通过glGetAttribLocation
获取in_pos
和in_col
的属性索引:
int attr_pos = glGetAttribLocation(program, "in_pos");
int attr_col = glGetAttribLocation(program, "in_col");
如果要通过glBindAttribLocation
设置属性索引,则必须在通过glLinkProgram
链接程序之前完成此操作,因为这是在链接过程中处理的信息。
OpenGL Shading Language (GLSL)中的颜色通道必须在[0.0,1.0]范围内,其中 RGB(0.0,0.0,0.0)完全是黑色,而 RGB(1.0, 1.0,1.0)是白色。因此颜色属性必须是浮点值:
float[] vertices = { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f };
float[] color = { 0, 0.5f, 0.5f, 0.5f, 0, 0.5f, 0.5f, 0.5f, 0 };
int[] indices = { 0, 1, 2 };
FloatBuffer vb = this.toBuffer(vertices);
FloatBuffer cb = this.toBuffer(color);
IntBuffer ib = this.toBuffer(indices);
生成数组缓冲区和索引缓冲区:
int vbo = glGenBuffers();
int cbo = glGenBuffers();
int ibo = glGenBuffers();
// Position
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, vb, GL_STATIC_DRAW);
// Color
glBindBuffer(GL_ARRAY_BUFFER, cbo);
glBufferData(GL_ARRAY_BUFFER, cb, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, ib, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
指定通用顶点属性数据的数组:
// Position
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glEnableVertexAttribArray(attr_pos);
glVertexAttribPointer(attr_pos, 2, GL_FLOAT, false, 0, 0);
// Color
glBindBuffer(GL_ARRAY_BUFFER, cbo);
glEnableVertexAttribArray(attr_col);
glVertexAttribPointer(attr_col, 3, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
要绘制对象,程序对象必须由glUseProgram
安装,并且必须绑定元素缓冲区:
glUseProgram(program);
while (glfwWindowShouldClose(this.window) == false) {
// ....
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0L);
// .....
}
请注意,固定功能属性(glVertexPointer
,...),客户端功能(glEnableClientState
/ glDisableClientState
)和固定功能矩阵堆栈(glMatrixMode
,{使用这样的着色器程序时,{1}},...)无效。
如果要使用矩阵转换,则必须使用glLoadIdentity
类型的Uniform变量并设置自己的投影,视图和模型矩阵-例如通过Matrix4f库。