Can't get to see my triangle when I use FloatUtil.makeLookAt

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Can't get to see my triangle when I use FloatUtil.makeLookAt

Kraft
Hi there.

I need your help because I have a bug in my sample code.

I'm trying to use modern openGL stuff (shaders).
so i went through jogamp demo code like this sample.

In my sample, I get quite easily to display a triangle and tranform it (scale, rotate, translate).
But as soon as I apply view and projection matrix, I can't get to see my triangle anymore.

I double-checked code with jogl demos and also drew my scene on paper to make sure I should see the triangle.

Obviously I am doing something wrong. But what ?
Can someone take a quick look at my Short, Self Contained, Correct (Compilable), Example ?
(Uncomment commented lines in display() to reproduce the issue)

Thanks in advance !

vs.glsl
#version 400
in vec3 position;
uniform mat4 modelToClipMatrix;
void main() {
    gl_Position = modelToClipMatrix * vec4(position, 1);
}

fs.glsl
#version 400
in vec3 interpolatedColor;
out vec4 outputColor;
void main() {
    outputColor = vec4(0, 1, 0, 1);
}

Demo.java
package demo;

import com.jogamp.newt.Display;
import com.jogamp.newt.NewtFactory;
import com.jogamp.newt.Screen;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.GL;
import static com.jogamp.opengl.GL.GL_NO_ERROR;
import static com.jogamp.opengl.GL2ES2.GL_FRAGMENT_SHADER;
import static com.jogamp.opengl.GL2ES2.GL_VERTEX_SHADER;
import com.jogamp.opengl.GL4;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLEventListener;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.math.FloatUtil;

import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.GLBuffers;
import com.jogamp.opengl.util.glsl.ShaderCode;
import com.jogamp.opengl.util.glsl.ShaderProgram;
import java.nio.FloatBuffer;

public class Demo implements GLEventListener
{
    private final String SHADERS_ROOT="/demo/shaders";
    
    public static GLWindow glWindow;
    public static Animator animator;
    
    private final int[] objects=new int[1];
    private int program, modelToClipMatrixUL;

    float g_vertex_buffer_data[]=
    {
        -1.0f, -1.0f, 0.0f,
        1.0f, -1.0f, 0.0f,
        0.0f, 1.0f, 0.0f
    };
    float[] cameraRaw=
    {
        4.0f, 3.0f, 3.0f,
        0.0f, 0.0f, 0.0f,
        0.0f, 1.0f, 0.0f
    };
    float[] translation=new float[16];
    float[] scale=new float[16];
    float[] rotation=new float[16];
    float[] model=new float[16];
    float[] view=new float[16];
    float[] projection=new float[16];
    float[] mvp=new float[16];
    float[] temp=new float[16];

    public static void main(String[] args)
    {
        // create window
        Display display=NewtFactory.createDisplay(null);
        Screen screen=NewtFactory.createScreen(display, 0);
        GLProfile glProfile=GLProfile.get(GLProfile.GL4);
        GLCapabilities glCapabilities=new GLCapabilities(glProfile);
        glCapabilities.setHardwareAccelerated(true);
        glWindow=GLWindow.create(screen, glCapabilities);
        glWindow.setSize(320, 240);
        glWindow.setVisible(true);

        Demo demo=new Demo();
        glWindow.addGLEventListener(demo);

        animator=new Animator(glWindow);
        animator.setRunAsFastAsPossible(true);
        animator.start();
    }

    public Demo()
    {
    }

    @Override
    public void init(GLAutoDrawable _drawable)
    {
        GL4 gl4=_drawable.getGL().getGL4();
        initVbo(gl4);
        initProgram(gl4);
        gl4.glEnable(GL4.GL_DEPTH_TEST);
    }

    @Override
    public void dispose(GLAutoDrawable _drawable)
    {
        GL4 gl4=_drawable.getGL().getGL4();
        gl4.glDeleteProgram(program);
        System.exit(0);
    }

