00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "OpenGLRenderer.h"
00029 #include "DispCmds.h"
00030 #include "Inform.h"
00031 #include "utilities.h"
00032 #include "VMDDisplayList.h"
00033 #include "Hershey.h"
00034
00035 #include <stdlib.h>
00036 #include <stdio.h>
00037 #include <math.h>
00038 #include "OpenGLStipples.h"
00039
00040
00041 #define VMDWIREGL 1
00042
00043 #if defined(VMDUSEOPENGLSHADER)
00044 #define VMDUSEGLSLSPHERES 1
00045 #if defined(GL_ARB_point_sprite)
00046 #define VMDUSEGLSLSPHERESPRITES 1
00047 #endif
00048 #endif
00049
00050 #if 0
00051 #define OGLERR { GLenum err; if ((err = glGetError()) != GL_NO_ERROR) { \
00052 msgErr << __FILE__ << " line " << __LINE__ << " " << \
00053 (const char *) gluErrorString(err) << sendmsg; }}
00054 #else
00055 #define OGLERR
00056 #endif
00057
00058 #define MIN_SPHERE_RES 4
00059 #define MAX_SPHERE_RES 30
00060
00061 void OpenGLRenderer::setup_initial_opengl_state(void) {
00062 int i;
00063
00064 if (getenv("VMDSIMPLEGRAPHICS") == NULL) {
00065 simplegraphics = 0;
00066 } else {
00067 simplegraphics = 1;
00068 msgWarn << "Simple graphics mode: OpenGL 1.0, no extensions" << sendmsg;
00069 }
00070
00071
00072
00073 objQuadric = gluNewQuadric();
00074 pointsQuadric = gluNewQuadric();
00075 gluQuadricDrawStyle(objQuadric, (GLenum)GLU_FILL);
00076 gluQuadricDrawStyle(pointsQuadric, (GLenum)GLU_POINT);
00077
00078
00079 ogl_cachelistbase = 2000;
00080 ogl_cacheenabled = 0;
00081 ogl_cachedebug = 0;
00082 if (getenv("VMDCACHEDLDEBUG") != NULL) {
00083 ogl_cachedebug = 1;
00084 }
00085
00086 wiregl = 0;
00087 immersadeskflip = 0;
00088 shearstereo = 0;
00089
00090
00091
00092 oglmaterialindex = -1;
00093 oglopacity = -1.0f;
00094 oglambient = -1.0f;
00095 ogldiffuse = -1.0f;
00096 oglspecular = -1.0f;
00097 oglshininess = -1.0f;
00098 ogloutline = -1.0f;
00099 ogloutlinewidth = -1.0f;
00100 ogltransmode = -1;
00101
00102 ogl_useblendedtrans = 0;
00103 ogl_transpass = 0;
00104 ogl_useglslshader = 0;
00105 ogl_acrobat3dcapture = 0;
00106 ogl_lightingenabled = 0;
00107 ogl_rendstateserial = 1;
00108 ogl_glslserial = 0;
00109 ogl_glsltoggle = 1;
00110 ogl_glslmaterialindex = -1;
00111 ogl_glslprojectionmode = DisplayDevice::PERSPECTIVE;
00112 ogl_glsltexturemode = 0;
00113
00114
00115 ext->find_renderer();
00116
00117
00118 if (!simplegraphics) {
00119 ext->find_extensions();
00120 }
00121
00122
00123 #if 0
00124
00125
00126
00127
00128 #if defined(__APPLE__)
00129
00130
00131
00132
00133
00134
00135 if (ext->hasstereo && ext->oglrenderer == OpenGLExtensions::NVIDIA) {
00136 msgInfo << "nVidia card detected, enabling mono drawing performance workaround" << sendmsg;
00137
00138
00139 ext->stereodrawforced = 1;
00140 }
00141 #endif
00142 #endif
00143
00144
00145
00146 #if 0 && defined(__linux)
00147
00148 if (ext->oglrenderer == OpenGLExtensions::ATI) {
00149 if (getenv("VMDDISABLEATILINUXWORKAROUND") == NULL) {
00150 msgInfo << "ATI Linux driver detected, limiting features to avoid driver bugs." << sendmsg;
00151 msgInfo << " Set the environment variable VMDDISABLEATILINUXWORKAROUND" << sendmsg;
00152 msgInfo << " to enable full functionality on a known-safe driver version." << sendmsg;
00153
00154 simplegraphics = 1;
00155 }
00156 }
00157 #endif
00158
00159 #if defined(VMDWIREGL)
00160
00161 if (ext->oglrenderer == OpenGLExtensions::WIREGL ||
00162 (getenv("VMDWIREGL") != NULL)) {
00163 msgInfo << "WireGL renderer detected, disabling unsupported OpenGL features." << sendmsg;
00164 wiregl=1;
00165
00166
00167 ext->hastex2d = 0;
00168 ext->hastex3d = 0;
00169 }
00170 #endif
00171
00172 glDepthFunc(GL_LEQUAL);
00173 glEnable(GL_DEPTH_TEST);
00174 glClearDepth(1.0);
00175
00176 #if 1
00177
00178
00179
00180
00181 glEnable(GL_NORMALIZE);
00182 #else
00183
00184
00185
00186
00187
00188
00189 if (simplegraphics || wiregl || ogl_acrobat3dcapture) {
00190
00191
00192
00193 glEnable(GL_NORMALIZE);
00194 } else {
00195 #if defined(_MSC_VER) || defined(__irix) || defined(__APPLE__)
00196
00197
00198 glEnable(GL_NORMALIZE);
00199 #else
00200 #if defined(GL_VERSION_1_2)
00201 ext->hasrescalenormalext = 1;
00202 glEnable(GL_RESCALE_NORMAL);
00203 #elif defined(GL_RESCALE_NORMAL_EXT)
00204 if (ext->vmdQueryExtension("GL_RESCALE_NORMAL_EXT")) {
00205 ext->hasrescalenormalext = 1;
00206 glEnable(GL_RESCALE_NORMAL_EXT);
00207 } else {
00208 glEnable(GL_NORMALIZE);
00209 }
00210 #else
00211 glEnable(GL_NORMALIZE);
00212 #endif
00213 #endif
00214 }
00215 #endif
00216
00217
00218 glLineStipple(1, 0x3333);
00219 glDisable(GL_LINE_STIPPLE);
00220
00221
00222
00223 glFogi(GL_FOG_MODE, GL_EXP2);
00224 glFogf(GL_FOG_DENSITY, 0.40f);
00225
00226
00227 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
00228 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE);
00229
00230 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
00231 glEnable(GL_COLOR_MATERIAL);
00232 glDisable(GL_POLYGON_SMOOTH);
00233
00234
00235 for (i=0; i < DISP_LIGHTS; i++) {
00236 ogl_lightstate[i] = 0;
00237 }
00238
00239
00240 for (i=0; i < VMD_MAX_CLIP_PLANE; i++) {
00241 ogl_clipmode[i] = 0;
00242 glDisable((GLenum) (GL_CLIP_PLANE0 + i));
00243 }
00244
00245
00246 glMatrixMode(GL_PROJECTION);
00247 glLoadIdentity();
00248 glMatrixMode(GL_MODELVIEW);
00249 glLoadIdentity();
00250
00251
00252 glMatrixMode(GL_MODELVIEW);
00253 for (i=MIN_SPHERE_RES; i<=MAX_SPHERE_RES; i++) {
00254 GLuint solidlist = glGenLists(1);
00255 glNewList(solidlist, GL_COMPILE);
00256 gluSphere(objQuadric, 1.0, i, i);
00257 glEndList();
00258 solidSphereLists.append(solidlist);
00259
00260 GLuint pointlist = glGenLists(1);
00261 glNewList(pointlist, GL_COMPILE);
00262 gluSphere(pointsQuadric, 1.0, i, i);
00263 glEndList();
00264 pointSphereLists.append(pointlist);
00265 }
00266
00267
00268 ogl_textMat.identity();
00269
00270
00271
00272 font1pxListBase = glGenLists(256);
00273 glListBase(font1pxListBase);
00274 for (i=0 ; i<256 ; i++) {
00275 glNewList(font1pxListBase+i, GL_COMPILE);
00276 hersheyDrawLetterOpenGL(i, 0);
00277 glEndList();
00278 }
00279
00280
00281
00282
00283 fontNpxListBase = glGenLists(256);
00284 glListBase(fontNpxListBase);
00285 for (i=0 ; i<256 ; i++) {
00286 glNewList(fontNpxListBase+i, GL_COMPILE);
00287 hersheyDrawLetterOpenGL(i, 1);
00288 glEndList();
00289 }
00290
00291
00292
00293 dpl_initialized = 1;
00294
00295 #if defined(GL_VERSION_1_1)
00296 if (!(simplegraphics || ogl_acrobat3dcapture)) {
00297
00298 glEnableClientState(GL_VERTEX_ARRAY);
00299 glEnableClientState(GL_NORMAL_ARRAY);
00300 glEnableClientState(GL_COLOR_ARRAY);
00301 }
00302 #endif
00303
00304
00305 #if defined(GL_VERSION_1_1)
00306 if (ext->hastex2d) {
00307 int i, sz;
00308 GLint x, y;
00309
00310
00311 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max2DtexSize);
00312
00313 for (i=0; (sz = 1 << i) <= max2DtexSize; i++) {
00314 glTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_RGB8,
00315 sz, sz, 0,
00316 GL_RGB, GL_UNSIGNED_BYTE, NULL);
00317
00318 glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &x);
00319 glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &y);
00320
00321 if (x > 0 && y > 0) {
00322 max2DtexX = x;
00323 max2DtexY = y;
00324 }
00325 }
00326
00327 if (max2DtexX > max2DtexSize)
00328 max2DtexX = max2DtexSize;
00329
00330 if (max2DtexY > max2DtexSize)
00331 max2DtexY = max2DtexSize;
00332 }
00333 #endif
00334
00335 #if defined(GL_VERSION_1_2)
00336 if (ext->hastex3d) {
00337 int i, sz;
00338 GLint x, y, z;
00339
00340
00341 max3DtexSize = 0;
00342 max3DtexX = 0;
00343 max3DtexY = 0;
00344 max3DtexZ = 0;
00345 glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &max3DtexSize);
00346
00347 for (i=0; (sz = 1 << i) <= max3DtexSize; i++) {
00348 GLTEXIMAGE3D(GL_PROXY_TEXTURE_3D, 0, GL_RGB8,
00349 sz, sz, sz, 0,
00350 GL_RGB, GL_UNSIGNED_BYTE, NULL);
00351
00352 glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_WIDTH, &x);
00353 glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_HEIGHT, &y);
00354 glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_DEPTH, &z);
00355
00356 if (x > 0 && y > 0 && z > 0) {
00357 max3DtexX = x;
00358 max3DtexY = y;
00359 max3DtexZ = z;
00360 }
00361 }
00362
00363 if (max3DtexX > max3DtexSize)
00364 max3DtexX = max3DtexSize;
00365
00366 if (max3DtexY > max3DtexSize)
00367 max3DtexY = max3DtexSize;
00368
00369 if (max3DtexZ > max3DtexSize)
00370 max3DtexZ = max3DtexSize;
00371
00372
00373 if (max3DtexX < 1 || max3DtexY < 1 || max3DtexZ < 1) {
00374 ext->hastex3d = 0;
00375 }
00376
00377 }
00378 #endif
00379
00380
00381
00382
00383
00384 #if defined(GL_VERSION_1_2) && !defined(__APPLE__)
00385 if (((ext->oglmajor == 1) && (ext->oglminor >= 2)) || (ext->oglmajor >= 2)) {
00386 if (ext->hastex2d || ext->hastex3d) {
00387
00388 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
00389 } else {
00390
00391 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
00392 }
00393 }
00394 #endif
00395
00396 ext->PrintExtensions();
00397
00398 #if defined(VMDUSEOPENGLSHADER)
00399 int glslextensionsavailable=0;
00400
00401
00402 if (!(simplegraphics || ogl_acrobat3dcapture) &&
00403 ext->hasglshadinglangarb &&
00404 ext->hasglfragmentshaderarb &&
00405 ext->hasglvertexshaderarb &&
00406 ext->hasglshaderobjectsarb) {
00407 glslextensionsavailable=1;
00408 }
00409
00410 if (glslextensionsavailable) {
00411 mainshader = new OpenGLShader(ext);
00412
00413 if (mainshader) {
00414 char *shaderpath = NULL;
00415
00416 if (getenv("VMDOGLSHADER") != NULL) {
00417 shaderpath = (char *) calloc(1, strlen(getenv("VMDOGLSHADER")) + 512);
00418 strcpy(shaderpath, getenv("VMDOGLSHADER"));
00419 } else if (getenv("VMDDIR") != NULL) {
00420 shaderpath = (char *) calloc(1, strlen(getenv("VMDDIR")) + 512);
00421 strcpy(shaderpath, getenv("VMDDIR"));
00422 strcat(shaderpath, "/shaders/vmd");
00423 } else {
00424 msgErr << "Unable to locate VMD vertex and fragment shader path, "
00425 << "VMDDIR environment variable not set" << sendmsg;
00426 delete mainshader;
00427 mainshader = NULL;
00428 }
00429
00430 if (mainshader) {
00431 #if defined(_MSC_VER)
00432
00433 int i, len;
00434 len=strlen(shaderpath);
00435 for (i=0; i<len; i++) {
00436 if (shaderpath[i] == '\\') {
00437 shaderpath[i] = '/';
00438 }
00439 }
00440 #endif
00441
00442 if (mainshader->LoadShader(shaderpath)) {
00443 mainshader->UseShader(0);
00444
00445
00446
00447 } else {
00448 msgWarn << "GPU driver failed to compile shader: " << sendmsg;
00449 msgWarn << " " << shaderpath << sendmsg;
00450 delete mainshader;
00451 mainshader = NULL;
00452 }
00453 }
00454
00455 if (shaderpath)
00456 free(shaderpath);
00457 }
00458 OGLERR
00459 }
00460
00461 #if defined(VMDUSEGLSLSPHERES)
00462
00463
00464 if (mainshader) {
00465 sphereshader = new OpenGLShader(ext);
00466 char *shaderpath = NULL;
00467
00468 if (getenv("VMDOGLSPHERESHADER") != NULL) {
00469 shaderpath = (char *) calloc(1, strlen(getenv("VMDOGLSPHERESHADER")) + 512);
00470 strcpy(shaderpath, getenv("VMDOGLSPHERESHADER"));
00471 } else if (getenv("VMDDIR") != NULL) {
00472 shaderpath = (char *) calloc(1, strlen(getenv("VMDDIR")) + 512);
00473 strcpy(shaderpath, getenv("VMDDIR"));
00474 strcat(shaderpath, "/shaders/vmdsphere");
00475 } else {
00476 msgWarn << "Unable to locate VMD sphere vertex and fragment shaders, "
00477 << "VMDDIR environment variable not set" << sendmsg;
00478 delete sphereshader;
00479 sphereshader = NULL;
00480 }
00481
00482 if (sphereshader) {
00483 #if defined(_MSC_VER)
00484
00485 int i, len;
00486 len=strlen(shaderpath);
00487 for (i=0; i<len; i++) {
00488 if (shaderpath[i] == '\\') {
00489 shaderpath[i] = '/';
00490 }
00491 }
00492 #endif
00493
00494 if (sphereshader->LoadShader(shaderpath)) {
00495 sphereshader->UseShader(0);
00496
00497
00498
00499 } else {
00500 msgWarn << "GPU driver failed to compile shader: " << sendmsg;
00501 msgWarn << " " << shaderpath << sendmsg;
00502 delete sphereshader;
00503 sphereshader = NULL;
00504 }
00505 }
00506
00507 if (shaderpath)
00508 free(shaderpath);
00509
00510 OGLERR
00511 }
00512 #endif
00513
00514
00515 #if defined(VMDUSEGLSLSPHERESPRITES)
00516
00517
00518 if (mainshader
00519 #if 0
00520 && getenv("VMDUSESPHERESPRITES")
00521 #endif
00522 ) {
00523 spherespriteshader = new OpenGLShader(ext);
00524 char *shaderpath = NULL;
00525
00526 if (getenv("VMDOGLSPHERESPRITESHADER") != NULL) {
00527 shaderpath = (char *) calloc(1, strlen(getenv("VMDOGLSPHERESPRITESHADER")) + 512);
00528 strcpy(shaderpath, getenv("VMDOGLSPHERESPRITESHADER"));
00529 } else if (getenv("VMDDIR") != NULL) {
00530 shaderpath = (char *) calloc(1, strlen(getenv("VMDDIR")) + 512);
00531 strcpy(shaderpath, getenv("VMDDIR"));
00532 strcat(shaderpath, "/shaders/vmdspheresprite");
00533 } else {
00534 msgWarn << "Unable to locate VMD sphere sprite vertex and fragment shaders, "
00535 << "VMDDIR environment variable not set" << sendmsg;
00536 delete spherespriteshader;
00537 spherespriteshader = NULL;
00538 }
00539
00540 if (spherespriteshader) {
00541 #if defined(_MSC_VER)
00542
00543 int i, len;
00544 len=strlen(shaderpath);
00545 for (i=0; i<len; i++) {
00546 if (shaderpath[i] == '\\') {
00547 shaderpath[i] = '/';
00548 }
00549 }
00550 #endif
00551
00552 if (spherespriteshader->LoadShader(shaderpath)) {
00553 spherespriteshader->UseShader(0);
00554
00555
00556
00557 } else {
00558 msgWarn << "GPU driver failed to compile shader: " << sendmsg;
00559 msgWarn << " " << shaderpath << sendmsg;
00560 delete spherespriteshader;
00561 spherespriteshader = NULL;
00562 }
00563 }
00564
00565 if (shaderpath)
00566 free(shaderpath);
00567
00568 OGLERR
00569 }
00570 #endif
00571
00572 if (mainshader && sphereshader
00573 #if defined(VMDUSEGLSLSPHERESPRITES)
00574 && ((spherespriteshader != 0)
00575 #if 0
00576 == (getenv("VMDUSESPHERESPRITES") != NULL)
00577 #endif
00578 )
00579 #endif
00580 ) {
00581 msgInfo << " Full GLSL rendering mode is available." << sendmsg;
00582 } else if (mainshader) {
00583 if (glslextensionsavailable) {
00584 msgWarn << "This GPU/driver is buggy, or doesn't fully implement GLSL." << sendmsg;
00585 msgWarn << "Set environment variable VMDGLSLVERBOSE for more info." << sendmsg;
00586 }
00587 msgInfo << " Basic GLSL rendering mode is available." << sendmsg;
00588 } else {
00589 if (glslextensionsavailable) {
00590 msgWarn << "This GPU/driver is buggy, or doesn't fully implement GLSL." << sendmsg;
00591 msgWarn << "Set environment variable VMDGLSLVERBOSE for more info." << sendmsg;
00592 }
00593 msgInfo << " GLSL rendering mode is NOT available." << sendmsg;
00594 }
00595 #endif
00596
00597
00598 if (ext->hastex2d || ext->hastex3d) {
00599 msgInfo << " Textures: ";
00600
00601 if (ext->hastex2d)
00602 msgInfo << "2-D (" << max2DtexX << "x" << max2DtexY << ")";
00603
00604 if (ext->hastex2d && ext->hastex3d)
00605 msgInfo << ", ";
00606
00607 if (ext->hastex3d)
00608 msgInfo << "3-D (" << max3DtexX << "x" << max3DtexY << "x" << max3DtexZ << ")";
00609
00610 if ((ext->hastex2d || ext->hastex3d) && ext->multitextureunits > 0)
00611 msgInfo << ", ";
00612
00613 if (ext->multitextureunits > 0)
00614 msgInfo << "Multitexture (" << ext->multitextureunits << ")";
00615
00616 msgInfo << sendmsg;
00617 }
00618
00619
00620 if (getenv("VMDIMMERSADESKFLIP") != NULL) {
00621 immersadeskflip = 1;
00622 msgInfo << " Enabled Immersadesk right-eye reflection stereo mode" << sendmsg;
00623 }
00624
00625
00626 if (getenv("VMDSHEARSTEREO") != NULL) {
00627 shearstereo = 1;
00628 msgInfo << " Enabled shear matrix stereo projection mode" << sendmsg;
00629 }
00630
00631 OGLERR
00632 }
00633
00634
00635 void OpenGLRenderer::update_lists(void) {
00636
00637 ResizeArray<GLuint> *lists = (sphereMode ==
00638 ::SOLIDSPHERE) ? &solidSphereLists : &pointSphereLists;
00639 int ind = sphereRes - MIN_SPHERE_RES;
00640 if (ind < 0)
00641 ind = 0;
00642 else if (ind >= lists->num())
00643 ind = lists->num()-1;
00644 SphereList = (*lists)[ind];
00645 }
00646
00648
00649 OpenGLRenderer::OpenGLRenderer(const char *nm) : DisplayDevice(nm) {
00650
00651 objQuadric = NULL;
00652 pointsQuadric = NULL;
00653
00654 #if defined(VMDUSEOPENGLSHADER)
00655 mainshader = NULL;
00656 sphereshader = NULL;
00657 spherespriteshader = NULL;
00658 #endif
00659 ext = new OpenGLExtensions;
00660
00661 dpl_initialized = 0;
00662 }
00663
00664
00665
00666 OpenGLRenderer::~OpenGLRenderer(void) {
00667 if (objQuadric != NULL)
00668 gluDeleteQuadric(objQuadric);
00669
00670 if (pointsQuadric != NULL)
00671 gluDeleteQuadric(pointsQuadric);
00672
00673 delete ext;
00674
00675 #if defined(VMDUSEOPENGLSHADER)
00676 delete mainshader;
00677 delete sphereshader;
00678 delete spherespriteshader;
00679 #endif
00680 }
00681
00682
00683 void OpenGLRenderer::free_opengl_ctx() {
00684 int i;
00685 GLuint tag;
00686
00687
00688 displaylistcache.markUnused();
00689 while ((tag = displaylistcache.deleteUnused()) != GLCACHE_FAIL) {
00690 glDeleteLists(tag, 1);
00691 }
00692
00693
00694 texturecache.markUnused();
00695 while ((tag = texturecache.deleteUnused()) != GLCACHE_FAIL) {
00696 glDeleteTextures(1, &tag);
00697 }
00698
00699 if (dpl_initialized) {
00700
00701 for (i=MIN_SPHERE_RES; i<=MAX_SPHERE_RES; i++) {
00702 glDeleteLists(solidSphereLists[i-MIN_SPHERE_RES], 1);
00703 glDeleteLists(pointSphereLists[i-MIN_SPHERE_RES], 1);
00704 }
00705
00706
00707 glDeleteLists(font1pxListBase, 256);
00708 glDeleteLists(fontNpxListBase, 256);
00709 }
00710 }
00711
00712
00714
00715
00716 void OpenGLRenderer::set_line_width(int w) {
00717 if(w > 0) {
00718 glLineWidth((GLfloat)w);
00719 lineWidth = w;
00720 }
00721 }
00722
00723
00724 void OpenGLRenderer::set_line_style(int s) {
00725 if(s == ::DASHEDLINE) {
00726 lineStyle = s;
00727 glEnable(GL_LINE_STIPPLE);
00728 } else {
00729 lineStyle = ::SOLIDLINE;
00730 glDisable(GL_LINE_STIPPLE);
00731 }
00732 }
00733
00734
00735
00736 void OpenGLRenderer::set_sphere_res(int r) {
00737
00738
00739 if (sphereRes == r)
00740 return;
00741
00742 if (r > 2)
00743 sphereRes = r;
00744 else
00745 sphereRes = 2;
00746
00747 update_lists();
00748 }
00749
00750
00751 void OpenGLRenderer::set_sphere_mode(int m) {
00752
00753
00754 if (sphereMode == m)
00755 return;
00756
00757 sphereMode = m;
00758 update_lists();
00759 }
00760
00761
00762
00763 void OpenGLRenderer::cylinder(float *end, float *start, int rod_res,
00764 float rod_radius, float rod_top_radius) {
00765 float R, RXY, phi, theta, lenaxis[3];
00766
00767
00768 lenaxis[0] = end[0] - start[0];
00769 lenaxis[1] = end[1] - start[1];
00770 lenaxis[2] = end[2] - start[2];
00771
00772 R = lenaxis[0]*lenaxis[0]+lenaxis[1]*lenaxis[1]+lenaxis[2]*lenaxis[2];
00773
00774 if (R <= 0.0)
00775 return;
00776
00777 R = sqrtf(R);
00778
00779
00780 phi = acosf(lenaxis[2] / R);
00781
00782
00783 RXY = sqrtf(lenaxis[0]*lenaxis[0]+lenaxis[1]*lenaxis[1]);
00784 if (RXY <= 0.0f) {
00785 theta = 0.0f;
00786 } else {
00787 theta = acosf(lenaxis[0] / RXY);
00788 if (lenaxis[1] < 0.0f)
00789 theta = (float) (2.0f * VMD_PI) - theta;
00790 }
00791
00792 glPushMatrix();
00793 glTranslatef((GLfloat)(start[0]), (GLfloat)(start[1]), (GLfloat)(start[2]));
00794 if (theta != 0.0f)
00795 glRotatef((GLfloat) ((theta / VMD_PI) * 180.0f), 0.0f, 0.0f, 1.0f);
00796 if (phi != 0.0f)
00797 glRotatef((GLfloat) ((phi / VMD_PI) * 180.0f), 0.0f, 1.0f, 0.0f);
00798
00799
00800 gluCylinder(objQuadric, (GLdouble)rod_radius, (GLdouble)rod_top_radius,
00801 (GLdouble)R, (GLint)rod_res, 1);
00802
00803
00804 gluQuadricOrientation(objQuadric, (GLenum)GLU_INSIDE);
00805 gluDisk(objQuadric, (GLdouble)0, (GLdouble)rod_radius, (GLint)rod_res, 1);
00806 gluQuadricOrientation(objQuadric, (GLenum)GLU_OUTSIDE);
00807
00808 glPopMatrix();
00809 }
00810
00811
00812
00813
00814
00815
00816
00817 static void cylinder_full(int num, float *edges, int filled) {
00818 int n = num;
00819 float *start = edges;
00820
00821 if (num < 2)
00822 return;
00823
00824 glBegin(GL_QUAD_STRIP);
00825 while (n-- > 0) {
00826 glNormal3fv(edges);
00827 glVertex3fv(edges+6);
00828 glVertex3fv(edges+3);
00829 edges += 9;
00830 }
00831 glNormal3fv(start);
00832 glVertex3fv(start+6);
00833 glVertex3fv(start+3);
00834 glEnd();
00835
00836
00837 if (filled) {
00838 float axis[3];
00839 axis[0] = start[6] - start[3];
00840 axis[1] = start[7] - start[4];
00841 axis[2] = start[8] - start[5];
00842 vec_normalize(axis);
00843
00844 if (filled & CYLINDER_LEADINGCAP) {
00845 n = num;
00846 edges = start + 3;
00847 glBegin(GL_POLYGON);
00848 glNormal3fv(axis);
00849 while (--n >= 0) {
00850 glVertex3fv(edges);
00851 edges += 9;
00852 }
00853 glEnd();
00854 }
00855 if (filled & CYLINDER_TRAILINGCAP) {
00856 n = num;
00857 edges = start + 6;
00858 glBegin(GL_POLYGON);
00859 glNormal3fv(axis);
00860 while (--n >= 0) {
00861 glVertex3fv(edges);
00862 edges += 9;
00863 }
00864 glEnd();
00865 }
00866 }
00867 }
00868
00869
00871
00872
00873 int OpenGLRenderer::do_define_light(int n, float *color, float *position) {
00874 int i;
00875
00876 for(i=0; i < 3; i++) {
00877 ogl_lightcolor[n][i] = color[i];
00878 ogl_lightpos[n][i] = position[i];
00879 }
00880 ogl_lightpos[n][3] = 0.0;
00881
00882 ogl_lightcolor[n][3] = 1.0;
00883
00884
00885 vec_normalize(&ogl_lightpos[n][0]);
00886
00887 glLightfv((GLenum)(GL_LIGHT0 + n), GL_POSITION, &ogl_lightpos[n][0]);
00888 glLightfv((GLenum)(GL_LIGHT0 + n), GL_SPECULAR, &ogl_lightcolor[n][0]);
00889
00890 ogl_rendstateserial++;
00891 _needRedraw = 1;
00892 return TRUE;
00893 }
00894
00895
00896 int OpenGLRenderer::do_activate_light(int n, int turnon) {
00897 if (turnon) {
00898 glEnable((GLenum)(GL_LIGHT0 + n));
00899 ogl_lightstate[n] = 1;
00900 } else {
00901 glDisable((GLenum)(GL_LIGHT0 + n));
00902 ogl_lightstate[n] = 0;
00903 }
00904
00905 ogl_rendstateserial++;
00906 _needRedraw = 1;
00907 return TRUE;
00908 }
00909
00910 void OpenGLRenderer::loadmatrix(const Matrix4 &m) {
00911 GLfloat tmpmat[16];
00912 for (int i=0; i<16; i++) tmpmat[i]=(GLfloat)(m.mat[i]);
00913 glLoadMatrixf(tmpmat);
00914 }
00915
00916 void OpenGLRenderer::multmatrix(const Matrix4 &m) {
00917 GLfloat tmpmat[16];
00918 for (int i=0; i<16; i++) tmpmat[i]=(GLfloat)(m.mat[i]);
00919 glMultMatrixf(tmpmat);
00920 }
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930 void OpenGLRenderer::abs_screen_loc_3D(float *loc, float *spos) {
00931 GLdouble modelMatrix[16], projMatrix[16];
00932 GLdouble pos[3];
00933 int i;
00934
00935
00936 for (i=0; i<16; i++) {
00937 modelMatrix[i] = ogl_mvmatrix[i];
00938 projMatrix[i] = ogl_pmatrix[i];
00939 }
00940
00941
00942 if(!gluProject((GLdouble)(loc[0]), (GLdouble)(loc[1]), (GLdouble)(loc[2]),
00943 modelMatrix, projMatrix, ogl_viewport, pos, pos + 1, pos + 2)) {
00944 msgErr << "Cannot determine window position of world coordinate.";
00945 msgErr << sendmsg;
00946 } else {
00947 spos[0] = (float) (pos[0] + (float)xOrig);
00948 spos[1] = (float) (pos[1] + (float)yOrig);
00949 spos[2] = (float) (pos[2]);
00950 }
00951 }
00952
00953 void OpenGLRenderer::abs_screen_loc_2D(float *loc, float *spos) {
00954 float newloc[3];
00955 newloc[0] = loc[0];
00956 newloc[1] = loc[1];
00957 newloc[2] = 0.0f;
00958 abs_screen_loc_3D(newloc, spos);
00959 }
00960
00961
00962
00963
00964
00965
00966
00967
00968 void OpenGLRenderer::find_3D_from_2D(const float *A3D, const float *B2D,
00969 float *B3D) {
00970 GLdouble modelMatrix[16], projMatrix[16], w1[3], w2[3];
00971 int i;
00972 float lsx, lsy;
00973
00974
00975 for (i=0; i<16; i++) {
00976 modelMatrix[i] = ogl_mvmatrix[i];
00977 projMatrix[i] = ogl_pmatrix[i];
00978 }
00979
00980
00981 lsx = B2D[0];
00982 lsy = B2D[1];
00983 lsx = lsx * (float)xSize;
00984 lsy = lsy * (float)ySize;
00985
00986
00987 if (!gluUnProject((GLdouble)lsx, (GLdouble)lsy, 0,
00988 modelMatrix, projMatrix, ogl_viewport, w1, w1 + 1, w1 + 2)) {
00989 msgErr << "Can't determine world coords of window position 1." << sendmsg;
00990 return;
00991 }
00992 if (!gluUnProject((GLdouble)lsx, (GLdouble)lsy, 1.0,
00993 modelMatrix, projMatrix, ogl_viewport, w2, w2 + 1, w2 + 2)) {
00994 msgErr << "Can't determine world coords of window position2." << sendmsg;
00995 return;
00996 }
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006 if(w1[2] == w2[2]) {
01007 memcpy(B3D, A3D, 3*sizeof(float));
01008 } else {
01009 float relchange = (float) ((A3D[2] - w1[2]) / (w2[2] - w1[2]));
01010 B3D[0] = (float) ((w2[0] - w1[0]) * relchange + w1[0]);
01011 B3D[1] = (float) ((w2[1] - w1[1]) * relchange + w1[1]);
01012 B3D[2] = A3D[2];
01013 }
01014 }
01015
01016
01017
01018
01019
01020
01021
01022 void OpenGLRenderer::aa_on(void) {
01023 if (inStereo == OPENGL_STEREO_STENCIL_CHECKERBOARD ||
01024 inStereo == OPENGL_STEREO_STENCIL_COLUMNS ||
01025 inStereo == OPENGL_STEREO_STENCIL_ROWS) {
01026 msgInfo << "Antialiasing must be disabled for stencil-based stereo modes."
01027 << sendmsg;
01028 msgInfo << "You may re-enable antialiasing when stereo is turned off." << sendmsg;
01029 aa_off();
01030 return;
01031 }
01032
01033 if (aaAvailable && !aaEnabled) {
01034 #if defined(GL_ARB_multisample)
01035 if (ext->hasmultisample) {
01036 glEnable(GL_MULTISAMPLE_ARB);
01037 aaEnabled = TRUE;
01038 _needRedraw = 1;
01039 return;
01040 }
01041 #endif
01042
01043 aaEnabled = TRUE;
01044 }
01045 }
01046
01047
01048 void OpenGLRenderer::aa_off(void) {
01049 if(aaAvailable && aaEnabled) {
01050 #if defined(GL_ARB_multisample)
01051 if (ext->hasmultisample) {
01052 glDisable(GL_MULTISAMPLE_ARB);
01053 aaEnabled = FALSE;
01054 _needRedraw = 1;
01055 return;
01056 }
01057 #else
01058 #endif
01059
01060 aaEnabled = FALSE;
01061 }
01062 }
01063
01064
01065 void OpenGLRenderer::cueing_on(void) {
01066 if (cueingAvailable && !cueingEnabled) {
01067 glEnable(GL_FOG);
01068 cueingEnabled = TRUE;
01069 _needRedraw = 1;
01070 }
01071 }
01072
01073
01074 void OpenGLRenderer::cueing_off(void) {
01075 if (cueingAvailable && cueingEnabled) {
01076 glDisable(GL_FOG);
01077 cueingEnabled = FALSE;
01078 _needRedraw = 1;
01079 }
01080 }
01081
01082
01083 void OpenGLRenderer::culling_on(void) {
01084 if (cullingAvailable && !cullingEnabled) {
01085 glFrontFace(GL_CCW);
01086 glPolygonMode(GL_FRONT, GL_FILL);
01087 glPolygonMode(GL_BACK, GL_LINE);
01088 glCullFace(GL_BACK);
01089 glEnable(GL_CULL_FACE);
01090 cullingEnabled = TRUE;
01091 _needRedraw = 1;
01092 }
01093 }
01094
01095 void OpenGLRenderer::culling_off(void) {
01096 if (cullingAvailable && cullingEnabled) {
01097 glPolygonMode(GL_FRONT, GL_FILL);
01098 glPolygonMode(GL_BACK, GL_FILL);
01099 glCullFace(GL_BACK);
01100 glDisable(GL_CULL_FACE);
01101 cullingEnabled = FALSE;
01102 _needRedraw = 1;
01103 }
01104 }
01105
01106 void OpenGLRenderer::set_background(const float *newback) {
01107 GLfloat r, g, b;
01108 r = (GLfloat)newback[0];
01109 g = (GLfloat)newback[1];
01110 b = (GLfloat)newback[2];
01111
01112
01113 GLfloat fogcol[4];
01114 fogcol[0] = r;
01115 fogcol[1] = g;
01116 fogcol[2] = b;
01117 fogcol[3] = 1.0;
01118
01119 glFogfv(GL_FOG_COLOR, fogcol);
01120
01121
01122 glClearColor((GLclampf)r,
01123 (GLclampf)g,
01124 (GLclampf)b, 1.0);
01125 }
01126
01127 void OpenGLRenderer::set_backgradient(const float *topcol,
01128 const float *botcol) {
01129 int i;
01130 for (i=0; i<3; i++) {
01131 ogl_backgradient[0][i] = topcol[i];
01132 ogl_backgradient[1][i] = botcol[i];
01133 }
01134 ogl_backgradient[0][3] = 1.0;
01135 ogl_backgradient[1][3] = 1.0;
01136 }
01137
01138
01139 void OpenGLRenderer::set_stereo_mode(int newMode) {
01140 if (inStereo == newMode)
01141 return;
01142
01143 if (inStereo == OPENGL_STEREO_STENCIL_CHECKERBOARD ||
01144 inStereo == OPENGL_STEREO_STENCIL_COLUMNS ||
01145 inStereo == OPENGL_STEREO_STENCIL_ROWS)
01146 disable_stencil_stereo();
01147
01148 if (newMode == OPENGL_STEREO_STENCIL_CHECKERBOARD ||
01149 newMode == OPENGL_STEREO_STENCIL_COLUMNS ||
01150 newMode == OPENGL_STEREO_STENCIL_ROWS)
01151 enable_stencil_stereo(newMode);
01152
01153 inStereo = newMode;
01154 reshape();
01155 normal();
01156
01157 clear();
01158 update();
01159
01160 _needRedraw = 1;
01161 }
01162
01163
01164 void OpenGLRenderer::set_cache_mode(int newMode) {
01165 cacheMode = newMode;
01166 ogl_cacheenabled = newMode;
01167 }
01168
01169
01170 void OpenGLRenderer::set_render_mode(int newMode) {
01171 if (renderMode == newMode)
01172 return;
01173
01174 renderMode = newMode;
01175
01176 switch (renderMode) {
01177 case OPENGL_RENDER_NORMAL:
01178 ogl_useblendedtrans = 0;
01179 ogl_useglslshader = 0;
01180 ogl_acrobat3dcapture = 0;
01181 break;
01182
01183 case OPENGL_RENDER_GLSL:
01184 #if defined(VMDUSEOPENGLSHADER)
01185
01186
01187 if (mainshader) {
01188 ogl_useblendedtrans = 1;
01189 ogl_useglslshader = 1;
01190 } else
01191 #endif
01192 {
01193 ogl_useblendedtrans = 0;
01194 ogl_useglslshader = 0;
01195 msgWarn << "OpenGL Programmable Shading not available." << sendmsg;
01196 }
01197 ogl_acrobat3dcapture = 0;
01198 break;
01199
01200 case OPENGL_RENDER_ACROBAT3D:
01201 ogl_useblendedtrans = 0;
01202 ogl_useglslshader = 0;
01203 ogl_acrobat3dcapture = 1;
01204 break;
01205 }
01206
01207 reshape();
01208 normal();
01209
01210 clear();
01211 update();
01212
01213 _needRedraw = 1;
01214 }
01215
01216
01217
01218 void OpenGLRenderer::normal(void) {
01219 glViewport(0, 0, (GLsizei)xSize, (GLsizei)ySize);
01220 set_persp();
01221
01222
01223 draw_background_gradient();
01224 }
01225
01226
01227 void OpenGLRenderer::enable_stencil_stereo(int newMode) {
01228 int i;
01229
01230 if (!ext->hasstencilbuffer) {
01231 set_stereo_mode(OPENGL_STEREO_OFF);
01232 msgInfo << "Stencil Buffer Stereo is NOT available." << sendmsg;
01233 return;
01234 }
01235
01236 if (aaEnabled) {
01237 msgInfo << "Antialiasing must be disabled for stencil-based stereo modes." << sendmsg;
01238 msgInfo << "Antialiasing will be re-enabled when stereo is turned off." << sendmsg;
01239 aaPrevious = aaEnabled;
01240 aa_off();
01241 }
01242
01243 glPushMatrix();
01244 glDisable(GL_DEPTH_TEST);
01245
01246 glViewport(0, 0, (GLsizei)xSize, (GLsizei)ySize);
01247 glMatrixMode(GL_MODELVIEW);
01248 glLoadIdentity();
01249 glMatrixMode (GL_PROJECTION);
01250 glLoadIdentity();
01251
01252 glOrtho(0.0, xSize, 0.0, ySize, -1.0, 1.0);
01253
01254 glMatrixMode(GL_MODELVIEW);
01255 glLoadIdentity();
01256
01257
01258 glDrawBuffer(GL_BACK);
01259
01260 glEnable(GL_STENCIL_TEST);
01261 glClearStencil(0);
01262 glClear(GL_STENCIL_BUFFER_BIT);
01263 glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
01264 glStencilFunc(GL_ALWAYS, 1, 1);
01265
01266 glColor4f(1,1,1,0);
01267
01268
01269
01270
01271 glLineWidth(1);
01272 glBegin(GL_LINES);
01273 if (newMode == OPENGL_STEREO_STENCIL_CHECKERBOARD) {
01274
01275
01276 for (i = -ySize; i < xSize+ySize; i += 2) {
01277 glVertex2f((GLfloat) i + 0.5f, (GLfloat) 0.5f);
01278 glVertex2f((GLfloat) i + ySize + 0.5f, (GLfloat) ySize + 0.5f);
01279 }
01280 } else if (newMode == OPENGL_STEREO_STENCIL_COLUMNS) {
01281
01282 for (i=0; i<xSize; i+=2) {
01283 glVertex2f((GLfloat) i + 0.5f, 0.0f);
01284 glVertex2f((GLfloat) i + 0.5f, (GLfloat) ySize);
01285 }
01286 } else if (newMode == OPENGL_STEREO_STENCIL_ROWS) {
01287
01288 for (i=0; i<ySize; i+=2) {
01289 glVertex2f( 0.0f, (GLfloat) i + 0.5f);
01290 glVertex2f((GLfloat) xSize, (GLfloat) i + 0.5f);
01291 }
01292 }
01293 glEnd();
01294
01295 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
01296
01297 glEnable(GL_DEPTH_TEST);
01298
01299 glPopMatrix();
01300 }
01301
01302 void OpenGLRenderer::disable_stencil_stereo(void) {
01303 glDisable(GL_STENCIL_TEST);
01304 if (aaPrevious) {
01305
01306
01307 int foo = inStereo;
01308 inStereo = OPENGL_STEREO_OFF;
01309 aa_on();
01310 inStereo = foo;
01311 msgInfo << "Antialiasing re-enabled." << sendmsg;
01312 }
01313 }
01314
01315
01316
01317
01318 void OpenGLRenderer::left(void) {
01319 DisplayEye cureye = LEFTEYE;
01320 if (stereoSwap) {
01321 switch (inStereo) {
01322 case OPENGL_STEREO_DTISIDE:
01323 case OPENGL_STEREO_SIDE:
01324 case OPENGL_STEREO_ABOVEBELOW:
01325 case OPENGL_STEREO_QUADBUFFER:
01326 case OPENGL_STEREO_STENCIL_CHECKERBOARD:
01327 case OPENGL_STEREO_STENCIL_COLUMNS:
01328 case OPENGL_STEREO_STENCIL_ROWS:
01329 case OPENGL_STEREO_ANAGLYPH:
01330 cureye = RIGHTEYE;
01331 break;
01332 }
01333 }
01334
01335 switch (inStereo) {
01336 case OPENGL_STEREO_DTISIDE:
01337 glViewport(0, 0, (GLsizei)xSize / 2, (GLsizei)ySize);
01338 set_persp(cureye);
01339 break;
01340
01341 case OPENGL_STEREO_SIDE:
01342 glViewport(0, 0, (GLsizei)xSize / 2, (GLsizei)ySize);
01343 set_persp(cureye);
01344 break;
01345
01346 case OPENGL_STEREO_ABOVEBELOW:
01347 glViewport(0, 0, (GLsizei)xSize, (GLsizei)ySize / 2);
01348 set_persp(cureye);
01349 break;
01350
01351 case OPENGL_STEREO_LEFT:
01352 set_persp(LEFTEYE);
01353 break;
01354
01355 case OPENGL_STEREO_RIGHT:
01356 set_persp(RIGHTEYE);
01357 break;
01358
01359 case OPENGL_STEREO_QUADBUFFER:
01360 if (ext->hasstereo)
01361 glDrawBuffer(GL_BACK_LEFT);
01362 else
01363
01364 glViewport(0, (GLint)ySize / 2, (GLsizei)xSize, (GLsizei)ySize / 2);
01365 set_persp(cureye);
01366 break;
01367
01368 case OPENGL_STEREO_STENCIL_CHECKERBOARD:
01369 case OPENGL_STEREO_STENCIL_COLUMNS:
01370 case OPENGL_STEREO_STENCIL_ROWS:
01371 glStencilFunc(GL_NOTEQUAL,1,1);
01372 set_persp(cureye);
01373 break;
01374
01375 case OPENGL_STEREO_ANAGLYPH:
01376 if(ext->hasstereo) {
01377 glDrawBuffer(GL_BACK_LEFT);
01378 }
01379
01380 glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE);
01381 set_persp(cureye);
01382 break;
01383
01384 default:
01385 normal();
01386
01387 #if defined(__APPLE__)
01388 if (ext->hasstereo && ext->stereodrawforced)
01389 glDrawBuffer(GL_BACK_LEFT);
01390 #endif
01391 break;
01392 }
01393
01394
01395 draw_background_gradient();
01396 }
01397
01398
01399
01400
01401 void OpenGLRenderer::right(void) {
01402 DisplayEye cureye = RIGHTEYE;
01403 if (stereoSwap) {
01404 switch (inStereo) {
01405 case OPENGL_STEREO_DTISIDE:
01406 case OPENGL_STEREO_SIDE:
01407 case OPENGL_STEREO_ABOVEBELOW:
01408 case OPENGL_STEREO_QUADBUFFER:
01409 case OPENGL_STEREO_STENCIL_CHECKERBOARD:
01410 case OPENGL_STEREO_STENCIL_COLUMNS:
01411 case OPENGL_STEREO_STENCIL_ROWS:
01412 case OPENGL_STEREO_ANAGLYPH:
01413 cureye = LEFTEYE;
01414 break;
01415 }
01416 }
01417
01418 switch (inStereo) {
01419 case OPENGL_STEREO_DTISIDE:
01420 glViewport((GLsizei)xSize / 2, 0, (GLsizei)xSize / 2, (GLsizei)ySize);
01421 set_persp(cureye);
01422 break;
01423
01424 case OPENGL_STEREO_SIDE:
01425 glViewport((GLsizei)xSize / 2, 0, (GLsizei)xSize / 2, (GLsizei)ySize);
01426 set_persp(cureye);
01427 break;
01428
01429 case OPENGL_STEREO_ABOVEBELOW:
01430 glViewport(0, (GLsizei)ySize / 2, (GLsizei)xSize, (GLsizei)ySize / 2);
01431 set_persp(cureye);
01432 break;
01433
01434 case OPENGL_STEREO_LEFT:
01435 case OPENGL_STEREO_RIGHT:
01436
01437 break;
01438
01439 case OPENGL_STEREO_QUADBUFFER:
01440 if (ext->hasstereo) {
01441 glDepthMask(GL_TRUE);
01442 #if defined(__APPLE__)
01443
01444
01445
01446
01447 glDrawBuffer(GL_BACK_RIGHT);
01448 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
01449 #else
01450
01451 glClear(GL_DEPTH_BUFFER_BIT);
01452 #endif
01453 glDrawBuffer(GL_BACK_RIGHT);
01454 } else {
01455
01456 glViewport(0, 0, (GLsizei)xSize, (GLsizei)ySize / 2);
01457 }
01458 set_persp(cureye);
01459 break;
01460
01461 case OPENGL_STEREO_STENCIL_CHECKERBOARD:
01462 case OPENGL_STEREO_STENCIL_COLUMNS:
01463 case OPENGL_STEREO_STENCIL_ROWS:
01464 glDepthMask(GL_TRUE);
01465 glClear(GL_DEPTH_BUFFER_BIT);
01466 glStencilFunc(GL_EQUAL,1,1);
01467 set_persp(cureye);
01468 break;
01469
01470 case OPENGL_STEREO_ANAGLYPH:
01471 if(ext->hasstereo) {
01472 glDrawBuffer(GL_BACK_RIGHT);
01473 }
01474
01475
01476 #if 1
01477
01478
01479 glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE);
01480 #else
01481
01482 glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE);
01483 #endif
01484 glDepthMask(GL_TRUE);
01485 glClear(GL_DEPTH_BUFFER_BIT);
01486 set_persp(cureye);
01487 break;
01488
01489 default:
01490 normal();
01491
01492 #if defined(__APPLE__)
01493 if (ext->hasstereo && ext->stereodrawforced)
01494 glDrawBuffer(GL_BACK_RIGHT);
01495 #endif
01496 break;
01497 }
01498
01499
01500 draw_background_gradient();
01501 }
01502
01503
01504
01505
01506 void OpenGLRenderer::set_persp(DisplayEye my_eye) {
01507
01508 GLdouble ep[3];
01509 switch (my_eye) {
01510 case LEFTEYE:
01511 ep[0] = eyePos[0] - eyeSepDir[0];
01512 ep[1] = eyePos[1] - eyeSepDir[1];
01513 ep[2] = eyePos[2] - eyeSepDir[2];
01514 DisplayDevice::left();
01515 break;
01516 case RIGHTEYE:
01517 ep[0] = eyePos[0] + eyeSepDir[0];
01518 ep[1] = eyePos[1] + eyeSepDir[1];
01519 ep[2] = eyePos[2] + eyeSepDir[2];
01520 DisplayDevice::right();
01521 break;
01522
01523 case NOSTEREO:
01524 default:
01525 ep[0] = eyePos[0];
01526 ep[1] = eyePos[1];
01527 ep[2] = eyePos[2];
01528 DisplayDevice::normal();
01529 break;
01530 }
01531
01532
01533 if (projection() == PERSPECTIVE) {
01534 ogl_glslprojectionmode = DisplayDevice::PERSPECTIVE;
01535
01536 if (shearstereo) {
01537
01538
01539
01540
01541
01542
01543
01544
01545 float eyeshift = float(ep[0] - eyePos[0]);
01546
01547 glMatrixMode(GL_PROJECTION);
01548 glLoadIdentity();
01549
01550
01551
01552
01553 glFrustum((GLdouble)cpLeft + (eyeshift * nearClip / eyeDist),
01554 (GLdouble)cpRight + (eyeshift * nearClip / eyeDist),
01555 (GLdouble)cpDown,
01556 (GLdouble)cpUp,
01557 (GLdouble)nearClip,
01558 (GLdouble)farClip);
01559
01560
01561
01562 glTranslatef(-eyeshift, 0.0, 0.0);
01563
01564 glMatrixMode(GL_MODELVIEW);
01565 glLoadIdentity();
01566 gluLookAt(eyePos[0], eyePos[1], eyePos[2],
01567 (GLdouble)(eyePos[0] + eyeDir[0]),
01568 (GLdouble)(eyePos[1] + eyeDir[1]),
01569 (GLdouble)(eyePos[2] + eyeDir[2]),
01570 (GLdouble)(upDir[0]),
01571 (GLdouble)(upDir[1]),
01572 (GLdouble)(upDir[2]));
01573 } else {
01574
01575
01576
01577
01578 glMatrixMode(GL_PROJECTION);
01579 glLoadIdentity();
01580 glFrustum((GLdouble)cpLeft, (GLdouble)cpRight, (GLdouble)cpDown,
01581 (GLdouble)cpUp, (GLdouble)nearClip, (GLdouble)farClip);
01582
01583
01584
01585
01586 if (immersadeskflip && my_eye == RIGHTEYE) {
01587
01588 glScalef(-1, 1, 1);
01589 }
01590
01591 glMatrixMode(GL_MODELVIEW);
01592 glLoadIdentity();
01593 gluLookAt(ep[0], ep[1], ep[2],
01594 (GLdouble)(eyePos[0] + eyeDir[0]),
01595 (GLdouble)(eyePos[1] + eyeDir[1]),
01596 (GLdouble)(eyePos[2] + eyeDir[2]),
01597 (GLdouble)(upDir[0]),
01598 (GLdouble)(upDir[1]),
01599 (GLdouble)(upDir[2]));
01600 }
01601 } else {
01602 ogl_glslprojectionmode = DisplayDevice::ORTHOGRAPHIC;
01603 glMatrixMode(GL_PROJECTION);
01604 glLoadIdentity();
01605
01606 glOrtho(-0.25 * vSize * Aspect, 0.25 * vSize * Aspect,
01607 -0.25 * vSize, 0.25 * vSize,
01608 nearClip, farClip);
01609
01610
01611
01612
01613
01614 glMatrixMode(GL_MODELVIEW);
01615 glLoadIdentity();
01616 gluLookAt(ep[0], ep[1], ep[2],
01617 (GLdouble)(eyePos[0] + eyeDir[0]),
01618 (GLdouble)(eyePos[1] + eyeDir[1]),
01619 (GLdouble)(eyePos[2] + eyeDir[2]),
01620 (GLdouble)(upDir[0]),
01621 (GLdouble)(upDir[1]),
01622 (GLdouble)(upDir[2]));
01623 }
01624
01625
01626 glGetFloatv(GL_PROJECTION_MATRIX, ogl_pmatrix);
01627 glGetFloatv(GL_MODELVIEW_MATRIX, ogl_mvmatrix);
01628 glGetIntegerv(GL_VIEWPORT, ogl_viewport);
01629 ogl_textMat.identity();
01630 ogl_textMat.multmatrix(ogl_pmatrix);
01631 ogl_textMat.multmatrix(ogl_mvmatrix);
01632 }
01633
01634
01635
01636 int OpenGLRenderer::prepare3D(int do_clear) {
01637 if (do_clear) {
01638 clear();
01639 } else {
01640 glDepthMask(GL_TRUE);
01641 glClear(GL_DEPTH_BUFFER_BIT);
01642 }
01643
01644
01645
01646
01647 oglmaterialindex = -1;
01648
01649
01650 displaylistcache.markUnused();
01651 texturecache.markUnused();
01652
01653 return TRUE;
01654 }
01655
01656
01657
01658 int OpenGLRenderer::prepareOpaque(void) {
01659 if (ogl_useblendedtrans) {
01660 glDepthMask(GL_TRUE);
01661 ogl_transpass = 0;
01662 }
01663
01664 return 1;
01665 }
01666
01667
01668 int OpenGLRenderer::prepareTrans(void) {
01669 if (ogl_useblendedtrans) {
01670 glDepthMask(GL_FALSE);
01671 ogl_transpass = 1;
01672 return 1;
01673 }
01674
01675 return 0;
01676 }
01677
01678
01679 void OpenGLRenderer::clear(void) {
01680
01681 switch (inStereo) {
01682 case OPENGL_STEREO_DTISIDE:
01683 case OPENGL_STEREO_SIDE:
01684 case OPENGL_STEREO_ABOVEBELOW:
01685 case OPENGL_STEREO_QUADBUFFER:
01686 case OPENGL_STEREO_ANAGLYPH:
01687 glViewport(0, 0, (GLsizei)xSize, (GLsizei)ySize);
01688 break;
01689 }
01690
01691 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
01692 glDepthMask(GL_TRUE);
01693 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
01694
01695
01696 #if defined(__APPLE__)
01697 if (ext->hasstereo && ext->stereodrawforced) {
01698 glDrawBuffer(GL_BACK_RIGHT);
01699 glClear(GL_COLOR_BUFFER_BIT);
01700 glDrawBuffer(GL_BACK);
01701 }
01702 #endif
01703 }
01704
01705
01706
01707 void OpenGLRenderer::draw_background_gradient(void) {
01708
01709
01710 if (backgroundmode != 0) {
01711 int i;
01712
01713
01714 for (i=0; i < VMD_MAX_CLIP_PLANE; i++) {
01715 ogl_clipmode[i] = 0;
01716 glDisable((GLenum) (GL_CLIP_PLANE0 + i));
01717 }
01718
01719 glDisable(GL_LIGHTING);
01720 ogl_lightingenabled=0;
01721 #if defined(VMDUSEOPENGLSHADER)
01722 if (mainshader && ogl_useglslshader) {
01723 mainshader->UseShader(0);
01724 }
01725 #endif
01726 glDisable(GL_DEPTH_TEST);
01727 glDepthMask(GL_FALSE);
01728
01729
01730 glDisable(GL_POLYGON_STIPPLE);
01731 glDisable(GL_BLEND);
01732
01733 glMatrixMode(GL_MODELVIEW);
01734 glPushMatrix();
01735 glLoadIdentity();
01736
01737 glMatrixMode (GL_PROJECTION);
01738 glPushMatrix();
01739 glLoadIdentity();
01740 glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
01741
01742 glMatrixMode(GL_MODELVIEW);
01743 glPushMatrix();
01744 glLoadIdentity();
01745
01746
01747 glBegin(GL_QUADS);
01748 glColor3fv(&ogl_backgradient[1][0]);
01749 glVertex2f(0.0f, 0.0f);
01750 glColor3fv(&ogl_backgradient[1][0]);
01751 glVertex2f(1.0f, 0.0f);
01752 glColor3fv(&ogl_backgradient[0][0]);
01753 glVertex2f(1.0f, 1.0f);
01754 glColor3fv(&ogl_backgradient[0][0]);
01755 glVertex2f(0.0f, 1.0f);
01756 glEnd();
01757
01758 glPopMatrix();
01759
01760 glMatrixMode (GL_PROJECTION);
01761 glPopMatrix();
01762
01763 glMatrixMode(GL_MODELVIEW);
01764 glPopMatrix();
01765
01766 glEnable(GL_DEPTH_TEST);
01767 glDepthMask(GL_TRUE);
01768 glEnable(GL_LIGHTING);
01769 ogl_lightingenabled=1;
01770 #if defined(VMDUSEOPENGLSHADER)
01771 if (mainshader && ogl_useglslshader) {
01772 mainshader->UseShader(1);
01773 }
01774 #endif
01775 }
01776 }
01777
01778
01779
01780
01781
01782
01783 void OpenGLRenderer::render(const VMDDisplayList *cmdList) {
01784 char *cmdptr = NULL;
01785 int tok;
01786 _needRedraw = 0;
01787
01788
01789 if (!cmdList)
01790 return;
01791
01792 if (ogl_useblendedtrans) {
01793 if (ogl_transpass) {
01794
01795 if (cmdList->opacity > 0.50)
01796 return;
01797 } else {
01798
01799 if (cmdList->opacity <= 0.50)
01800 return;
01801 }
01802 } else {
01803 if (cmdList->opacity < 0.0625)
01804 return;
01805 }
01806
01807
01808
01809
01810 if (ogl_acrobat3dcapture) {
01811 oglmaterialindex = -1;
01812 oglambient = -1;
01813 ogldiffuse = -1;
01814 oglspecular = -1;
01815 oglshininess = -1;
01816 ogloutline = -1;
01817 ogloutlinewidth = -1;
01818 ogltransmode = -1;
01819 }
01820
01821
01822
01823
01824 if (oglmaterialindex != cmdList->materialtag) {
01825 float matbuf[4];
01826 matbuf[3] = 1.0f;
01827 int recalcambientlights = 0;
01828 int recalcdiffuselights = 0;
01829
01830 oglmaterialindex = cmdList->materialtag;
01831 if (oglopacity != cmdList->opacity) {
01832 oglopacity = cmdList->opacity;
01833
01834 if (ogl_useblendedtrans) {
01835 glDisable(GL_POLYGON_STIPPLE);
01836 if (oglopacity > 0.999) {
01837
01838 glDisable(GL_BLEND);
01839 } else {
01840 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
01841 glEnable(GL_BLEND);
01842 }
01843 } else {
01844
01845 glDisable(GL_BLEND);
01846
01847
01848 if (oglopacity > 0.9375) {
01849 glDisable(GL_POLYGON_STIPPLE);
01850 } else {
01851
01852 if (oglopacity > 0.875)
01853 glPolygonStipple(ninesixteentone);
01854 else if (oglopacity > 0.75)
01855 glPolygonStipple(seveneighthtone);
01856 else if (oglopacity > 0.5)
01857 glPolygonStipple(threequartertone);
01858 else if (oglopacity > 0.25)
01859 glPolygonStipple(halftone);
01860 else if (oglopacity > 0.125)
01861 glPolygonStipple(quartertone);
01862 else if (oglopacity > 0.0625)
01863 glPolygonStipple(eighthtone);
01864 else
01865 return;
01866
01867 glEnable(GL_POLYGON_STIPPLE);
01868 }
01869 }
01870 }
01871
01872 if (ogloutline != cmdList->outline) {
01873 ogloutline = cmdList->outline;
01874 }
01875
01876 if (ogloutlinewidth != cmdList->outlinewidth) {
01877 ogloutlinewidth = cmdList->outlinewidth;
01878 }
01879
01880 if (ogltransmode != (int) cmdList->transmode) {
01881 ogltransmode = (int) cmdList->transmode;
01882 }
01883
01884 if (oglambient != cmdList->ambient) {
01885 oglambient = cmdList->ambient;
01886 recalcambientlights = 1;
01887 matbuf[0] = matbuf[1] = matbuf[2] = oglambient;
01888 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, matbuf);
01889 }
01890
01891 if (ogldiffuse != cmdList->diffuse) {
01892 ogldiffuse = cmdList->diffuse;
01893 recalcdiffuselights = 1;
01894 matbuf[0] = matbuf[1] = matbuf[2] = ogldiffuse;
01895 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matbuf);
01896 }
01897
01898 if (oglspecular != cmdList->specular) {
01899 oglspecular = cmdList->specular;
01900 matbuf[0] = matbuf[1] = matbuf[2] = oglspecular;
01901 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matbuf);
01902 }
01903
01904 if (oglshininess != cmdList->shininess) {
01905 oglshininess = cmdList->shininess;
01906
01907
01908
01909
01910 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS,
01911 (GLfloat) (oglshininess < 128.0f) ? oglshininess : 128.0f);
01912 }
01913
01914
01915 if (recalcambientlights) {
01916 for (int z=0; z<DISP_LIGHTS; z++) {
01917 GLfloat d[4];
01918 d[0] = ogl_lightcolor[z][0] * oglambient;
01919 d[1] = ogl_lightcolor[z][1] * oglambient;
01920 d[2] = ogl_lightcolor[z][2] * oglambient;
01921 d[3] = 1.0;
01922 glLightfv((GLenum)(GL_LIGHT0 + z), GL_AMBIENT, d);
01923 }
01924 }
01925
01926 if (recalcdiffuselights) {
01927 for (int z=0; z<DISP_LIGHTS; z++) {
01928 GLfloat d[4];
01929 d[0] = ogl_lightcolor[z][0] * ogldiffuse;
01930 d[1] = ogl_lightcolor[z][1] * ogldiffuse;
01931 d[2] = ogl_lightcolor[z][2] * ogldiffuse;
01932 d[3] = 1.0;
01933 glLightfv((GLenum)(GL_LIGHT0 + z), GL_DIFFUSE, d);
01934 }
01935 }
01936 }
01937
01938
01939
01940
01941
01942 ogl_fogmode = 0;
01943
01944 if (cueingEnabled) {
01945 switch (cueMode) {
01946 case CUE_LINEAR:
01947 glFogi(GL_FOG_MODE, GL_LINEAR);
01948 ogl_fogmode = 1;
01949 break;
01950
01951 case CUE_EXP:
01952 glFogi(GL_FOG_MODE, GL_EXP);
01953 ogl_fogmode = 2;
01954 break;
01955
01956 case CUE_EXP2:
01957 glFogi(GL_FOG_MODE, GL_EXP2);
01958 ogl_fogmode = 3;
01959 break;
01960
01961 case NUM_CUE_MODES:
01962
01963 break;
01964 }
01965
01966 glFogf(GL_FOG_DENSITY, (GLfloat) get_cue_density());
01967 glFogf(GL_FOG_START, (GLfloat) get_cue_start());
01968 glFogf(GL_FOG_END, (GLfloat) get_cue_end());
01969 }
01970
01971 #if defined(VMDUSEOPENGLSHADER)
01972
01973 if (mainshader) {
01974 if (ogl_useglslshader) {
01975 mainshader->UseShader(1);
01976
01977 if ((ogl_glslmaterialindex != cmdList->materialtag) || ogl_glsltoggle) {
01978 ogl_glslmaterialindex = cmdList->materialtag;
01979 ogl_glsltoggle = 0;
01980 update_shader_uniforms(mainshader, 1);
01981 }
01982 } else {
01983 mainshader->UseShader(0);
01984 }
01985 }
01986 #endif
01987
01988
01989 glMatrixMode(GL_MODELVIEW);
01990 glPushMatrix();
01991 multmatrix(cmdList->mat);
01992
01993
01994 GLfloat textsize = 1;
01995 Matrix4 textMat(ogl_textMat);
01996 textMat.multmatrix(cmdList->mat);
01997
01998
01999 GLuint ogl_cachedid = 0;
02000 int ogl_cachecreated = 0;
02001 int ogl_cacheskip;
02002
02003
02004
02005 ogl_cacheskip = (cmdList->cacheskip || ogl_useglslshader);
02006
02007
02008 for (int cp=0; cp<VMD_MAX_CLIP_PLANE; cp++) {
02009
02010
02011 if (cmdList->clipplanes[cp].mode) {
02012 GLdouble cpeq[4];
02013 cpeq[0] = cmdList->clipplanes[cp].normal[0];
02014 cpeq[1] = cmdList->clipplanes[cp].normal[1];
02015 cpeq[2] = cmdList->clipplanes[cp].normal[2];
02016
02017
02018 cpeq[3] =
02019 -(cmdList->clipplanes[cp].normal[0] * cmdList->clipplanes[cp].center[0] +
02020 cmdList->clipplanes[cp].normal[1] * cmdList->clipplanes[cp].center[1] +
02021 cmdList->clipplanes[cp].normal[2] * cmdList->clipplanes[cp].center[2]);
02022 glClipPlane((GLenum) (GL_CLIP_PLANE0 + cp), cpeq);
02023 glEnable((GLenum) (GL_CLIP_PLANE0 + cp));
02024
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035
02036
02037
02038
02039
02040
02041
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051 } else {
02052
02053 if (ogl_clipmode[cp] != cmdList->clipplanes[cp].mode) {
02054 glDisable((GLenum) (GL_CLIP_PLANE0 + cp));
02055 }
02056 }
02057
02058
02059 ogl_clipmode[cp] = cmdList->clipplanes[cp].mode;
02060 }
02061
02062
02063
02064 ResizeArray<Matrix4> pbcImages;
02065 find_pbc_images(cmdList, pbcImages);
02066
02067
02068
02069
02070 float textoffset_x = 0, textoffset_y = 0;
02071
02072 int nimages = pbcImages.num();
02073 for (int pbcimage = 0; pbcimage < nimages; pbcimage++) {
02074 glPushMatrix();
02075 multmatrix(pbcImages[pbcimage]);
02076
02077 if (ogl_cachedebug) {
02078 msgInfo << "Rendering scene: cache enable=" << ogl_cacheenabled
02079 << ", created=" << ogl_cachecreated << ", serial=" << (int)cmdList->serial
02080 << ", id=" << (int)ogl_cachedid << ", skip=" << ogl_cacheskip << sendmsg;
02081 }
02082
02083
02084 if (ogl_cacheenabled && !ogl_cacheskip) {
02085 ogl_cachedid = displaylistcache.markUsed(cmdList->serial);
02086
02087
02088 if (ogl_cachedid == GLCACHE_FAIL) {
02089 ogl_cachedid = glGenLists(1);
02090 displaylistcache.encache(cmdList->serial, ogl_cachedid);
02091
02092
02093 glNewList(ogl_cachedid, GL_COMPILE_AND_EXECUTE);
02094 ogl_cachecreated = 1;
02095 }
02096 }
02097
02098
02099
02100 if ((!ogl_cacheenabled) || ogl_cacheskip || (ogl_cacheenabled && ogl_cachecreated)) {
02101
02102
02103
02104 VMDDisplayList::VMDLinkIter cmditer;
02105 cmdList->first(&cmditer);
02106 while((tok = cmdList->next(&cmditer, cmdptr)) != DLASTCOMMAND) {
02107 OGLERR
02108
02109 switch (tok) {
02110 case DPOINT:
02111
02112 glBegin(GL_POINTS);
02113 glVertex3fv(((DispCmdPoint *)cmdptr)->pos);
02114 glEnd();
02115 break;
02116
02117 case DPOINTARRAY:
02118 {
02119 DispCmdPointArray *pa = (DispCmdPointArray *)cmdptr;
02120 float *centers;
02121 float *colors;
02122 pa->getpointers(centers, colors);
02123 #if defined(GL_VERSION_1_1)
02124 if (!(simplegraphics || ogl_acrobat3dcapture)) {
02125
02126 glDisable(GL_LIGHTING);
02127 ogl_lightingenabled=0;
02128 glEnableClientState(GL_VERTEX_ARRAY);
02129 glEnableClientState(GL_COLOR_ARRAY);
02130 glDisableClientState(GL_NORMAL_ARRAY);
02131 glVertexPointer(3, GL_FLOAT, 12, (void *) centers);
02132 glColorPointer(3, GL_FLOAT, 12, (void *) colors);
02133
02134 #if defined(GL_EXT_compiled_vertex_array)
02135 if (ext->hascompiledvertexarrayext) {
02136 GLLOCKARRAYSEXT(0, pa->numpoints);
02137 }
02138 #endif
02139
02140
02141 glPointSize(pa->size);
02142 glEnable(GL_POINT_SMOOTH);
02143 glEnable(GL_BLEND);
02144 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
02145
02146 #if defined(VMDUSEGLSLSPHERESPRITES) && defined(GL_ARB_point_sprite)
02147
02148 if (ext->hasglpointspritearb &&
02149 spherespriteshader && ogl_useglslshader) {
02150 glEnable(GL_POINT_SPRITE_ARB);
02151 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
02152 mainshader->UseShader(0);
02153 spherespriteshader->UseShader(1);
02154 update_shader_uniforms(spherespriteshader, 1);
02155
02156
02157 GLint loc;
02158 loc = GLGETUNIFORMLOCATIONARB(spherespriteshader->ProgramObject,
02159 "vmdspritesize");
02160 GLfloat sz = pa->size;
02161 GLUNIFORM1FVARB(loc, 1, &sz);
02162
02163
02164 glPushAttrib(GL_TEXTURE_BIT);
02165 glTexEnvf(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);
02166 OGLERR;
02167 }
02168 #endif
02169
02170 #if defined(GL_ARB_point_parameters)
02171 int dodepthscaling = 0;
02172
02173
02174 if (ext->hasglpointparametersext && (projection() == PERSPECTIVE)) {
02175 dodepthscaling = 1;
02176
02177 GLfloat abc[4] = {0.0, 0.0, 1.0};
02178 GLPOINTPARAMETERFVARB(GL_POINT_DISTANCE_ATTENUATION_ARB, abc);
02179 }
02180 #endif
02181
02182 glDrawArrays(GL_POINTS, 0, pa->numpoints);
02183
02184 #if defined(GL_ARB_point_parameters)
02185
02186 if (dodepthscaling) {
02187 GLfloat abc[4] = {1.0, 0.0, 0.0};
02188 GLPOINTPARAMETERFVARB(GL_POINT_DISTANCE_ATTENUATION_ARB, abc);
02189 }
02190 #endif
02191
02192
02193 glDisable(GL_BLEND);
02194 glDisable(GL_POINT_SMOOTH);
02195
02196 #if defined(GL_EXT_compiled_vertex_array)
02197 if (ext->hascompiledvertexarrayext) {
02198 GLUNLOCKARRAYSEXT();
02199 }
02200 #endif
02201
02202 #if defined(VMDUSEGLSLSPHERESPRITES) && defined(GL_ARB_point_sprite)
02203
02204 if (ext->hasglpointspritearb &&
02205 spherespriteshader && ogl_useglslshader) {
02206 glPopAttrib();
02207 glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
02208 glDisable(GL_POINT_SPRITE_ARB);
02209 spherespriteshader->UseShader(0);
02210 mainshader->UseShader(1);
02211 OGLERR;
02212 }
02213 #endif
02214
02215 glEnableClientState(GL_NORMAL_ARRAY);
02216 glPointSize(1.0);
02217 } else {
02218 #endif
02219
02220 int i, ind;
02221 glBegin(GL_POINTS);
02222 ind = 0;
02223 for (i=0; i<pa->numpoints; i++) {
02224 glColor3fv(&colors[ind]);
02225 glVertex3fv(¢ers[ind]);
02226 ind += 3;
02227 }
02228 glEnd();
02229 #if defined(GL_VERSION_1_1)
02230 }
02231 #endif
02232 }
02233 break;
02234
02235 case DLITPOINTARRAY:
02236 {
02237 DispCmdLitPointArray *pa = (DispCmdLitPointArray *)cmdptr;
02238 float *centers;
02239 float *normals;
02240 float *colors;
02241 pa->getpointers(centers, normals, colors);
02242 #if defined(GL_VERSION_1_1)
02243 if (!(simplegraphics || ogl_acrobat3dcapture)) {
02244
02245 glEnableClientState(GL_VERTEX_ARRAY);
02246 glEnableClientState(GL_COLOR_ARRAY);
02247 glEnableClientState(GL_NORMAL_ARRAY);
02248 glVertexPointer(3, GL_FLOAT, 12, (void *) centers);
02249 glNormalPointer(GL_FLOAT, 12, (void *) normals);
02250 glColorPointer(3, GL_FLOAT, 12, (void *) colors);
02251
02252 #if defined(GL_EXT_compiled_vertex_array)
02253 if (ext->hascompiledvertexarrayext) {
02254 GLLOCKARRAYSEXT(0, pa->numpoints);
02255 }
02256 #endif
02257
02258
02259 glPointSize(pa->size);
02260 glEnable(GL_POINT_SMOOTH);
02261
02262 #if defined(GL_ARB_point_parameters)
02263 int dodepthscaling = 0;
02264
02265 if (ext->hasglpointparametersext && (projection() == PERSPECTIVE)) {
02266 dodepthscaling = 1;
02267 GLfloat abc[4] = {0.0, 0.0, 1.0};
02268 GLPOINTPARAMETERFVARB(GL_POINT_DISTANCE_ATTENUATION_ARB, abc);
02269 }
02270 #endif
02271
02272 glDrawArrays(GL_POINTS, 0, pa->numpoints);
02273
02274 #if defined(GL_ARB_point_parameters)
02275
02276 if (dodepthscaling) {
02277 GLfloat abc[4] = {1.0, 0.0, 0.0};
02278 GLPOINTPARAMETERFVARB(GL_POINT_DISTANCE_ATTENUATION_ARB, abc);
02279 }
02280 #endif
02281
02282
02283 glDisable(GL_BLEND);
02284 glDisable(GL_POINT_SMOOTH);
02285
02286 #if defined(GL_EXT_compiled_vertex_array)
02287 if (ext->hascompiledvertexarrayext) {
02288 GLUNLOCKARRAYSEXT();
02289 }
02290 #endif
02291
02292 glPointSize(1.0);
02293 } else {
02294 #endif
02295
02296 int i, ind;
02297 glBegin(GL_POINTS);
02298 ind = 0;
02299 for (i=0; i<pa->numpoints; i++) {
02300 glColor3fv(&colors[ind]);
02301 glNormal3fv(&normals[ind]);
02302 glVertex3fv(¢ers[ind]);
02303 ind += 3;
02304 }
02305 glEnd();
02306 #if defined(GL_VERSION_1_1)
02307 }
02308 #endif
02309 }
02310 break;
02311
02312 case DLINE:
02313
02314 glBegin(GL_LINES);
02315 glVertex3fv(((DispCmdLine *)cmdptr)->pos1);
02316 glVertex3fv(((DispCmdLine *)cmdptr)->pos2);
02317 glEnd();
02318 break;
02319
02320 case DLINEARRAY:
02321 {
02322 float *v = (float *)(cmdptr);
02323 int nlines = (int)v[0];
02324 v++;
02325
02326 #if defined(GL_VERSION_1_1)
02327 if (!(simplegraphics || ogl_acrobat3dcapture)) {
02328
02329 glInterleavedArrays(GL_V3F, 0, v);
02330
02331 #if defined(GL_EXT_compiled_vertex_array)
02332 if (ext->hascompiledvertexarrayext) {
02333 GLLOCKARRAYSEXT(0, 2*nlines);
02334 }
02335 #endif
02336
02337 glDrawArrays(GL_LINES, 0, 2*nlines);
02338
02339 #if defined(GL_EXT_compiled_vertex_array)
02340 if (ext->hascompiledvertexarrayext) {
02341 GLUNLOCKARRAYSEXT();
02342 }
02343 #endif
02344 } else {
02345 #endif
02346
02347 glBegin(GL_LINES);
02348 for (int i=0; i<nlines; i++) {
02349 glVertex3fv(v);
02350 glVertex3fv(v+3);
02351 v += 6;
02352 }
02353 glEnd();
02354 #if defined(GL_VERSION_1_1)
02355 }
02356 #endif
02357 }
02358 break;
02359
02360 case DPOLYLINEARRAY:
02361 {
02362 float *v = (float *)(cmdptr);
02363 int nverts = (int)v[0];
02364 v++;
02365
02366 #if defined(GL_VERSION_1_1)
02367 if (!(simplegraphics || ogl_acrobat3dcapture)) {
02368
02369 glInterleavedArrays(GL_V3F, 0, v);
02370
02371 #if defined(GL_EXT_compiled_vertex_array)
02372 if (ext->hascompiledvertexarrayext) {
02373 GLLOCKARRAYSEXT(0, nverts);
02374 }
02375 #endif
02376
02377 glDrawArrays(GL_LINE_STRIP, 0, nverts);
02378
02379 #if defined(GL_EXT_compiled_vertex_array)
02380 if (ext->hascompiledvertexarrayext) {
02381 GLUNLOCKARRAYSEXT();
02382 }
02383 #endif
02384 } else {
02385 #endif
02386
02387 glBegin(GL_LINE_STRIP);
02388 for (int i=0; i<nverts; i++) {
02389 glVertex3fv(v);
02390 v += 3;
02391 }
02392 glEnd();
02393 #if defined(GL_VERSION_1_1)
02394 }
02395 #endif
02396 }
02397 break;
02398
02399 case DSPHERE:
02400 {
02401 float *p = (float *)cmdptr;
02402 glPushMatrix();
02403 glTranslatef(p[0], p[1], p[2]);
02404 glScalef(p[3], p[3], p[3]);
02405 glCallList(SphereList);
02406 glPopMatrix();
02407 }
02408 break;
02409
02410 case DSPHEREARRAY:
02411 {
02412 DispCmdSphereArray *sa = (DispCmdSphereArray *)cmdptr;
02413 int i, ind;
02414 float * centers;
02415 float * radii;
02416 float * colors;
02417 sa->getpointers(centers, radii, colors);
02418
02419 #if defined(VMDUSEGLSLSPHERES)
02420
02421 if (sphereshader && ogl_useglslshader) {
02422
02423 GLfloat v0[] = {-1.0, -1.0, -1.0};
02424 GLfloat v1[] = { 1.0, -1.0, -1.0};
02425 GLfloat v2[] = {-1.0, 1.0, -1.0};
02426 GLfloat v3[] = { 1.0, 1.0, -1.0};
02427 GLfloat v4[] = {-1.0, -1.0, 1.0};
02428 GLfloat v5[] = { 1.0, -1.0, 1.0};
02429 GLfloat v6[] = {-1.0, 1.0, 1.0};
02430 GLfloat v7[] = { 1.0, 1.0, 1.0};
02431
02432 mainshader->UseShader(0);
02433 sphereshader->UseShader(1);
02434 update_shader_uniforms(sphereshader, 1);
02435
02436
02437 GLfloat projparms[4];
02438 projparms[0] = nearClip;
02439 projparms[1] = farClip;
02440 projparms[2] = 0.5f * (farClip + nearClip);
02441 projparms[3] = 1.0f / (farClip - nearClip);
02442 GLint projloc = GLGETUNIFORMLOCATIONARB(sphereshader->ProgramObject, "vmdprojparms");
02443 GLUNIFORM4FVARB(projloc, 1, projparms);
02444 OGLERR;
02445
02446 ind = 0;
02447 for (i=0; i<sa->numspheres; i++) {
02448 glPushMatrix();
02449 glTranslatef(centers[ind], centers[ind + 1], centers[ind + 2]);
02450 glScalef(radii[i], radii[i], radii[i]);
02451 glColor3fv(&colors[ind]);
02452
02453
02454
02455
02456
02457
02458
02459 glBegin(GL_QUADS);
02460 glVertex3fv((GLfloat *) v0);
02461 glVertex3fv((GLfloat *) v1);
02462 glVertex3fv((GLfloat *) v3);
02463 glVertex3fv((GLfloat *) v2);
02464
02465 glVertex3fv((GLfloat *) v4);
02466 glVertex3fv((GLfloat *) v5);
02467 glVertex3fv((GLfloat *) v7);
02468 glVertex3fv((GLfloat *) v6);
02469
02470 glVertex3fv((GLfloat *) v0);
02471 glVertex3fv((GLfloat *) v1);
02472 glVertex3fv((GLfloat *) v5);
02473 glVertex3fv((GLfloat *) v4);
02474
02475 glVertex3fv((GLfloat *) v2);
02476 glVertex3fv((GLfloat *) v3);
02477 glVertex3fv((GLfloat *) v7);
02478 glVertex3fv((GLfloat *) v6);
02479
02480 glVertex3fv((GLfloat *) v0);
02481 glVertex3fv((GLfloat *) v2);
02482 glVertex3fv((GLfloat *) v6);
02483 glVertex3fv((GLfloat *) v4);
02484
02485 glVertex3fv((GLfloat *) v1);
02486 glVertex3fv((GLfloat *) v3);
02487 glVertex3fv((GLfloat *) v7);
02488 glVertex3fv((GLfloat *) v5);
02489 glEnd();
02490 glPopMatrix();
02491 ind += 3;
02492 }
02493
02494 sphereshader->UseShader(0);
02495 mainshader->UseShader(1);
02496 OGLERR;
02497 } else {
02498 #endif
02499
02500 set_sphere_res(sa->sphereres);
02501
02502
02503
02504 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
02505 ind = 0;
02506 for (i=0; i<sa->numspheres; i++) {
02507 glPushMatrix();
02508 glTranslatef(centers[ind], centers[ind + 1], centers[ind + 2]);
02509 glScalef(radii[i], radii[i], radii[i]);
02510 glColor3fv(&colors[ind]);
02511 glCallList(SphereList);
02512 glPopMatrix();
02513 ind += 3;
02514 }
02515 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
02516 #if defined(VMDUSEGLSLSPHERES)
02517 }
02518 #endif
02519
02520 }
02521 break;
02522
02523 case DTRIANGLE:
02524 {
02525 DispCmdTriangle *cmd = (DispCmdTriangle *)cmdptr;
02526 glBegin(GL_TRIANGLES);
02527 glNormal3fv(cmd->norm1);
02528 glVertex3fv(cmd->pos1);
02529 glNormal3fv(cmd->norm2);
02530 glVertex3fv(cmd->pos2);
02531 glNormal3fv(cmd->norm3);
02532 glVertex3fv(cmd->pos3);
02533 glEnd();
02534 }
02535 break;
02536
02537 case DSQUARE:
02538
02539 {
02540 DispCmdSquare *cmd = (DispCmdSquare *)cmdptr;
02541 glBegin(GL_QUADS);
02542 glNormal3fv((GLfloat *) cmd->norml);
02543 glVertex3fv((GLfloat *) cmd->pos1);
02544 glVertex3fv((GLfloat *) cmd->pos2);
02545 glVertex3fv((GLfloat *) cmd->pos3);
02546 glVertex3fv((GLfloat *) cmd->pos4);
02547 glEnd();
02548 }
02549 break;
02550
02551 #if 0
02552 case DSTRIPETEX:
02553 if (ext->hastex3d) {
02554 #if defined(GL_VERSION_1_2)
02555 #define STRIPEWIDTH 32
02556 GLubyte stripeImage[4 * STRIPEWIDTH];
02557 GLuint texName = 0;
02558
02559 int i;
02560 for (i=0; i<STRIPEWIDTH; i++) {
02561 stripeImage[4*i ] = (GLubyte) ((i>4) ? 255 : 0);
02562 stripeImage[4*i + 1] = (GLubyte) ((i>4) ? 255 : 0);
02563 stripeImage[4*i + 2] = (GLubyte) ((i>4) ? 255 : 0);
02564 stripeImage[4*i + 3] = (GLubyte) 255;
02565 }
02566
02567 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
02568 glBindTexture(GL_TEXTURE_1D, texName);
02569 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT);
02570 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_REPEAT);
02571 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_R, GL_REPEAT);
02572 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
02573 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
02574 glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, STRIPEWIDTH,
02575 0, GL_RGBA, GL_UNSIGNED_BYTE, stripeImage);
02576
02577
02578
02579
02580
02581 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
02582 GLfloat xplaneeq[4] = {0.5, 0.0, 0.0, 0.0};
02583 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
02584 glTexGenfv(GL_S, GL_EYE_PLANE, xplaneeq);
02585 glEnable(GL_TEXTURE_GEN_S);
02586 glEnable(GL_TEXTURE_1D);
02587 #endif
02588 }
02589 break;
02590
02591 case DSTRIPETEXOFF:
02592 if (ext->hastex3d) {
02593 #if defined(GL_VERSION_1_2)
02594 glDisable(GL_TEXTURE_GEN_S);
02595 glDisable(GL_TEXTURE_1D);
02596 #endif
02597 }
02598 break;
02599 #endif
02600
02601 case DVOLUMETEXTURE:
02602 if (ext->hastex3d)
02603 #if defined(GL_VERSION_1_2)
02604 {
02605
02606 #if defined(GL_GENERATE_MIPMAP_HINT)
02607
02608 glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
02609 #endif
02610 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
02611
02612 DispCmdVolumeTexture *cmd = (DispCmdVolumeTexture *)cmdptr;
02613 require_volume_texture(cmd->ID,
02614 cmd->xsize, cmd->ysize, cmd->zsize,
02615 cmd->texmap);
02616
02617 GLfloat xplaneeq[4];
02618 GLfloat yplaneeq[4];
02619 GLfloat zplaneeq[4];
02620 int i;
02621
02622 glEnable(GL_TEXTURE_3D);
02623 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
02624
02625 #if defined(VMDUSEOPENGLSHADER)
02626
02627 if (mainshader && ogl_useglslshader) {
02628 if (!ogl_lightingenabled)
02629 mainshader->UseShader(1);
02630 ogl_glsltexturemode = 1;
02631 GLint vmdtexturemode = 1;
02632 GLint loc = GLGETUNIFORMLOCATIONARB(mainshader->ProgramObject, "vmdtexturemode");
02633 GLUNIFORM1IARB(loc, vmdtexturemode);
02634
02635
02636 loc = GLGETUNIFORMLOCATIONARB(mainshader->ProgramObject, "vmdtex0");
02637 GLUNIFORM1IARB(loc, 0);
02638 if (!ogl_lightingenabled)
02639 mainshader->UseShader(0);
02640 }
02641 #endif
02642
02643
02644
02645
02646
02647 for (i=0; i<3; i++) {
02648 xplaneeq[i] = cmd->v1[i];
02649 yplaneeq[i] = cmd->v2[i];
02650 zplaneeq[i] = cmd->v3[i];
02651 }
02652 xplaneeq[3] = cmd->v0[0];
02653 yplaneeq[3] = cmd->v0[1];
02654 zplaneeq[3] = cmd->v0[2];
02655
02656 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
02657 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
02658 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
02659 glTexGenfv(GL_S, GL_EYE_PLANE, xplaneeq);
02660 glTexGenfv(GL_T, GL_EYE_PLANE, yplaneeq);
02661 glTexGenfv(GL_R, GL_EYE_PLANE, zplaneeq);
02662 glEnable(GL_TEXTURE_GEN_S);
02663 glEnable(GL_TEXTURE_GEN_T);
02664 glEnable(GL_TEXTURE_GEN_R);
02665 #endif
02666 }
02667 break;
02668
02669 case DVOLTEXON:
02670 if (ext->hastex3d) {
02671 #if defined(GL_VERSION_1_2)
02672 glEnable(GL_TEXTURE_3D);
02673 #if defined(VMDUSEOPENGLSHADER)
02674
02675 if (mainshader && ogl_useglslshader) {
02676 if (!ogl_lightingenabled)
02677 mainshader->UseShader(1);
02678 ogl_glsltexturemode = 1;
02679 GLint vmdtexturemode = 1;
02680 GLint loc = GLGETUNIFORMLOCATIONARB(mainshader->ProgramObject, "vmdtexturemode");
02681 GLUNIFORM1IARB(loc, vmdtexturemode);
02682 if (!ogl_lightingenabled)
02683 mainshader->UseShader(0);
02684 }
02685 #endif
02686 glEnable(GL_TEXTURE_GEN_S);
02687 glEnable(GL_TEXTURE_GEN_T);
02688 glEnable(GL_TEXTURE_GEN_R);
02689 #endif
02690 }
02691 break;
02692
02693 case DVOLTEXOFF:
02694 if (ext->hastex3d) {
02695 #if defined(GL_VERSION_1_2)
02696 glDisable(GL_TEXTURE_3D);
02697 #if defined(VMDUSEOPENGLSHADER)
02698
02699 if (mainshader && ogl_useglslshader) {
02700 if (!ogl_lightingenabled)
02701 mainshader->UseShader(1);
02702 ogl_glsltexturemode = 0;
02703 GLint vmdtexturemode = 0;
02704 GLint loc = GLGETUNIFORMLOCATIONARB(mainshader->ProgramObject, "vmdtexturemode");
02705 GLUNIFORM1IARB(loc, vmdtexturemode);
02706 if (!ogl_lightingenabled)
02707 mainshader->UseShader(0);
02708 }
02709 #endif
02710
02711 glDisable(GL_TEXTURE_GEN_S);
02712 glDisable(GL_TEXTURE_GEN_T);
02713 glDisable(GL_TEXTURE_GEN_R);
02714 #endif
02715 }
02716 break;
02717
02718
02719 case DVOLSLICE:
02720 if (ext->hastex3d) {
02721 DispCmdVolSlice *cmd = (DispCmdVolSlice *)cmdptr;
02722 #if defined(GL_VERSION_1_2)
02723
02724
02725
02726 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
02727
02728
02729 switch (cmd->texmode) {
02730 case 2:
02731 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
02732 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
02733 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
02734 break;
02735
02736 case 1:
02737 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_DONT_CARE);
02738 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
02739 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
02740 break;
02741
02742 case 0:
02743 default:
02744 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
02745 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
02746 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
02747 break;
02748 }
02749
02750
02751 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
02752 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
02753 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
02754
02755 #if defined(VMDUSEOPENGLSHADER)
02756
02757 if (mainshader && ogl_useglslshader) {
02758 ogl_glsltexturemode = 2;
02759 GLint vmdtexturemode = 2;
02760 GLint loc = GLGETUNIFORMLOCATIONARB(mainshader->ProgramObject, "vmdtexturemode");
02761 GLUNIFORM1IARB(loc, vmdtexturemode);
02762 }
02763 #endif
02764 glBegin(GL_QUADS);
02765 for (int i=0; i<4; i++) {
02766 glNormal3fv(cmd->normal);
02767 glVertex3fv(cmd->v + 3*i);
02768 }
02769 glEnd();
02770 #endif // GL_VERSION_1_2
02771 }
02772 break;
02773
02774 case DTRIMESH_C3F_N3F_V3F:
02775 {
02776
02777 DispCmdTriMesh *cmd = (DispCmdTriMesh *) cmdptr;
02778 float *colors=NULL, *normals=NULL, *vertices=NULL;
02779
02780 if (cmd->pervertexcolors)
02781 cmd->getpointers(colors, normals, vertices);
02782 else
02783 cmd->getpointers(normals, vertices);
02784
02785 #if 1
02786 #if defined(GL_VERSION_1_1)
02787 if (!(simplegraphics || ogl_acrobat3dcapture)) {
02788
02789 if (cmd->pervertexcolors)
02790 glEnableClientState(GL_COLOR_ARRAY);
02791 else
02792 glDisableClientState(GL_COLOR_ARRAY);
02793 glEnableClientState(GL_NORMAL_ARRAY);
02794 glEnableClientState(GL_VERTEX_ARRAY);
02795
02796 if (cmd->pervertexcolors)
02797 glColorPointer(3, GL_FLOAT, 0, (void *) colors);
02798 glNormalPointer(GL_FLOAT, 0, (void *) normals);
02799 glVertexPointer(3, GL_FLOAT, 0, (void *) vertices);
02800
02801 #if defined(GL_EXT_compiled_vertex_array)
02802 if (ext->hascompiledvertexarrayext) {
02803 GLLOCKARRAYSEXT(0, cmd->numverts);
02804 }
02805 #endif
02806
02807 glDrawArrays(GL_TRIANGLES, 0, cmd->numverts);
02808
02809 #if defined(GL_EXT_compiled_vertex_array)
02810 if (ext->hascompiledvertexarrayext) {
02811 GLUNLOCKARRAYSEXT();
02812 }
02813 #endif
02814 } else {
02815 #endif
02816
02817 int i, ind;
02818 glBegin(GL_TRIANGLES);
02819 ind = 0;
02820 if (cmd->pervertexcolors) {
02821 for (i=0; i<cmd->numverts; i++) {
02822 glColor3fv(&colors[ind]);
02823 glNormal3fv(&normals[ind]);
02824 glVertex3fv(&vertices[ind]);
02825 ind += 3;
02826 }
02827 } else {
02828 for (i=0; i<cmd->numverts; i++) {
02829 glNormal3fv(&normals[ind]);
02830 glVertex3fv(&vertices[ind]);
02831 ind += 3;
02832 }
02833 }
02834
02835 glEnd();
02836 #if defined(GL_VERSION_1_1)
02837 }
02838 #endif
02839
02840 #endif
02841 }
02842 break;
02843
02844 case DTRIMESH_C4F_N3F_V3F:
02845 {
02846
02847 DispCmdTriMesh *cmd = (DispCmdTriMesh *) cmdptr;
02848 int ind = cmd->numfacets * 3;
02849 float *cnv;
02850 int *f;
02851 cmd->getpointers(cnv, f);
02852
02853 #if defined(GL_VERSION_1_1)
02854
02855 if (!(simplegraphics || ogl_acrobat3dcapture)) {
02856
02857 glInterleavedArrays(GL_C4F_N3F_V3F, 0, cnv);
02858
02859 #if defined(GL_EXT_compiled_vertex_array)
02860 if (ext->hascompiledvertexarrayext) {
02861 GLLOCKARRAYSEXT(0, cmd->numverts);
02862 }
02863 #endif
02864
02865 glDrawElements(GL_TRIANGLES, ind, GL_UNSIGNED_INT, f);
02866
02867 #if defined(GL_EXT_compiled_vertex_array)
02868 if (ext->hascompiledvertexarrayext) {
02869 GLUNLOCKARRAYSEXT();
02870 }
02871 #endif
02872 } else {
02873 #endif
02874
02875
02876 if (!ogl_acrobat3dcapture) {
02877 int i, ind2;
02878 glBegin(GL_TRIANGLES);
02879 for (i=0; i<ind; i++) {
02880 ind2 = f[i] * 10;
02881 glColor3fv(cnv + ind2 );
02882 glNormal3fv(cnv + ind2 + 4);
02883 glVertex3fv(cnv + ind2 + 7);
02884 }
02885 glEnd();
02886 } else {
02887
02888
02889
02890 int i;
02891 for (i=0; i<cmd->numfacets; i++) {
02892 int ind = i * 3;
02893 float tmp[3], tmp2[3];
02894
02895 int v0 = f[ind ] * 10;
02896 int v1 = f[ind + 1] * 10;
02897 int v2 = f[ind + 2] * 10;
02898
02899 vec_add(tmp, cnv + v0, cnv + v1);
02900 vec_add(tmp2, tmp, cnv + v2);
02901 vec_scale(tmp, 0.3333333f, tmp2);
02902 glBegin(GL_TRIANGLES);
02903 glColor3fv(tmp);
02904 glNormal3fv(cnv + v0 + 4);
02905 glVertex3fv(cnv + v0 + 7);
02906 glNormal3fv(cnv + v1 + 4);
02907 glVertex3fv(cnv + v1 + 7);
02908 glNormal3fv(cnv + v2 + 4);
02909 glVertex3fv(cnv + v2 + 7);
02910 glEnd();
02911 }
02912 }
02913
02914 #if defined(GL_VERSION_1_1)
02915 }
02916 #endif
02917 }
02918 break;
02919
02920
02921 case DTRIMESH_C4U_N3F_V3F:
02922 {
02923
02924 DispCmdTriMesh *cmd = (DispCmdTriMesh *) cmdptr;
02925 unsigned char *colors=NULL;
02926 float *normals=NULL, *vertices=NULL;
02927
02928 if (cmd->pervertexcolors)
02929 cmd->getpointers(colors, normals, vertices);
02930 else
02931 cmd->getpointers(normals, vertices);
02932
02933 #if 1
02934 #if defined(GL_VERSION_1_1)
02935 if (!(simplegraphics || ogl_acrobat3dcapture)) {
02936
02937 if (cmd->pervertexcolors)
02938 glEnableClientState(GL_COLOR_ARRAY);
02939 else
02940 glDisableClientState(GL_COLOR_ARRAY);
02941 glEnableClientState(GL_NORMAL_ARRAY);
02942 glEnableClientState(GL_VERTEX_ARRAY);
02943
02944 if (cmd->pervertexcolors)
02945 glColorPointer(4, GL_UNSIGNED_BYTE, 0, (void *) colors);
02946 glNormalPointer(GL_FLOAT, 0, (void *) normals);
02947 glVertexPointer(3, GL_FLOAT, 0, (void *) vertices);
02948
02949 #if defined(GL_EXT_compiled_vertex_array)
02950 if (ext->hascompiledvertexarrayext) {
02951 GLLOCKARRAYSEXT(0, cmd->numverts);
02952 }
02953 #endif
02954
02955 glDrawArrays(GL_TRIANGLES, 0, cmd->numverts);
02956
02957 #if defined(GL_EXT_compiled_vertex_array)
02958 if (ext->hascompiledvertexarrayext) {
02959 GLUNLOCKARRAYSEXT();
02960 }
02961 #endif
02962 } else {
02963 #endif
02964
02965 int i, ind;
02966 glBegin(GL_TRIANGLES);
02967 ind = 0;
02968 if (cmd->pervertexcolors) {
02969 for (i=0; i<cmd->numverts; i++) {
02970 glColor3ubv(&colors[ind]);
02971 glNormal3fv(&normals[ind]);
02972 glVertex3fv(&vertices[ind]);
02973 ind += 3;
02974 }
02975 } else {
02976 for (i=0; i<cmd->numverts; i++) {
02977 glNormal3fv(&normals[ind]);
02978 glVertex3fv(&vertices[ind]);
02979 ind += 3;
02980 }
02981 }
02982
02983 glEnd();
02984 #if defined(GL_VERSION_1_1)
02985 }
02986 #endif
02987
02988 #endif
02989 }
02990 break;
02991
02992
02993 case DTRIMESH_C4U_N3B_V3F:
02994 {
02995
02996 DispCmdTriMesh *cmd = (DispCmdTriMesh *) cmdptr;
02997 unsigned char *colors=NULL;
02998 char *normals=NULL;
02999 float *vertices=NULL;
03000
03001 if (cmd->pervertexcolors)
03002 cmd->getpointers(colors, normals, vertices);
03003 else
03004 cmd->getpointers(normals, vertices);
03005
03006 #if 1
03007 #if defined(GL_VERSION_1_1)
03008 if (!(simplegraphics || ogl_acrobat3dcapture)) {
03009
03010 if (cmd->pervertexcolors)
03011 glEnableClientState(GL_COLOR_ARRAY);
03012 else
03013 glDisableClientState(GL_COLOR_ARRAY);
03014 glEnableClientState(GL_NORMAL_ARRAY);
03015 glEnableClientState(GL_VERTEX_ARRAY);
03016
03017 if (cmd->pervertexcolors)
03018 glColorPointer(4, GL_UNSIGNED_BYTE, 0, (void *) colors);
03019 glNormalPointer(GL_BYTE, 0, (void *) normals);
03020 glVertexPointer(3, GL_FLOAT, 0, (void *) vertices);
03021
03022 #if defined(GL_EXT_compiled_vertex_array)
03023 if (ext->hascompiledvertexarrayext) {
03024 GLLOCKARRAYSEXT(0, cmd->numverts);
03025 }
03026 #endif
03027
03028 glDrawArrays(GL_TRIANGLES, 0, cmd->numverts);
03029
03030 #if defined(GL_EXT_compiled_vertex_array)
03031 if (ext->hascompiledvertexarrayext) {
03032 GLUNLOCKARRAYSEXT();
03033 }
03034 #endif
03035 } else {
03036 #endif
03037
03038 int i, ind;
03039 glBegin(GL_TRIANGLES);
03040 ind = 0;
03041 if (cmd->pervertexcolors) {
03042 for (i=0; i<cmd->numverts; i++) {
03043 glColor3ubv(&colors[ind]);
03044 glNormal3bv((GLbyte *) &normals[ind]);
03045 glVertex3fv(&vertices[ind]);
03046 ind += 3;
03047 }
03048 } else {
03049 for (i=0; i<cmd->numverts; i++) {
03050 glNormal3bv((GLbyte *) &normals[ind]);
03051 glVertex3fv(&vertices[ind]);
03052 ind += 3;
03053 }
03054 }
03055
03056 glEnd();
03057 #if defined(GL_VERSION_1_1)
03058 }
03059 #endif
03060
03061 #endif
03062 }
03063 break;
03064
03065
03066 case DTRISTRIP:
03067 {
03068
03069 DispCmdTriStrips *cmd = (DispCmdTriStrips *) cmdptr;
03070 int numstrips = cmd->numstrips;
03071 int strip;
03072
03073 float *cnv;
03074 int *f;
03075 int *vertsperstrip;
03076
03077 cmd->getpointers(cnv, f, vertsperstrip);
03078
03079
03080
03081 if (!cmd->doublesided) {
03082 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
03083 }
03084
03085 #if defined(GL_VERSION_1_1)
03086 if (!(simplegraphics || ogl_acrobat3dcapture)) {
03087
03088 glInterleavedArrays(GL_C4F_N3F_V3F, 0, cnv);
03089
03090 #if defined(GL_EXT_compiled_vertex_array)
03091 if (ext->hascompiledvertexarrayext) {
03092 GLLOCKARRAYSEXT(0, cmd->numverts);
03093 }
03094 #endif
03095
03096 #if defined(GL_EXT_multi_draw_arrays)
03097
03098 if (ext->hasmultidrawext) {
03099 int **indices = new int *[cmd->numstrips];
03100
03101
03102
03103 int qv=0;
03104 for (int i=0; i<numstrips; i++) {
03105 indices[i] = (int *) ((char *)f + qv * sizeof(int));
03106 qv += vertsperstrip[i];
03107 }
03108
03109 GLMULTIDRAWELEMENTSEXT(GL_TRIANGLE_STRIP,
03110 (GLsizei *) vertsperstrip,
03111 GL_UNSIGNED_INT,
03112 (const GLvoid **) indices,
03113 numstrips);
03114
03115 delete [] indices;
03116 }
03117 else
03118 #endif
03119
03120 {
03121 int qv=0;
03122 for (strip=0; strip < numstrips; strip++) {
03123 glDrawElements(GL_TRIANGLE_STRIP, vertsperstrip[strip],
03124 GL_UNSIGNED_INT, (int *) ((char *) f + qv * sizeof(int)));
03125 qv += vertsperstrip[strip];
03126 }
03127 }
03128
03129 #if defined(GL_EXT_compiled_vertex_array)
03130 if (ext->hascompiledvertexarrayext) {
03131 GLUNLOCKARRAYSEXT();
03132 }
03133 #endif
03134 } else {
03135 #endif
03136
03137 if (!ogl_acrobat3dcapture) {
03138
03139 int t, ind;
03140 int v = 0;
03141
03142 for (strip=0; strip < numstrips; strip++) {
03143 glBegin(GL_TRIANGLE_STRIP);
03144
03145 for (t = 0; t < vertsperstrip[strip]; t++) {
03146 ind = f[v] * 10;
03147 glColor3fv(cnv + ind );
03148 glNormal3fv(cnv + ind + 4);
03149 glVertex3fv(cnv + ind + 7);
03150 v++;
03151 }
03152 glEnd();
03153 }
03154 } else {
03155
03156
03157
03158
03159
03160
03161
03162
03163 int strip, t, v = 0;
03164 int stripaddr[2][3] = { {0, 1, 2}, {1, 0, 2} };
03165
03166
03167 for (strip=0; strip < numstrips; strip++) {
03168
03169 glBegin(GL_TRIANGLES);
03170
03171 for (t = 0; t < (vertsperstrip[strip] - 2); t++) {
03172
03173 int v0 = f[v + (stripaddr[t & 0x01][0])] * 10;
03174 int v1 = f[v + (stripaddr[t & 0x01][1])] * 10;
03175 int v2 = f[v + (stripaddr[t & 0x01][2])] * 10;
03176
03177 #if 1
03178
03179
03180
03181 float tmp[3], tmp2[3];
03182 vec_add(tmp, cnv + v0, cnv + v1);
03183 vec_add(tmp2, tmp, cnv + v2);
03184 vec_scale(tmp, 0.3333333f, tmp2);
03185 glColor3fv(tmp);
03186 glNormal3fv(cnv + v0 + 4);
03187 glVertex3fv(cnv + v0 + 7);
03188 glNormal3fv(cnv + v1 + 4);
03189 glVertex3fv(cnv + v1 + 7);
03190 glNormal3fv(cnv + v2 + 4);
03191 glVertex3fv(cnv + v2 + 7);
03192 #else
03193 glColor3fv(cnv + v0 );
03194 glNormal3fv(cnv + v0 + 4);
03195 glVertex3fv(cnv + v0 + 7);
03196 glColor3fv(cnv + v1 );
03197 glNormal3fv(cnv + v1 + 4);
03198 glVertex3fv(cnv + v1 + 7);
03199 glColor3fv(cnv + v2 );
03200 glNormal3fv(cnv + v2 + 4);
03201 glVertex3fv(cnv + v2 + 7);
03202 #endif
03203
03204 v++;
03205 }
03206 glEnd();
03207 v+=2;
03208 }
03209 }
03210
03211 #if defined(GL_VERSION_1_1)
03212 }
03213 #endif
03214
03215
03216 if (!cmd->doublesided) {
03217 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
03218 }
03219 }
03220 break;
03221
03222 case DWIREMESH:
03223 {
03224
03225 DispCmdWireMesh *cmd = (DispCmdWireMesh *) cmdptr;
03226 int ind = cmd->numlines * 2;
03227 float *cnv;
03228 int *l;
03229 cmd->getpointers(cnv, l);
03230 #if defined(GL_VERSION_1_1)
03231 if (!simplegraphics) {
03232 glInterleavedArrays(GL_C4F_N3F_V3F, 0, cnv);
03233
03234 #if defined(GL_EXT_compiled_vertex_array)
03235 if (ext->hascompiledvertexarrayext) {
03236 GLLOCKARRAYSEXT(0, cmd->numverts);
03237 }
03238 #endif
03239
03240 glDrawElements(GL_LINES, ind, GL_UNSIGNED_INT, l);
03241
03242 #if defined(GL_EXT_compiled_vertex_array)
03243 if (ext->hascompiledvertexarrayext) {
03244 GLUNLOCKARRAYSEXT();
03245 }
03246 #endif
03247 } else {
03248 #endif
03249 int i, ind2;
03250 glBegin(GL_LINES);
03251 for (i=0; i<ind; i++) {
03252 ind2 = l[i] * 10;
03253 glColor3fv(cnv + ind2 );
03254 glNormal3fv(cnv + ind2 + 4);
03255 glVertex3fv(cnv + ind2 + 7);
03256 }
03257 glEnd();
03258 #if defined(GL_VERSION_1_1)
03259 }
03260 #endif
03261 }
03262 break;
03263
03264 case DCYLINDER:
03265 {
03266
03267 float *cmd = (float *)cmdptr;
03268 cylinder_full((int)(cmd[7]), cmd+9, (int)(cmd[8]));
03269 }
03270 break;
03271
03272 case DCONE:
03273 {
03274 DispCmdCone *cmd = (DispCmdCone *)cmdptr;
03275
03276 cylinder(cmd->pos2, cmd->pos1, cmd->res, cmd->radius, cmd->radius2);
03277 }
03278 break;
03279
03280 case DTEXTSIZE:
03281 textsize = ((DispCmdTextSize *)cmdptr)->size;
03282 break;
03283
03284 case DTEXTOFFSET:
03285 textoffset_x = ((DispCmdTextOffset *)cmdptr)->x;
03286 textoffset_y = ((DispCmdTextOffset *)cmdptr)->y;
03287 break;
03288
03289 case DTEXT:
03290 {
03291 float *pos = (float *)cmdptr;
03292 float thickness = pos[3];
03293 char *txt = (char *)(pos+4);
03294 float wp[4];
03295 float mp[4] = { 0, 0, 0, 1};
03296
03297 #ifdef VMDWIREGL
03298
03299
03300
03301 GLfloat tmppointSize;
03302 GLfloat tmplineWidth;
03303 GLboolean tmplineStipple;
03304 GLint tmplineSRepeat;
03305 GLint tmplineSPattern;
03306 #endif
03307
03308 mp[0] = pos[0]; mp[1] = pos[1]; mp[2] = pos[2];
03309 textMat.multpoint4d(mp,wp);
03310
03311 glPushMatrix();
03312 glLoadIdentity();
03313 glMatrixMode(GL_PROJECTION);
03314 glPushMatrix();
03315 glLoadIdentity();
03316 glTranslatef((wp[0]+textoffset_x)/wp[3],
03317 (wp[1]+textoffset_y)/wp[3],
03318 wp[2]/wp[3]);
03319
03320 glScalef(textsize/Aspect,textsize,textsize);
03321
03322 #ifdef VMDWIREGL
03323 glGetFloatv(GL_POINT_SIZE, &tmppointSize );
03324 glGetFloatv(GL_LINE_WIDTH, &tmplineWidth );
03325 glGetIntegerv(GL_LINE_STIPPLE_REPEAT, &tmplineSRepeat );
03326 glGetIntegerv(GL_LINE_STIPPLE_PATTERN,&tmplineSPattern);
03327 tmplineStipple = glIsEnabled(GL_LINE_STIPPLE);
03328 #else
03329 glPushAttrib(GL_LINE_BIT | GL_POINT_BIT);
03330 #endif
03331
03332
03333 glEnable(GL_BLEND);
03334 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
03335 glEnable(GL_LINE_SMOOTH);
03336
03337
03338
03339
03340
03341
03342 #if defined(VMDMSAAFONTTOGGLE)
03343 #if defined(GL_ARB_multisample)
03344
03345 if (aaEnabled) {
03346 glDisable(GL_MULTISAMPLE_ARB);
03347 }
03348 glLineWidth(thickness);
03349 glPointSize(thickness * 0.95f);
03350 #endif
03351 #else
03352 glLineWidth(thickness);
03353 glPointSize(thickness * 0.95f);
03354 #endif
03355
03356 glDisable(GL_LINE_STIPPLE);
03357 if (thickness > 2.0f)
03358 glListBase(fontNpxListBase);
03359 else
03360 glListBase(font1pxListBase);
03361
03362 glCallLists(strlen(txt), GL_UNSIGNED_BYTE, (GLubyte *)txt);
03363
03364 #if defined(VMDMSAAFONTTOGGLE)
03365 #if defined(GL_ARB_multisample)
03366
03367 if (aaEnabled) {
03368 glEnable(GL_MULTISAMPLE_ARB);
03369 }
03370 #endif
03371 #endif
03372
03373
03374 glDisable(GL_BLEND);
03375 glDisable(GL_LINE_SMOOTH);
03376
03377 #ifdef VMDWIREGL
03378 glLineWidth(tmplineWidth);
03379 glPointSize(tmppointSize);
03380 glLineStipple(tmplineSRepeat, (GLushort) tmplineSPattern);
03381 if (tmplineStipple == GL_TRUE)
03382 glEnable(GL_LINE_STIPPLE);
03383 else
03384 glDisable(GL_LINE_STIPPLE);
03385 #else
03386 glPopAttrib();
03387 #endif
03388
03389
03390 glPopMatrix();
03391 glMatrixMode(GL_MODELVIEW);
03392 glPopMatrix();
03393 }
03394 break;
03395
03396 case DCOLORINDEX:
03397
03398
03399 glColor3fv((GLfloat *)(colorData+3*(((DispCmdColorIndex *)cmdptr)->color)));
03400 break;
03401
03402 case DMATERIALON:
03403 glEnable(GL_LIGHTING);
03404 ogl_lightingenabled=1;
03405 #if defined(VMDUSEOPENGLSHADER)
03406 if (mainshader && ogl_useglslshader) {
03407 mainshader->UseShader(1);
03408 }
03409 #endif
03410 break;
03411
03412 case DMATERIALOFF:
03413 glDisable(GL_LIGHTING);
03414 ogl_lightingenabled=0;
03415 #if defined(VMDUSEOPENGLSHADER)
03416 if (mainshader && ogl_useglslshader) {
03417 mainshader->UseShader(0);
03418 }
03419 #endif
03420 break;
03421
03422 case DSPHERERES:
03423
03424 set_sphere_res(((DispCmdSphereRes *)cmdptr)->res);
03425 break;
03426
03427 case DSPHERETYPE:
03428
03429 set_sphere_mode(((DispCmdSphereType *)cmdptr)->type);
03430 break;
03431
03432 case DLINESTYLE:
03433
03434 set_line_style(((DispCmdLineType *)cmdptr)->type);
03435 break;
03436
03437 case DLINEWIDTH:
03438
03439 set_line_width(((DispCmdLineWidth *)cmdptr)->width);
03440 break;
03441
03442 case DPICKPOINT:
03443 case DPICKPOINT_ARRAY:
03444 default:
03445
03446
03447 break;
03448
03449 }
03450 }
03451
03452 }
03453
03454
03455 if (ogl_cacheenabled && (!ogl_cacheskip)) {
03456 if (ogl_cachecreated) {
03457 glEndList();
03458 } else {
03459 if (ogl_cachedebug) {
03460 msgInfo << "Calling cached geometry: id=" << (int)ogl_cachedid << sendmsg;
03461 }
03462 glCallList(ogl_cachedid);
03463 }
03464 }
03465
03466 glPopMatrix();
03467 }
03468
03469
03470 glPopMatrix();
03471 }
03472
03473 void OpenGLRenderer::render_done() {
03474 ogl_glsltoggle = 1;
03475
03476 GLuint tag;
03477
03478 while ((tag = displaylistcache.deleteUnused()) != GLCACHE_FAIL) {
03479 glDeleteLists(tag, 1);
03480 }
03481
03482
03483 while ((tag = texturecache.deleteUnused()) != GLCACHE_FAIL) {
03484 glDeleteTextures(1, &tag);
03485 }
03486 }
03487
03488 void OpenGLRenderer::require_volume_texture(unsigned long ID,
03489 unsigned xsize, unsigned ysize, unsigned zsize,
03490 unsigned char *texmap) {
03491
03492 if (!ext->hastex3d) return;
03493 GLuint texName;
03494 if ((texName = texturecache.markUsed(ID)) == 0) {
03495 glGenTextures(1, &texName);
03496 texturecache.encache(ID, texName);
03497 glBindTexture(GL_TEXTURE_3D, texName);
03498
03499
03500 GLfloat texborder[4] = {0.0, 0.0, 0.0, 1.0};
03501 glTexParameterfv(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, texborder);
03502
03503
03504 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP);
03505 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
03506 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);
03507
03508
03509 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
03510 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
03511
03512 if (build3Dmipmaps(xsize, ysize, zsize, texmap)) {
03513 msgErr << "OpenGLRenderer failed to download 3-D texture map!"
03514 << sendmsg;
03515 }
03516 } else {
03517 glBindTexture(GL_TEXTURE_3D, texName);
03518 }
03519 }
03520
03521
03522 int OpenGLRenderer::build3Dmipmaps(int width, int height, int depth, unsigned char *tx) {
03523 #if defined(GL_VERSION_1_2)
03524 if (ext->hastex3d) {
03525 int xsize=width;
03526 int ysize=height;
03527 int zsize=depth;
03528 int xstep=1;
03529 int ystep=1;
03530 int zstep=1;
03531 int x,y,z;
03532
03533 if (tx == NULL) {
03534 msgErr << "Skipping MIP map generation for NULL 3-D texture map"
03535 << sendmsg;
03536 return 1;
03537 }
03538
03539
03540 if (xsize > max3DtexX || ysize > max3DtexY || zsize > max3DtexZ) {
03541 unsigned char *texmap;
03542
03543 while (xsize > max3DtexX) {
03544 xsize >>= 1;
03545 xstep <<= 1;
03546 }
03547
03548 while (ysize > max3DtexY) {
03549 ysize >>= 1;
03550 ystep <<= 1;
03551 }
03552
03553 while (zsize > max3DtexZ) {
03554 zsize >>= 1;
03555 zstep <<= 1;
03556 }
03557
03558 if (xsize == 0 || ysize == 0 || zsize == 0)
03559 return 1;
03560
03561 texmap = (unsigned char *) malloc(xsize*ysize*zsize*3);
03562 if (texmap == NULL) {
03563 msgErr << "Failed to allocate MIP map for downsampled texture"
03564 << sendmsg;
03565 return 1;
03566 }
03567
03568 #if 0
03569
03570 msgError << "3-D texture map can't fit into accelerator memory, aborted."
03571 << sendmsg;
03572
03573 for (z=0; z<zsize; z++) {
03574 for (y=0; y<ysize; y++) {
03575 int addr = z*xsize*ysize + y*xsize;
03576 for (x=0; x<xsize; x++) {
03577 if ((x + y + z) % 2) {
03578 texmap[(addr + x)*3 ] = 0;
03579 texmap[(addr + x)*3 + 1] = 0;
03580 texmap[(addr + x)*3 + 2] = 0;
03581 } else {
03582 texmap[(addr + x)*3 ] = 255;
03583 texmap[(addr + x)*3 + 1] = 255;
03584 texmap[(addr + x)*3 + 2] = 255;
03585 }
03586 }
03587 }
03588 }
03589
03590 #else
03591 msgInfo << "Downsampling 3-D texture map from "
03592 << width << "x" << height << "x" << depth << " to "
03593 << xsize << "x" << ysize << "x" << zsize << sendmsg;
03594
03595 for (z=0; z<zsize; z++) {
03596 for (y=0; y<ysize; y++) {
03597 int addr = z*xsize*ysize + y*xsize;
03598 for (x=0; x<xsize; x++) {
03599 int sumR=0, sumG=0, sumB=0;
03600 int texelcount = 0;
03601 int ox, oxs, oxe;
03602 int oy, oys, oye;
03603 int oz, ozs, oze;
03604
03605 oxs = x * xstep;
03606 oys = y * ystep;
03607 ozs = z * zstep;
03608
03609 oxe = oxs + xstep;
03610 oye = oys + ystep;
03611 oze = ozs + zstep;
03612 if (oxe > width) oxe=width;
03613 if (oye > height) oye=height;
03614 if (oze > depth) oze=depth;
03615
03616 for (oz=ozs; oz<oze; oz++) {
03617 for (oy=oys; oy<oye; oy++) {
03618 int oaddr = oz*width*height + oy*width;
03619 for (ox=oxs; ox<oxe; ox++) {
03620 int oadx = (oaddr + ox)*3;
03621 sumR += tx[oadx ];
03622 sumG += tx[oadx + 1];
03623 sumB += tx[oadx + 2];
03624 texelcount++;
03625 }
03626 }
03627 }
03628
03629 int adx = (addr + x)*3;
03630 texmap[adx ] = (unsigned char) (sumR / ((float) texelcount));
03631 texmap[adx + 1] = (unsigned char) (sumG / ((float) texelcount));
03632 texmap[adx + 2] = (unsigned char) (sumB / ((float) texelcount));
03633 }
03634 }
03635 }
03636 #endif
03637
03638 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
03639 GLTEXIMAGE3D(GL_TEXTURE_3D, 0, GL_RGB8, xsize, ysize, zsize,
03640 0, GL_RGB, GL_UNSIGNED_BYTE, texmap);
03641
03642 free(texmap);
03643 } else {
03644 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
03645 GLTEXIMAGE3D(GL_TEXTURE_3D, 0, GL_RGB8, width, height, depth,
03646 0, GL_RGB, GL_UNSIGNED_BYTE, tx);
03647 }
03648
03649 return 0;
03650 }
03651 #endif
03652
03653 return 1;
03654 }
03655
03656 void OpenGLRenderer::update_shader_uniforms(void * voidshader, int forceupdate) {
03657 #if defined(VMDUSEOPENGLSHADER)
03658 OpenGLShader *sh = (OpenGLShader *) voidshader;
03659 GLint loc;
03660
03661
03662 GLint vmdprojectionmode = (ogl_glslprojectionmode == DisplayDevice::PERSPECTIVE) ? 1 : 0;
03663 loc = GLGETUNIFORMLOCATIONARB(sh->ProgramObject, "vmdprojectionmode");
03664 GLUNIFORM1IARB(loc, vmdprojectionmode);
03665
03666
03667 GLint vmdtexturemode = ogl_glsltexturemode;
03668 loc = GLGETUNIFORMLOCATIONARB(sh->ProgramObject, "vmdtexturemode");
03669 GLUNIFORM1IARB(loc, vmdtexturemode);
03670
03671
03672
03673 GLfloat matparms[4];
03674 matparms[0] = oglambient;
03675 matparms[1] = ogldiffuse;
03676 matparms[2] = oglspecular;
03677 matparms[3] = oglshininess;
03678 loc = GLGETUNIFORMLOCATIONARB(sh->ProgramObject, "vmdmaterial");
03679 GLUNIFORM4FVARB(loc, 1, matparms);
03680
03681
03682 GLfloat vmdopacity[1];
03683 vmdopacity[0] = oglopacity;
03684 loc = GLGETUNIFORMLOCATIONARB(sh->ProgramObject, "vmdopacity");
03685 GLUNIFORM1FVARB(loc, 1, vmdopacity);
03686
03687
03688 GLfloat vmdoutline[1];
03689 vmdoutline[0] = ogloutline;
03690 loc = GLGETUNIFORMLOCATIONARB(sh->ProgramObject, "vmdoutline");
03691 GLUNIFORM1FVARB(loc, 1, vmdoutline);
03692
03693 GLfloat vmdoutlinewidth[1];
03694 vmdoutlinewidth[0] = ogloutlinewidth;
03695 loc = GLGETUNIFORMLOCATIONARB(sh->ProgramObject, "vmdoutlinewidth");
03696 GLUNIFORM1FVARB(loc, 1, vmdoutlinewidth);
03697
03698
03699 loc = GLGETUNIFORMLOCATIONARB(sh->ProgramObject, "vmdtransmode");
03700 GLUNIFORM1IARB(loc, ogltransmode);
03701
03702
03703 loc = GLGETUNIFORMLOCATIONARB(sh->ProgramObject, "vmdfogmode");
03704 GLUNIFORM1IARB(loc, ogl_fogmode);
03705
03706
03707 loc = GLGETUNIFORMLOCATIONARB(sh->ProgramObject, "vmdtex0");
03708 GLUNIFORM1IARB(loc, 0);
03709
03710
03711
03712
03713
03714 if (forceupdate || (ogl_glslserial != ogl_rendstateserial)) {
03715 int i;
03716
03717 if (!forceupdate) {
03718
03719 ogl_glslserial = ogl_rendstateserial;
03720 }
03721
03722
03723
03724 for (i=0; i<DISP_LIGHTS; i++) {
03725 char varbuf[32];
03726 sprintf(varbuf, "vmdlight%d", i);
03727 GLint loc = GLGETUNIFORMLOCATIONARB(sh->ProgramObject, varbuf);
03728 GLUNIFORM3FVARB(loc, 1, &ogl_lightpos[i][0]);
03729
03730
03731
03732
03733
03734 float L[3], V[3];
03735 GLfloat Hvec[3];
03736 (transMat.top()).multpoint3d(&ogl_lightpos[i][0], L);
03737 vec_scale(V, -1.0, eyeDir);
03738 vec_normalize(V);
03739 Hvec[0] = L[0] + V[0];
03740 Hvec[1] = L[1] + V[1];
03741 Hvec[2] = L[2] + V[2];
03742 vec_normalize(Hvec);
03743 sprintf(varbuf, "vmdlight%dH", i);
03744 loc = GLGETUNIFORMLOCATIONARB(mainshader->ProgramObject, varbuf);
03745 GLUNIFORM3FVARB(loc, 1, Hvec);
03746 }
03747
03748
03749
03750
03751
03752 loc = GLGETUNIFORMLOCATIONARB(sh->ProgramObject, "vmdlightscale");
03753 GLfloat vmdlightscale[DISP_LIGHTS];
03754 for (i=0; i<DISP_LIGHTS; i++) {
03755 vmdlightscale[i] = (float) ogl_lightstate[i];
03756 }
03757 GLUNIFORM4FVARB(loc, 1, vmdlightscale);
03758 }
03759 #endif
03760 }
03761
03762