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