⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 opengl_renderer.cpp

📁 ncbi源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/* * =========================================================================== * PRODUCTION $Log: opengl_renderer.cpp,v $ * PRODUCTION Revision 1000.3  2004/06/01 18:28:52  gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.79 * PRODUCTION * =========================================================================== *//*  $Id: opengl_renderer.cpp,v 1000.3 2004/06/01 18:28:52 gouriano Exp $* ===========================================================================**                            PUBLIC DOMAIN NOTICE*               National Center for Biotechnology Information**  This software/database is a "United States Government Work" under the*  terms of the United States Copyright Act.  It was written as part of*  the author's official duties as a United States Government employee and*  thus cannot be copyrighted.  This software/database is freely available*  to the public for use. The National Library of Medicine and the U.S.*  Government have not placed any restriction on its use or reproduction.**  Although all reasonable efforts have been taken to ensure the accuracy*  and reliability of the software and data, the NLM and the U.S.*  Government do not and cannot warrant the performance or results that*  may be obtained by using this software or data. The NLM and the U.S.*  Government disclaim all warranties, express or implied, including*  warranties of performance, merchantability or fitness for any particular*  purpose.**  Please cite the author in any work or product based on this material.** ===========================================================================** Authors:  Paul Thiessen** File Description:*      Classes to hold the OpenGL rendering engine** ===========================================================================*/#ifdef _MSC_VER#pragma warning(disable:4018)   // disable signed/unsigned mismatch warning in MSVC#endif#include <ncbi_pch.hpp>#include <corelib/ncbistd.hpp>#include <corelib/ncbitime.hpp> // avoids some 'CurrentTime' conflict later on...#include <corelib/ncbiobj.hpp>#if defined(__WXMSW__)#include <windows.h>#include <GL/gl.h>#include <GL/glu.h>#elif defined(__WXGTK__)#include <GL/gl.h>#include <GL/glu.h>#include <GL/glx.h>#include <gdk/gdk.h>    // needed for GdkFont#elif defined(__WXMAC__)//#include <Fonts.h>#include <OpenGL/gl.h>#include <OpenGL/glu.h>#endif#include <math.h>#include <stdlib.h> // for rand, srand#include <objects/cn3d/Cn3d_GL_matrix.hpp>#include <objects/cn3d/Cn3d_vector.hpp>#include "opengl_renderer.hpp"#include "structure_window.hpp"#include "cn3d_glcanvas.hpp"#include "structure_set.hpp"#include "style_manager.hpp"#include "messenger.hpp"#include "cn3d_tools.hpp"#include "asn_converter.hpp"#include "cn3d_colors.hpp"USING_NCBI_SCOPE;USING_SCOPE(objects);BEGIN_SCOPE(Cn3D)static const double PI = acos(-1.0);static inline double DegreesToRad(double deg) { return deg*PI/180.0; }static inline double RadToDegrees(double rad) { return rad*180.0/PI; }const unsigned int OpenGLRenderer::NO_LIST = 0;const unsigned int OpenGLRenderer::FIRST_LIST = 1;const unsigned int OpenGLRenderer::FONT_BASE = 1000;static const unsigned int ALL_FRAMES = 4294967295;// it's easier to keep one global qobj for nowstatic GLUquadricObj *qobj = NULL;// pick bufferconst unsigned int OpenGLRenderer::NO_NAME = 0;static const int pickBufSize = 1024;static GLuint selectBuf[pickBufSize];/* these are used for both matrial colors and light colors */static const GLfloat Color_Off[4] = { 0.0f, 0.0f, 0.0f, 1.0f };static const GLfloat Color_MostlyOff[4] = { 0.05f, 0.05f, 0.05f, 1.0f };static const GLfloat Color_MostlyOn[4] = { 0.95f, 0.95f, 0.95f, 1.0f };static const GLfloat Color_On[4] = { 1.0f, 1.0f, 1.0f, 1.0f };static const GLfloat Color_Specular[4] = { 0.5f, 0.5f, 0.5f, 1.0f };static const GLint Shininess = 40;// to cache registry valuesstatic int atomSlices, atomStacks, bondSides, wormSides, wormSegments, helixSides;static bool highlightsOn;static string projectionType;// matrix conversion utility functions// convert from Matrix to GL-matrix orderingstatic void Matrix2GL(const Matrix& m, GLdouble *g){    g[0]=m.m[0];  g[4]=m.m[1];  g[8]=m.m[2];   g[12]=m.m[3];    g[1]=m.m[4];  g[5]=m.m[5];  g[9]=m.m[6];   g[13]=m.m[7];    g[2]=m.m[8];  g[6]=m.m[9];  g[10]=m.m[10]; g[14]=m.m[11];    g[3]=m.m[12]; g[7]=m.m[13]; g[11]=m.m[14]; g[15]=m.m[15];}// convert from GL-matrix to Matrix orderingstatic void GL2Matrix(GLdouble *g, Matrix *m){    m->m[0]=g[0];  m->m[1]=g[4];  m->m[2]=g[8];   m->m[3]=g[12];    m->m[4]=g[1];  m->m[5]=g[5];  m->m[6]=g[9];   m->m[7]=g[13];    m->m[8]=g[2];  m->m[9]=g[6];  m->m[10]=g[10]; m->m[11]=g[14];    m->m[12]=g[3]; m->m[13]=g[7]; m->m[14]=g[11]; m->m[15]=g[15];}// OpenGLRenderer methods - initialization and setupOpenGLRenderer::OpenGLRenderer(Cn3DGLCanvas *parentGLCanvas) :    structureSet(NULL), glCanvas(parentGLCanvas),    selectMode(false), currentDisplayList(NO_LIST), cameraAngleRad(0.0), rotateSpeed(0.5),    stereoOn(false){    // make sure a name will fit in a GLuint    if (sizeof(GLuint) < sizeof(unsigned int))        FATALMSG("Cn3D requires that sizeof(GLuint) >= sizeof(unsigned int)");}void OpenGLRenderer::Init(void) const{    glMatrixMode(GL_MODELVIEW);    glLoadIdentity();    // set up the lighting    // directional light (faster) when LightPosition[4] == 0.0    GLfloat LightPosition[4] = { 0.0f, 0.0f, 1.0f, 0.0f };    glLightfv(GL_LIGHT0, GL_POSITION, LightPosition);    glLightfv(GL_LIGHT0, GL_AMBIENT, Color_Off);    glLightfv(GL_LIGHT0, GL_DIFFUSE, Color_MostlyOn);    glLightfv(GL_LIGHT0, GL_SPECULAR, Color_On);    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, Color_On); // global ambience    glEnable(GL_LIGHTING);    glEnable(GL_LIGHT0);    // set these material colors    glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Color_Off);    glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, Shininess);    // turn on culling to speed rendering    glEnable(GL_CULL_FACE);    glCullFace(GL_BACK);    glFrontFace(GL_CCW);    // misc options    glShadeModel(GL_SMOOTH);    glEnable(GL_DEPTH_TEST);    glDisable(GL_NORMALIZE);    glDisable(GL_SCISSOR_TEST);    RecreateQuadric();}// methods dealing with the viewvoid OpenGLRenderer::NewView(double eyeTranslateToAngleDegrees) const{    if (cameraAngleRad <= 0.0) return;    GLint Viewport[4];    glGetIntegerv(GL_VIEWPORT, Viewport);    glMatrixMode(GL_PROJECTION);    glLoadIdentity();    if (selectMode) {        gluPickMatrix(static_cast<GLdouble>(selectX),                      static_cast<GLdouble>(Viewport[3] - selectY),                      1.0, 1.0, Viewport);    }    GLdouble aspect = (static_cast<GLdouble>(Viewport[2])) / Viewport[3];    // set camera angle/perspective    if (projectionType == "Perspective") {        gluPerspective(RadToDegrees(cameraAngleRad),    // viewing angle (degrees)                       aspect,                          // w/h aspect                       cameraClipNear,                  // near clipping plane                       cameraClipFar);                  // far clipping plane    } else { // Orthographic        GLdouble right, top;        top = ((cameraClipNear + cameraClipFar) / 2.0) * sin(cameraAngleRad / 2.0);        right = top * aspect;        glOrtho(-right,             // sides of viewing box, assuming eye is at (0,0,0)                right,                -top,                top,                cameraClipNear,     // near clipping plane                cameraClipFar);     // far clipping plane    }    Vector cameraLoc(0.0, 0.0, cameraDistance);    if (stereoOn && eyeTranslateToAngleDegrees != 0.0) {        Vector view(cameraLookAtX, cameraLookAtY, -cameraDistance);        Vector translate = vector_cross(view, Vector(0.0, 1.0, 0.0));        translate.normalize();        translate *= view.length() * tan(DegreesToRad(eyeTranslateToAngleDegrees));        cameraLoc += translate;    }    // set camera position and direction    gluLookAt(cameraLoc.x, cameraLoc.y, cameraLoc.z,    // the camera position              cameraLookAtX, cameraLookAtY, 0.0,        // the "look-at" point              0.0, 1.0, 0.0);                           // the up direction    glMatrixMode(GL_MODELVIEW);}void OpenGLRenderer::Display(void){    if (structureSet) {        const Vector& background = structureSet->styleManager->GetBackgroundColor();        glClearColor(background[0], background[1], background[2], 1.0);    } else        glClearColor(0.0, 0.0, 0.0, 1.0);    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    if (selectMode) {        glInitNames();        glPushName(0);    }    GLint viewport[4] = {0, 0, 0, 0};    double eyeSeparationDegrees = 0.0;    if (stereoOn) {        bool proximalStereo;        glGetIntegerv(GL_VIEWPORT, viewport);        if (!RegistryGetDouble(REG_ADVANCED_SECTION, REG_STEREO_SEPARATION, &eyeSeparationDegrees) ||            !RegistryGetBoolean(REG_ADVANCED_SECTION, REG_PROXIMAL_STEREO, &proximalStereo))        {            ERRORMSG("OpenGLRenderer::Display() - error getting stereo settings from registry");            return;        }        if (!proximalStereo)            eyeSeparationDegrees = -eyeSeparationDegrees;    }    int first = 1, last = stereoOn ? 2 : 1;    for (int e=first; e<=last; ++e) {        glLoadMatrixd(viewMatrix);        // adjust viewport & camera angle for stereo        if (stereoOn) {            if (e == first) {                // left side                glViewport(0, viewport[1], viewport[2] / 2, viewport[3]);                NewView(eyeSeparationDegrees / 2);            } else {                // right side                glViewport(viewport[2] / 2, viewport[1], viewport[2] - viewport[2] / 2, viewport[3]);                NewView(-eyeSeparationDegrees / 2);            }        }        if (structureSet) {            if (currentFrame == ALL_FRAMES) {                for (unsigned int i=FIRST_LIST; i<=structureSet->lastDisplayList; ++i) {                    PushMatrix(*(structureSet->transformMap[i]));                    glCallList(i);                    PopMatrix();                    AddTransparentSpheresForList(i);                }            } else {                StructureSet::DisplayLists::const_iterator                    l, le=structureSet->frameMap[currentFrame].end();                for (l=structureSet->frameMap[currentFrame].begin(); l!=le; ++l) {                    PushMatrix(*(structureSet->transformMap[*l]));                    glCallList(*l);                    PopMatrix();                    AddTransparentSpheresForList(*l);                }            }            // draw transparent spheres, which are already stored in view-transformed coordinates            glLoadIdentity();            RenderTransparentSpheres();        }        // draw logo if no structure        else {            glCallList(FIRST_LIST);        }    }    glFlush();    // restore full viewport    if (stereoOn)        glViewport(0, viewport[1], viewport[2], viewport[3]);}void OpenGLRenderer::EnableStereo(bool enableStereo){    TRACEMSG("turning " << (enableStereo ? "on" : "off" ) << " stereo");    stereoOn = enableStereo;    if (!stereoOn)        NewView();}void OpenGLRenderer::ResetCamera(void){    // set up initial camera    glLoadIdentity();    cameraLookAtX = cameraLookAtY = 0.0;    if (structureSet) { // for structure        cameraAngleRad = DegreesToRad(35.0);        // calculate camera distance so that structure fits exactly in        // the window in any rotation (based on structureSet's maxDistFromCenter)        GLint Viewport[4];        glGetIntegerv(GL_VIEWPORT, Viewport);        double angle = cameraAngleRad, aspect = (static_cast<double>(Viewport[2])) / Viewport[3];        if (aspect < 1.0) angle *= aspect;        cameraDistance = structureSet->maxDistFromCenter / sin(angle/2);        // allow a little "extra" room between clipping planes        cameraClipNear = (cameraDistance - structureSet->maxDistFromCenter) * 0.66;        cameraClipFar = (cameraDistance + structureSet->maxDistFromCenter) * 1.2;        // move structureSet's center to origin        glTranslated(-structureSet->center.x, -structureSet->center.y, -structureSet->center.z);        structureSet->rotationCenter = structureSet->center;    } else { // for logo        cameraAngleRad = PI / 14;        cameraDistance = 200;        cameraClipNear = 0.5*cameraDistance;        cameraClipFar = 1.5*cameraDistance;    }    // reset matrix    glGetDoublev(GL_MODELVIEW_MATRIX, viewMatrix);    NewView();}void OpenGLRenderer::ChangeView(eViewAdjust control, int dX, int dY, int X2, int Y2){    bool doTranslation = false;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -