Trying to render something, don't work.

Started by MySLF, December 12, 2015, 11:22:39

Previous topic - Next topic

MySLF

Hey,

At first, english is not my native language, so please excuse the mistakes :)

Im working on a 2D render engine using software rendering for a few month. Now I thought it would be cool to do some stuff in openGL. So I want to use LWJGL because I use Java a lot, at home and university.

So i looked for a few references and some basic open GL stuff and reviewed some tutorial and example code. I cam up with a really simple Programm (at least i thought that) which should render a nice little window with a small quad ( or 2 triangles as quad) in it. But.. it won't work. No errors, the window come up and the clearColour is displayed. but the quad wont show up.
Now im looking for some hints, heres my code:
btw.: I work on a mac, but tried it on windows and linux too.. same result :(

import java.nio.FloatBuffer;
import org.lwjgl.BufferUtils;
import static org.lwjgl.glfw.GLFW.*;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL11;
import static org.lwjgl.opengl.GL11.glClearColor;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL32;
import org.lwjgl.opengl.GLCapabilities;
import static org.lwjgl.system.MemoryUtil.NULL;

public class Game {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

        System.setProperty("org.lwjgl.librarypath", "/Users/xxxcxxx/libs/lwjgl/native");//load the natives 

        Game game = new Game();
        game.run();

    }
    private boolean isRunning = false;
    int width = 800, height = 600;
    long window;

    public void init() {
        if (glfwInit() != GL11.GL_TRUE) {
            return;
        }

        glfwDefaultWindowHints(); 
        glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); 
        glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); 

        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
        glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL11.GL_TRUE);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);

        window = glfwCreateWindow(width, height, "Test", NULL, NULL);

        if (window == NULL) {
            return;
        }

        GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
        glfwSetWindowPos(window, (vidmode.width() - width) / 2, (vidmode.height() - height) / 2);

        glfwMakeContextCurrent(window);
        glfwShowWindow(window);

        GLCapabilities createCapabilities = GL.createCapabilities();
        GL.setCapabilities(createCapabilities);
        glClearColor(1.0f, 0.0f, 0.0f, 1.0f);

        isRunning = true;
    }

    int CreateShader(int shadertype, String shaderString) {
        int shader = GL20.glCreateShader(shadertype);
        GL20.glShaderSource(shader, shaderString);
        GL20.glCompileShader(shader);
        int status = GL20.glGetShaderi(shader, GL20.GL_COMPILE_STATUS);
        if (status == GL11.GL_FALSE) {

            String error = GL20.glGetShaderInfoLog(shader);

            String ShaderTypeString = null;
            switch (shadertype) {
                case GL20.GL_VERTEX_SHADER:
                    ShaderTypeString = "vertex";
                    break;
                case GL32.GL_GEOMETRY_SHADER:
                    ShaderTypeString = "geometry";
                    break;
                case GL20.GL_FRAGMENT_SHADER:
                    ShaderTypeString = "fragment";
                    break;
            }

            System.err.println("Compile failure in " + ShaderTypeString + " shader:\n" + error);
        }
        return shader;
    }

    public int createShaderProgramme(int[] shaders) {
        int program = GL20.glCreateProgram();
        for (int i = 0; i < shaders.length; i++) {
            GL20.glAttachShader(program, shaders[i]);
        }
        GL20.glLinkProgram(program);

        int status = GL20.glGetShaderi(program, GL20.GL_LINK_STATUS);
        if (status == GL11.GL_FALSE) {
            String error = GL20.glGetProgramInfoLog(program);
            System.err.println("Linker failure: " + error);
        }
        for (int i = 0; i < shaders.length; i++) {
            GL20.glDetachShader(program, shaders[i]);
        }
        return program;
    }

    public int createShaderProgramme(int[] shadertypes, String[] shaders) {
        int[] shaderids = new int[shaders.length];
        for (int i = 0; i < shaderids.length; i++) {
            shaderids[i] = CreateShader(shadertypes[i], shaders[i]);
        }
        return createShaderProgramme(shaderids);
    }

    public void run() {
        init();

////////////////Prepare the Data////////////////
        float[] data = new float[]{
            -0.5f, -0.5f,
            -0.5f, 0.5f,
            0.5f, -0.5f,
            0.5f, 0.5f,
            -0.5f, 0.5f,
            0.5f, -0.5f,};
        FloatBuffer DataBuffer = BufferUtils.createFloatBuffer(data.length);//position at 0.
        DataBuffer.put(data);

        DataBuffer.flip();


        int buffer = GL15.glGenBuffers();
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, buffer);
        GL15.glBufferData(GL15.GL_ARRAY_BUFFER, DataBuffer, GL15.GL_STATIC_DRAW);
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);

        String vert
                = "#version 330 core                               \n"
                + "in vec2 position;                           \n"
                + "void main(){                                \n"
                + "    gl_Position= vec4(position, 0.0f, 1.0f);    \n"
                + "}                                           \n";
        String frag
                = "#version 330 core                                \n"
                + "out vec4 out_color;                         \n"
                + "void main(){                                \n"
                + "    out_color= vec4(0.0f, 1.0f, 1.0f, 1.0f);        \n"
                + "}                                           \n";
        int shader = createShaderProgramme(new int[]{
            GL20.GL_VERTEX_SHADER, GL20.GL_FRAGMENT_SHADER
        }, new String[]{
            vert, frag
        });


        while (isRunning) {
            GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);

            GL20.glUseProgram(shader);

            GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, buffer);
            GL20.glBindAttribLocation(shader, 0, "position");
            GL20.glEnableVertexAttribArray(0);
            
            GL20.glVertexAttribPointer(0, 2, GL11.GL_FLOAT, false, 0, 0);
            GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, 6);

            GL20.glDisableVertexAttribArray(0);
            GL20.glUseProgram(0);

            glfwSwapBuffers(window);

            glfwPollEvents();
            if (glfwWindowShouldClose(window) == GL11.GL_TRUE) {
                isRunning = false;
            }
        }
    }
}


Thank you!

Kai

Starting with the core profile in OpenGL 3.2 you need to have a Vertex Array Object bound when invoking a draw call.
A simple working solution would be to put the following line after your call to `glClearColor`:
GL30.glBindVertexArray(GL30.glGenVertexArrays());

Also invoking a draw call would have generated a INVALID_OPERATION 1282 error with your current code, which glGetError() should have reported after the draw call.
Also to spot errors without polluting your code with lots of glGetError() calls, you can install a debug callback to be notified, like so:
// As field somewhere in your class:
Closure debugProc;

// After GL.createCapabilities():
debugProc = GLUtil.setupDebugMessageCallback();


EDIT: Just by the way:
There is also another small issue with your code: Your repeated call to glBindAttribLocation in your render loop has no effect. You should call glBindAttribLocation once before linking the shader program in order to set the vertex attribute index for the named attribute/in in the vertex shader.
Very likely you will however still see the rectangle being rendered since likely the "position" attribute will be allocated to 0 implicitly when linking. That is however not guaranteed.

spasi

Also set:

glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);


otherwise the debug callback might not produce any output.

MySLF

Yeah this was easy^^ Thank you for the quick answer!

At the moment i can't figure out why my other code isn't running (Not the one in the opening post), but I will try to understand it!