📄 opengl_renderer.cpp
字号:
Vector rotCenter; double pixelSize; GLint viewport[4]; // find out where rotation center is in current GL coordinates if (structureSet && (control==eXYRotateHV || control==eZRotateH) && structureSet->rotationCenter != structureSet->center) { Matrix m; GL2Matrix(viewMatrix, &m); rotCenter = structureSet->rotationCenter; ApplyTransformation(&rotCenter, m); doTranslation = true; } glLoadIdentity(); // rotate relative to rotationCenter if (doTranslation) glTranslated(rotCenter.x, rotCenter.y, rotCenter.z);#define MIN_CAMERA_ANGLE 0.001#define MAX_CAMERA_ANGLE (0.999 * PI) switch (control) { case eXYRotateHV: glRotated(rotateSpeed*dY, 1.0, 0.0, 0.0); glRotated(rotateSpeed*dX, 0.0, 1.0, 0.0); break; case eZRotateH: glRotated(rotateSpeed*dX, 0.0, 0.0, 1.0); break; case eXYTranslateHV: glGetIntegerv(GL_VIEWPORT, viewport); pixelSize = tan(cameraAngleRad / 2.0) * 2.0 * cameraDistance / viewport[3]; cameraLookAtX -= dX * pixelSize; cameraLookAtY += dY * pixelSize; NewView(); break; case eZoomH: cameraAngleRad *= 1.0 - 0.01 * dX; if (cameraAngleRad < MIN_CAMERA_ANGLE) cameraAngleRad = MIN_CAMERA_ANGLE; else if (cameraAngleRad > MAX_CAMERA_ANGLE) cameraAngleRad = MAX_CAMERA_ANGLE; NewView(); break; case eZoomHHVV: break; case eZoomOut: cameraAngleRad *= 1.5; if (cameraAngleRad > MAX_CAMERA_ANGLE) cameraAngleRad = MAX_CAMERA_ANGLE; NewView(); break; case eZoomIn: cameraAngleRad /= 1.5; if (cameraAngleRad < MIN_CAMERA_ANGLE) cameraAngleRad = MIN_CAMERA_ANGLE; NewView(); break; case eCenterCamera: cameraLookAtX = cameraLookAtY = 0.0; NewView(); break; } if (doTranslation) glTranslated(-rotCenter.x, -rotCenter.y, -rotCenter.z); glMultMatrixd(viewMatrix); glGetDoublev(GL_MODELVIEW_MATRIX, viewMatrix);}void OpenGLRenderer::CenterView(const Vector& viewCenter, double radius){ ResetCamera(); structureSet->rotationCenter = viewCenter; Vector cameraLocation(0.0, 0.0, cameraDistance); Vector centerWRTcamera = viewCenter - structureSet->center; Vector direction = centerWRTcamera - cameraLocation; direction.normalize(); double cosAngleZ = -direction.z; Vector lookAt = centerWRTcamera + direction * (centerWRTcamera.z / cosAngleZ); cameraLookAtX = lookAt.x; cameraLookAtY = lookAt.y; cameraAngleRad = 2.0 * atan(radius / (cameraLocation - centerWRTcamera).length()); NewView(); TRACEMSG("looking at " << lookAt << " angle " << RadToDegrees(cameraAngleRad)); // do this so that this view is used upon restore SaveToASNViewSettings(NULL);}void OpenGLRenderer::PushMatrix(const Matrix* m){ glPushMatrix(); if (m) { GLdouble g[16]; Matrix2GL(*m, g); glMultMatrixd(g); }}void OpenGLRenderer::PopMatrix(void){ glPopMatrix();}// display list management stuffvoid OpenGLRenderer::StartDisplayList(unsigned int list){ if (list >= FONT_BASE) { ERRORMSG("OpenGLRenderer::StartDisplayList() - too many display lists;\n" << "increase OpenGLRenderer::FONT_BASE"); return; } ClearTransparentSpheresForList(list); SetColor(GL_NONE); // reset color caches in SetColor glNewList(list, GL_COMPILE); currentDisplayList = list; if (currentDisplayList >= displayListEmpty.size()) displayListEmpty.resize(currentDisplayList + 1, true); displayListEmpty[currentDisplayList] = true;}void OpenGLRenderer::EndDisplayList(void){ glEndList(); currentDisplayList = NO_LIST;}// frame management methodsvoid OpenGLRenderer::ShowAllFrames(void){ if (structureSet) currentFrame = ALL_FRAMES;}bool OpenGLRenderer::IsFrameEmpty(unsigned int frame) const{ if (!structureSet || structureSet->frameMap.size() <= frame) return false; StructureSet::DisplayLists::const_iterator l, le=structureSet->frameMap[frame].end(); for (l=structureSet->frameMap[frame].begin(); l!=le; ++l) if (!displayListEmpty[*l]) return false; return true;}void OpenGLRenderer::ShowFirstFrame(void){ if (!structureSet || structureSet->frameMap.size() == 0) return; currentFrame = 0; while (IsFrameEmpty(currentFrame) && currentFrame < structureSet->frameMap.size() - 1) ++currentFrame;}void OpenGLRenderer::ShowLastFrame(void){ if (!structureSet || structureSet->frameMap.size() == 0) return; currentFrame = structureSet->frameMap.size() - 1; while (IsFrameEmpty(currentFrame) && currentFrame > 0) --currentFrame;}void OpenGLRenderer::ShowNextFrame(void){ if (!structureSet || structureSet->frameMap.size() == 0) return; if (currentFrame == ALL_FRAMES) currentFrame = structureSet->frameMap.size() - 1; int originalFrame = currentFrame; do { if (currentFrame == structureSet->frameMap.size() - 1) currentFrame = 0; else ++currentFrame; } while (IsFrameEmpty(currentFrame) && currentFrame != originalFrame);}void OpenGLRenderer::ShowPreviousFrame(void){ if (!structureSet || structureSet->frameMap.size() == 0) return; if (currentFrame == ALL_FRAMES) currentFrame = 0; int originalFrame = currentFrame; do { if (currentFrame == 0) currentFrame = structureSet->frameMap.size() - 1; else --currentFrame; } while (IsFrameEmpty(currentFrame) && currentFrame != originalFrame);}void OpenGLRenderer::ShowFrameNumber(int frame){ if (!structureSet) return; if (frame >= 0 && frame < structureSet->frameMap.size() && !IsFrameEmpty(frame)) currentFrame = frame; else currentFrame = ALL_FRAMES;}// process selection; return gl-name of resultbool OpenGLRenderer::GetSelected(int x, int y, unsigned int *name){ // render with GL_SELECT mode, to fill selection buffer glSelectBuffer(pickBufSize, selectBuf); glRenderMode(GL_SELECT); selectMode = true; selectX = x; selectY = y; NewView(); Display(); GLint hits = glRenderMode(GL_RENDER); selectMode = false; NewView(); // parse selection buffer to find name of selected item int i, j, p=0, n, top=0; GLuint minZ=0; *name = NO_NAME; for (i=0; i<hits; ++i) { n = selectBuf[p++]; // # names if (i==0 || minZ > selectBuf[p]) { // find item with min depth minZ = selectBuf[p]; top = 1; } else top = 0; ++p; ++p; // skip max depth for (j=0; j<n; ++j) { // loop through n names switch (j) { case 0: if (top) *name = static_cast<unsigned int>(selectBuf[p]); break; default: WARNINGMSG("GL select: Got more than 1 name!"); } ++p; } } if (*name != NO_NAME) return true; else return false;}void OpenGLRenderer::AttachStructureSet(StructureSet *targetStructureSet){ structureSet = targetStructureSet; currentFrame = ALL_FRAMES; if (!structureSet) initialViewFromASN.Reset(); Init(); // init GL system Construct(); // draw structures RestoreSavedView(); // load initial view if present}void OpenGLRenderer::RecreateQuadric(void) const{ if (qobj) gluDeleteQuadric(qobj); if (!(qobj = gluNewQuadric())) { ERRORMSG("unable to create a new GLUQuadricObj"); return; } gluQuadricDrawStyle(qobj, (GLenum) GLU_FILL); gluQuadricNormals(qobj, (GLenum) GLU_SMOOTH); gluQuadricOrientation(qobj, (GLenum) GLU_OUTSIDE); gluQuadricTexture(qobj, GL_FALSE);}void OpenGLRenderer::Construct(void){ glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if (structureSet) { // get quality values from registry - assumes some values have been set already! if (!RegistryGetInteger(REG_QUALITY_SECTION, REG_QUALITY_ATOM_SLICES, &atomSlices) || !RegistryGetInteger(REG_QUALITY_SECTION, REG_QUALITY_ATOM_STACKS, &atomStacks) || !RegistryGetInteger(REG_QUALITY_SECTION, REG_QUALITY_BOND_SIDES, &bondSides) || !RegistryGetInteger(REG_QUALITY_SECTION, REG_QUALITY_WORM_SIDES, &wormSides) || !RegistryGetInteger(REG_QUALITY_SECTION, REG_QUALITY_WORM_SEGMENTS, &wormSegments) || !RegistryGetInteger(REG_QUALITY_SECTION, REG_QUALITY_HELIX_SIDES, &helixSides) || !RegistryGetBoolean(REG_QUALITY_SECTION, REG_HIGHLIGHTS_ON, &highlightsOn) || !RegistryGetString(REG_QUALITY_SECTION, REG_PROJECTION_TYPE, &projectionType)) ERRORMSG("OpenGLRenderer::Construct() - error getting quality setting from registry"); // do the drawing structureSet->DrawAll(); } else { SetColor(GL_NONE); ConstructLogo(); } GlobalMessenger()->UnPostStructureRedraws();}// set current GL color; don't change color if it's same as what's currentvoid OpenGLRenderer::SetColor(int type, double red, double green, double blue, double alpha){ static double pr, pg, pb, pa; static GLenum pt = GL_NONE; if (type == GL_NONE) { pt = GL_NONE; return; } if (alpha <= 0.0) WARNINGMSG("SetColor request alpha <= 0.0"); if (red != pr || green != pg || blue != pb || type != pt || alpha != pa) { if (type != pt) { if (type == GL_DIFFUSE) { glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, Color_MostlyOff); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, highlightsOn ? Color_Specular : Color_Off); } else if (type == GL_AMBIENT) { glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, Color_Off); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, Color_Off); // no specular for ambient coloring } else { ERRORMSG("don't know how to handle material type " << type); } pt = (GLenum) type; } GLfloat rgba[4] = { red, green, blue, alpha }; glMaterialfv(GL_FRONT_AND_BACK, (GLenum) type, rgba); // this is necessary so that fonts are rendered in correct // color in SGI's OpenGL implementation, and maybe others if (type == GL_AMBIENT) glColor4fv(rgba); pr = red; pg = green; pb = blue; pa = alpha; }}/* create display list with logo */void OpenGLRenderer::ConstructLogo(void){ static const GLfloat logoColor[3] = { 100.0f/255, 240.0f/255, 150.0f/255 }; static const int LOGO_SIDES = 36, segments = 180; int i, n, s, g; GLdouble bigRad = 12.0, height = 24.0, minRad = 0.1, maxRad = 2.0, ringPts[LOGO_SIDES * 3], *pRingPts = ringPts, prevRing[LOGO_SIDES * 3], *pPrevRing = prevRing, *tmp, ringNorm[LOGO_SIDES * 3], *pRingNorm = ringNorm, prevNorm[LOGO_SIDES * 3], *pPrevNorm = prevNorm, length, startRad, midRad, phase, currentRad, CR[3], H[3], V[3]; ClearTransparentSpheresForList(FIRST_LIST); glNewList(FIRST_LIST, GL_COMPILE); /* create logo */ SetColor(GL_DIFFUSE, logoColor[0], logoColor[1], logoColor[2]); for (n = 0; n < 2; ++n) { /* helix strand */ if (n == 0) { startRad = maxRad; midRad = minRad; phase = 0; } else { startRad = minRad; midRad = maxRad;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -