void __glcore_transform_vertices (GLcontext *g) { GLrenderstate *r = g->renderstate; GL_vertex *verts = r->verts; GL_procvert *procverts = r->procverts; int i; GL_float modelview[4][4]; GL_float projection[4][4]; GL_float texture[4][4]; GL_float composite[4][4]; GL_float invmodelview[4][4]; minit(modelview, g->trans.modelview[g->trans.modelviewdepth]); minit(projection, g->trans.projection[g->trans.projectiondepth]); minit(texture, g->trans.texture[g->trans.texturedepth]); mmult(composite, projection, modelview); minvtrans(invmodelview, modelview); for (i = 0; i < r->nverts; i++) { /* position */ mmultv(procverts[i].position, composite, verts[i].position); /* eye position */ mmultv(procverts[i].eyeposition, modelview, verts[i].position); /* color */ if (g->lighting.lighting) { GL_float objnormal[4]; GL_float normal[4]; /* object space normal */ vcopy(objnormal, verts[i].normal); objnormal[3] = 0.0f; if (verts[i].position[3] != 0.0f) { objnormal[3] = -vdot3(objnormal, verts[i].position); objnormal[3] /= verts[i].position[3]; } /* eye space normal */ mmultv(normal, invmodelview, objnormal); if (g->current.normalize) vnorm3(normal, normal); /* front color */ compute_lighting(g, procverts[i].frontcolor, procverts[i].eyeposition, normal, &verts[i].frontmaterial); /* back color */ if (g->lighting.lightmodeltwoside) { vscale(normal, normal, -1.0f); compute_lighting(g, procverts[i].backcolor, procverts[i].eyeposition, normal, &verts[i].backmaterial); } } else { vcopy(procverts[i].frontcolor, verts[i].color); vcopy(procverts[i].backcolor, verts[i].color); } vclamp(procverts[i].frontcolor, procverts[i].frontcolor, 0.0f, 1.0f); vclamp(procverts[i].backcolor, procverts[i].backcolor, 0.0f, 1.0f); /* no texture coordinate generation */ /* texture coords */ mmultv(procverts[i].texcoord, texture, verts[i].texcoord); } }
color scene_3D::cast_ray(line_3D line, double threshold, unsigned int recursion_depth) { unsigned int k, l, m; triangle_3D triangle; color final_color, helper_color, add_color; double depth, t; double *texture_coords_a, *texture_coords_b, *texture_coords_c; double barycentric_a, barycentric_b, barycentric_c; point_3D starting_point; point_3D normal,normal_a,normal_b,normal_c; point_3D reflection_vector, incoming_vector_reverse; material mat; int color_sum[3]; line.get_point(0,starting_point); depth = 99999999; final_color.red = this->background_color.red; final_color.green = this->background_color.green; final_color.blue = this->background_color.blue; for (k = 0; k < this->meshes.size(); k++) { if (!line.intersects_sphere(this->meshes[k]->bounding_sphere_center,this->meshes[k]->bounding_sphere_radius)) continue; for (l = 0; l < this->meshes[k]->triangle_indices.size(); l += 3) { triangle.a = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l]].position; triangle.b = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l + 1]].position; triangle.c = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l + 2]].position; texture_coords_a = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l]].texture_coords; texture_coords_b = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l + 1]].texture_coords; texture_coords_c = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l + 2]].texture_coords; if (line.intersects_triangle(triangle,barycentric_a,barycentric_b,barycentric_c,t)) { point_3D intersection; line.get_point(t,intersection); double distance = point_distance(starting_point,intersection); mat = this->meshes[k]->get_material(); if (distance < depth && distance > threshold) // depth test { depth = distance; normal_a = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l]].normal; normal_b = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l + 1]].normal; normal_c = this->meshes[k]->vertices[this->meshes[k]->triangle_indices[l + 2]].normal; normal.x = 0; normal.y = 0; normal.z = 0; normal.x = barycentric_a * normal_a.x + barycentric_b * normal_b.x + barycentric_c * normal_c.x; normal.y = barycentric_a * normal_a.y + barycentric_b * normal_b.y + barycentric_c * normal_c.y; normal.z = barycentric_a * normal_a.z + barycentric_b * normal_b.z + barycentric_c * normal_c.z; normalize(normal); // interpolation breaks normalization if (!this->meshes[k]->use_3D_texture && this->meshes[k]->get_texture() != 0) // 2d texture { double u,v; u = barycentric_a * texture_coords_a[0] + barycentric_b * texture_coords_b[0] + barycentric_c * texture_coords_c[0]; v = barycentric_a * texture_coords_a[1] + barycentric_b * texture_coords_b[1] + barycentric_c * texture_coords_c[1]; color_buffer_get_pixel(this->meshes[k]->get_texture(),u * this->meshes[k]->get_texture()->width,v * this->meshes[k]->get_texture()->height,&final_color.red,&final_color.green,&final_color.blue); } else if (this->meshes[k]->use_3D_texture && this->meshes[k]->get_texture_3D() != 0) // 3d texture { final_color = this->meshes[k]->get_texture_3D()->get_color(intersection.x,intersection.y,intersection.z); } else // mesh color { final_color.red = 255; final_color.green = 255; final_color.blue = 255; } helper_color = compute_lighting(intersection,mat,normal); final_color = multiply_colors(helper_color,final_color); if (recursion_depth != 0) { incoming_vector_reverse = line.get_vector_to_origin(); if (mat.reflection > 0) // reflection { color_sum[0] = 0; color_sum[1] = 0; color_sum[2] = 0; for (m = 0; m < this->reflection_rays; m++) { point_3D helper_point; reflection_vector = make_reflection_vector(normal,incoming_vector_reverse); reflection_vector.x *= -1; reflection_vector.y *= -1; reflection_vector.z *= -1; if (m > 0) // alter the ray slightly alter_vector(reflection_vector,this->reflection_range); helper_point.x = intersection.x + reflection_vector.x; helper_point.y = intersection.y + reflection_vector.y; helper_point.z = intersection.z + reflection_vector.z; line_3D reflection_line(intersection,helper_point); add_color = cast_ray(reflection_line,ERROR_OFFSET,recursion_depth - 1); color_sum[0] += add_color.red; color_sum[1] += add_color.green; color_sum[2] += add_color.blue; } add_color.red = color_sum[0] / this->reflection_rays; add_color.green = color_sum[1] / this->reflection_rays; add_color.blue = color_sum[2] / this->reflection_rays; final_color = interpolate_colors(final_color,add_color,mat.reflection); } if (mat.transparency > 0) // refraction { color_sum[0] = 0; color_sum[1] = 0; color_sum[2] = 0; for (m = 0; m < this->refraction_rays; m++) { point_3D helper_point; point_3D refraction_vector; refraction_vector = make_refraction_vector(normal,incoming_vector_reverse,mat.refractive_index); if (m > 0) // alter the ray slightly alter_vector(refraction_vector,this->refraction_range); helper_point.x = intersection.x + refraction_vector.x; helper_point.y = intersection.y + refraction_vector.y; helper_point.z = intersection.z + refraction_vector.z; line_3D refraction_line(intersection,helper_point); add_color = cast_ray(refraction_line,ERROR_OFFSET,recursion_depth - 1); color_sum[0] += add_color.red; color_sum[1] += add_color.green; color_sum[2] += add_color.blue; } add_color.red = color_sum[0] / this->refraction_rays; add_color.green = color_sum[1] / this->refraction_rays; add_color.blue = color_sum[2] / this->refraction_rays; final_color = interpolate_colors(final_color,add_color,mat.transparency); } } } } } } return final_color; }