使用lwjgl的基本openGL 3.2设置-未呈现对象 [英] Basic openGL 3.2 Setup with lwjgl - Object not rendered

查看:110
本文介绍了使用lwjgl的基本openGL 3.2设置-未呈现对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里有点绝望. 我正在尝试更新/重构用旧版opengl编写的现有代码,以利用opengl 3.2+版本的现代方式".

I am little bit desperate here. I am trying to update/refactor an existing code written in legacy opengl to make use of the "modern way" of opengl version 3.2+.

它是用lwjgl用Java编写的.我已经剥离了大多数功能以测试基本设置.目前对我而言,这实际上是关于使用从obj文件加载的顶点设置vbo并对其进行渲染.我的问题是,显示窗口保持为空.如果它能给我显示一些东西,我将感到非常高兴.

It is written in Java with lwjgl. I already stripped away most of the functionality to test the basic setup. For me at the moment it is really just about setting up the vbo with vertices loaded from an obj file and render it. My problem is, that the display window stays empty. If it would display me just something, I would be really happy.

也许你们可以帮助我我在这里缺少的东西.

Maybe you guys can help me what I am missing here.

public class Mobile {
    private final String texturePath = "../CGSS15Ex3MobileDS/dataEx3/Textures";
    private int
            width = 1200,
            height = 800,
            fps = 0,
            cameraDist = 2000,
            fillMode = GL_LINE,
            ticksPerSecond = 60,
            frameCounter = 0,
            vaoId,
            vboId,
            vboiID,
            pId,
            vsId,
            fsId;

    private long
            time,
            lastTime,
            lastFPS,
            lastKeySpace,
            frameCounterTime,
            avgTime = 0;

    private float
            dx = 0f,                   // mouse x distance
            dy = 0f,                   // mouse y distance
            diffTime = 0f,             // frame length
            mouseSensitivity = 0.5f,
            movementSpeed = 800.0f;     // move 10 units per second.

    private Fork fork;
    private CameraController camera;

    FloatBuffer kugelBuff, indexBuff;
    int kugelVertCount;

    static LinkedList<Integer> textureIDs = new LinkedList<>();


    public Mobile() {
        run();
    }

    private void run() {
        init();
        while (!exit()) {
            update();
            draw();
            updateFPS();
        }
        fini();
    }

    private void init() {
        // OpenGL Setup
        // create display
        try {

            PixelFormat pixelFormat = new PixelFormat();
            ContextAttribs contextAtrributes = new ContextAttribs(3, 2)
                    .withProfileCore(true)
                    .withForwardCompatible(true);

            Display.setDisplayMode(new DisplayMode(width, height));
            Display.setTitle("Mobile by Aaron Scheu");
            Display.create(pixelFormat, contextAtrributes);

            GL11.glClearColor(0.3f, 0.3f, 0.3f, 0f);
            GL11.glViewport(0, 0, width, height);
        } catch (LWJGLException e) {
            e.printStackTrace();
            System.exit(-1);
        }

        // setup scene //
        setupSphere();
        setupShaders();
        setupTex();

        // set Timer
        frameCounterTime = lastFPS = getTime();
        System.out.println("Start timer ...");
    }


    private void setupTex() {
        for (String file : getTextureFiles(texturePath)) {
            try {
                TextureReader.Texture texture = TextureReader.readTexture(file);
                textureIDs.add(glGenTextures());

                GL13.glActiveTexture(GL13.GL_TEXTURE0);
                GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureIDs.getLast());

                // Upload tex and generate mipmap for scaling
                glTexImage2D(
                        GL_TEXTURE_2D, 0, GL_RGB, texture.getWidth(), texture.getHeight(), 0,
                        GL_RGB, GL_UNSIGNED_BYTE, texture.getPixels()
                );
                GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);

                // Setup the ST coordinate system
                GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
                GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);

