⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hemicube.cpp

📁 The goal of this project is to explore the idea of point-based radiosity, which is a shooting radio
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*+-------------------------------------------------------------------
  Ben Landon
  CSCI E-235 
  
  Final Project

  HemiCube.cpp - Contains the implementation of the HemiCube class,
  including methods for performing the renderings from each of the
  five faces of the hemicube.  This class also manages the buffers
  that hold the flat and diffuse renderings. 

  Typically there is only one HemiCube object per program, although
  there is nothing that would prevent more of them.

*/

#include <stdio.h>
#include <math.h>
#include "HemiCube.hpp"
#include "Texture.hpp"
#include "gl_common.h"
#include "pgm_util.hpp"
#include "Map_of.hpp"


// Enumeration describing to refer to a particular
// side of the hemicube. 
enum HemiCubeSide
{
    Center,
    Left, 
    Bottom, 
    Right, 
    Top
};


/*+-------------------------------------------------------------------
  The HemiCube is 2.0 units on a side.
  
  The hemicube is responsible for managing the sets of renderings
  (depth, item, color, cosine texture).

  m_center_pixel_width and m_center_pixel_height are the dimensions of
  the center face of the hemicube.  The sides of the hemicube are
  m_side_pixel_width by m_side_pixel_height.

*/
HemiCube::HemiCube (void)
    : 
    m_center_pixel_width(32),
    m_center_pixel_height(32),
    m_side_pixel_width(32), 
    m_side_pixel_height(16),
    m_components_per_pixel(3),
    m_center_rc_buffer(NULL),
    m_left_rc_buffer(NULL),
    m_bottom_rc_buffer(NULL),
    m_right_rc_buffer(NULL),
    m_top_rc_buffer(NULL),
    m_center_cosine_texture(NULL),
    m_bottom_cosine_texture(NULL)
{
    // OpenGL must be enabled for this constructor to 
    // work properly since this creates textures. 
    
    this->load_cosine_image();
    
    size_t center_depth_buffer_size = 
	m_center_pixel_width * m_center_pixel_height;

    m_center_depth_buffer = 
	new float[center_depth_buffer_size];
    
    size_t side_depth_buffer_size = m_side_pixel_width * m_side_pixel_height;
    
    m_left_depth_buffer = 
	new float[side_depth_buffer_size];
    
    m_bottom_depth_buffer = 
	new float[side_depth_buffer_size];

    m_right_depth_buffer = 
	new float[side_depth_buffer_size];

    m_top_depth_buffer = 
	new float[side_depth_buffer_size];

    size_t center_rgb_buffer_size = 
	m_components_per_pixel * m_center_pixel_width * m_center_pixel_height;

    m_center_item_buffer = 
	new unsigned char [center_rgb_buffer_size];
	
    size_t side_rgb_buffer_size = 
	m_components_per_pixel * m_side_pixel_width * m_side_pixel_height;
    
    m_left_item_buffer = new unsigned char [side_rgb_buffer_size];
    m_bottom_item_buffer = new unsigned char [side_rgb_buffer_size];
    m_right_item_buffer = new unsigned char [side_rgb_buffer_size];
    m_top_item_buffer = new unsigned char [side_rgb_buffer_size];

    this->clear_item_buffers();      
    
    m_center_rc_buffer = new float[center_rgb_buffer_size];

    m_left_rc_buffer = new float [side_rgb_buffer_size];
    m_bottom_rc_buffer = new float [side_rgb_buffer_size];
    m_right_rc_buffer = new float [side_rgb_buffer_size];
    m_top_rc_buffer = new float [side_rgb_buffer_size];

    this->clear_rc_buffers();
}
 
   
/*+-------------------------------------------------------------------
  HemiCube destructor

  Delete all of the dynamically allocated buffers.  Also delete
  any textures created by the HemiCube object.

*/
HemiCube::~HemiCube ()
{
    if (m_center_item_buffer)
    {
	delete [] m_center_item_buffer;
	m_center_item_buffer = NULL;
    }
    
    if (m_left_item_buffer)
    {
	delete [] m_left_item_buffer;
	m_left_item_buffer = NULL;
    }

    if (m_bottom_item_buffer)
    {
	delete [] m_bottom_item_buffer;
	m_bottom_item_buffer = NULL;
    }
    
    if (m_right_item_buffer)
    {
	delete [] m_right_item_buffer;
	m_right_item_buffer = NULL;
    }
    
    if (m_top_item_buffer)
    {
	delete [] m_top_item_buffer;
	m_top_item_buffer = NULL;
    }
    
    if (m_center_depth_buffer)
    {
	delete [] m_center_depth_buffer;
	m_center_depth_buffer = NULL;
    }

    if (m_left_depth_buffer)
    {
	delete [] m_left_depth_buffer;
	m_left_depth_buffer = NULL;
    }
    
    if (m_bottom_depth_buffer)
    {
	delete [] m_bottom_depth_buffer;
	m_bottom_depth_buffer = NULL;
    }

    if (m_right_depth_buffer)
    {
	delete [] m_right_depth_buffer;
	m_right_depth_buffer = NULL;
    }
    
    if (m_top_depth_buffer)
    {
	delete [] m_top_depth_buffer;
	m_top_depth_buffer = NULL;
    }

    if (m_center_rc_buffer)
    {
	delete [] m_center_rc_buffer;
	m_center_rc_buffer = NULL;
    }

    if (m_left_rc_buffer)
    {
	delete [] m_left_rc_buffer;
	m_left_rc_buffer = NULL;
    }

    if (m_bottom_rc_buffer)
    {
	delete [] m_bottom_rc_buffer;
	m_bottom_rc_buffer = NULL;
    }

    if (m_right_rc_buffer)
    {
	delete [] m_right_rc_buffer;
	m_right_rc_buffer = NULL;
    }

    if (m_top_rc_buffer)
    {
	delete [] m_top_rc_buffer;
	m_top_rc_buffer = NULL;
    }

    if (m_pCenter_cos_map)
    {
        delete m_pCenter_cos_map;
        m_pCenter_cos_map = NULL;
    }
    
    if (m_pLeft_cos_map)
    {
        delete m_pLeft_cos_map;
        m_pLeft_cos_map = NULL;
    }
    
    if (m_pBottom_cos_map)
    {
        delete m_pBottom_cos_map;
        m_pBottom_cos_map = NULL;
    }

    if (m_pRight_cos_map)
    {
        delete m_pRight_cos_map;
        m_pRight_cos_map = NULL;
    }
    
    if (m_pTop_cos_map)
    {
        delete m_pTop_cos_map;
        m_pTop_cos_map = NULL;
    }
    
    if (m_center_cosine_texture)
    {
	delete m_center_cosine_texture;
	m_center_cosine_texture = NULL;
    }
    
    if (m_bottom_cosine_texture)
    {
	delete m_bottom_cosine_texture;
	m_bottom_cosine_texture = NULL;
    }
}


