📄 scene.cpp
字号:
unsigned int i = 0;
for (i = 0; i < num_triangles; i++)
{
SceneTriangle* element = m_scene_triangles.get(i);
element->draw_with_accumulation_texture();
}
GLenum err = glGetError();
}
/*+-------------------------------------------------------------------
Simple scene data. The following sets of data are used to construct
a simple scene object. The simple scene is the inside of a box.
There is no front, only a left, right, back, ceiling and floor.
Each side of the box is a square composed of two SceneTriangle
objects, one for the upper_left corner of the face, and one
for the lower_right side of face.
*/
float upper_left_tex_coords[] =
{
0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f
};
float lower_right_tex_coords[] =
{
1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f
};
// z = -5.0f
Point back_wall_upper_left[] = {
Point(-5.0f, 5.0f, -5.0f),
Point(-5.0f, -5.0f, -5.0f),
Point(5.0f, 5.0f, -5.0f)
};
Point back_wall_lower_right[] = {
Point(5.0f, 5.0f, -5.0f),
Point(-5.0f, -5.0f, -5.0f),
Point(5.0f, -5.0f, -5.0f)
};
// x = -5.0f
Point left_wall_upper_left[] = {
Point(-5.0f, 5.0f, 5.0f),
Point(-5.0f, -5.0f, 5.0f),
Point(-5.0f, 5.0f, -5.0f)
};
// x = -5.0f
Point left_wall_lower_right[] = {
Point(-5.0f, 5.0f, -5.0f),
Point(-5.0f, -5.0f, 5.0f),
Point(-5.0f, -5.0f, -5.0f)
};
// x = 5.0f
Point right_wall_upper_left[] = {
Point(5.0f, 5.0f, -5.0f),
Point(5.0f,-5.0f, -5.0f),
Point(5.0f, 5.0f, 5.0f)
};
Point right_wall_lower_right[] = {
Point(5.0f, 5.0f, 5.0f),
Point(5.0f, -5.0f, -5.0f),
Point(5.0f, -5.0f, 5.0f)
};
// y = -5.0f
Point floor_upper_left[] = {
Point(-5.0f, -5.0f, -5.0f),
Point(-5.0f, -5.0f, 5.0f),
Point(5.0f, -5.0f, -5.0f)
};
// y = -0.5
Point floor_lower_right[] = {
Point(5.0f, -5.0f, -5.0f),
Point(-5.0f, -5.0f, 5.0f),
Point(5.0f, -5.0f, 5.0f)
};
// y = + 5.0f
Point ceiling_upper_left[] = {
Point(-5.0f, 5.0f, 5.0f),
Point(-5.0f, 5.0f, -5.0f),
Point(5.0f, 5.0f, 5.0f)
};
Point ceiling_lower_right[] = {
Point( 5.0f, 5.0f, 5.0f),
Point(-5.0f, 5.0f, -5.0f),
Point( 5.0f, 5.0f, -5.0f)
};
/*+-------------------------------------------------------------------
Scene::load_simple_scene
Static method to load a simple scene and encapsulate it in the
returned Scene object.
This is a real hack, and this should be replaced with a
more general scene loader. Right now, many scene parameters
are set directly, where they can be computed.
*/
Scene* Scene::load_simple_scene (void)
{
Scene* scene = new Scene;
for (unsigned int index = 0; index < 10; index++)
{
Point* point_array = NULL;
float* texture_coords = NULL;
Color diffuse_color;
Vector normal;
Vector up(0.0f, 1.0f, 0.0f);
Point bbox_center;
float ortho_width = 10.0f;
float ortho_height = 10.0f;
switch(index)
{
case 0:
point_array = back_wall_upper_left;
texture_coords = upper_left_tex_coords;
diffuse_color = white;
normal.set (0.0f, 0.0f, 1.0f);
bbox_center.set(0.0f, 0.0f, -5.0f);
break;
case 1:
point_array = back_wall_lower_right;
texture_coords = lower_right_tex_coords;
diffuse_color = white;
normal.set (0.0f, 0.0f, 1.0f);
bbox_center.set(0.0f, 0.0f, -5.0f);
break;
case 2:
point_array = left_wall_upper_left;
texture_coords = upper_left_tex_coords;
diffuse_color = red;
normal.set(1.0f, 0.0f, 0.0f);
bbox_center.set(-5.0f, 0.0f, 0.0f);
break;
case 3:
point_array = left_wall_lower_right;
texture_coords = lower_right_tex_coords;
diffuse_color = red;
normal.set(1.0f, 0.0f, 0.0f);
bbox_center.set(-5.0f, 0.0f, 0.0f);
break;
case 4:
point_array = right_wall_upper_left;
texture_coords = upper_left_tex_coords;
diffuse_color = green;
normal.set(-1.0f, 0.0f, 0.0f);
bbox_center.set(5.0f, 0.0f, 0.0f);
break;
case 5:
point_array = right_wall_lower_right;
texture_coords = lower_right_tex_coords;
diffuse_color = green;
normal.set(-1.0f, 0.0f, 0.0f);
bbox_center.set(5.0f, 0.0f, 0.0f);
break;
case 6:
point_array = floor_upper_left;
texture_coords = upper_left_tex_coords;
diffuse_color = yellow;
normal.set(0.0f, 1.0f, 0.0f);
bbox_center.set(0.0f, -5.0f, 0.0f);
up.set(0.0f, 0.0f, -1.0f);
break;
case 7:
point_array = floor_lower_right;
texture_coords = lower_right_tex_coords;
diffuse_color = yellow;
normal.set(0.0f, 1.0f, 0.0f);
bbox_center.set(0.0f, -5.0f, 0.0f);
up.set(0.0f, 0.0f, -1.0f);
break;
case 8:
point_array = ceiling_upper_left;
texture_coords = upper_left_tex_coords;
diffuse_color = gray;
normal.set(0.0f, -1.0f, 0.0f);
bbox_center.set(0.0f, 5.0f, 0.0f);
up.set(0.0f, 0.0f, 1.0f);
break;
case 9:
point_array = ceiling_lower_right;
texture_coords = lower_right_tex_coords;
diffuse_color = gray;
normal.set(0.0f, -1.0f, 0.0f);
bbox_center.set(0.0f, 5.0f, 0.0f);
up.set(0.0f, 0.0f, 1.0f);
break;
}
SceneTriangle* triangle = new SceneTriangle(diffuse_color,
normal,
point_array,
3);
if (!triangle)
throw SceneException();
// left wall, lower right. This is such an egregious
// hack. Replace this with a scene loader ASAP.
if (index == 3)
{
triangle->init_light_source_in_patch(white,
0.5f,
0.3f,
0.2f,
0.2f);
}
triangle->m_accumulation_texture->tell_opengl();
triangle->m_emissive_texture->tell_opengl();
triangle->m_up = up;
triangle->m_bbox_center = bbox_center;
triangle->m_ortho_width = ortho_width;
triangle->m_ortho_height = ortho_height;
triangle->m_debug_id = index;
scene->m_scene_triangles.append(triangle);
memcpy(triangle->m_tex_coords, texture_coords, 6 * sizeof(float));
}
return scene;
}
/*+-------------------------------------------------------------------
Scene::get_brightest_texel
Returns the SceneTriangle with the brightest texel. It also
returns the texture coordinates (u, v) from the emissive texture
containing the brightest texel, and it returns the color of
the brightest texel.
*/
SceneTriangle* Scene::get_brightest_texel (Point& pt, Color& texel,
int& u, int& v) const
{
unsigned int num_scene_triangles = m_scene_triangles.num_elements();
if (num_scene_triangles == 0)
return NULL;
SceneTriangle* brightest_tri = NULL;
float brightest_tri_energy_density = 0.0f;
for (unsigned int index = 0; index < num_scene_triangles; index++)
{
SceneTriangle* triangle = m_scene_triangles.get(index);
float texture_energy_density =
triangle->get_emissive_texture_energy_density();
if ((brightest_tri == NULL) ||
(texture_energy_density > brightest_tri_energy_density))
{
brightest_tri_energy_density = texture_energy_density;
brightest_tri = triangle;
}
}
assert(brightest_tri != NULL);
brightest_tri->get_brightest_texel(pt, texel, u, v);
return brightest_tri;
}
/*+-------------------------------------------------------------------
Scene::rgb_to_index
Given an RGB triple, compute which Scene element
this refers to, and return it.
FIXME - This can be optimized with a table lookup.
Right now this does a linear search through the set of
triangles, which is sloooow.
*/
SceneTriangle* Scene::item_rgb_to_triangle (unsigned char r,
unsigned char g,
unsigned char b)
{
unsigned int index = 0;
index = SceneTriangle::item_rgb_to_id(r, g, b);
unsigned int num_scene_triangles = m_scene_triangles.num_elements();
if (num_scene_triangles == 0)
return NULL;
for (unsigned int tri_index = 0; tri_index < num_scene_triangles; tri_index++)
{
SceneTriangle* triangle = m_scene_triangles.get(tri_index);
if (triangle->id() == index)
{
return triangle;
}
}
return NULL;
}
/*+-------------------------------------------------------------------
Scene::clear_all_splats
Clear all reprojected points associated with each element
(SceneTriangle) of the scene.
*/
void Scene::clear_all_splats (void)
{
unsigned int num_scene_triangles = m_scene_triangles.num_elements();
if (num_scene_triangles == 0)
return;
for (unsigned int i = 0; i < num_scene_triangles; i++)
{
SceneTriangle* triangle = m_scene_triangles.get(i);
if (triangle)
triangle->clear_splats();
}
}
/*+-------------------------------------------------------------------
accumulate_all_splats
Go through all the triangles and accumulate the splats.
If use_gl_points is true, then the reprojected points are
rendered into the accumulation texture using GL_POINTS,
otherwise do the accumulation in software.
*/
void Scene::accumulate_all_splats (bool use_gl_points)
{
unsigned int num_scene_triangles = m_scene_triangles.num_elements();
if (num_scene_triangles == 0)
return;
for (unsigned int i = 0; i < num_scene_triangles; i++)
{
SceneTriangle* triangle = m_scene_triangles.get(i);
if (triangle)
triangle->accumulate_splats(use_gl_points);
}
}
/*+-------------------------------------------------------------------
Scene::examine_all_triangles
This is a debugging method which is often useful to
watch with a source debugger. It computes some information
about the emissive and accumulation texture which might
be useful to track where the reprojected points are going.
*/
void Scene::examine_all_triangles (void)
{
unsigned int num_scene_triangles = m_scene_triangles.num_elements();
if (num_scene_triangles == 0)
return;
for (unsigned int i = 0; i < num_scene_triangles; i++)
{
SceneTriangle* triangle = m_scene_triangles.get(i);
// Debugging code
float emissive_sum =
triangle->m_emissive_texture->get_texel_sum();
float accumulation_sum =
triangle->m_accumulation_texture->get_texel_sum();
}
}
/*+-------------------------------------------------------------------
Scene::reset_gl_textures
The accumulation texture and emissive textures for a SceneTriangle
object are maintained separately from OpenGL. This might
change in the future. When we want to render with these
textures, we have to tell the emissive and accumulation
textures to reset OpenGL's idea about their contents
(using glTexImage2D or something similar for mipmaps).
*/
void Scene::reset_gl_textures (void)
{
unsigned int num_scene_triangles = m_scene_triangles.num_elements();
if (num_scene_triangles == 0)
return;
for (unsigned int i = 0; i < num_scene_triangles; i++)
{
SceneTriangle* triangle = m_scene_triangles.get(i);
//triangle->m_accumulation_texture->normalize();
// triangle->m_emissive_texture->normalize();
triangle->m_emissive_texture->tell_opengl();
triangle->m_accumulation_texture->tell_opengl();
}
}
/*+-------------------------------------------------------------------
Scene::debug_draw_splats
This is a debugging method for drawing where the reprojected points
are going. This method simply goes through each of the scene
elements (SceneTriangle) and invokes the debug_draw_splats method on
it. See the comments in SceneTriangle::debug_draw_splats for more
information.
*/
void Scene::debug_draw_splats (void) const
{
unsigned int num_scene_triangles = m_scene_triangles.num_elements();
if (num_scene_triangles == 0)
return;
for (unsigned int i = 0; i < num_scene_triangles; i++)
{
SceneTriangle* triangle = m_scene_triangles.get(i);
triangle->debug_draw_splats();
}
}
/*+-------------------------------------------------------------------
Scene::draw_wireframe
This is a debugging method to see where the scene boundaries
are. See SceneTriangle::draw_wireframe for more information.
*/
void Scene::draw_wireframe (void) const
{
unsigned int num_scene_triangles = m_scene_triangles.num_elements();
for (unsigned int i = 0; i < num_scene_triangles; i++)
{
SceneTriangle* triangle = m_scene_triangles.get(i);
triangle->draw_wireframe();
}
}
/*+-------------------------------------------------------------------
Scene::debug_num_splats
Debugging method for calculating the total number of splats
in a scene that are waiting to be accumulated.
*/
int Scene::debug_num_splats (void) const
{
int result = 0;
unsigned int num_scene_triangles = m_scene_triangles.num_elements();
for (unsigned int i = 0; i < num_scene_triangles; i++)
{
SceneTriangle* triangle = m_scene_triangles.get(i);
result += triangle->debug_num_splats();
}
return result;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -