首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java/LWJGL 3优化与渲染错误

Java/LWJGL 3优化与渲染错误
EN

Stack Overflow用户
提问于 2021-10-21 00:47:37
回答 1查看 174关注 0票数 0

我正在学习ThinMatrix关于OPENGL/LWJGL 3 3D游戏教程系列(在这里)的教程,尽管我的代码与他的有些不同,但效果很好。

我可以使用基本的LWJGL 3方法呈现像下面的图像那样的对象来呈现/阴影。基本上,在呈现类中使用此方法:

代码语言:javascript
复制
 //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();
    }

并在类中调用它,如下所示:

代码语言:javascript
复制
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类:

代码语言:javascript
复制
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类中使用新方法:

代码语言:javascript
复制
//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);
        
    }

最后,我调整了类,就像他在视频中所做的那样。

代码语言:javascript
复制
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();    
        }

它不仅不起作用,还买下了一个日志错误:

代码语言:javascript
复制
#
# 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“的事故会发生。有人能帮我吗?如果这个问题令人困惑,请告诉我,这样我就能更好地解释它。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-28 02:07:53

所以,在处理了大学和工作方面的问题后,我终于回到了这段代码中,我终于可以纠正我的错误了。向尼克·克拉克大喊大叫,因为它对与瓦奥相关的缓冲区发表了评论。

这个问题似乎是因为这一行代码而发生的。

代码语言:javascript
复制
 glDrawElements(GL_TRIANGLES, model.createModel().getVertexCount(), GL_UNSIGNED_INT, 0);

特别是在"model.createModel()“部分。它创建了另一个干净的网格,没有与其VAO相关的缓冲区。旧方法之所以有效,是因为我直接从网格对象调用“顶点计数”(实际上是索引计数,并将其命名错误),如下所示:

代码语言:javascript
复制
MeshLoader mesh = model.createModel();
...
glDrawElements(GL_TRIANGLES, mesh.getVertexCount(), GL_UNSIGNED_INT, 0);

因此,为了修复错误,我将这两个方法合并到一个新的方法中:

代码语言:javascript
复制
//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();
    }
    
}

现在,我可以以理论上优化的方式呈现对象。

代码语言:javascript
复制
//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术语的理解都很差。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69654576

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档