/* * hemirenderer.C : tool class to render data defined on the * hemisphere. */ #include #include "hemirenderer.H" #include "vector.h" #include "color.h" #include "render.h" #include "renderhook.h" // Constructor : nr. of steps in phi and theta CHemisphereRenderer::CHemisphereRenderer() { m_phiSteps = m_thetaSteps = 0; m_renderData = NULL; m_renderEnabled = false; } CHemisphereRenderer::~CHemisphereRenderer(void) { if(m_renderData != NULL) { EnableRendering(false); delete[] m_renderData; m_renderData = NULL; } } // AcquireData fills in the data on the hemisphere. // The callback is called for every phi and theta value. void CHemisphereRenderer::Initialize(int Nphi, int Ntheta, VECTOR center, COORDSYS *coordsys, CHRAcquireCallback cb, void *cbData) { VECTOR vec; RGB col; double curPhi, curTheta, dist; int t,p, index; // Copy parameters m_center = center; m_coordsys = *coordsys; // Allocate enough room for the data if((Nphi != m_phiSteps) || (Ntheta != m_thetaSteps)) { // different resolution if(m_renderData != NULL) { delete[] m_renderData; m_renderData = NULL; } m_phiSteps = Nphi; m_thetaSteps = Ntheta; m_deltaPhi = 2.0 * M_PI / m_phiSteps; m_deltaTheta = 0.5 * M_PI / m_thetaSteps; } if(m_renderData == NULL) { m_renderData = new CHRVertexData[m_phiSteps * (m_thetaSteps - 1)]; } // Now fill the data array curTheta = M_PI / 2.0; // theta = 0 -> Z-axis = top of hemisphere index = 0; for(t = 0; t < m_thetaSteps - 1; t++) { curPhi = 0.0; for(p = 0; p < m_phiSteps; p++) { // Calculate WC vector SphericalCoordToVector(&m_coordsys, &curPhi, &curTheta, &vec); cb(&vec, &m_coordsys, curPhi, curTheta, cbData, &col, &dist); VECTORADDSCALED(m_center, dist, vec, m_renderData[index].point); VECTORCOPY(vec, m_renderData[index].normal); m_renderData[index].rgb = col; curPhi += m_deltaPhi; index++; } curTheta -= m_deltaTheta; } // Now fill in the top of the hemisphere curPhi = 0; curTheta = 0; SphericalCoordToVector(&m_coordsys, &curPhi, &curTheta, &vec); cb(&vec, &m_coordsys, curPhi, curTheta, cbData, &col, &dist); VECTORADDSCALED(m_center, dist, vec, m_top.point); VECTORCOPY(vec, m_top.normal); m_top.rgb = col; } // Render : renders the hemispherical data void CHemisphereRenderer::Render(void) { int t,p, index1, index2; if(m_renderData == NULL) return; index1 = 0; // First row index2 = m_phiSteps; // Second row for(t = 0; t < m_thetaSteps - 2; t++) { // Start a new triangle strip RenderBeginTriangleStrip(); for(p = 0; p < m_phiSteps; p++) { RenderNextTrianglePoint(&m_renderData[index2].point, &m_renderData[index2].rgb); RenderNextTrianglePoint(&m_renderData[index1].point, &m_renderData[index1].rgb); index1++; index2++; } // Send first points again to close strip RenderNextTrianglePoint(&m_renderData[index1].point, &m_renderData[index1].rgb); RenderNextTrianglePoint(&m_renderData[index1 - m_phiSteps].point, &m_renderData[index1 - m_phiSteps].rgb); // End triangle strip RenderEndTriangleStrip(); } // Now render the top of the hemisphere // Start a new triangle strip RenderBeginTriangleStrip(); for(p = 0; p < m_phiSteps; p++) { RenderNextTrianglePoint(&m_top.point, &m_top.rgb); RenderNextTrianglePoint(&m_renderData[index1].point, &m_renderData[index1].rgb); index1++; } // Send first points again to close strip RenderNextTrianglePoint(&m_top.point, &m_top.rgb); RenderNextTrianglePoint(&m_renderData[index1 - m_phiSteps].point, &m_renderData[index1 - m_phiSteps].rgb); // End triangle strip RenderEndTriangleStrip(); } // Callback needed for the render hook static void RenderHemisphereHook(void *data) { CHemisphereRenderer *hr = (CHemisphereRenderer *)data; hr->Render(); } void CHemisphereRenderer::EnableRendering(bool flag) { if(flag) { if(!m_renderEnabled) { AddRenderHook(RenderHemisphereHook, this); } } else { if(m_renderEnabled) { RemoveRenderHook(RenderHemisphereHook, this); } } m_renderEnabled = flag; }