    @Override
    public void display(GLAutoDrawable _drawable)
    {
        GL4 gl4=_drawable.getGL().getGL4();
        
        long time = System.currentTimeMillis();

        // create model matrix
        FloatUtil.makeScale(scale, true, 1.5f, 1.5f, 1.5f);
        FloatUtil.makeRotationEuler(rotation, 0, 0.0f, 0.0f, (time%1000)/1000.0f);
        FloatUtil.makeTranslation(translation, true, 0.0f, 0.0f, 0.0f);
        FloatUtil.makeIdentity(model);
        FloatUtil.multMatrix(model, scale);
        FloatUtil.multMatrix(model, rotation);
        FloatUtil.multMatrix(model, translation);

        // create mvp matrix
        FloatUtil.makeLookAt(view, 0, cameraRaw, 0, cameraRaw, 3, cameraRaw, 6, temp);
        FloatUtil.makePerspective(projection, 0, true, FloatUtil.HALF_PI, 4.0f/3.0f, 0.1f, 100.0f);
        FloatUtil.makeIdentity(mvp);
        FloatUtil.multMatrix(mvp, model);
//        FloatUtil.multMatrix(mvp, view); // uncomment both lines to trigger the issue
//        FloatUtil.multMatrix(mvp, projection); // uncomment both lines to trigger the issue

        gl4.glClearColor(0f, .33f, 0.66f, 1f);
        gl4.glClearDepthf(1f);
        gl4.glClear(GL4.GL_COLOR_BUFFER_BIT|GL4.GL_DEPTH_BUFFER_BIT);

        gl4.glUseProgram(program);
        gl4.glUniformMatrix4fv(modelToClipMatrixUL, 1, false, mvp, 0);

        // push buffer
        gl4.glBindBuffer(GL4.GL_ARRAY_BUFFER, objects[0]);
        gl4.glEnableVertexAttribArray(0);
        gl4.glVertexAttribPointer(0, 3, GL4.GL_FLOAT, false, 0, 0);

        // draw the triangle
        gl4.glDrawArrays(GL4.GL_TRIANGLES, 0, 3);
        gl4.glDisableVertexAttribArray(0);

        gl4.glUseProgram(0);
    }

    @Override
    public void reshape(GLAutoDrawable glad, int i, int i1, int i2, int i3)
    {
    }
    
    private void initVbo(GL4 gl4)
    {
        // create vertex coordinates VBO
        gl4.glGenBuffers(1, objects, 0);
        // The following commands will talk about our 'vertexbuffer' buffer
        gl4.glBindBuffer(GL4.GL_ARRAY_BUFFER, objects[0]);
        // Give our vertices to OpenGL.
        FloatBuffer vertexBuffer=GLBuffers.newDirectFloatBuffer(g_vertex_buffer_data);
        int size=g_vertex_buffer_data.length*GLBuffers.SIZEOF_FLOAT;
        gl4.glBufferData(GL4.GL_ARRAY_BUFFER, g_vertex_buffer_data.length*Float.BYTES,
                vertexBuffer, GL4.GL_STATIC_DRAW);
    }

    private void initProgram(GL4 gl4)
    {
        ShaderCode vertShader=ShaderCode.create(gl4, GL_VERTEX_SHADER, this.getClass(),
                SHADERS_ROOT, null, "vs", "glsl", null, true);
        ShaderCode fragShader=ShaderCode.create(gl4, GL_FRAGMENT_SHADER, this.getClass(),
                SHADERS_ROOT, null, "fs", "glsl", null, true);

        ShaderProgram shaderProgram=new ShaderProgram();
        shaderProgram.add(vertShader);
        shaderProgram.add(fragShader);

        shaderProgram.init(gl4);

        program=shaderProgram.program();

        gl4.glBindAttribLocation(program, 0, "position");
        gl4.glBindAttribLocation(program, 3 , "color");
        gl4.glBindFragDataLocation(program, 0, "outputColor");

        shaderProgram.link(gl4, System.out);
        modelToClipMatrixUL=gl4.glGetUniformLocation(program, "modelToClipMatrix");

        checkError(gl4);
    }

    protected void checkError(GL gl)
    {
        int error=gl.glGetError();
        if(error!=GL_NO_ERROR)
            throw new Error("OpenGL Error "+error);
    }
}
Reply | Threaded
Open this post in threaded view
|

Re: Can't get to see my triangle when I use FloatUtil.makeLookAt

Kraft
Still searching on the internet for clues on how to use FloatUtil.makeLookAt and FloatUtil.makePerspective to produce the mvp matrix that I send to the vertex shader.

