00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00022 #include "VMDDisplayList.h"
00023 #include "VMDApp.h"
00024 #include "Matrix4.h"
00025 #include "Inform.h"
00026
00027
00028
00029 #define ALLOC_ALIGNMENT 16
00030 #define ALLOC_ALIGNMASK (ALLOC_ALIGNMENT - 1)
00031
00032
00033
00034
00035
00036
00037 #define BASE_DISPLAYLIST_SIZE 64
00038
00039
00040
00041
00042
00043 #define GROWN_DISPLAYLIST_SIZE 16384
00044
00045 void *VMDDisplayList::operator new(size_t n) {
00046 return vmd_alloc(n);
00047 }
00048
00049 void VMDDisplayList::operator delete(void *p, size_t) {
00050 vmd_dealloc(p);
00051 }
00052
00053 VMDDisplayList::VMDDisplayList() {
00054 materialtag = 0;
00055 serial=0;
00056 cacheskip=0;
00057 pbc = PBC_NONE;
00058 npbc = 1;
00059 instanceset = INSTANCE_ALL;
00060 instances.clear();
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 listsize = 0;
00072 poolsize = 0;
00073 poolused = 0;
00074 pool = NULL;
00075 }
00076
00077 VMDDisplayList::~VMDDisplayList() {
00078 if (pool) vmd_dealloc(pool);
00079 }
00080
00081 void *VMDDisplayList::append(int code, long size) {
00082 unsigned long neededBytes = (sizeof(CommandHeader) + size + ALLOC_ALIGNMASK) & ~(ALLOC_ALIGNMASK);
00083 if (neededBytes + poolused > poolsize) {
00084 unsigned long newsize;
00085 if (!pool) {
00086 newsize = (neededBytes < BASE_DISPLAYLIST_SIZE) ?
00087 BASE_DISPLAYLIST_SIZE : neededBytes;
00088 } else {
00089 newsize = (unsigned long) (1.2f * (poolsize + neededBytes));
00090 if (newsize < GROWN_DISPLAYLIST_SIZE)
00091 newsize = GROWN_DISPLAYLIST_SIZE;
00092 }
00093
00094 char *tmp = (char *) vmd_resize_alloc(pool, poolused, newsize);
00095
00096 if (!tmp) {
00097 msgErr << "Failed to increase display list memory pool size, system out of memory" << sendmsg;
00098 msgErr << " Previous pool size: " << ((unsigned long) (poolsize / (1024*1024))) << "MB" << sendmsg;
00099 msgErr << " Requested pool size: " << ((unsigned long) (newsize / (1024*1024))) << "MB" << sendmsg;
00100 return NULL;
00101 }
00102 poolsize = newsize;
00103 pool = tmp;
00104 }
00105
00106 CommandHeader *header = (CommandHeader *)(pool + poolused);
00107 poolused += neededBytes;
00108
00109 header->code = code;
00110 header->size = neededBytes;
00111
00112
00113 ++listsize;
00114 return header+1;
00115 }
00116
00117 void VMDDisplayList::reset_and_free(unsigned long newserial) {
00118
00119
00120 if (poolsize > BASE_DISPLAYLIST_SIZE &&
00121 poolused / (float)poolsize < 0.25f) {
00122 vmd_dealloc(pool);
00123 pool = NULL;
00124 poolsize = 0;
00125 }
00126 poolused = 0;
00127 listsize = 0;
00128 serial = newserial;
00129 }
00130
00131 int VMDDisplayList::set_clip_normal(int i, const float *normal) {
00132 if (i < 0 || i >= VMD_MAX_CLIP_PLANE) return 0;
00133 float length = norm(normal);
00134 if (!length) return 0;
00135 clipplanes[i].normal[0] = normal[0]/length;
00136 clipplanes[i].normal[1] = normal[1]/length;
00137 clipplanes[i].normal[2] = normal[2]/length;
00138 return 1;
00139 }
00140
00141 int VMDDisplayList::set_clip_center(int i, const float *center) {
00142 if (i < 0 || i >= VMD_MAX_CLIP_PLANE) return 0;
00143 clipplanes[i].center[0] = center[0];
00144 clipplanes[i].center[1] = center[1];
00145 clipplanes[i].center[2] = center[2];
00146 return 1;
00147 }
00148
00149 int VMDDisplayList::set_clip_color(int i, const float *color) {
00150 if (i < 0 || i >= VMD_MAX_CLIP_PLANE) return 0;
00151 clipplanes[i].color[0] = color[0];
00152 clipplanes[i].color[1] = color[1];
00153 clipplanes[i].color[2] = color[2];
00154 return 1;
00155 }
00156
00157 int VMDDisplayList::set_clip_status(int i, int mode) {
00158 if (i < 0 || i >= VMD_MAX_CLIP_PLANE) return 0;
00159 clipplanes[i].mode = mode;
00160 return 1;
00161 }
00162
00163 int VMDDisplayList::get_clip_status(int i, int &mode) {
00164 if (i < 0 || i >= VMD_MAX_CLIP_PLANE) return 0;
00165 mode = clipplanes[i].mode;
00166 return 1;
00167 }
00168