git fetch origin git checkout -b project2 origin/master git push -u private project2The above commands assume that the default class code is on the origin remote, and your personal remote is named private. Furthermore, your working directory must be clean (no uncommitted changes to files under version control), before checking out a new branch. If this is not the case, add and commit you changes locally before switching to a project2 branch.
Once you and your partner have pushed the project2 branches, you can each checkout a shared2 branch to follow your partner's changes
git fetch partner git checkout -b shared2 partner/project2Note you should not merge into either the master, shared, or shared2 branches as you will later be unable to push your changes. Make sure you are on either the working or project2 branch before merging.
Later, once we get this pattern down, we can delete old local shared or project branches and just reuse the name shared to refer to our partner's current project. But I am waiting to do this until I verify that your submitted project1 correctly.
The mypanelopengl class is pretty much the same too, except I have added, but not used, a Triangle* object tri. An initial goal is to finish the implementation of the Triangle class so that we could replace the current VBO, and vertices, and glDrawArrays call in mypanelopengl with tri->draw(shaderProgram);. Once we can draw one triangle this way, we can create lists of triangles, circles, rectangles, and other Drawable things and draw them all in the PaintGL method by looping over this list.
Each class above should inherit from the Drawable base class. Multiple inheritance is supported in C++ if you want a richer class hierarchy, but this is not required.
Each class must have a void move(GLfloat dx, GLfloat dy) method that translates the object by an amount dx in the horizontal direction and dy in the vertical direction. In our OpenGL context, a positive dx/dy should move the shape right/up, respectively.
Each class must have a copy constructor that can create a copy or clone of a given object. The cloned copy should initially have the same geometry and color, but can later be moved independently of the original object. Triangles can only clone other Triangles. It does not make sense to have a copy constructor for Triangles that accept Circles.
Additional geometries (points, polygons, ellipses) may be added, or you can add additional features (line thickness, outline color, etc.) if you would like.
Next, follow the outline in Triangle::draw to implement the drawing of the triangle. Once you think you have it working, modify mypanelopengl.cpp to draw the triangle tri instead of the default triangle. Once you are sure you are drawing tri correctly, you can remove code in mypanelopengl related to createVBOs, destroyVBOs, vboVertices, numVertices and vertices.
Instead of using tri, create a QList<Drawable*> list to store multiple drawable things. Test that you can draw two Triangles by looping through this list
Implement and test the move and copy constructor Triangle methods. Use the write method (instead of allocate) in the QGLBuffer class to implement the move method.
Add other shapes. Note you will need to update the CMakeLists.txt file to include/compile the new files. Don't forget to add new files to version control with git add
Read the documentation for glDrawArrays. You probably don't want to use GL_TRIANGLES as the first option for all shapes. See also page 58-60 in the text.
Add one feature at a time and go back and test. Lather, rinse, repeat until all features are implemented.
If you program dynamically allocates memory (it probably should) using new, be sure to free the memory by calling delete in the appropriate place.
If a class dynamically allocates memory, be sure to write an appropriate destructor.
I did this by creating helper functions in a geomfun.h and geomfun.cpp. My geomfun.h has the following form.
#ifndef _GEOMFUN_H #define _GEOMFUN_H #include <QtOpenGL> typedef QVector2D vec2; typedef QVector3D vec3; typedef QVector4D vec4; namespace cs40{ /* return true if p1 is left of line from p2 to p3 */ bool leftOf(const vec2& p1, const vec2& p2, const vec2& p3); } //namespace #endif //GEOMFUN_HThe QVector3D class can automatically upcast QVector2D objects, and there is a static method QVector3D::crossProduct
x=xc+r*cos(t) y=yc+r*sin(t)For (axis-aligned) ellipses, instead of one radius, there are two semi-major axes lengths denoted a and b in the horizontal and vertical directions. It is often convenient to specify an ellipse by opposite corners of the rectangle bounding the ellipse. Computing the semi-major axes and the parametric form of an ellipse are left as an optional exercise.