summaryrefslogtreecommitdiffstats
path: root/dev/a5-artrender/edge_mesh.h
blob: 5120d0b60141273972d4b59777b61b4f5cb020ff (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/** CSci-4611 Assignment 5:  Art Render
 */

#ifndef EDGE_MESH_H
#define EDGE_MESH_H

#include <mingfx.h>
using namespace mingfx;

#include <vector>


/** This special kind of mesh stores two triangles that form a quadralateral
 along each edge of an existing mesh.  The quad initially has a width=0, but
 when rendered, two of the vertices are extended along the surfaces normal
 direction, which creates a "fin" that can be drawn as a thick border.  This
 can be used to create a silhouette edge renderer if the shader only extends
 the edges that lie along a silhouette of the mesh.
 */
class EdgeMesh {
public:
    EdgeMesh();
    virtual ~EdgeMesh();

    /// Creates two triangles along each edge of the mesh passed in.
    void CreateFromMesh(const Mesh &mesh);

    /// Saves the mesh data to the GPU - must be called with InitOpenGL or Draw.
    void UpdateGPUMemory();
    
    /// Num vertices in the edge mesh
    int num_vertices() const;
    
    /// Num triangles in the edge mesh
    int num_triangles() const;
    
    /// Access to vertex position by vertex number
    Point3 vertex(int vertexID) const;

    /// Access to vertex normal by vertex number
    Vector3 normal(int vertexID) const;

    /// Access to vertex color by vertex number
    Color color(int vertexID) const;

    /// Access to vertex texture coords by vertex number
    Point2 tex_coords(int textureUnit, int vertexID) const;
    

    /// Draws the mesh assuming a shader has already been bound.
    void Draw();
    
private:
    
    // Some routines and variables are needed internally to construct the edge
    // mesh from a regular mesh.
    
    typedef std::map<std::pair<int,int>,int> EdgeMap;
    EdgeMap edgeMap;

    void addEdge(std::vector<Point3> *vertices,
                 std::vector<Vector3> *normals,
                 std::vector<Vector3> *leftNormals,
                 std::vector<Vector3> *rightNormals,
                 std::vector< std::vector<unsigned int> > *triangles,
                 const Mesh &mesh, int v0, int v1, Vector3 n);

    std::vector<float> verts_;          // vertex positions
    std::vector<float> norms_;          // normals
    std::vector<unsigned int> indices_; // indices
    std::vector<float> leftNorms_;      // normals of adjacent triangles
    std::vector<float> rightNorms_;

    GLuint vertexBuffer_;
    GLuint vertexArray_;
    GLuint elementBuffer_;

    bool gpuDirty_;
};

#endif