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 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: // No shading R3BeginPolygon(); R3LoadPoint(v[0]->Position()); R3LoadPoint(v[1]->Position()); R3LoadPoint(v[2]->Position()); R3EndPolygon(); break; 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_VERTEX_COLORS_DRAW_FLAG: // Color interpolation R3BeginPolygon(); RNLoadRgb(v[0]->Color()); R3LoadPoint(v[0]->Position()); RNLoadRgb(v[1]->Color()); R3LoadPoint(v[1]->Position()); RNLoadRgb(v[2]->Color()); 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 color if (flags[R3_VERTEX_COLORS_DRAW_FLAG]) { RNLoadRgb(v[i]->Color()); } // 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; } }