现在我正在进行渲染对象的简单步骤。我在这里关注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);
}
}
1条答案
按热度按时间vdzxcuhz1#
几何图形(三角形)由透视投影的近平面剪裁。通过透视投影,观察体积是一个平截头体。不在观察体积中且不在近平面和远平面之间的任何几何图形都将被剪裁。
几何图形(三角形)绘制在(z=0.0)。近窗格为0.001,dat平面为1000。因此,几何体被剪裁。沿负z轴移动几何体:
请注意,视图空间坐标系是右手坐标系。x轴指向右侧,y轴指向上方。因此,z轴指向视口之外。要在近平面和远平面之间移动几何体,必须沿z轴沿负方向移动几何体。
投影矩阵从视图空间转换到剪辑空间。剪辑空间是右手系统。对于从左手系统到右手系统的转换,投影矩阵“翻转”z轴。