wiki:project3
Last modified 5 years ago Last modified on 02/13/13 13:05:25

Getting pre-started on Project 3

You can work in your projects/02 directory, but edit code while in a project3 branch.

You will use a 4x4 matrix to represent the coordinate transform from screen/mouse coordinates to OpenGL GLSL clip coordinates. On the CPU/QT side, the matrix type is QMatrix4x4. On the GPU/GLSL the type is mat4.

To use a matrix transform in your vertex shader, follow the steps below.

shader mods

First modify your vertex shader vshader.glsl to take a uniform mat4 as input

#version 130

uniform mat4 mview;
in vec4 vPosition;

void main()
{
    vec4 pos = vPosition;
    pos.w=1.;
    gl_Position =  mview*pos;
}

The pos.w=1; line explicitly sets the last component of the four-tuple to 1., indicating that pos is a point.

setUniformValue

Next, add a private member variable QMatrix4x4 m_matrix; to your MyPanelOpenGL header file. Connect your matrix to the shader in paintGL()

shaderProgram->setUniformValue("mview", m_matrix);

Everything should compile and run at this point with no visible changes.

Quick Test

You can quickly test that your matrix is working by adding

m_matrix(0,0)=0.5;
m_matrix(1,1)=0.5;

ahead of the call to setUniformValue. The scene should shrink to half size. If this test works, you can remove the two scaling lines.

A real transformation

Recall that the real matrix transformation we want to convert from screen coordinates to clip coordinates is

2/w 0 0 -1
0 -2/h 0 1
0 0 1 0
0 0 0 1

The first and second columns will change whenever the GL window resizes.

In the MyPanelOpenGL constructor add

m_matrix.setColumn(3,QVector4D(-1,1,0,1)); 

In resizeGL(int w, int h) add

m_matrix.setColumn(0,QVector4D(2./w,0,0,0));
m_matrix.setColumn(1,QVector4D(0,-2./h,0,0));
updateGL();

At this point, all previous shapes declared will have their vertices premultiplied by m_matrix, likely resulting in nothing showing up. Add a new shape specified in screen coordinates and verify that this shape appears on the screen

mousePressEvent

To capture clicks from the user, add the method void mousePressEvent(QMouseEvent *event); to the list of protected methods in the MyPanelOpenGL header file. A sample implementation might start like this

void MyPanelOpenGL::mousePressEvent(QMouseEvent *event){
    vec2 click(event->posF().x(),event->posF().y());
    QVector4D worldPoint(click, 0, 1);
    QVector4D clipPoint=m_matrix*worldPoint;
    cout << clipPoint.toVector2D() << endl;
}

Verify that your mouse handler is working by clicking on points in the GL canvas. You should see the coordinate output of your clicks in clip coordinates. Does this match your expectations? If so, proceed with the rest of the lab.