我正在学习ThinMatrix关于OPENGL/LWJGL 3 3D游戏教程系列(在这里)的教程,尽管我的代码与他的有些不同,但效果很好。
我可以使用基本的LWJGL 3方法呈现像下面的图像那样的对象来呈现/阴影。基本上,在呈现类中使用此方法:
//Old method
public void createModel(EntityLoader entity, StaticShader shader) {
ModelLoader model = entity.getModel();
MeshLoader mesh = model.createModel();
glBindVertexArray(mesh.getVaoId());
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
shader.setUniformFloat("shineDamper", model.getShineDamper());
shader.setUniformFloat("reflectivity", model.getReflectivity());
Matrix4f transformationMatrix = Maths.createTransfMatrix(entity.getPosition(), entity.getRotX(), entity.getRotY(),
entity.getRotZ(), entity.getScale());
shader.setUniformMatrix("transformationMatrix", transformationMatrix);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, model.getTexture());
glUniform1i(glGetUniformLocation(shader.getID(), "texture"), 0);
glDrawElements(GL_TRIANGLES, mesh.getVertexCount(), GL_UNSIGNED_INT, 0);
mesh.cleanUp();
}并在主类中调用它,如下所示:
public static void main(String[] args){
Render render = new Render();
window = render.init();
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
glfwShowWindow(window);
createCapabilities();
Light light = new Light(new Vector3f(0,0,20), new Vector3f(1,1,1));
ObjLoader obj = new ObjLoader();
ModelLoader squareModel = obj.loadObj("game_engine/src/Objetos/Ico.obj");
EntityLoader squareEntity = new EntityLoader(squareModel, new Vector3f(0,0,-5),0,0,0,1);
squareModel.setShineDamper(10);
squareModel.setReflectivity(1);
squareModel.loadTexture("game_engine/src/Texturas/awesomeface.png");
Camera camera = new Camera();
StaticShader shader = new StaticShader();
shader.start();
shader.use();
while(!glfwWindowShouldClose(window))
{
render.prepare();
processInput(window);
glfwSetFramebufferSizeCallback(window, resizeWindow);
GLFW.glfwSetScrollCallback(window, new GLFWScrollCallback() {
@Override public void invoke (long win, double dx, double dy) {
XScroll = (float) dx;
YScroll = (float) dy;
}
});
camera.move(window, YScroll);
YScroll = 0;
shader.setUniformVector("lightPosition", light.getPosition());
shader.setUniformVector("lightColour", light.getColour());
Matrix4f viewMatrix = Maths.createViewMatrix(camera);
shader.setUniformMatrix("viewMatrix", viewMatrix);
shader.setUniformMatrix("projectionMatrix", render.getProjectionMatrix());
render.createModel(squareEntity, shader);
glfwSwapBuffers(window);
glfwPollEvents();
}
shader.cleanup();
glfwTerminate();
}

