00001
00002 #include "ABuffer.h"
00003
00004
00005
00006
00007 ABuffer::ABuffer(int w,int h,int subpixels)
00008 {
00009 SS_ASSERT(w > 0);
00010 SS_ASSERT(h > 0);
00011 SS_ASSERT(subpixels > 0);
00012
00013 m_width = w;
00014 m_height = h;
00015 m_subpixels = subpixels;
00016 m_oofsubpixels = 1.0f / (float)subpixels;
00017
00018 m_firstFragments = new int[w*h*subpixels];
00019 m_fragmentsAllocated = 4*w*h*subpixels;
00020 m_fragments.resize(m_fragmentsAllocated);
00021
00022 m_sortBuffer.resize(100);
00023
00024 clear();
00025 }
00026
00027
00028
00029
00030 ABuffer::~ABuffer(void)
00031 {
00032 if( m_firstFragments )
00033 {
00034 delete[] m_firstFragments;
00035 }
00036 m_firstFragments = NULL;
00037 m_width = 0;
00038 m_height = 0;
00039 m_subpixels = 0;
00040 }
00041
00042
00043
00044
00045 void ABuffer::clear(void)
00046 {
00047 memset(m_firstFragments,-1,sizeof(int)*m_width*m_height*m_subpixels);
00048
00049 m_firstFreeFragment = 0;
00050 m_averageFragmentsPerPixel = 0;
00051 }
00052
00053
00054
00055
00056 void ABuffer::appendFragment(int x, int y, int subpixel, const ABuffer::Fragment &f)
00057 {
00058 SS_ASSERT(x>=0&&x<m_width);
00059 SS_ASSERT(y>=0&&y<m_height);
00060 SS_ASSERT(subpixel>=0&&subpixel<m_subpixels);
00061
00062 int &stub = m_firstFragments[(y*m_width+x)*m_subpixels+subpixel];
00063
00064
00065 if(m_firstFreeFragment == m_fragmentsAllocated)
00066 {
00067 svPrint("abuffer fragment resize: %d => %d\n",m_fragmentsAllocated,m_fragmentsAllocated*2);
00068 m_fragmentsAllocated *= 2;
00069 m_fragments.resize(m_fragmentsAllocated);
00070 }
00071 int newf = m_firstFreeFragment++;
00072 m_fragments[newf] = f;
00073 m_fragments[newf].nextFragment = stub;
00074 stub = newf;
00075 }
00076
00077
00078
00079
00080 void ABuffer::collapseToFrameBuffer (Color* frameBuffer, const Vector4 &background, bool zrange, float zthreshold)
00081 {
00082 int totalFragments = 0;
00083 int totalPixels = 0;
00084
00085 for(int y=0;y<m_height;y++)
00086 for(int x=0;x<m_width;x++)
00087 {
00088 Vector4 pixelcolor(0,0,0,0);
00089
00090 for(int j=0;j<m_subpixels;++j)
00091 {
00092 unsigned int coverageMask = 0;
00093 Vector4 subpixelcolor(0,0,0,0);
00094
00095
00096 int fragmentCount = 0;
00097 int fragmentIndex = m_firstFragments[(y*m_width+x)*m_subpixels+j];
00098 while(fragmentIndex != -1)
00099 {
00100 if( fragmentCount >= m_sortBuffer.size() )
00101 {
00102 svPrint("abuffer sortbuffer resize: %d => %d\n",m_sortBuffer.size(),m_sortBuffer.size()*2);
00103 m_sortBuffer.resize( fragmentCount * 2 );
00104 }
00105 m_sortBuffer[fragmentCount] = &m_fragments[fragmentIndex];
00106 fragmentIndex = m_fragments[fragmentIndex].nextFragment;
00107 fragmentCount++;
00108 }
00109
00110 for(int i=0;i<fragmentCount-1;i++)
00111 {
00112 for(int k=i+1;k<fragmentCount;k++)
00113 {
00114 if( (zrange && (m_sortBuffer[i]->zmin > m_sortBuffer[k]->zmin)) ||
00115 (!zrange && (m_sortBuffer[i]->z > m_sortBuffer[k]->z)) )
00116 {
00117 swap( m_sortBuffer[i], m_sortBuffer[k]);
00118 }
00119 }
00120 }
00121 if( fragmentCount )
00122 {
00123 totalFragments += fragmentCount;
00124 totalPixels++;
00125 }
00126
00127
00128 int i = 0;
00129 while(i < fragmentCount)
00130 {
00131 const Fragment *f1 = m_sortBuffer[i];
00132 i++;
00133
00134 float surfaceweight = f1->weight;
00135 Vector4 surfacecolor;
00136 f1->color.toVector4( surfacecolor );
00137 surfacecolor *= surfaceweight;
00138
00139
00140 if( !zrange )
00141 {
00142
00143 float prevz = f1->z;
00144 while(i < fragmentCount)
00145 {
00146 const Fragment *f2 = m_sortBuffer[i];
00147
00148 if( f2->dotSign != f1->dotSign ) break;
00149 if( f2->z > prevz + zthreshold ) break;
00150
00151 surfacecolor += f2->color.toVector4() * f2->weight;
00152 surfaceweight += f2->weight;
00153
00154 prevz = f2->z;
00155 i++;
00156 f1 = f2;
00157 }
00158 }
00159 else
00160 {
00161
00162 float zmax = f1->zmax;
00163 while(i < fragmentCount)
00164 {
00165 const Fragment *f2 = m_sortBuffer[i];
00166
00167 if( f2->dotSign != f1->dotSign ) break;
00168 if( f2->zmin > zmax ) break;
00169 if( f2->zmax > zmax ) zmax = f2->zmax;
00170
00171 surfacecolor += f2->color.toVector4() * f2->weight;
00172 surfaceweight += f2->weight;
00173
00174 i++;
00175 f1 = f2;
00176 }
00177 }
00178
00179 surfacecolor *= 1.0f/surfaceweight;
00180
00181 if( surfacecolor.w >= 0.999f )
00182 {
00183 surfacecolor.w = 1.0f;
00184 coverageMask = 1;
00185 }
00186
00187 subpixelcolor += surfacecolor * (1.0f - subpixelcolor.w);
00188
00189 if( coverageMask )
00190 break;
00191 }
00192
00193
00194 if( !coverageMask )
00195 subpixelcolor += background * (1.0f - subpixelcolor.w);
00196 pixelcolor += subpixelcolor;
00197 }
00198
00199 const float oofsubpixels = 1.0f / (float)m_subpixels;
00200 pixelcolor *= oofsubpixels;
00201 frameBuffer[y*m_width + x] = pixelcolor;
00202 }
00203
00204 m_averageFragmentsPerPixel = (float)totalFragments / (float)totalPixels;
00205 }
00206
00207
00208