Basic openGL 3.2 Setup with lwjgl - Object not rendered

纵饮孤独 提交于 2020-01-07 03:04:07

问题


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+.

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();
    }

}

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


回答1:


Don't be desperate, amaridev.

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

  • 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

  • debug your application step by step

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

  • 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);

like here, no matrices and a simple

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

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

    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

  • start fetching color

  • enable again texturing and start fetching texture coordinates again

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



来源:https://stackoverflow.com/questions/38020841/basic-opengl-3-2-setup-with-lwjgl-object-not-rendered

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!