直到13个视频,优化,在这里,他教如何做同样的过程,以一种更优化的方式,使用HashMaps和ArrayLists存储实体,并在每个实体列表中只调用一次VAO元素。因此,我制作了一个MasterRender类:
public class Master {
private StaticShader shader = new StaticShader();
private Render renderer = new Render(shader);
private Map<ModelLoader, List<EntityLoader>> entities = new HashMap<ModelLoader, List<EntityLoader>>();
public void render(Light sun, Camera camera){
renderer.prepare();
shader.start();
shader.use();
shader.setUniformVector("lightPosition", sun.getPosition());
shader.setUniformVector("lightColour", sun.getColour());
Matrix4f viewMatrix = Maths.createViewMatrix(camera);
shader.setUniformMatrix("viewMatrix", viewMatrix);
shader.setUniformMatrix("projectionMatrix", renderer.getProjectionMatrix());
}
public void processEntity(EntityLoader entity) {
ModelLoader entityModel = entity.getModel();
List<EntityLoader> batch = entities.get(entityModel);
if(batch!=null) {
batch.add(entity);
}else {
List<EntityLoader> newBatch = new ArrayList<EntityLoader>();
newBatch.add(entity);
entities.put(entityModel, newBatch);
}
}
public void renderEntity() {
renderer.render(entities);
shader.stop();
entities.clear();
}
public long loadWindow() {
return renderer.init();
}
public void cleanup() {
shader.cleanup();
}
}并在Render类中使用新方法:
//Optimized methods
public void render(Map<ModelLoader, List<EntityLoader>> entities) {
for(ModelLoader model:entities.keySet()) {
prepareModel(model);
List<EntityLoader> batch = entities.get(model);
for(EntityLoader entity : batch) {
prepareEntity(entity);
glDrawElements(GL_TRIANGLES, model.createModel().getVertexCount(), GL_UNSIGNED_INT, 0);
}
unbindModel();
}
}
private void prepareModel(ModelLoader model) {
MeshLoader mesh = model.createModel();
glBindVertexArray(mesh.getVaoId());
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
shader.setUniformFloat("shineDamper", model.getShineDamper());
shader.setUniformFloat("reflectivity", model.getReflectivity());
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, model.getTexture());
glUniform1i(glGetUniformLocation(shader.getID(), "texture"), 0);
}
private void unbindModel() {
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
}
private void prepareEntity(EntityLoader entity) {
Matrix4f transformationMatrix = Maths.createTransfMatrix(entity.getPosition(), entity.getRotX(), entity.getRotY(),
entity.getRotZ(), entity.getScale());
shader.setUniformMatrix("transformationMatrix", transformationMatrix);
}最后,我调整了主类,就像他在视频中所做的那样。
public static void main(String[] args){
Master render = new Master();
window = render.loadWindow();
...
List<EntityLoader> allIcos = new ArrayList<EntityLoader>();
allIcos.add(new EntityLoader(squareModel, new Vector3f(0,0,-5),0,0,0,1));
while(!glfwWindowShouldClose(window))
{
processInput(window);
glfwSetFramebufferSizeCallback(window, resizeWindow);
GLFW.glfwSetScrollCallback(window, new GLFWScrollCallback() {
@Override public void invoke (long win, double dx, double dy) {
XScroll = (float) dx;
YScroll = (float) dy;
}
});
camera.move(window, YScroll);
YScroll = 0;
render.render(light, camera);
for(EntityLoader Ico : allIcos) {
render.processEntity(Ico);
Ico.changeRot(0, 3, 0);
}
render.renderEntity();
glfwSwapBuffers(window);
glfwPollEvents();
}它不仅不起作用,还买下了一个日志错误:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ff8b8cd07b0, pid=11800, tid=7260
#
# JRE version: OpenJDK Runtime Environment (16.0.2+7) (build 16.0.2+7-67)
# Java VM: OpenJDK 64-Bit Server VM (16.0.2+7-67, mixed mode, tiered, compressed oops, compressed class ptrs, g1 gc, windows-amd64)
# Problematic frame:
# C [nvoglv64.dll+0x8507b0]
#
# No core dump will be written. Minidumps are not enabled by default on client versions of Windows
#
# If you would like to submit a bug report, please visit:
# https://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
--------------- S U M M A R Y ------------
Command Line: -Dfile.encoding=Cp1252 -XX:+ShowCodeDetailsInExceptionMessages br.com.renanlima.git.main
--------------- T H R E A D ---------------
Current thread (0x000001ae5e0ce780): JavaThread "main" [_thread_in_native, id=7260, stack(0x0000007d29000000,0x0000007d29100000)]
Stack: [0x0000007d29000000,0x0000007d29100000], sp=0x0000007d290ff350, free space=1020k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [nvoglv64.dll+0x8507b0]
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j org.lwjgl.opengl.GL11C.nglDrawElements(IIIJ)V+0
j org.lwjgl.opengl.GL11C.glDrawElements(IIIJ)V+4
j org.lwjgl.opengl.GL11.glDrawElements(IIIJ)V+4
j br.com.renanlima.render.Render.render(Ljava/util/Map;)V+84
j br.com.renanlima.render.Master.renderEntity()V+8
j br.com.renanlima.git.main.main([Ljava/lang/String;)V+254
v ~StubRoutines::call_stub
siginfo: EXCEPTION_ACCESS_VIOLATION (0xc0000005), reading address 0x0000000000000000
...我的问题是:在这种新的渲染方法中,我做错了什么?除了ThinMatrix的教程之外,我还查阅了其他教程,他们看到所有教程都以类似的方式完成。
所以,使用的调试器,我发现了两件事:1--由于某种原因,"transformationMatrix“加载的方式不同,尽管这两种方法是相同的,它们得到的参数也是相同的。
这是使用"createModel()“方法的矩阵变量,该方法可以工作
还有这个是使用优化方法的矩阵变量,是不起作用的变量
这似乎是唯一发生这种情况的矩阵/顶点,但我可能忽略了一些东西。
我想我已经确定了坠机的具体部位。当运行"glDrawElements“方法时。

更具体地说,关于方法的这一部分:

但是在调用该方法之前,似乎没有一个变量是错误的。同样,我可能忽略了一些东西,但是在"findNative()“部分有一个sh*的变量按钮,所以我会更好地研究它。
编辑1.2:解决了transformationMatrix错误。这是因为"changeRot(0,3,0)“被提前调用。但我仍然找不出为什么"glDrawElements“的事故会发生。有人能帮我吗?如果这个问题令人困惑,请告诉我,这样我就能更好地解释它。
发布于 2021-12-28 02:07:53
所以,在处理了大学和工作方面的问题后,我终于回到了这段代码中,我终于可以纠正我的错误了。向尼克·克拉克大喊大叫,因为它对与瓦奥相关的缓冲区发表了评论。
这个问题似乎是因为这一行代码而发生的。
glDrawElements(GL_TRIANGLES, model.createModel().getVertexCount(), GL_UNSIGNED_INT, 0);特别是在"model.createModel()“部分。它创建了另一个干净的网格,没有与其VAO相关的缓冲区。旧方法之所以有效,是因为我直接从网格对象调用“顶点计数”(实际上是索引计数,并将其命名错误),如下所示:
MeshLoader mesh = model.createModel();
...
glDrawElements(GL_TRIANGLES, mesh.getVertexCount(), GL_UNSIGNED_INT, 0);因此,为了修复错误,我将这两个方法合并到一个新的方法中:
//Optimized method
public void render(Map<ModelLoader, List<EntityLoader>> entities) {
for(ModelLoader model:entities.keySet()) {
MeshLoader mesh = model.createModel();
glBindVertexArray(mesh.getVaoId());
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
shader.setUniformFloat("shineDamper", model.getShineDamper());
shader.setUniformFloat("reflectivity", model.getReflectivity());
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, model.getTexture());
glUniform1i(glGetUniformLocation(shader.getID(), "texture"), 0);
List<EntityLoader> batch = entities.get(model);
for(EntityLoader entity : batch) {
prepareEntity(entity);
glDrawElements(GL_TRIANGLES, mesh.getVertexCount(), GL_UNSIGNED_INT, 0);
}
mesh.cleanUp();
}
}现在,我可以以理论上优化的方式呈现对象。
//main class
List<EntityLoader> allIcos = new ArrayList<EntityLoader>();
allIcos.add(new EntityLoader(squareModel, new Vector3f(0,0,-5),0,0,0,1));
allIcos.add(new EntityLoader(squareModel, new Vector3f(0,5,-5),0,0,0,1));
allIcos.add(new EntityLoader(squareModel, new Vector3f(0,-5,-5),0,0,0,1));
...
render.render(light, camera);
for(EntityLoader Ico : allIcos) {
render.processEntity(Ico);
}
render.renderEntity();

我将尝试优化和清理这段代码,但现在它将是如何工作的。请随时纠正这个答案中的任何命名/术语错误,这主要是因为我对英语和Java术语的理解都很差。
https://stackoverflow.com/questions/69654576
复制相似问题