According your experience, is this the right way to do ?

        // create model matrix
        FloatUtil.makeScale(scale, true, 1.5f, 1.5f, 1.5f);
        FloatUtil.makeRotationEuler(rotation, 0, 0.0f, 0.0f, (time%1000)/1000.0f);
        FloatUtil.makeTranslation(translation, true, 0.0f, 0.0f, 0.0f);
        FloatUtil.makeIdentity(model);
        FloatUtil.multMatrix(model, scale);
        FloatUtil.multMatrix(model, rotation);
        FloatUtil.multMatrix(model, translation);

        // create mvp matrix
        FloatUtil.makeLookAt(view, 0, cameraRaw, 0, cameraRaw, 3, cameraRaw, 6, temp);
        FloatUtil.makePerspective(projection, 0, true, FloatUtil.HALF_PI, 4.0f/3.0f, 0.1f, 100.0f);
        FloatUtil.makeIdentity(mvp);
        FloatUtil.multMatrix(mvp, model);
        FloatUtil.multMatrix(mvp, view);
        FloatUtil.multMatrix(mvp, projection);
        ...
        gl4.glUseProgram(program);
        gl4.glUniformMatrix4fv(modelToClipMatrixUL, 1, false, mvp, 0);
Reply | Threaded
Open this post in threaded view
|

Re: Can't get to see my triangle when I use FloatUtil.makeLookAt

Kraft
In reply to this post by Kraft
Ok i got it ! I finally get to see my sweet triangle !

My mistake was in the multiplication order.

Instead of
        FloatUtil.multMatrix(model, scale);
        FloatUtil.multMatrix(model, rotation);
        FloatUtil.multMatrix(model, translation);
        ...
        FloatUtil.multMatrix(mvp, model);
        FloatUtil.multMatrix(mvp, view);
        FloatUtil.multMatrix(mvp, projection);
I should have done
        FloatUtil.multMatrix(scale, model, model);
        FloatUtil.multMatrix(rotation, model, model);
        FloatUtil.multMatrix(translation, model, model);
        ...
        FloatUtil.multMatrix(model, mvp, mvp);
        FloatUtil.multMatrix(view, mvp, mvp);
        FloatUtil.multMatrix(projection, mvp, mvp);

Someone here to confirm and maybe explain ?
Reply | Threaded
Open this post in threaded view
|

Re: Can't get to see my triangle when I use FloatUtil.makeLookAt

gouessej
Administrator
I'll give it a look very soon...
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Can't get to see my triangle when I use FloatUtil.makeLookAt

elect
In reply to this post by Kraft
Kraft wrote
Ok i got it ! I finally get to see my sweet triangle !

My mistake was in the multiplication order.

Instead of
        FloatUtil.multMatrix(model, scale);
        FloatUtil.multMatrix(model, rotation);
        FloatUtil.multMatrix(model, translation);
        ...
        FloatUtil.multMatrix(mvp, model);
        FloatUtil.multMatrix(mvp, view);
        FloatUtil.multMatrix(mvp, projection);
I should have done
        FloatUtil.multMatrix(scale, model, model);
        FloatUtil.multMatrix(rotation, model, model);
        FloatUtil.multMatrix(translation, model, model);
        ...
        FloatUtil.multMatrix(model, mvp, mvp);
        FloatUtil.multMatrix(view, mvp, mvp);
        FloatUtil.multMatrix(projection, mvp, mvp);

Someone here to confirm and maybe explain ?
FloatUtil.multMatrix(A, B, C) is A*B=C

FloatUtil.multMatrix(A, B) is A*=B, or A = A*B

mvp must be equal to projection*view*model

you can optimize this code

        FloatUtil.multMatrix(model, mvp, mvp);
        FloatUtil.multMatrix(view, mvp, mvp);
        FloatUtil.multMatrix(projection, mvp, mvp);

to this

        FloatUtil.multMatrix(projection, view, mvp);
        FloatUtil.multMatrix(mvp, model);

You can avoid setting mvp to identity, since the first multMatrix will overwrite automatically whatever is in mvp
Reply | Threaded
Open this post in threaded view
|

Re: Can't get to see my triangle when I use FloatUtil.makeLookAt

Kraft
Ok great !
Thanks elect