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

📄 opengl_renderer.cpp

📁 ncbi源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            phase = PI;        }        for (g = 0; g <= segments; ++g) { /* segment (bottom to top) */            if (g < segments/2)                currentRad = startRad + (midRad - startRad) *                    (0.5 - 0.5 * cos(PI * g / (segments/2)));            else                currentRad = midRad + (startRad - midRad) *                    (0.5 - 0.5 * cos(PI * (g - segments/2) / (segments/2)));            CR[1] = height * g / segments - height/2;            if (g > 0) phase += PI * 2 / segments;            CR[2] = bigRad * cos(phase);            CR[0] = bigRad * sin(phase);            /* make a strip around the strand circumference */            for (s = 0; s < LOGO_SIDES; ++s) {                V[0] = CR[0];                V[2] = CR[2];                V[1] = 0;                length = sqrt(V[0]*V[0] + V[1]*V[1] + V[2]*V[2]);                for (i = 0; i < 3; ++i) V[i] /= length;                H[0] = H[2] = 0;                H[1] = 1;                for (i = 0; i < 3; ++i) {                    pRingNorm[3*s + i] = V[i] * cos(PI * 2 * s / LOGO_SIDES) +                                         H[i] * sin(PI * 2 * s / LOGO_SIDES);                    pRingPts[3*s + i] = CR[i] + pRingNorm[3*s + i] * currentRad;                }            }            if (g > 0) {                glBegin(GL_TRIANGLE_STRIP);                for (s = 0; s < LOGO_SIDES; ++s) {                    glNormal3d(pPrevNorm[3*s], pPrevNorm[3*s + 1], pPrevNorm[3*s + 2]);                    glVertex3d(pPrevRing[3*s], pPrevRing[3*s + 1], pPrevRing[3*s + 2]);                    glNormal3d(pRingNorm[3*s], pRingNorm[3*s + 1], pRingNorm[3*s + 2]);                    glVertex3d(pRingPts[3*s], pRingPts[3*s + 1], pRingPts[3*s + 2]);                }                glNormal3d(pPrevNorm[0], pPrevNorm[1], pPrevNorm[2]);                glVertex3d(pPrevRing[0], pPrevRing[1], pPrevRing[2]);                glNormal3d(pRingNorm[0], pRingNorm[1], pRingNorm[2]);                glVertex3d(pRingPts[0], pRingPts[1], pRingPts[2]);                glEnd();            }            /* cap the ends */            glBegin(GL_POLYGON);            if ((g == 0 && n == 0) || (g == segments && n == 1))                glNormal3d(-1, 0, 0);            else                glNormal3d(1, 0, 0);            if (g == 0) {                for (s = 0; s < LOGO_SIDES; ++s)                    glVertex3d(pRingPts[3*s], pRingPts[3*s + 1], pRingPts[3*s + 2]);            } else if (g == segments) {                for (s = LOGO_SIDES - 1; s >= 0; --s)                    glVertex3d(pRingPts[3*s], pRingPts[3*s + 1], pRingPts[3*s + 2]);            }            glEnd();            /* switch pointers to store previous ring */            tmp = pPrevRing;            pPrevRing = pRingPts;            pRingPts = tmp;            tmp = pPrevNorm;            pPrevNorm = pRingNorm;            pRingNorm = tmp;        }    }    glEndList();}// stuff dealing with rendering of transparent spheresvoid OpenGLRenderer::AddTransparentSphere(const Vector& color, unsigned int name,    const Vector& site, double radius, double alpha){    if (currentDisplayList == NO_LIST) {        WARNINGMSG("OpenGLRenderer::AddTransparentSphere() - not called during display list creation");        return;    }    SphereList& spheres = transparentSphereMap[currentDisplayList];    spheres.resize(spheres.size() + 1);    SphereInfo& info = spheres.back();    info.site = site;    info.name = name;    info.color = color;    info.radius = radius;    info.alpha = alpha;}// add spheres associated with this display list; calculate distance from camera to each onevoid OpenGLRenderer::AddTransparentSpheresForList(unsigned int list){    SphereMap::const_iterator sL = transparentSphereMap.find(list);    if (sL == transparentSphereMap.end()) return;    const SphereList& sphereList = sL->second;    Matrix view;    GL2Matrix(viewMatrix, &view);    transparentSpheresToRender.resize(transparentSpheresToRender.size() + sphereList.size());    SpherePtrList::reverse_iterator sph = transparentSpheresToRender.rbegin();    SphereList::const_iterator i, ie=sphereList.end();    const Matrix *slaveTransform;    for (i=sphereList.begin(); i!=ie; ++i, ++sph) {        sph->siteGL = i->site;        slaveTransform = *(structureSet->transformMap[list]);        if (slaveTransform)            ApplyTransformation(&(sph->siteGL), *slaveTransform);               // slave->master transform        ApplyTransformation(&(sph->siteGL), view);                              // current view transform        sph->distanceFromCamera = (Vector(0,0,cameraDistance) - sph->siteGL).length() - i->radius;        sph->ptr = &(*i);    }}void OpenGLRenderer::RenderTransparentSpheres(void){    if (transparentSpheresToRender.size() == 0) return;    // sort spheres by distance from camera, via operator < defined for SpherePtr    transparentSpheresToRender.sort();    // turn on blending    glEnable(GL_BLEND);    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);    SetColor(GL_NONE); // reset color caches in SetColor    // render spheres in order (farthest first)    SpherePtrList::reverse_iterator i, ie=transparentSpheresToRender.rend();    for (i=transparentSpheresToRender.rbegin(); i!=ie; ++i) {        SetColor(GL_DIFFUSE, i->ptr->color[0], i->ptr->color[1], i->ptr->color[2], i->ptr->alpha);        glLoadName(static_cast<GLuint>(i->ptr->name));        glPushMatrix();        glTranslated(i->siteGL.x, i->siteGL.y, i->siteGL.z);        // apply a random spin so they're not all facing the same direction        srand(static_cast<unsigned int>(fabs(i->ptr->site.x * 1000)));        glRotated(360.0*rand()/RAND_MAX,            1.0*rand()/RAND_MAX - 0.5, 1.0*rand()/RAND_MAX - 0.5, 1.0*rand()/RAND_MAX - 0.5);        gluSphere(qobj, i->ptr->radius, atomSlices, atomStacks);        glPopMatrix();    }    // turn off blending    glDisable(GL_BLEND);    // clear list; recreate it upon each Display()    transparentSpheresToRender.clear();}void OpenGLRenderer::DrawAtom(const Vector& site, const AtomStyle& atomStyle){    if (atomStyle.style == StyleManager::eNotDisplayed || atomStyle.radius <= 0.0)        return;    if (atomStyle.style == StyleManager::eSolidAtom) {        SetColor(GL_DIFFUSE, atomStyle.color[0], atomStyle.color[1], atomStyle.color[2]);        glLoadName(static_cast<GLuint>(atomStyle.name));        glPushMatrix();        glTranslated(site.x, site.y, site.z);        gluSphere(qobj, atomStyle.radius, atomSlices, atomStacks);        glPopMatrix();    }    // need to delay rendering of transparent spheres    else {        AddTransparentSphere(atomStyle.color, atomStyle.name, site, atomStyle.radius, atomStyle.alpha);        // but can put labels on now        if (atomStyle.centerLabel.size() > 0)            DrawLabel(atomStyle.centerLabel, site,                (atomStyle.isHighlighted ? GlobalColors()->Get(Colors::eHighlight) : Vector(1,1,1)));    }    displayListEmpty[currentDisplayList] = false;}/* add a thick splined curve from point 1 *halfway* to point 2 */static void DrawHalfWorm(const Vector *p0, const Vector& p1,    const Vector& p2, const Vector *p3,    double radius, bool cap1, bool cap2,    double tension){    int i, j, k, m, offset;    Vector R1, R2, Qt, p, dQt, H, V;    double len, MG[4][3], T[4], t, prevlen=0.0, cosj, sinj;    GLdouble *Nx = NULL, *Ny, *Nz, *Cx, *Cy, *Cz,        *pNx, *pNy, *pNz, *pCx, *pCy, *pCz, *tmp;    if (!p0 || !p3) {        ERRORMSG("DrawHalfWorm: got NULL 0th and/or 3rd coords for worm");        return;    }    /*     * The Hermite matrix Mh.     */    static double Mh[4][4] = {        { 2, -2,  1,  1},        {-3,  3, -2, -1},        { 0,  0,  1,  0},        { 1,  0,  0,  0}    };    /*     * Variables that affect the curve shape     *   a=b=0 = Catmull-Rom     */    double a = tension,         /* tension    (adjustable)  */        c = 0,                  /* continuity (should be 0) */        b = 0;                  /* bias       (should be 0) */    if (wormSides % 2) {        WARNINGMSG("worm sides must be an even number");        ++wormSides;    }    GLdouble *fblock = NULL;    /* First, calculate the coordinate points of the center of the worm,     * using the Kochanek-Bartels variant of the Hermite curve.     */    R1 = 0.5 * (1 - a) * (1 + b) * (1 + c) * (p1 - *p0) + 0.5 * (1 - a) * (1 - b) * (1 - c) * ( p2 - p1);    R2 = 0.5 * (1 - a) * (1 + b) * (1 - c) * (p2 -  p1) + 0.5 * (1 - a) * (1 - b) * (1 + c) * (*p3 - p2);    /*     * Multiply MG=Mh.Gh, where Gh = [ P(1) P(2) R(1) R(2) ]. This     * 4x1 matrix of vectors is constant for each segment.     */    for (i = 0; i < 4; ++i) {   /* calculate Mh.Gh */        MG[i][0] = Mh[i][0] * p1.x + Mh[i][1] * p2.x + Mh[i][2] * R1.x + Mh[i][3] * R2.x;        MG[i][1] = Mh[i][0] * p1.y + Mh[i][1] * p2.y + Mh[i][2] * R1.y + Mh[i][3] * R2.y;        MG[i][2] = Mh[i][0] * p1.z + Mh[i][1] * p2.z + Mh[i][2] * R1.z + Mh[i][3] * R2.z;    }    for (i = 0; i <= wormSegments; ++i) {        /* t goes from [0,1] from P(1) to P(2) (and we want to go halfway only),           and the function Q(t) defines the curve of this segment. */        t = (0.5 / wormSegments) * i;        /*           * Q(t)=T.(Mh.Gh), where T = [ t^3 t^2 t 1 ]         */        T[0] = t * t * t;        T[1] = t * t;        T[2] = t;        //T[3] = 1;        Qt.x = T[0] * MG[0][0] + T[1] * MG[1][0] + T[2] * MG[2][0] + MG[3][0] /* *T[3] */ ;        Qt.y = T[0] * MG[0][1] + T[1] * MG[1][1] + T[2] * MG[2][1] + MG[3][1] /* *T[3] */ ;        Qt.z = T[0] * MG[0][2] + T[1] * MG[1][2] + T[2] * MG[2][2] + MG[3][2] /* *T[3] */ ;        if (radius == 0.0) {            if (i > 0) {                glBegin(GL_LINES);                glVertex3d(p.x, p.y, p.z);                glVertex3d(Qt.x, Qt.y, Qt.z);                glEnd();            }            /* save to use as previous point for connecting points together */            p = Qt;        } else {            /* construct a circle of points centered at and               in a plane normal to the curve at t - these points will               be used to construct the "thick" worm */            /* allocate single block of storage for two circles of points */            if (!Nx) {                fblock = new GLdouble[12 * wormSides];                Nx = fblock;                Ny = &Nx[wormSides];                Nz = &Nx[wormSides * 2];                Cx = &Nx[wormSides * 3];                Cy = &Nx[wormSides * 4];                Cz = &Nx[wormSides * 5];                pNx = &Nx[wormSides * 6];                pNy = &Nx[wormSides * 7];                pNz = &Nx[wormSides * 8];                pCx = &Nx[wormSides * 9];                pCy = &Nx[wormSides * 10];                pCz = &Nx[wormSides * 11];            }            /*             * The first derivative of Q(t), d(Q(t))/dt, is the slope             * (tangent) at point Q(t); now T = [ 3t^2 2t 1 0 ]             */            T[0] = t * t * 3;            T[1] = t * 2;            //T[2] = 1;            //T[3] = 0;            dQt.x = T[0] * MG[0][0] + T[1] * MG[1][0] + MG[2][0] /* *T[2] + T[3]*MG[3][0] */ ;            dQt.y = T[0] * MG[0][1] + T[1] * MG[1][1] + MG[2][1] /* *T[2] + T[3]*MG[3][1] */ ;            dQt.z = T[0] * MG[0][2] + T[1] * MG[1][2] + MG[2][2] /* *T[2] + T[3]*MG[3][2] */ ;            /* use cross prod't of [1,0,0] x normal as horizontal */            H.Set(0.0, -dQt.z, dQt.y);            if (H.length() < 0.000001) /* nearly colinear - use [1,0.1,0] instead */                H.Set(0.1 * dQt.z, -dQt.z, dQt.y - 0.1 * dQt.x);            H.normalize();            /* and a vertical vector = normal x H */            V = vector_cross(dQt, H);            V.normalize();            /* finally, the worm circumference points (C) and normals (N) are               simple trigonometric combinations of H and V */            for (j = 0; j < wormSides; ++j) {                cosj = cos(2 * PI * j / wormSides);                sinj = sin(2 * PI * j / wormSides);                Nx[j] = H.x * cosj + V.x * sinj;                Ny[j] = H.y * cosj + V.y * sinj;                Nz[j] = H.z * cosj + V.z * sinj;                Cx[j] = Qt.x + Nx[j] * radius;                Cy[j] = Qt.y + Ny[j] * radius;                Cz[j] = Qt.z + Nz[j] * radius;            }            /* figure out which points on the previous circle "match" best               with these, to minimize envelope twisting */            if (i > 0) {                for (m = 0; m < wormSides; ++m) {                    len = 0.0;                    for (j = 0; j < wormSides; ++j) {                        k = j + m;                        if (k >= wormSides)                            k -= wormSides;                        len += (Cx[k] - pCx[j]) * (Cx[k] - pCx[j]) +                               (Cy[k] - pCy[j]) * (Cy[k] - pCy[j]) +                               (Cz[k] - pCz[j]) * (Cz[k] - pCz[j]);                    }                    if (m == 0 || len < prevlen) {                        prevlen = len;                        offset = m;                    }                }            }            /* create triangles from points along this and previous circle */            if (i > 0) {                glBegin(GL_TRIANGLE_STRIP);                for (j = 0; j < wormSides; ++j) {                    k = j + offset;                    if (k >= wormSides) k -= wormSides;                    glNormal3d(Nx[k], Ny[k], Nz[k]);                    glVertex3d(Cx[k], Cy[k], Cz[k]);                    glNormal3d(pNx[j], pNy[j], pNz[j]);                    glVertex3d(pCx[j], pCy[j], pCz[j]);                }                glNormal3d(Nx[offset], Ny[offset], Nz[offset]);                glVertex3d(Cx[offset], Cy[offset], Cz[offset]);                glNormal3d(pNx[0], pNy[0], pNz[0]);                glVertex3d(pCx[0], pCy[0], pCz[0]);                glEnd();            }            /* put caps on the end */            if (cap1 && i == 0) {                glBegin(GL_POLYGON);                dQt.normalize();                glNormal3d(-dQt.x, -dQt.y, -dQt.z);                for (j = wormSides - 1; j >= 0; --j) {                    glVertex3d(Cx[j], Cy[j], Cz[j]);                }                glEnd();            }            else if (cap2 && i == wormSegments) {                glBegin(GL_POLYGON);                dQt.normalize();

⌨️ 快捷键说明

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