                // Setup what to do when the texture has to be scaled
                GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER,
                        GL11.GL_NEAREST);
                GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER,
                        GL11.GL_LINEAR_MIPMAP_LINEAR);


            } catch(IOException e) {
                System.out.println(e);
            }
        }
    }

    private void setupShaders() {
        // Load the vertex shader
        // vsId = GLDrawHelper.compileShader("../CGSS15Ex3MobileDS/dataEx3/Shader/phong_vertex.glsl", GL20.GL_VERTEX_SHADER);
        vsId = GLDrawHelper.compileShader("shader/vert_shader.glsl", GL20.GL_VERTEX_SHADER);
        // Load the fragment shader
        // fsId = GLDrawHelper.compileShader("../CGSS15Ex3MobileDS/dataEx3/Shader/phong_fragment.glsl", GL20.GL_FRAGMENT_SHADER);
        fsId = GLDrawHelper.compileShader("shader/frac_shader.glsl", GL20.GL_FRAGMENT_SHADER);

        // Create a new shader program that links both shaders
        pId = GL20.glCreateProgram();
        GL20.glAttachShader(pId, vsId);
        GL20.glAttachShader(pId, fsId);

        // Bind shader data to vbo attribute list
        // GL20.glBindAttribLocation(pId, 0, "vert_in");
        // GL20.glBindAttribLocation(pId, 1, "col_in");
        // GL20.glBindAttribLocation(pId, 2, "tex0_in");
        // GL20.glBindAttribLocation(pId, 3, "norm_in");

        // Test Shader
        GL20.glBindAttribLocation(pId, 0, "in_Position");
        GL20.glBindAttribLocation(pId, 1, "in_Color");
        GL20.glBindAttribLocation(pId, 2, "in_TextureCoord");

        GL20.glLinkProgram(pId);
        GL20.glValidateProgram(pId);
    }

    private void setupSphere() {
        Model sphere = null;

        try {
            sphere = OBJLoader.loadModel(new File("sphere.obj"));
        } catch (IOException e) {
            e.printStackTrace();
            Display.destroy();
            System.exit(1);
        }


        kugelBuff = GLDrawHelper.directFloatBuffer(sphere.getVVVNNNTT());
        indexBuff = GLDrawHelper.directFloatBuffer(sphere.getVertIndices());
        kugelVertCount = sphere.getVertCount();

        // Create a new Vertex Array Object in memory and select it (bind)
        vaoId = GL30.glGenVertexArrays();
        GL30.glBindVertexArray(vaoId);

        // Create a new Vertex Buffer Object in memory and select it (bind)
        vboId = GL15.glGenBuffers();
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboId);
        GL15.glBufferData(GL15.GL_ARRAY_BUFFER, kugelBuff, GL15.GL_STATIC_DRAW);

        // Attribute Pointer - list id, size, type, normalize, sprite, offset
        GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 8*4, 0); // Vertex
        // GL20.glVertexAttribPointer(1, 3, GL11.GL_FLOAT, false, 3, 0); // Color
        GL20.glVertexAttribPointer(2, 2, GL11.GL_FLOAT, false, 8*4, 6*4); // UV Tex
        // GL20.glVertexAttribPointer(3, 3, GL11.GL_FLOAT, false, 8*4, 3*4); // Normals


        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);

        // Deselect (bind to 0) the VAO
        GL30.glBindVertexArray(0);

        // Create a new VBO for the indices and select it (bind) - INDICES
        vboiID = GL15.glGenBuffers();
        GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboiID);
        GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indexBuff, GL15.GL_STATIC_DRAW);
        GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);

    }

    private void update() {
        // limit framerate
        // Display.sync(ticksPerSecond);

        // get time
        time = getTime();
        diffTime = (time - lastTime)/1000.0f;
        lastTime = time;

        // Distance mouse has been moved
        dx = Mouse.getDX();
        dy = Mouse.getDY();

        // toggle wireframe
        if(Keyboard.isKeyDown(Keyboard.KEY_SPACE)) {
            if (time - lastKeySpace > 100) {
                fillMode = fillMode == GL_FILL ? GL_LINE : GL_FILL;
                glPolygonMode(GL_FRONT_AND_BACK, fillMode);
            }
            lastKeySpace = time;
        }

        // mouse control
        camera.yaw(dx * mouseSensitivity);
        camera.pitch(dy * mouseSensitivity);

        // WASD control
        if (Keyboard.isKeyDown(Keyboard.KEY_W)) {
            camera.walkForward(movementSpeed * diffTime);
        }
        if (Keyboard.isKeyDown(Keyboard.KEY_S)) {
            camera.walkBackwards(movementSpeed * diffTime);
        }
        if (Keyboard.isKeyDown(Keyboard.KEY_A)) {
            camera.strafeLeft(movementSpeed * diffTime);
        }
        if (Keyboard.isKeyDown(Keyboard.KEY_D)) {
            camera.strafeRight(movementSpeed * diffTime);
        }

    }

    private boolean exit() {
        return Display.isCloseRequested() || Keyboard.isKeyDown(Keyboard.KEY_ESCAPE);
    }

    // runner is finished, clean up
    private void fini() {
        // glDisable(GL_DEPTH_BITS);

        // Delete all textures
        textureIDs.stream().forEach(GL11::glDeleteTextures);

        // Delete the shaders
        GL20.glUseProgram(0);
        GL20.glDetachShader(pId, vsId);
        GL20.glDetachShader(pId, fsId);

        GL20.glDeleteShader(vsId);
        GL20.glDeleteShader(fsId);
        GL20.glDeleteProgram(pId);

        // Select the VAO
        GL30.glBindVertexArray(vaoId);

        // Disable the VBO index from the VAO attributes list
        GL20.glDisableVertexAttribArray(0);
        GL20.glDisableVertexAttribArray(1);

        // Delete the vertex VBO
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
        GL15.glDeleteBuffers(vboId);

        // Delete the index VBO
        // GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
        // GL15.glDeleteBuffers(vboiId);

        // Delete the VAO
        GL30.glBindVertexArray(0);
        GL30.glDeleteVertexArrays(vaoId);

        Display.destroy();
    }

    private void updateFPS() {
        long time = getTime();
        String title;

        if (time - lastFPS > 1000) {
            // Display.setTitle("FPS: " + fps);
            title = "FPS: " + fps + "  ||  avg time per frame: " + (avgTime != 0 ? avgTime/1000f : "-/-") + " ms";
            Display.setTitle(title);
            fps = 0;
            lastFPS += 1000;
        }
        fps++;

        // Frame Count over 1000
        if (frameCounter == 1000) {
            avgTime = time - frameCounterTime;
            // System.out.println("Time for 1000 frames: " + avgTime + " ms.");
            frameCounter = 0;
            frameCounterTime = time;
        }
        frameCounter++;
    }

    private long getTime() {
        return (Sys.getTime() * 1000 / Sys.getTimerResolution());
    }

    private void draw() {

        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);

        GL20.glUseProgram(pId);

        // Bind the texture
        GL13.glActiveTexture(GL13.GL_TEXTURE0);
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureIDs.get(0));

        // Bind to the VAO that has all the information about the vertices
        GL30.glBindVertexArray(vaoId);
        GL20.glEnableVertexAttribArray(0);
        // GL20.glEnableVertexAttribArray(1);
        GL20.glEnableVertexAttribArray(2);
        GL20.glEnableVertexAttribArray(3);

        // Bind to the index VBO that has all the information about the order of the vertices
        GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboiID);

        // Draw the vertices
        GL11.glDrawElements(GL11.GL_TRIANGLES, kugelVertCount, GL11.GL_UNSIGNED_BYTE, 0);

        // Put everything back to default (deselect)
        GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
        GL20.glDisableVertexAttribArray(0);
        // GL20.glDisableVertexAttribArray(1);
        GL20.glDisableVertexAttribArray(2);
        GL20.glDisableVertexAttribArray(3);
        GL30.glBindVertexArray(0);

        GL20.glUseProgram(0);

        Display.update();
    }

    private static String[] getTextureFiles(String directory) {
        File pathfile = new File(directory);
        File[] files = pathfile.listFiles( (File dir, String name) ->
                name.endsWith(".jpg") || name.endsWith(".png")
        );
        return Arrays.stream(files).map(File::toString).toArray(String[]::new);
    }



    public static void main(String[] args) {
        new Mobile();
    }

}

