java - 未设置 LWJGL OpenGL 制服
问题描述
现在我正在进行渲染对象的简单步骤。我在这里关注 gitbook ,虽然我的设置几乎相同,但屏幕上什么也没有。
我试过了:
- 仔细检查我的视图矩阵数学(实际上是错误的,但已修复)
- 在不使用着色器的情况下尝试渲染(效果很好)
- 尝试使用着色器进行渲染,但没有制服(工作正常)
但是一旦我穿上制服,屏幕上除了我清晰的颜色之外什么也没有。任何有关如何使这些古怪制服工作的帮助将不胜感激。谢谢!
我的应用程序窗口类的代码:
package flaff.gameengine.internal;
import flaff.gameengine.*;
import java.util.List;
import org.lwjgl.BufferUtils;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.opengl.GL;
import static org.lwjgl.opengl.GL30.*;
public class ApplicationWindow
{
private int width;
private int height;
private String title;
private boolean resized;
private long window;
public ApplicationWindow(int width, int height, String title)
{
this.width = width;
this.height = height;
this.title = title;
}
public void start()
{
if (!GLFW.glfwInit())
{
System.err.println("Error: Couldn't initialize GLFW");
System.exit(-1);
}
this.window = GLFW.glfwCreateWindow(this.width, this.height, this.title, 0, 0);
if (window == 0)
{
System.err.println("Error: Window couldn't be created");
System.exit(-1);
}
GLFW.glfwMakeContextCurrent(this.window);
GL.createCapabilities();
GLFW.glfwSetFramebufferSizeCallback(this.window, (unusedW, width, height) ->
{
this.width = width;
this.height = height;
this.resized = true;
});
glClearColor(0.1921569f, 0.3019608f, 0.4745098f, 0f);
GLFWVidMode videoMode = GLFW.glfwGetVideoMode(GLFW.glfwGetPrimaryMonitor());
// centers the window
GLFW.glfwSetWindowPos(this.window, (videoMode.width() - this.width) / 2, (videoMode.height() - this.height) / 2);
// show the video
GLFW.glfwShowWindow(this.window);
glEnable(GL_DEPTH_TEST);
}
public void render()
{
if (this.resized)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_MODELVIEW);
this.resized = false;
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
List<Renderer> rendererList = GObject.findObjectsOfType(Renderer.class);
for (int index = 0; index < rendererList.size(); index++)
rendererList.get(index).render();
}
public boolean isClosed()
{
return GLFW.glfwWindowShouldClose(this.window);
}
public void nextFrame()
{
// non-relevant code
GLFW.glfwPollEvents();
// more non-relevant code
// render loop
this.render();
// more non-relevant code
GLFW.glfwSwapBuffers(this.window);
}
}
我的实例类的代码:
package flaff.gameengine;
import java.util.List;
import flaff.gameengine.internal.*;
import flaff.gameengine.renderers.MeshRenderer;
public class Instance
{
private ApplicationWindow window;
private Instance(int width, int height, String title)
{
this.window = new ApplicationWindow(width, height, title);
}
public ApplicationWindow getWindow()
{
return this.window;
}
public void run()
{
this.window.start();
Shader shader = Shader.getDefault();
shader.createUniform("projectionMatrix");
MeshRenderer renderer = new MeshRenderer();
renderer.setShader(shader);
Mesh mesh = new Mesh(new float[] {
0.0f, 0.5f, 0f,
-0.5f, -0.5f, 0f,
0.5f, -0.5f, 0f
});
renderer.setMesh(mesh);
while (!this.window.isClosed())
{
this.window.nextFrame();
}
// non-relevant code
}
// entry point
public static void main(String[] args)
{
new Instance(800, 600, "Test").run();
}
}
网格渲染器:
package flaff.gameengine.renderers;
import flaff.gameengine.Application;
import flaff.gameengine.Mesh;
import flaff.utils.geometry.Mathg;
import flaff.utils.geometry.matrix.Matrix4x4f;
public class MeshRenderer extends Renderer
{
private Mesh mesh;
private Matrix4x4f perspectiveMatrix;
public MeshRenderer()
{
super();
}
public void setMesh(Mesh value)
{
this.mesh = value;
}
@Override
public void render()
{
float aspectRatio = (float)Application.getWidth() / Application.getHeight();
float fov = Mathg.DEG2RAD * 90F;
float zNear = 0.001F;
float zFar = 1000F;
if (this.perspectiveMatrix == null)
this.perspectiveMatrix = Matrix4x4f.createPerspectiveFieldOfView(aspectRatio, fov, zNear, zFar);
shader.bind();
shader.setUniform("projectionMatrix", this.perspectiveMatrix);
glBindVertexArray(mesh.getVaoId());
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, mesh.getVertexCount());
// Restore state
glDisableVertexAttribArray(0);
glBindVertexArray(0);
shader.unbind();
}
}
渲染器类:
package flaff.gameengine.renderers;
import flaff.gameengine.Behaviour;
import flaff.gameengine.SerializeField;
import flaff.gameengine.internal.Shader;
public abstract class Renderer extends Behaviour
{
@SerializeField
protected Shader shader;
public Renderer()
{
super();
}
public void setShader(Shader shader)
{
this.shader = shader;
}
public abstract void render();
}
着色器类:
package flaff.gameengine.internal;
import static org.lwjgl.opengl.GL30.*;
import java.nio.FloatBuffer;
import java.util.HashMap;
import java.util.Map;
import org.lwjgl.system.MemoryStack;
import flaff.utils.geometry.matrix.Matrix4x4f;
public class Shader
{
private final int programId;
private int vertexShaderId;
private int fragmentShaderId;
private Map<String, Integer> uniforms;
public Shader(String vertexShader, String fragmentShader)
{
this.uniforms = new HashMap<String, Integer>();
this.programId = glCreateProgram();
if (programId == 0)
throw new RuntimeException("FML");
this.vertexShaderId = this.createShader(vertexShader, GL_VERTEX_SHADER);
this.fragmentShaderId = this.createShader(fragmentShader, GL_FRAGMENT_SHADER);
this.link();
}
private int createShader(String shaderCode, int shaderType)
{
int shaderId = glCreateShader(shaderType);
if (shaderId == 0)
throw new RuntimeException("Error creating a shader. FML: " + shaderType);
glShaderSource(shaderId, shaderCode);
glCompileShader(shaderId);
if (glGetShaderi(shaderId, GL_COMPILE_STATUS) == 0)
throw new RuntimeException("Error compiling Shader code: " + glGetShaderInfoLog(shaderId, 1024));
glAttachShader(this.programId, shaderId);
return shaderId;
}
public void link()
{
glLinkProgram(this.programId);
if (glGetProgrami(this.programId, GL_LINK_STATUS) == 0)
throw new RuntimeException("Error linking Shader code: " + glGetProgramInfoLog(programId, 1024));
if (this.vertexShaderId != 0)
glDetachShader(this.programId, this.vertexShaderId);
if (this.fragmentShaderId != 0)
glDetachShader(programId, this.fragmentShaderId);
glValidateProgram(this.programId);
if (glGetProgrami(this.programId, GL_VALIDATE_STATUS) == 0)
System.err.println("Warning validating Shader code: " + glGetProgramInfoLog(programId, 1024));
}
public void bind()
{
glUseProgram(this.programId);
}
public void unbind()
{
glUseProgram(0);
}
public void cleanup()
{
unbind();
if (this.programId != 0)
glDeleteProgram(this.programId);
}
public void createUniform(String uniformName)
{
int uniformLocation = glGetUniformLocation(this.programId, uniformName);
if (uniformLocation < 0)
throw new RuntimeException("Could not find uniform: " + uniformName);
uniforms.put(uniformName, uniformLocation);
}
public void setUniform(String uniformName, Matrix4x4f matrix)
{
try (MemoryStack stack = MemoryStack.stackPush())
{
FloatBuffer fb = stack.mallocFloat(16);
matrix.updateBuffer(fb);
glUniformMatrix4fv(uniforms.get(uniformName), false, fb);
}
}
public static Shader getDefault()
{
return new Shader(
"#version 330\n"
+ "\n"
+ "\n"
+ "layout (location=0) in vec3 position;\n"
+ "\n"
+ "uniform mat4 projectionMatrix;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = projectionMatrix * vec4(position, 1.0);\n"
+ "}",
"#version 330\n"
+ "\n"
+ "\n"
+ "out vec4 fragColor;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " fragColor = vec4(0.5, 0.5, 0.5, 1.0);\n"
+ "}");
}
}
网格类:
package flaff.gameengine;
import java.nio.FloatBuffer;
import static org.lwjgl.opengl.GL30.*;
import org.lwjgl.system.MemoryUtil;
public class Mesh extends GObject
{
private final int vaoId;
private final int vboId;
private final int vertexCount;
public Mesh(float[] positions) //TODO: Implement indices
{
FloatBuffer verticesBuffer = null;
verticesBuffer = MemoryUtil.memAllocFloat(positions.length);
vertexCount = positions.length / 3;
verticesBuffer.put(positions).flip();
vaoId = glGenVertexArrays();
glBindVertexArray(vaoId);
vboId = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, verticesBuffer, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
MemoryUtil.memFree(verticesBuffer);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
public int getVaoId()
{
return vaoId;
}
public int getVertexCount()
{
return vertexCount;
}
private void onDestroy()
{
glDisableVertexAttribArray(0);
// Delete the VBO
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDeleteBuffers(vboId);
// Delete the VAO
glBindVertexArray(0);
glDeleteVertexArrays(vaoId);
}
}
解决方案
The geometry (triangle) is clipped by the near plane of the Perspective Projection. With Perspective Projection the viewing volume is a Frustum. Any geometries that are not in the viewing volume and not between the near and far planes are clipped.
Your geometry (triangle) is drawn at (z=0.0). The near pane is 0.001 and the dat plane is 1000. Therefor the geometry is clipped. Shift the geometry along the negative z-axis:
Mesh mesh = new Mesh(new float[] {
0.0f, 0.5f, -5.0f,
-0.5f, -0.5f, -5.0f,
0.5f, -0.5f, -5.0f
});
Note that the view space coordinate system is a right-handed system. The x-axis points to the right, the y-axis points upwards. Therefore, the z-axis points out of the viewport. To move the geometry between the near and far planes, you must move the geometry in the negative direction along the z-axis.
The projection matrix converts from the view space to the clip space. Clip space is a right-handed system. For the transformation from a left-handed system to a right-handed system, the projection matrix "flips" the z-axis.
推荐阅读
- apache - Apache 拒绝连接
- javascript - 为什么选择选项没有显示数字?
- blazor-server-side - 未找到 Blazor 路线 - 如何前往站点基地?
- spring-boot - Spring Boot + WebFlux。如何显示一个简单的 index.jsp?
- javascript - 运行反应应用程序时出现 Chokidar UNKNOWN 错误
- mongodb - 在 webapp 中嵌入 CSV 文件或连接到 MongoDB 更好吗?
- css - How do I get webkit styling to work with Vue.js?
- python - 具有相同外键 1 关系的 SQLAlchemy 2 列 - 或查询?
- amazon-web-services - 如何在aws中为python设置docker?
- python - 用pygame放大和缩小