void R3Span:: Draw(void) const { // Draw span R3BeginLine(); R3LoadPoint(Start()); R3LoadPoint(End()); R3EndLine(); }
void R3Line:: Draw(void) const { // Draw line R3BeginLine(); R3LoadPoint(Point()); R3LoadPoint(Point() + Vector()); R3EndLine(); }
void R3Ray:: Draw(void) const { // Draw ray R3BeginLine(); R3LoadPoint(Start()); R3LoadPoint((Start() + Vector())); R3EndLine(); }
void R3Vector:: Draw(void) const { // Draw vector from (0,0,0) R3BeginLine(); R3LoadPoint(R3zero_point); R3LoadPoint((R3zero_point + *this)); R3EndLine(); }
void R3Point:: Draw(void) const { // Draw point R3BeginLine(); R3LoadPoint(v); R3LoadPoint(v); R3EndLine(); }
static void DrawLights(R3Scene *scene) { // Draw all lights double radius = scene->BBox().DiagonalRadius(); for (int i = 0; i < scene->NLights(); i++) { R3Light *light = scene->Light(i); RNLoadRgb(light->Color()); if (light->ClassID() == R3DirectionalLight::CLASS_ID()) { R3DirectionalLight *directional_light = (R3DirectionalLight *) light; R3Vector direction = directional_light->Direction(); // Draw direction vector glBegin(GL_LINES); R3Point centroid = scene->BBox().Centroid(); R3LoadPoint(centroid - radius * direction); R3LoadPoint(centroid - 1.25 * radius * direction); glEnd(); } else if (light->ClassID() == R3PointLight::CLASS_ID()) { // Draw sphere at point light position R3PointLight *point_light = (R3PointLight *) light; R3Point position = point_light->Position(); // Draw sphere at light position R3Sphere(position, 0.1 * radius).Draw(); } else if (light->ClassID() == R3SpotLight::CLASS_ID()) { R3SpotLight *spot_light = (R3SpotLight *) light; R3Point position = spot_light->Position(); R3Vector direction = spot_light->Direction(); // Draw sphere at light position R3Sphere(position, 0.1 * radius).Draw(); // Draw direction vector glBegin(GL_LINES); R3LoadPoint(position); R3LoadPoint(position + 0.25 * radius * direction); glEnd(); } else { fprintf(stderr, "Unrecognized light type: %d\n", light->ClassID()); return; } } }
void R3Rectangle:: Draw(const R3DrawFlags draw_flags) const { // Check if box is empty if (IsEmpty()) return; /* Get texture coordinates */ static R2Point texcoords[4] = { R2Point(0.0, 0.0), R2Point(1.0, 0.0), R2Point(1.0, 1.0), R2Point(0.0, 1.0) }; /* Get box corner points */ R3Point corners[4]; corners[0] = Corner(RN_NN_QUADRANT); corners[1] = Corner(RN_PN_QUADRANT); corners[2] = Corner(RN_PP_QUADRANT); corners[3] = Corner(RN_NP_QUADRANT); // Draw surface if (draw_flags[R3_SURFACES_DRAW_FLAG]) { if (draw_flags[R3_SURFACE_NORMALS_DRAW_FLAG]) R3LoadNormal(Normal()); R3BeginPolygon(); for (int j = 0; j < 4; j++) { if (draw_flags[R3_VERTEX_TEXTURE_COORDS_DRAW_FLAG]) R3LoadTextureCoords(texcoords[j]); R3LoadPoint(corners[j]); } R3EndPolygon(); } // Draw edges if (draw_flags[R3_EDGES_DRAW_FLAG]) { R3BeginLoop(); for (int i = 0; i < 4; i++) R3LoadPoint(corners[i]); R3EndLoop(); } }
void R3Circle:: Draw(const R3DrawFlags draw_flags) const { // Push matrix (Zaxis -> ScaledNormal + OffsetToCenter) R4Matrix matrix = R4identity_matrix; matrix.Translate(center.Vector()); matrix.Rotate(R3posz_vector, Normal()); matrix.Push(); // Draw surface if (draw_flags[R3_SURFACES_DRAW_FLAG]) { // Load normal if (draw_flags[R3_SURFACE_NORMALS_DRAW_FLAG]) R3LoadNormal(R3posz_vector); // Draw circle in XY plane R3BeginPolygon(); for (int i = 0; i < R3circle_npoints; i++) { if (draw_flags[R3_VERTEX_TEXTURE_COORDS_DRAW_FLAG]) R3LoadTextureCoords(R3circle_texcoords[i]); R3LoadPoint(R3circle_points[i] * radius); } R3EndPolygon(); } // Draw edges if (draw_flags[R3_EDGES_DRAW_FLAG]) { R3BeginLoop(); for (int i = 0; i < R3circle_npoints; i++) R3LoadPoint(R3circle_points[i] * radius); R3EndLoop(); } // Pop matrix matrix.Pop(); }
void R3CoordSystem:: Draw(void) const { // Draw three rays R3BeginLine(); R3LoadPoint(Origin()); R3LoadPoint((Origin() + Axes().Axis(RN_X))); R3EndLine(); R3BeginLine(); R3LoadPoint(Origin()); R3LoadPoint((Origin() + Axes().Axis(RN_Y))); R3EndLine(); R3BeginLine(); R3LoadPoint(Origin()); R3LoadPoint((Origin() + Axes().Axis(RN_Z))); R3EndLine(); }
void R3Triad:: Draw(void) const { // Draw three rays R3BeginLine(); R3LoadPoint(R3zero_point); R3LoadPoint((R3zero_point + Axis(RN_X))); R3EndLine(); R3BeginLine(); R3LoadPoint(R3zero_point); R3LoadPoint((R3zero_point + Axis(RN_Y))); R3EndLine(); R3BeginLine(); R3LoadPoint(R3zero_point); R3LoadPoint((R3zero_point + Axis(RN_Z))); R3EndLine(); }
void R3OrientedBox:: Draw(const R3DrawFlags draw_flags) const { // Check if box is empty if (IsEmpty()) return; static R2Point texcoords[4] = { R2Point(0.0, 0.0), R2Point(1.0, 0.0), R2Point(1.0, 1.0), R2Point(0.0, 1.0) }; static int surface_paths[6][4] = { { 3, 0, 1, 2 }, { 4, 7, 6, 5 }, { 0, 4, 5, 1 }, { 7, 3, 2, 6 }, { 3, 7, 4, 0 }, { 1, 5, 6, 2 } }; static int outline_path[16] = { 0, 1, 2, 3, 0, 4, 5, 6, 7, 4, 5, 1, 2, 6, 7, 3 }; /* Get box corner points */ R3Point corners[8]; corners[0] = Corner(RN_NNN_OCTANT); corners[1] = Corner(RN_NNP_OCTANT); corners[2] = Corner(RN_NPP_OCTANT); corners[3] = Corner(RN_NPN_OCTANT); corners[4] = Corner(RN_PNN_OCTANT); corners[5] = Corner(RN_PNP_OCTANT); corners[6] = Corner(RN_PPP_OCTANT); corners[7] = Corner(RN_PPN_OCTANT); // Draw surface if (draw_flags[R3_SURFACES_DRAW_FLAG]) { for (int i = 0; i < 6; i++) { R3BeginPolygon(); if (draw_flags[R3_SURFACE_NORMALS_DRAW_FLAG]) { RNScalar sign = (i < 3) ? 1.0 : -1.0; R3LoadNormal(sign * Axis(i%3)); } for (int j = 0; j < 4; j++) { if (draw_flags[R3_VERTEX_TEXTURE_COORDS_DRAW_FLAG]) R3LoadTextureCoords(texcoords[j]); R3LoadPoint(corners[surface_paths[i][j]]); } R3EndPolygon(); } } // Draw edges if (draw_flags[R3_EDGES_DRAW_FLAG]) { R3BeginLine(); for (int i = 0; i < 16; i++) R3LoadPoint(corners[outline_path[i]]); R3EndLine(); } }
void R3Triangle:: Draw(const R3DrawFlags draw_flags) const { // Ammend draw flags R3DrawFlags flags(Flags() & draw_flags); RNDimension dim = 0, dim1 = 0, dim2 = 0; // Unroll flags/loops for efficiency switch (flags) { case R3_SURFACES_DRAW_FLAG | R3_SURFACE_NORMALS_DRAW_FLAG: // Flat shading R3BeginPolygon(); R3LoadNormal(Normal()); R3LoadPoint(v[0]->Position()); R3LoadPoint(v[1]->Position()); R3LoadPoint(v[2]->Position()); R3EndPolygon(); break; case R3_SURFACES_DRAW_FLAG | R3_SURFACE_NORMALS_DRAW_FLAG | R3_VERTEX_NORMALS_DRAW_FLAG: // Gouraud shading R3BeginPolygon(); R3LoadNormal(v[0]->Normal()); R3LoadPoint(v[0]->Position()); R3LoadNormal(v[1]->Normal()); R3LoadPoint(v[1]->Position()); R3LoadNormal(v[2]->Normal()); R3LoadPoint(v[2]->Position()); R3EndPolygon(); break; case R3_SURFACES_DRAW_FLAG | R3_SURFACE_NORMALS_DRAW_FLAG | R3_SURFACE_TEXTURE_DRAW_FLAG | R3_VERTEX_TEXTURE_COORDS_DRAW_FLAG: // Flat shading with texture coordinates R3BeginPolygon(); R3LoadNormal(Normal()); R3LoadTextureCoords(v[0]->TextureCoords()); R3LoadPoint(v[0]->Position()); R3LoadTextureCoords(v[1]->TextureCoords()); R3LoadPoint(v[1]->Position()); R3LoadTextureCoords(v[2]->TextureCoords()); R3LoadPoint(v[2]->Position()); R3EndPolygon(); break; case R3_SURFACES_DRAW_FLAG | R3_SURFACE_NORMALS_DRAW_FLAG | R3_SURFACE_TEXTURE_DRAW_FLAG: // Flat shading with texture coordinate generation dim = Normal().MaxDimension(); dim1 = (dim + 1) % 3; dim2 = (dim + 2) % 3; R3BeginPolygon(); R3LoadNormal(Normal()); R3LoadTextureCoords(v[0]->Position()[dim1], v[0]->Position()[dim2]); R3LoadPoint(v[0]->Position()); R3LoadTextureCoords(v[1]->Position()[dim1], v[1]->Position()[dim2]); R3LoadPoint(v[1]->Position()); R3LoadTextureCoords(v[2]->Position()[dim1], v[2]->Position()[dim2]); R3LoadPoint(v[2]->Position()); R3EndPolygon(); break; case R3_SURFACES_DRAW_FLAG | R3_SURFACE_NORMALS_DRAW_FLAG | R3_VERTEX_NORMALS_DRAW_FLAG | R3_SURFACE_TEXTURE_DRAW_FLAG | R3_VERTEX_TEXTURE_COORDS_DRAW_FLAG: // Gouraud shading with texture coordinates R3BeginPolygon(); R3LoadTextureCoords(v[0]->TextureCoords()); R3LoadNormal(v[0]->Normal()); R3LoadPoint(v[0]->Position()); R3LoadTextureCoords(v[1]->TextureCoords()); R3LoadNormal(v[1]->Normal()); R3LoadPoint(v[1]->Position()); R3LoadTextureCoords(v[2]->TextureCoords()); R3LoadNormal(v[2]->Normal()); R3LoadPoint(v[2]->Position()); R3EndPolygon(); break; case R3_SURFACES_DRAW_FLAG | R3_SURFACE_NORMALS_DRAW_FLAG | R3_VERTEX_NORMALS_DRAW_FLAG | R3_SURFACE_TEXTURE_DRAW_FLAG: // Gouraud shading with texture coordinate generation dim = Normal().MaxDimension(); dim1 = (dim + 1) % 3; dim2 = (dim + 2) % 3; R3BeginPolygon(); R3LoadTextureCoords(v[0]->Position()[dim1], v[0]->Position()[dim2]); R3LoadNormal(v[0]->Normal()); R3LoadPoint(v[0]->Position()); R3LoadTextureCoords(v[1]->Position()[dim1], v[1]->Position()[dim2]); R3LoadNormal(v[1]->Normal()); R3LoadPoint(v[1]->Position()); R3LoadTextureCoords(v[2]->Position()[dim1], v[2]->Position()[dim2]); R3LoadNormal(v[2]->Normal()); R3LoadPoint(v[2]->Position()); R3EndPolygon(); break; default: // Draw surface if (flags[R3_SURFACES_DRAW_FLAG]) { // Begin polygon R3BeginPolygon(); // Load polygon normal if ((flags[R3_SURFACE_NORMALS_DRAW_FLAG]) && (!flags[R3_VERTEX_NORMALS_DRAW_FLAG])) R3LoadNormal(Normal()); // Compute stuff for texture coordinates if ((draw_flags[R3_VERTEX_TEXTURE_COORDS_DRAW_FLAG]) && (!flags[R3_VERTEX_TEXTURE_COORDS_DRAW_FLAG])) { dim = Normal().MaxDimension(); dim1 = (dim + 1) % 3; dim2 = (dim + 2) % 3; } // Load triangle vertices for (int i = 0; i < 3; i++) { // Load vertex normal if (flags[R3_VERTEX_NORMALS_DRAW_FLAG]) R3LoadNormal(v[i]->normal); // Load vertex texture coordinates if (draw_flags[R3_VERTEX_TEXTURE_COORDS_DRAW_FLAG]) { if (flags[R3_VERTEX_TEXTURE_COORDS_DRAW_FLAG]) R3LoadTextureCoords(v[i]->TextureCoords()); else R3LoadTextureCoords(v[i]->Position()[dim1], v[i]->Position()[dim2]); } // Load vertex R3LoadPoint(v[i]->Position()); } // End polygon R3EndPolygon(); } // Draw edges if (flags[R3_EDGES_DRAW_FLAG]) { R3BeginLoop(); R3LoadPoint(v[0]->Position()); R3LoadPoint(v[1]->Position()); R3LoadPoint(v[2]->Position()); R3EndLoop(); } break; } }
void R3Model:: Draw(const R3DrawFlags draw_flags) const { // Check triangles if (!triangles) return; if (triangles->NTriangles() == 0) return; assert(triangle_materials.NEntries() == NTriangles()); assert(material_triangles.NEntries() == NMaterials()); // Draw model if (draw_flags != 0) { # if (DRAW_METHOD == DRAW_WITH_VBO) // Initialize material R3null_material.Draw(TRUE); // Create VBO if (opengl_id == 0) { // Load materials for (int i = 0; i < NMaterials(); i++) { R3Material *material = Material(i); material->Load(); } // Create VBO vertex array VBOVertex *vbo_vertices = new VBOVertex [ NVertices() ]; for (int i = 0; i < NVertices(); i++) { R3TriangleVertex *vertex = Vertex(i); const R3Point& position = vertex->Position(); const R2Point& texcoords = vertex->TextureCoords(); vbo_vertices[i].x = position.X(); vbo_vertices[i].y = position.Y(); vbo_vertices[i].z = position.Z(); vbo_vertices[i].s = texcoords.X(); vbo_vertices[i].t = texcoords.Y(); vertex->SetMark(i); } // Create VBO triangle array GLint *vbo_triangles = new GLint [ 3 * NTriangles() ]; for (int i = 0; i < NTriangles(); i++) { R3Triangle *triangle = Triangle(i); R3TriangleVertex *v0 = triangle->Vertex(0); R3TriangleVertex *v1 = triangle->Vertex(0); R3TriangleVertex *v2 = triangle->Vertex(0); vbo_triangles[3*i+0] = v0->Mark(); vbo_triangles[3*i+1] = v1->Mark(); vbo_triangles[3*i+2] = v2->Mark(); } // Create VBO for vertices glGenBuffers(1, &opengl_id); glBindBuffer(GL_ARRAY_BUFFER, opengl_id); glBufferData(GL_ARRAY_BUFFER, NVertices() * sizeof(VBOVertex), vbo_vertices, GL_STATIC_DRAW); // Create VBO for triangles glGenBuffers(1, &opengl_id2); glBindBuffer(GL_ARRAY_BUFFER, opengl_id2); glBufferData(GL_ELEMENT_BUFFER, 3 * NTriangles() * sizeof(GLuint), vbo_triangles, GL_STATIC_DRAW); // Delete VBO data delete [] vbo_vertices; delete [] vbo_triangles; } // Draw VBO glBindBuffer(GL_ARRAY_BUFFER, opengl_id); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(3, GL_FLOAT, sizeof(VBOVertex), (void *) 0); glTexCoordPointer(2, GL_FLOAT, sizeof(VBOVertex), (void *) (3 * sizeof(GLfloat))); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, opengl_id2); glDrawElements(GL_TRIANGLES, NTriangles(), GL_UNSIGNED_INT, (void *) 0); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); // Reset material R3null_material.Draw(TRUE); # elif (DRAW_METHOD == DRAW_WITH_DISPLAY_LIST) // Initialize material R3null_material.Draw(TRUE); // Create display list if (opengl_id == 0) { // Load materials for (int i = 0; i < NMaterials(); i++) { R3Material *material = Material(i); material->Load(); } // Begin display list R3Model *model = (R3Model *) this; model->opengl_id = glGenLists(1); glNewList(opengl_id, GL_COMPILE); // Draw triangles for (int i = 0; i < NMaterials(); i++) { R3Material *material = Material(i); material->Draw(); glBegin(GL_TRIANGLES); for (int j = 0; j < material_triangles[i]->NEntries(); j++) { R3Triangle *triangle = material_triangles[i]->Kth(j); R3LoadNormal(triangle->Normal()); R3TriangleVertex *v0 = triangle->Vertex(0); R3LoadTextureCoords(v0->TextureCoords()); R3LoadPoint(v0->Position()); R3TriangleVertex *v1 = triangle->Vertex(1); R3LoadTextureCoords(v1->TextureCoords()); R3LoadPoint(v1->Position()); R3TriangleVertex *v2 = triangle->Vertex(2); R3LoadTextureCoords(v2->TextureCoords()); R3LoadPoint(v2->Position()); } glEnd(); } // End display list glEndList(); } // Call display list glCallList(opengl_id); // Reset material R3null_material.Draw(TRUE); # else // Draw individual triangles for (int i = 0; i < NMaterials(); i++) { R3Material *material = Material(i); material->Draw(); glBegin(GL_TRIANGLES); for (int j = 0; j < material_triangles[i]->NEntries(); j++) { R3Triangle *triangle = material_triangles[i]->Kth(j); R3LoadNormal(triangle->Normal()); R3TriangleVertex *v0 = triangle->Vertex(0); R3LoadTextureCoords(v0->TextureCoords()); R3LoadPoint(v0->Position()); R3TriangleVertex *v1 = triangle->Vertex(1); R3LoadTextureCoords(v1->TextureCoords()); R3LoadPoint(v1->Position()); R3TriangleVertex *v2 = triangle->Vertex(2); R3LoadTextureCoords(v2->TextureCoords()); R3LoadPoint(v2->Position()); } glEnd(); } # endif } else { // Draw triangles glBegin(GL_TRIANGLES); for (int i = 0; i < NTriangles(); i++) { R3Triangle *triangle = Triangle(i); R3LoadNormal(triangle->Normal()); R3TriangleVertex *v0 = triangle->Vertex(0); R3LoadPoint(v0->Position()); R3TriangleVertex *v1 = triangle->Vertex(1); R3LoadPoint(v1->Position()); R3TriangleVertex *v2 = triangle->Vertex(2); R3LoadPoint(v2->Position()); } glEnd(); } }