对不起,代码混乱.也许这是更好的可读性. https://codeshare.io/1SEQK

Sorry for the code mess. Maybe this is better readable. https://codeshare.io/1SEQK

推荐答案

不要绝望,amaridev.

Don't be desperate, amaridev.

当您无法渲染任何内容时,通常有两种选择:

When you can't get nothing rendered you have in general two option:

  • 从一些基本且可行的东西开始(例如我的你好三角形,这简直是慢跑,但您可以非常轻松地将其移植到lwjgl),并在此基础上构建

  • start from something basic and working (like this hello triangle from mine, it's jogl but you can port it to lwjgl very easily) and build on top of that

逐步调试应用程序

如果您决定第二个,则可能要先禁用光照,禁用任何矩阵乘法和纹理处理:

In case you decide for the second one, you may want to disable first and lighting, any matrix multiplication and any texturing:

  • 通过测试是否看到设置的清晰颜色来检查渲染目标设置
  • 通过运行带有以下内容的硬编码顶点着色器来检查glViewport和片段着色器是否正常工作:
  • check your rendering targets setup by testing if you see the clear color you set
  • check if glViewport and the fragment shader work by running an hardcoded vertex shader with:

gl_Position = vec4(4.0 * float(gl_VertexID % 2) - 1.0, 4.0 * float(gl_VertexID / 2) - 1.0, 0.0, 1.0);

这里,没有矩阵,很简单

glDrawArrays(GL_TRIANGLES, 3, 0);

您可能还希望对颜色输出进行硬编码

you may want also to hardcode the color output

  • 通过将每个顶点属性依次输出到颜色片段着色器来检查是否正在读取有效的顶点属性

  • check if you are reading valid vertex attributes, by outputting each of them in turn to the color fragment shader

输出块 { vec4颜色 } outBlock; ... outBlock.color =位置;

out Block { vec4 color } outBlock; ... outBlock.color = position;

在块中 { vec4颜色; } inBlock; outputColor = inBlock.color;

in Block { vec4 color; } inBlock; outputColor = inBlock.color;

启用矩阵乘法并传递一个简单的硬编码三角形,以检查是否有任何矩阵(第一个项目,然后是视图,最后还有模型)是否按预期工作

enable matrix multiplication and pass a simple hardcoded triangle to check if any matrix (first proj, then view and finally also model) works as expected

开始从您的真实球体几何中获取

start fetching from your real sphere geometry

开始获取颜色

再次启用纹理并再次开始获取纹理坐标

enable again texturing and start fetching texture coordinates again

输出光和材质值以输出颜色,然后也将其重新启用

output light and materials values to output color and then enable them back as well

这篇关于使用lwjgl的基本openGL 3.2设置-未呈现对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