/*+-------------------------------------------------------------------
  HemiCube::load_cosine_image

  Get the cosine texture from a PGM file.  This is done
  once when the HemiCube is created. 

  If something goes wrong with loading cosine.pgm, this 
  method can throw a HemiCubeException.
  

*/
void HemiCube::load_cosine_image (void)
{
    unsigned char* data = NULL;
    unsigned int width, height, colorDepth;
    
    if (!read_pgm_file("cosine.pgm", &width, &height, &colorDepth, &data))
	throw HemiCubeException();
    
    // Go through the cosine image and populate some maps.
    // Read the cosine.pgm image into a Map_of<float>
    

    unsigned int counter = 0;
    Map_of<float> temp_gray_map(width, height);
    
    for (int j = 0; j < (int)height; j++)
    {
	for (int i = 0; i < (int)width; i++)
	{
	    temp_gray_map.set(float(data[counter++])/255.0f, i, j);
	}
    }

    // Now that the data from the texture is in the map.  
    // the array of uchars can be deleted.
    if (data)
    {
        delete [] data;
        data = NULL;
    }
    
    // Now create the 5 textures.
    for (unsigned int tex_index = 0; tex_index < 5; tex_index++)
    {
	unsigned int tex_width, tex_height, tex_x, tex_y;
	Map_of<float>* pMap = NULL;
	
	HemiCubeSide which_side = (HemiCubeSide)tex_index;

	switch (which_side)
	{
	case Center:
	    tex_width = width / 2;
	    tex_height = height / 2;
	    tex_x = width / 4;
	    tex_y = height / 4;
	    m_pCenter_cos_map = new Map_of<float>(tex_width, tex_height);
            pMap = m_pCenter_cos_map;
            break;

	case Left:
	    tex_width = width /4;
	    tex_height = height / 2;
	    tex_x = 0;
	    tex_y = height / 4;
            m_pLeft_cos_map = new Map_of<float>(tex_width, tex_height);
            pMap = m_pLeft_cos_map;
            break;

	case Bottom:
	    tex_width = width / 2;
	    tex_height = height / 4;
	    tex_x = width / 4;
	    tex_y = 0;
	    m_pBottom_cos_map = new Map_of<float>(tex_width, tex_height);
            pMap = m_pBottom_cos_map;
            break;
	    
	case Right:
	    tex_width = width /4;
	    tex_height = height / 2;
	    tex_x = 3 * (width / 4);
	    tex_y = (height / 4);
	    m_pRight_cos_map = new Map_of<float>(tex_width, tex_height);
            pMap = m_pRight_cos_map;
            break;
	    
	case Top:
	    tex_width = width /2;
	    tex_height = height / 4;
	    tex_x = width / 4;
	    tex_y = 3 * (height / 4);
            m_pTop_cos_map = new Map_of<float>(tex_width, tex_height);
            pMap = m_pTop_cos_map;
            break;
	}

	if (!pMap) 
	    throw HemiCubeException();

        for (int i = 0; i < (int)tex_width; i++)
	{
	    for (int j = 0; j < (int)tex_height; j++)
	    {
                float gray_val = temp_gray_map.get(i + tex_x, j + tex_y);
                pMap->set(gray_val, i, j);			  
	    }
	}
    }

    // Create the center and bottom grayscale textures 
    assert(m_pCenter_cos_map != NULL);
    assert(m_pBottom_cos_map != NULL);

    m_center_cosine_texture = new GrayscaleTexture(*m_pCenter_cos_map);
    m_bottom_cosine_texture = new GrayscaleTexture(*m_pBottom_cos_map);

}


/*+-------------------------------------------------------------------
  HemiCube::debug_draw_rc_buffer 
  
  This is a method for debugging the HemiCube class.  It just
  draws the buffer holding the center diffuse scene at the
  current raster position.

*/
void HemiCube::debug_draw_rc_buffer (void)
{
    glDrawPixels(m_center_pixel_width, 
		 m_center_pixel_height, 
		 GL_RGB, GL_FLOAT,
		 m_center_rc_buffer);
}


/*+-------------------------------------------------------------------
  HemiCube::debug_draw_item_buffer

  This is also a debugging tool.  It draws the item 
  buffer to the current raster position. The item buffer
  is the buffer that contains a rendering of the scene, 
  with flat shading and no lighting.  The item buffer is used

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -