Blender V2.61 - r43446
|
00001 00004 // 00005 #include <iostream> 00006 00007 #include "RAS_ListRasterizer.h" 00008 00009 #ifdef WIN32 00010 #include <windows.h> 00011 #endif // WIN32 00012 00013 #include "GL/glew.h" 00014 00015 #include "RAS_MaterialBucket.h" 00016 #include "RAS_TexVert.h" 00017 #include "MT_assert.h" 00018 00019 //#if defined(DEBUG) 00020 //#ifdef WIN32 00021 //#define spit(x) std::cout << x << std::endl; 00022 //#endif //WIN32 00023 //#else 00024 #define spit(x) 00025 //#endif 00026 00027 RAS_ListSlot::RAS_ListSlot(RAS_ListRasterizer* rasty) 00028 : KX_ListSlot(), 00029 m_list(0), 00030 m_flag(LIST_MODIFY|LIST_CREATE), 00031 m_matnr(0), 00032 m_rasty(rasty) 00033 { 00034 } 00035 00036 int RAS_ListSlot::Release() 00037 { 00038 if (--m_refcount > 0) 00039 return m_refcount; 00040 m_rasty->RemoveListSlot(this); 00041 delete this; 00042 return 0; 00043 } 00044 00045 RAS_ListSlot::~RAS_ListSlot() 00046 { 00047 RemoveList(); 00048 } 00049 00050 00051 void RAS_ListSlot::RemoveList() 00052 { 00053 if(m_list != 0) { 00054 spit("Releasing display list (" << m_list << ")"); 00055 glDeleteLists((GLuint)m_list, 1); 00056 m_list =0; 00057 } 00058 } 00059 00060 void RAS_ListSlot::DrawList() 00061 { 00062 if(m_flag &LIST_STREAM || m_flag& LIST_NOCREATE) { 00063 RemoveList(); 00064 return; 00065 } 00066 if(m_flag &LIST_MODIFY) { 00067 if(m_flag &LIST_CREATE) { 00068 if(m_list == 0) { 00069 m_list = (unsigned int)glGenLists(1); 00070 m_flag = m_flag &~ LIST_CREATE; 00071 spit("Created display list (" << m_list << ")"); 00072 } 00073 } 00074 if(m_list != 0) 00075 glNewList((GLuint)m_list, GL_COMPILE); 00076 00077 m_flag |= LIST_BEGIN; 00078 return; 00079 } 00080 glCallList(m_list); 00081 } 00082 00083 void RAS_ListSlot::EndList() 00084 { 00085 if(m_flag & LIST_BEGIN) { 00086 glEndList(); 00087 m_flag = m_flag &~(LIST_BEGIN|LIST_MODIFY); 00088 m_flag |= LIST_END; 00089 glCallList(m_list); 00090 } 00091 } 00092 00093 void RAS_ListSlot::SetModified(bool mod) 00094 { 00095 if(mod && !(m_flag & LIST_MODIFY)) { 00096 spit("Modifying list (" << m_list << ")"); 00097 m_flag = m_flag &~ LIST_END; 00098 m_flag |= LIST_STREAM; 00099 } 00100 } 00101 00102 bool RAS_ListSlot::End() 00103 { 00104 return (m_flag &LIST_END)!=0; 00105 } 00106 00107 00108 00109 RAS_ListRasterizer::RAS_ListRasterizer(RAS_ICanvas* canvas, bool useVertexArrays, bool lock) 00110 : RAS_VAOpenGLRasterizer(canvas, lock), 00111 mUseVertexArrays(useVertexArrays), 00112 mATI(false) 00113 { 00114 if (!strcmp((const char*)glGetString(GL_VENDOR), "ATI Technologies Inc.")) 00115 mATI = true; 00116 } 00117 00118 RAS_ListRasterizer::~RAS_ListRasterizer() 00119 { 00120 ReleaseAlloc(); 00121 } 00122 00123 void RAS_ListRasterizer::RemoveListSlot(RAS_ListSlot* list) 00124 { 00125 if (list->m_flag & LIST_DERIVEDMESH) { 00126 RAS_DerivedMeshLists::iterator it = mDerivedMeshLists.begin(); 00127 while(it != mDerivedMeshLists.end()) { 00128 RAS_ListSlots *slots = it->second; 00129 if (slots->size() > list->m_matnr && slots->at(list->m_matnr) == list) { 00130 (*slots)[list->m_matnr] = NULL; 00131 // check if all slots are NULL and if yes, delete the entry 00132 int i; 00133 for (i=slots->size(); i-- > 0; ) { 00134 if (slots->at(i) != NULL) 00135 break; 00136 } 00137 if (i < 0) { 00138 slots->clear(); 00139 delete slots; 00140 mDerivedMeshLists.erase(it); 00141 } 00142 break; 00143 } 00144 ++it; 00145 } 00146 } else { 00147 RAS_ArrayLists::iterator it = mArrayLists.begin(); 00148 while(it != mArrayLists.end()) { 00149 if (it->second == list) { 00150 mArrayLists.erase(it); 00151 break; 00152 } 00153 it++; 00154 } 00155 } 00156 } 00157 00158 RAS_ListSlot* RAS_ListRasterizer::FindOrAdd(RAS_MeshSlot& ms) 00159 { 00160 /* 00161 Keep a copy of constant lists submitted for rendering, 00162 this guards against (replicated)new...delete every frame, 00163 and we can reuse lists! 00164 :: sorted by mesh slot 00165 */ 00166 RAS_ListSlot* localSlot = (RAS_ListSlot*)ms.m_DisplayList; 00167 if(!localSlot) { 00168 if (ms.m_pDerivedMesh) { 00169 // that means that we draw based on derived mesh, a display list is possible 00170 // Note that we come here only for static derived mesh 00171 int matnr = ms.m_bucket->GetPolyMaterial()->GetMaterialIndex(); 00172 RAS_ListSlot* nullSlot = NULL; 00173 RAS_ListSlots *listVector; 00174 RAS_DerivedMeshLists::iterator it = mDerivedMeshLists.find(ms.m_pDerivedMesh); 00175 if(it == mDerivedMeshLists.end()) { 00176 listVector = new RAS_ListSlots(matnr+4, nullSlot); 00177 localSlot = new RAS_ListSlot(this); 00178 localSlot->m_flag |= LIST_DERIVEDMESH; 00179 localSlot->m_matnr = matnr; 00180 listVector->at(matnr) = localSlot; 00181 mDerivedMeshLists.insert(std::pair<DerivedMesh*, RAS_ListSlots*>(ms.m_pDerivedMesh, listVector)); 00182 } else { 00183 listVector = it->second; 00184 if (listVector->size() <= matnr) 00185 listVector->resize(matnr+4, nullSlot); 00186 if ((localSlot = listVector->at(matnr)) == NULL) { 00187 localSlot = new RAS_ListSlot(this); 00188 localSlot->m_flag |= LIST_DERIVEDMESH; 00189 localSlot->m_matnr = matnr; 00190 listVector->at(matnr) = localSlot; 00191 } else { 00192 localSlot->AddRef(); 00193 } 00194 } 00195 } else { 00196 RAS_ArrayLists::iterator it = mArrayLists.find(ms.m_displayArrays); 00197 if(it == mArrayLists.end()) { 00198 localSlot = new RAS_ListSlot(this); 00199 mArrayLists.insert(std::pair<RAS_DisplayArrayList, RAS_ListSlot*>(ms.m_displayArrays, localSlot)); 00200 } else { 00201 localSlot = static_cast<RAS_ListSlot*>(it->second->AddRef()); 00202 } 00203 } 00204 } 00205 MT_assert(localSlot); 00206 return localSlot; 00207 } 00208 00209 void RAS_ListRasterizer::ReleaseAlloc() 00210 { 00211 for(RAS_ArrayLists::iterator it = mArrayLists.begin();it != mArrayLists.end();++it) 00212 delete it->second; 00213 mArrayLists.clear(); 00214 for (RAS_DerivedMeshLists::iterator it = mDerivedMeshLists.begin();it != mDerivedMeshLists.end();++it) { 00215 RAS_ListSlots* slots = it->second; 00216 for (int i=slots->size(); i-- > 0; ) { 00217 RAS_ListSlot* slot = slots->at(i); 00218 if (slot) 00219 delete slot; 00220 } 00221 slots->clear(); 00222 delete slots; 00223 } 00224 mDerivedMeshLists.clear(); 00225 } 00226 00227 void RAS_ListRasterizer::IndexPrimitives(RAS_MeshSlot& ms) 00228 { 00229 RAS_ListSlot* localSlot =0; 00230 00231 if(ms.m_bDisplayList) { 00232 localSlot = FindOrAdd(ms); 00233 localSlot->DrawList(); 00234 if(localSlot->End()) { 00235 // save slot here too, needed for replicas and object using same mesh 00236 // => they have the same vertexarray but different mesh slot 00237 ms.m_DisplayList = localSlot; 00238 return; 00239 } 00240 } 00241 // derived mesh cannot use vertex array 00242 if (mUseVertexArrays && !ms.m_pDerivedMesh) 00243 RAS_VAOpenGLRasterizer::IndexPrimitives(ms); 00244 else 00245 RAS_OpenGLRasterizer::IndexPrimitives(ms); 00246 00247 if(ms.m_bDisplayList) { 00248 localSlot->EndList(); 00249 ms.m_DisplayList = localSlot; 00250 } 00251 } 00252 00253 00254 void RAS_ListRasterizer::IndexPrimitivesMulti(RAS_MeshSlot& ms) 00255 { 00256 RAS_ListSlot* localSlot =0; 00257 00258 if(ms.m_bDisplayList) { 00259 localSlot = FindOrAdd(ms); 00260 localSlot->DrawList(); 00261 00262 if(localSlot->End()) { 00263 // save slot here too, needed for replicas and object using same mesh 00264 // => they have the same vertexarray but different mesh slot 00265 ms.m_DisplayList = localSlot; 00266 return; 00267 } 00268 } 00269 00270 // workaround: note how we do not use vertex arrays for making display 00271 // lists, since glVertexAttribPointerARB doesn't seem to work correct 00272 // in display lists on ATI? either a bug in the driver or in Blender .. 00273 if (mUseVertexArrays && !mATI && !ms.m_pDerivedMesh) 00274 RAS_VAOpenGLRasterizer::IndexPrimitivesMulti(ms); 00275 else 00276 RAS_OpenGLRasterizer::IndexPrimitivesMulti(ms); 00277 00278 if(ms.m_bDisplayList) { 00279 localSlot->EndList(); 00280 ms.m_DisplayList = localSlot; 00281 } 00282 } 00283 00284 bool RAS_ListRasterizer::Init(void) 00285 { 00286 if (mUseVertexArrays) { 00287 return RAS_VAOpenGLRasterizer::Init(); 00288 } else { 00289 return RAS_OpenGLRasterizer::Init(); 00290 } 00291 } 00292 00293 void RAS_ListRasterizer::SetDrawingMode(int drawingmode) 00294 { 00295 if (mUseVertexArrays) { 00296 RAS_VAOpenGLRasterizer::SetDrawingMode(drawingmode); 00297 } else { 00298 RAS_OpenGLRasterizer::SetDrawingMode(drawingmode); 00299 } 00300 } 00301 00302 void RAS_ListRasterizer::Exit() 00303 { 00304 if (mUseVertexArrays) { 00305 RAS_VAOpenGLRasterizer::Exit(); 00306 } else { 00307 RAS_OpenGLRasterizer::Exit(); 00308 } 00309 } 00310 00311 // eof