我有一个项目正在处理它在何处创建窗口,创建顶点和着色器,着色器程序,MemoryBuffer等的项目。到目前为止,我已经经历了很多错误,并且在运行代码时没有错误。 glClearColor()调用不会设置屏幕颜色,并且不会绘制三角形。
教程我在关注:
https://github.com/SilverTiger/lwjgl3-tutorial/wiki/Rendering
主要:
public class DungeonRunners {
private double lastTick;
private float timeCount;
private int fps;
private int fpsCount;
private int ups;
private int upsCount;
public static void main(String[] args) {
System.out.println("LWJGL Version: " + Version.getVersion());
int width = 1240;
int height = 720;
boolean legacyGL = false;
for (int i = 0; i < args.length; i++) {
String arg = args[i];
switch (arg) {
case "width:":
try {
width = Integer.parseInt(args[i+1]);
i++;
} catch (NumberFormatException ignored) { }
break;
case "height:":
try {
height = Integer.parseInt(args[i+1]);
} catch (NumberFormatException ignored) { }
break;
case "-useLegacyGL":
legacyGL = true;
break;
}
}
DungeonRunners dungeonRunners = new DungeonRunners();
dungeonRunners.start(width, height, legacyGL);
}
private void start(int width, int height, Boolean legacyGL) {
GLFW.glfwInit();
if(!legacyGL) {
GLFW.glfwDefaultWindowHints();
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, 3);
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, 2);
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_PROFILE, GLFW.GLFW_OPENGL_CORE_PROFILE);
GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_FORWARD_COMPAT, GLFW.GLFW_TRUE);
} else {
GLFW.glfwDefaultWindowHints();
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, 2);
GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, 1);
}
GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, GLFW.GLFW_FALSE);
long window = GLFW.glfwCreateWindow(width, height, "Dungeon Runners", MemoryUtil.NULL, MemoryUtil.NULL);
GLFW.glfwMakeContextCurrent(window);
GL.createCapabilities(true);
RenderEngine engine = new RenderEngine(legacyGL);
GLFW.glfwWindowHint(GLFW.GLFW_RESIZABLE, GLFW.GLFW_TRUE);
GLFW.glfwShowWindow(window);
try ( MemoryStack stack = MemoryStack.stackPush() ) {
IntBuffer pWidth = stack.mallocInt(1);
IntBuffer pHeight = stack.mallocInt(1);
GLFW.glfwGetWindowSize(window, pWidth, pHeight);
GLFWVidMode vidmode = GLFW.glfwGetVideoMode(GLFW.glfwGetPrimaryMonitor());
assert vidmode != null;
GLFW.glfwSetWindowPos(
window,
(vidmode.width() - pWidth.get(0)) / 2,
(vidmode.height() - pHeight.get(0)) / 2
);
}
while(!GLFW.glfwWindowShouldClose(window)) {
update();
engine.frame();
GLFW.glfwPollEvents();
}
engine.clean();
GL.destroy();
GLFW.glfwDestroyWindow(window);
GLFW.glfwTerminate();
try {
Objects.requireNonNull(GLFW.glfwSetErrorCallback(null)).free();
} catch(NullPointerException e) {
System.exit(-1);
}
}
private void update() {
if (timeCount > 1f) {
fps = fpsCount;
fpsCount = 0;
ups = upsCount;
upsCount = 0;
timeCount -= 1f;
}
}
private float getDelta() {
double time = getTime();
float delta = (float) (time - lastTick);
lastTick = time;
timeCount += delta;
return delta;
}
private double getTime() {
return System.nanoTime() / 1000000000.0;
}
private void updateFPS() {
fpsCount++;
}
private void updateUPS() {
upsCount++;
}
}
RenderEngine:
public class RenderEngine {
private int shaderProgram;
private int vao = GL30.glGenVertexArrays();
private int fragmentShader;
private int vertexShader;
private List<Integer> vbos = new ArrayList<>();
private String vertexShaderCode =
"#version 150 core\n"+
"\n"+
"in vec3 position;\n"+
"in vec3 color;\n"+
"\n"+
"out vec3 vertexColor;\n"+
"\n"+
"uniform mat4 model;\n"+
"uniform mat4 view;\n"+
"uniform mat4 projection;\n"+
"\n"+
"void main() {\n"+
" vertexColor = color;\n"+
" mat4 mvp = projection * view * model;\n"+
" gl_Position = mvp * vec4(position, 1.0);\n"+
"}";
private String fragmentShaderCode =
"#version 150 core\n"+
"\n"+
"in vec3 vertexColor;\n"+
"\n"+
"out vec4 fragColor;\n"+
"\n"+
"void main() {\n"+
" fragColor = vec4(vertexColor, 1.0);\n"+
"}";
private String legacyVertexShaderCode =
"#version 120\n"+
"\n"+
"attribute vec3 position;\n"+
"attribute vec3 color;\n"+
"\n"+
"varying vec3 vertexColor;\n"+
"\n"+
"uniform mat4 model;\n"+
"uniform mat4 view;\n"+
"uniform mat4 projection;\n"+
"\n"+
"void main() {\n"+
" vertexColor = color;\n"+
" mat4 mvp = projection * view * model;\n"+
" gl_Position = mvp * vec4(position, 1.0);\n"+
"}";
private String legacyFragmentShaderCode =
"#version 120\n"+
"\n"+
"varying vec3 vertexColor;\n"+
"\n"+
"void main() {\n"+
" gl_FragColor = vec4(vertexColor, 1.0);\n"+
"}";
public RenderEngine(Boolean legacyGL) {
GL30.glBindVertexArray(vao);
setVertexAttribs();
setupShaders(legacyGL);
GL20.glUseProgram(shaderProgram);
setUniformVars();
bindImage();
}
private void bindImage() {
MemoryStack stack = MemoryStack.stackPush();
FloatBuffer vertices = stack.mallocFloat(3*6);
vertices.put(-0.6f).put(-0.4f).put(0f).put(1f).put(0f).put(0f);
vertices.put(0.6f).put(-0.4f).put(0f).put(0f).put(1f).put(0f);
vertices.put(0f).put(0.6f).put(0f).put(0f).put(0f).put(1f);
vertices.flip();
int vbo = GL15.glGenBuffers();
vbos.add(vbo);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vertices, GL15.GL_STATIC_DRAW);
MemoryStack.stackPop();
}
public void frame() {
GL11.glClearColor(1, 0, 0, 0);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
bindImage();
GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, 3);
}
public void clean() {
GL30.glDeleteVertexArrays(vao);
for(int vbo : vbos)
GL15.glDeleteBuffers(vbo);
GL20.glDeleteShader(vertexShader);
GL20.glDeleteShader(fragmentShader);
GL20.glDeleteProgram(shaderProgram);
}
private void setUniformVars() {
int uniModel = GL20.glGetUniformLocation(shaderProgram, "model");
UtilMatrix4f model = new UtilMatrix4f();
GL20.glUniformMatrix4fv(uniModel, false, model.getBuffer());
int uniView = GL20.glGetUniformLocation(shaderProgram, "view");
UtilMatrix4f view = new UtilMatrix4f();
GL20.glUniformMatrix4fv(uniView, false, view.getBuffer());
int uniProjection = GL20.glGetUniformLocation(shaderProgram, "projection");
float ratio = 640f/480f;
UtilMatrix4f projection = UtilMatrix4f.orthographic(-ratio, ratio, -1f, 1f, -1f, 1f);
GL20.glUniformMatrix4fv(uniProjection, false, projection.getBuffer());
}
private void setVertexAttribs() {
int floatSize = 4;
int posAttrib = GL20.glGetAttribLocation(shaderProgram, "position");
GL20.glEnableVertexAttribArray(posAttrib);
GL20.glVertexAttribPointer(posAttrib, 3, GL11.GL_FLOAT, false, 6*floatSize, 0);
int colAttrib = GL20.glGetAttribLocation(shaderProgram, "color");
GL20.glEnableVertexAttribArray(colAttrib);
GL20.glVertexAttribPointer(colAttrib, 3, GL11.GL_FLOAT, false, 6*floatSize, 3*floatSize);
}
private void setupShaders(boolean legacyGL) {
vertexShader = GL20.glCreateShader(GL20.GL_VERTEX_SHADER);
if (legacyGL)
GL20.glShaderSource(vertexShader, legacyVertexShaderCode);
else
GL20.glShaderSource(vertexShader, vertexShaderCode);
GL20.glCompileShader(vertexShader);
int status = GL20.glGetShaderi(vertexShader, GL20.GL_COMPILE_STATUS);
if (status != GL11.GL_TRUE) {
throw new RuntimeException(GL20.glGetShaderInfoLog(vertexShader));
}
fragmentShader = GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER);
if (legacyGL)
GL20.glShaderSource(fragmentShader, legacyFragmentShaderCode);
else
GL20.glShaderSource(fragmentShader, fragmentShaderCode);
GL20.glCompileShader(fragmentShader);
status = GL20.glGetShaderi(fragmentShader, GL20.GL_COMPILE_STATUS);
if (status != GL11.GL_TRUE) {
throw new RuntimeException(GL20.glGetShaderInfoLog(fragmentShader));
}
shaderProgram = GL20.glCreateProgram();
GL20.glAttachShader(shaderProgram, vertexShader);
GL20.glAttachShader(shaderProgram, fragmentShader);
GL30.glBindFragDataLocation(shaderProgram, 0, "fragColor");
GL20.glLinkProgram(shaderProgram);
status = GL20.glGetProgrami(shaderProgram, GL20.GL_LINK_STATUS);
if (status != GL11.GL_TRUE) {
throw new RuntimeException(GL20.glGetProgramInfoLog(shaderProgram));
}
}
}
最佳答案
glfwSwapBuffers
丢失,以使呈现“可见”:
while(!GLFW.glfwWindowShouldClose(window)) {
update();
engine.frame();
GLFW.glfwSwapBuffers(window);
GLFW.glfwPollEvents();
}
链接着色器程序并绑定顶点数组对象后,必须获取顶点属性的位置:
setupShaders(legacyGL);
bindImage();
GL30.glBindVertexArray(vao);
setVertexAttribs();
GL20.glUseProgram(shaderProgram);
setUniformVars();
注意,
glGetAttribLocation
要求提供活动程序资源的索引,并且在通过glLinkProgram
喜欢着色器程序时,将确定活动程序资源。此外,如果应将最后一个参数视为缓冲区对象数据存储区中的字节偏移(当然,尤其是在核心模式下),则在调用
glBindBuffer
之前,已命名的顶点缓冲区必须由glVertexAttribPointer
绑定。