source: trunk/RNA3D/RNA3D_OpenGLEngine.cxx

Last change on this file was 16766, checked in by westram, 7 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.8 KB
Line 
1#include "RNA3D_GlobalHeader.hxx"
2#include "RNA3D_Global.hxx"
3#include "RNA3D_OpenGLEngine.hxx"
4#include "RNA3D_OpenGLGraphics.hxx"
5#include "RNA3D_StructureData.hxx"
6#include "RNA3D_Textures.hxx"
7#include "RNA3D_Renderer.hxx"
8#include "RNA3D_Graphics.hxx"
9#include "RNA3D_Interface.hxx"
10
11#include <iostream>
12
13#include <aw_root.hxx>
14#include <aw_awars.hxx>
15#include <BI_basepos.hxx>
16
17#include <GL/aw_window_ogl.hxx>
18
19// --------------------------------------------------------------------------------
20// global data
21
22RNA3D_Global *RNA3D = NULp;
23
24void RNA3D_init_global_data(ED4_plugin_host& host) {
25    if (!RNA3D) {
26        RNA3D = new RNA3D_Global(host);
27    }
28}
29
30RNA3D_Global::RNA3D_Global(ED4_plugin_host& host) {
31    OpenGLEngineState = -1;
32    iRotateMolecule   = 0;
33    bPointSpritesSupported           = false;
34    bEColiRefInitialized             = false;
35    bMapSaiDispListCreated           = false;
36    bAutoRotate                      = false;
37    bRotateMolecule                  = false;
38    bDisplayMask                     = false;
39    bDisplayComments                 = false;
40    bMapSearchStringsDispListCreated = false;
41
42    ROTATION_SPEED = 0.5;
43    scale = 0.01;
44
45    cGraphics  = new OpenGLGraphics;
46    cStructure = new Structure3D(host);
47    cTexture   = new Texture2D;
48    cRenderer  = new GLRenderer;
49
50    Viewer = Vector3(0.0, 0.0, -2);
51    Center = Vector3(0.0, 0.0, 0.0);
52    Up     = Vector3(0.0, 1.0, 0.0);
53}
54
55RNA3D_Global::~RNA3D_Global() {
56    delete cGraphics;
57    delete cStructure;
58    delete cTexture;
59    delete cRenderer;
60}
61
62// end of global data section
63// --------------------------------------------------------------------------------
64
65static float fAspectRatio;
66const float fViewAngle = 40.0;
67const float fClipNear  = 0.5f;
68const float fClipFar   = 100;
69
70static Display *dpy;
71static GLXContext glx_context;
72
73static int DoubleBufferWithAlpha[] = { GLX_RGBA,
74                                       GLX_DEPTH_SIZE, 12,
75                                       GLX_RED_SIZE, 4,
76                                       GLX_GREEN_SIZE, 4,
77                                       GLX_BLUE_SIZE, 4,
78                                       GLX_ALPHA_SIZE, 4,
79                                       GLX_DOUBLEBUFFER,
80                                       None };
81
82static int DoubleBuffer[] = { GLX_RGBA,
83                              GLX_DEPTH_SIZE, 12,
84                              GLX_RED_SIZE, 4,
85                              GLX_GREEN_SIZE, 4,
86                              GLX_BLUE_SIZE, 4,
87                              GLX_DOUBLEBUFFER,
88                              None };
89
90static int SingleBuffer[] = { GLX_RGBA,
91                              GLX_DEPTH_SIZE, 12,
92                              GLX_RED_SIZE, 4,
93                              GLX_GREEN_SIZE, 4,
94                              GLX_BLUE_SIZE, 4,
95                              None };
96
97static GLfloat rotation_matrix[16];
98static GLfloat rot_x = 0.0, rot_y = 0.0;
99
100static int iScreenWidth, iScreenHeight;
101
102static bool bMapSpDispListCreated     = false;
103static bool bCursorPosDispListCreated = false;
104static bool bHelixNrDispListCreated   = false;
105
106using namespace std;
107
108static void ShowVendorInformation() {
109    const GLubyte *vendor = NULp;
110    vendor = glGetString(GL_VENDOR);   cout<<"Vendor  : "<<vendor<<endl;
111    vendor = glGetString(GL_RENDERER); cout<<"Renderer: "<<vendor<<endl;
112    vendor = glGetString(GL_VERSION);  cout<<"Version : "<<vendor<<endl;
113}
114
115static void initExtensions() {
116    // check mandatory for extensions
117    char missingExtensions[500]="";
118    if (!GLEW_VERSION_1_2) {
119        strcat(missingExtensions, "\nOpenGL Version 1.2");
120    }
121    if (strlen(missingExtensions) > 0) {
122        GBK_terminatef("ERROR: Some needed extensions are not present:%s\n", missingExtensions);
123    }
124
125#ifdef DEBUG
126    printf("DEBUG: All mandatory extensions seem to be ok.\n");
127#endif // DEBUG
128
129    // the following code checks if point sprites could be used and activates them if possible
130    missingExtensions[0] = 0;
131    if (!GLEW_EXT_point_parameters) strcat(missingExtensions, "\nGL_EXT_point_parameters");
132    if (!GLEW_ARB_point_sprite)     strcat(missingExtensions, "\nGL_ARB_point_sprite");
133    if (strlen(missingExtensions) > 0) {
134        printf("Some extra extensions are not present:%s\n", missingExtensions);
135        printf("Molecule Display: Quality of Rendering is LOW!!\n");
136        RNA3D->bPointSpritesSupported = false;
137    }
138    else {
139#ifdef DEBUG
140        printf("DEBUG: All extra extensions seem to be ok as well.\n");
141#endif // DEBUG
142        RNA3D->bPointSpritesSupported = true;
143    }
144}
145
146void ReshapeOpenGLWindow(GLint width, GLint height) {
147    iScreenWidth  = width;
148    iScreenHeight = height;
149
150    fAspectRatio = (float) width / (float) height;
151
152    glViewport(0, 0, width, height);
153    glMatrixMode(GL_PROJECTION);
154    glLoadIdentity();
155    gluPerspective(fViewAngle, fAspectRatio, fClipNear, fClipFar);
156    glMatrixMode(GL_MODELVIEW);
157    glLoadIdentity();
158}
159
160static void CalculateRotationMatrix() {
161    static int initialized = 0;
162    GLfloat new_rotation_matrix[16];
163
164    // calculate new rotation matrix
165    glPushMatrix();
166    glLoadIdentity();
167    glRotatef(-rot_x, 1.0, 0.0, 0.0);
168    glRotatef(rot_y, 0.0, 1.0, 0.0);
169    glGetFloatv(GL_MODELVIEW_MATRIX, new_rotation_matrix);
170    glPopMatrix();
171
172    // calculate total rotation
173    glPushMatrix();
174    glLoadIdentity();
175    glMultMatrixf(new_rotation_matrix);
176    if (initialized) {
177        glMultMatrixf(rotation_matrix);
178    }
179
180    glGetFloatv(GL_MODELVIEW_MATRIX, rotation_matrix);
181    initialized = 1;
182    glPopMatrix();
183}
184
185void InitializeOpenGLEngine(GLint width, GLint height) {
186    cout<<"RNA3D: Initializing OpenGLEngine : "<<width<<" x "<<height<<endl;
187
188    RNA3D->saved_x = RNA3D->saved_y = 2.0f;
189    ComputeRotationXY(1, 1);
190
191    // Get Information about Vendor & Version
192    ShowVendorInformation();
193
194    GLenum err = glewInit();
195    if (GLEW_OK != err) {
196        // problem: glewInit failed, something is seriously wrong
197        fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
198    }
199    fprintf(stdout, "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));
200
201    initExtensions();
202
203    // Prepare the structure Data  and Generate Display Lists
204
205    RNA3D->cStructure->ReadCoOrdinateFile();    // Reading Structure information
206    RNA3D->cStructure->GetSecondaryStructureInfo();  // Getting Secondary Structure Information
207    RNA3D->cStructure->Combine2Dand3DstructureInfo(); // Combining Secondary Structure data with 3D Coordinates
208
209    RNA3D->cStructure->GenerateDisplayLists(); // Generating Display Lists for Rendering
210
211    // Generate Textures
212    RNA3D->cTexture->LoadGLTextures();  // Load The Texture(s)
213
214    glShadeModel(GL_SMOOTH);
215    glClearColor(0, 0, 0, 1);
216    glClearDepth(1.0f);
217
218    glEnable(GL_DEPTH_TEST);         // Enables Depth Testing
219    glDepthFunc(GL_LEQUAL);          // The Type Of Depth Test To Do
220
221    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
222    glEnable(GL_TEXTURE_2D);    // Enable Texture Mapping
223
224    ReshapeOpenGLWindow(width, height);
225
226    CalculateRotationMatrix();
227}
228
229void ComputeRotationXY(int x, int y) {
230    rot_y = (GLfloat)(x - RNA3D->saved_x) * RNA3D->ROTATION_SPEED;
231    rot_x = (GLfloat)(y - RNA3D->saved_y) * RNA3D->ROTATION_SPEED;
232    RNA3D->saved_x = x;
233    RNA3D->saved_y = y;
234}
235
236static void update_HelixNrDispList() {
237    // update of DisplayLists for displaying Helix Numbers
238    GLRenderer  *cRenderer  = RNA3D->cRenderer;
239    Structure3D *cStructure = RNA3D->cStructure;
240
241    if (!bHelixNrDispListCreated && (cRenderer->iHelixNrs || cRenderer->iHelixMidPoint)) {
242        cStructure->GenerateHelixNrDispList(cRenderer->iStartHelix, cRenderer->iEndHelix);
243        bHelixNrDispListCreated = true;
244    }
245}
246
247void MapDisplayParameters(AW_root *root) {
248    GLRenderer  *cRenderer  = RNA3D->cRenderer;
249    Structure3D *cStructure = RNA3D->cStructure;
250
251    // General Molecule Display Section
252    cRenderer->iBackBone       = root->awar(AWAR_3D_MOL_BACKBONE)->read_int();
253    cRenderer->iColorise       = root->awar(AWAR_3D_MOL_COLORIZE)->read_int();
254    cRenderer->fSkeletonSize   = root->awar(AWAR_3D_MOL_SIZE)->read_float();
255    cRenderer->iDispPos        = root->awar(AWAR_3D_MOL_DISP_POS)->read_int();
256    cStructure->iInterval      = root->awar(AWAR_3D_MOL_POS_INTERVAL)->read_int();
257    cRenderer->iDispCursorPos  = root->awar(AWAR_3D_CURSOR_POSITION)->read_int();
258    RNA3D->iRotateMolecule    = root->awar(AWAR_3D_MOL_ROTATE)->read_int();
259
260    // Display Bases Section
261    cRenderer->iDisplayBases     = root->awar(AWAR_3D_DISPLAY_BASES)->read_int();
262    cRenderer->ObjectSize        = root->awar(AWAR_3D_DISPLAY_SIZE)->read_float();
263    cRenderer->iBaseMode         = root->awar(AWAR_3D_BASES_MODE)->read_int();
264    cRenderer->iBaseHelix        = root->awar(AWAR_3D_BASES_HELIX)->read_int();
265    cRenderer->iBaseUnpairHelix  = root->awar(AWAR_3D_BASES_UNPAIRED_HELIX)->read_int();
266    cRenderer->iBaseNonHelix     = root->awar(AWAR_3D_BASES_NON_HELIX)->read_int();
267    cRenderer->iShapeHelix       = root->awar(AWAR_3D_SHAPES_HELIX)->read_int();
268    cRenderer->iShapeUnpairHelix = root->awar(AWAR_3D_SHAPES_UNPAIRED_HELIX)->read_int();
269    cRenderer->iShapeNonHelix    = root->awar(AWAR_3D_SHAPES_NON_HELIX)->read_int();
270
271    // Display Helices Section
272    cRenderer->iDisplayHelix  = root->awar(AWAR_3D_DISPLAY_HELIX)->read_int();
273    cRenderer->iHelixMidPoint = root->awar(AWAR_3D_HELIX_MIDPOINT)->read_int();
274    cRenderer->iHelixNrs      = root->awar(AWAR_3D_HELIX_NUMBER)->read_int();
275    cRenderer->fHelixSize     = root->awar(AWAR_3D_HELIX_SIZE)->read_float();
276    cRenderer->iHelixBackBone = root->awar(AWAR_3D_HELIX_BACKBONE)->read_int();
277    cRenderer->iStartHelix    = root->awar(AWAR_3D_HELIX_FROM)->read_int();
278    cRenderer->iEndHelix      = root->awar(AWAR_3D_HELIX_TO)->read_int();
279    cRenderer->iDispTerInt    = root->awar(AWAR_3D_DISPLAY_TERTIARY_INTRACTIONS)->read_int();
280
281    // Mapping Sequence Data Section
282    cStructure->iMapSAI           = root->awar(AWAR_3D_MAP_SAI)->read_int();
283    cStructure->iMapSearch        = root->awar(AWAR_3D_MAP_SEARCH_STRINGS)->read_int();
284    cStructure->iMapEnable        = root->awar(AWAR_3D_MAP_ENABLE)->read_int();
285    cRenderer->iMapSpecies        = root->awar(AWAR_3D_MAP_SPECIES)->read_int();
286    cRenderer->iMapSpeciesBase    = root->awar(AWAR_3D_MAP_SPECIES_DISP_BASE)->read_int();
287    cRenderer->iMapSpeciesPos     = root->awar(AWAR_3D_MAP_SPECIES_DISP_POS)->read_int();
288    cRenderer->iMapSpeciesDels    = root->awar(AWAR_3D_MAP_SPECIES_DISP_DELETIONS)->read_int();
289    cRenderer->iMapSpeciesMiss    = root->awar(AWAR_3D_MAP_SPECIES_DISP_MISSING)->read_int();
290    cRenderer->iMapSpeciesIns     = root->awar(AWAR_3D_MAP_SPECIES_DISP_INSERTIONS)->read_int();
291    cRenderer->iMapSpeciesInsInfo = root->awar(AWAR_3D_MAP_SPECIES_DISP_INSERTIONS_INFO)->read_int();
292
293    // force valid helix range (in case something is wrong with AWAR values)
294    cRenderer->fixInvalidHelixPositions(cStructure->calc_helix_count());
295    update_HelixNrDispList();
296
297    // Validation of Base Position display
298    if (cStructure->iInterval < 1) {
299        cout<<"WARNING: Invalid POSITION Interval!! Setting it to Default Value (25)."<<endl;
300        root->awar(AWAR_3D_MOL_POS_INTERVAL)->write_int(25);
301    }
302
303    if (cStructure->iMapEnable) {
304        if (cStructure->iMapSearch) {
305            if (!RNA3D->bMapSearchStringsDispListCreated) {
306                cStructure->MapSearchStringsToEcoliTemplate(root);
307            }
308        }
309        if (cStructure->iMapSAI) {
310            if (!RNA3D->bMapSaiDispListCreated) {
311                cStructure->MapSaiToEcoliTemplate();
312            }
313        }
314        if (!bMapSpDispListCreated) {
315            cStructure->MapCurrentSpeciesToEcoliTemplate(root);
316            bMapSpDispListCreated = true;
317        }
318    }
319}
320
321
322void DisplayPostionsIntervalChanged_CB(AW_root *awr) {
323    MapDisplayParameters(awr);
324    glDeleteLists(STRUCTURE_POS, 2);
325    RNA3D->cStructure->ComputeBasePositions();
326    RefreshOpenGLDisplay();
327}
328
329void MapSelectedSpeciesChanged_CB(AW_root *awr) {
330
331    // If Selected Species (in Primary Editor) changed and
332    // the MapSpecies display lists created then,
333    //  1. Delete the display lists;
334    //  2. Recalculate the Display lists for current species;
335    //  3. Map it to EColi Template;
336
337    if (RNA3D->cStructure->iMapEnable &&
338        RNA3D->cRenderer->iMapSpecies &&
339        bMapSpDispListCreated)
340    {
341        glDeleteLists(MAP_SPECIES_BASE_DIFFERENCE, 9);
342        RNA3D->cStructure->MapCurrentSpeciesToEcoliTemplate(awr);
343    }
344
345    // If selected species changed then regenerate the SearchStrings DisplayList
346    MapSearchStringsToEcoliTemplateChanged_CB(awr);
347
348    RefreshOpenGLDisplay();
349}
350
351void MapSaiToEcoliTemplateChanged_CB(AW_root */*awr*/) {
352    // if SAI changed in EDIT4 then display lists should be recalculated
353
354    if (RNA3D->cStructure->iMapEnable  &&
355        RNA3D->cStructure->iMapSAI     &&
356        RNA3D->bMapSaiDispListCreated)
357    {
358        RNA3D->bMapSaiDispListCreated = false;
359        glDeleteLists(MAP_SAI_TO_STRUCTURE, 1);
360        RNA3D->cStructure->MapSaiToEcoliTemplate();
361    }
362
363    RefreshOpenGLDisplay();
364}
365
366void MapSearchStringsToEcoliTemplateChanged_CB(AW_root *awr) {
367
368    // If selected species changed then regenerate the
369    // SearchStrings DisplayList
370
371    if (RNA3D->cStructure->iMapEnable  &&
372        RNA3D->cStructure->iMapSearch  &&
373        RNA3D->bMapSearchStringsDispListCreated)
374    {
375        RNA3D->bMapSearchStringsDispListCreated = false;
376        glDeleteLists(MAP_SEARCH_STRINGS_TO_STRUCTURE, 2);
377        RNA3D->cStructure->MapSearchStringsToEcoliTemplate(awr);
378    }
379}
380
381void CursorPositionChanged_CB(AW_root *awr) {
382
383    if (RNA3D->bEColiRefInitialized) {
384        long iCursorPos = awr->awar(AWAR_CURSOR_POSITION)->read_int();
385        long EColiPos   = RNA3D->cStructure->EColiRef->abs_2_rel(iCursorPos); // @@@ calls abs_2_rel with biopos (1..N)! this is wrong
386
387        if (!bCursorPosDispListCreated) {
388            RNA3D->cStructure->GenerateCursorPositionDispList(EColiPos);
389            bMapSpDispListCreated = true;
390        }
391        else {
392            glDeleteLists(ECOLI_CURSOR_POSITION, 1);
393            RNA3D->cStructure->GenerateCursorPositionDispList(EColiPos);
394        }
395        RefreshOpenGLDisplay();
396    }
397}
398
399void DisplayHelixNrsChanged_CB(AW_root *awr, bool upper_limit_changed) {
400    AW_awar *awar_lower  = awr->awar(AWAR_3D_HELIX_FROM);
401    AW_awar *awar_upper  = awr->awar(AWAR_3D_HELIX_TO);
402    long     NoOfHelices = RNA3D->cStructure->calc_helix_count();
403
404    if (upper_limit_changed) {
405        awar_upper->write_int(force_in_range(1L, awar_upper->read_int(), NoOfHelices));
406        awar_lower->write_int(force_in_range(1L, awar_lower->read_int(), awar_upper->read_int()));
407    }
408    else {
409        awar_lower->write_int(force_in_range(1L,                     awar_lower->read_int(), NoOfHelices));
410        awar_upper->write_int(force_in_range(awar_lower->read_int(), awar_upper->read_int(), NoOfHelices));
411    }
412
413    if (bHelixNrDispListCreated) { // force update (done by MapDisplayParameters below)
414        glDeleteLists(HELIX_NUMBERS, 2);
415        bHelixNrDispListCreated = false;
416    }
417    MapDisplayParameters(awr);
418
419    RefreshOpenGLDisplay();
420}
421
422static void DrawStructure() {
423    GLRenderer *cRenderer = RNA3D->cRenderer;
424
425    // Drawing Molecule Skeleton
426    cRenderer->DisplayMolecule(RNA3D->cStructure);
427
428    // Mapping Helices to The molecule
429    cRenderer->DoHelixMapping();
430
431    // Texture Mapping
432    cRenderer->BeginTexturizer();
433    cRenderer->TexturizeStructure(RNA3D->cTexture, RNA3D->cStructure);
434    cRenderer->EndTexturizer();
435}
436
437void RenderOpenGLScene(Widget w) {
438    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
439
440    // setting the BackGround Color of the OpenGL Scene
441    RNA3D->cGraphics->SetOpenGLBackGroundColor();
442
443    glLoadIdentity();
444
445    gluLookAt(RNA3D->Viewer.x, RNA3D->Viewer.y, RNA3D->Viewer.z,
446              RNA3D->Center.x, RNA3D->Center.y, RNA3D->Center.z,
447              RNA3D->Up.x,     RNA3D->Up.y,     RNA3D->Up.z);
448
449    { // Displaying Molecule Name
450        RNA3D->cRenderer->DisplayMoleculeName(iScreenWidth, iScreenHeight, RNA3D->cStructure);
451    }
452
453    glScalef(RNA3D->scale, RNA3D->scale, RNA3D->scale);
454
455    RNA3D->cRenderer->DisplayMoleculeMask(iScreenWidth, iScreenHeight);
456
457    if (RNA3D->bRotateMolecule || RNA3D->bAutoRotate) {
458        CalculateRotationMatrix();
459    }
460
461    glMultMatrixf(rotation_matrix);
462
463    Vector3& strCen = *RNA3D->cStructure->strCen;
464    glTranslatef(-strCen.x, -strCen.y, -strCen.z);
465
466    DrawStructure();
467
468    glFlush();
469    glXWaitX();
470    glXSwapBuffers (XtDisplay(w), XtWindow(w));
471}
472
473void InitializeOpenGLWindow(Widget w) {
474
475    if (RNA3D->OpenGLEngineState == CREATED) return;
476
477    Arg args[1];
478    XVisualInfo *vi;
479
480    XtSetArg(args[0], (char *) GLwNvisualInfo, &vi);
481    XtGetValues(w, args, 1);
482
483    dpy = XtDisplay(w);
484    if (!dpy) {
485        fprintf(stderr, "could not open display\n");
486    }
487    else {
488        if (AW_alpha_Size_Supported) {
489            vi = glXChooseVisual(dpy, DefaultScreen(dpy), DoubleBufferWithAlpha);
490            printf("RNA3D: Double Buffered Visual With Alpha Size Supported !\n");
491        }
492        else {
493            vi = glXChooseVisual(dpy, DefaultScreen(dpy), DoubleBuffer);
494            printf("RNA3D: Double Buffered Visual Supported !\n");
495        }
496
497        if (!vi) {
498            fprintf(stderr, "try to get a single buffered visual\n");
499            vi = glXChooseVisual(dpy, DefaultScreen(dpy), SingleBuffer);
500            if (!vi)
501                fprintf(stderr, "could not get visual\n");
502        }
503        else {
504            glx_context = glXCreateContext(dpy, vi, NULp, GL_TRUE);
505            if (!glXIsDirect(dpy, glx_context))
506                fprintf(stderr, "direct rendering not supported\n");
507            else
508                printf("RNA3D: Direct rendering supported\n");
509
510            GLwDrawingAreaMakeCurrent(w, glx_context);
511
512            RNA3D->glw = w;
513
514            RNA3D->OpenGLEngineState = CREATED;
515
516            // Initializing fonts
517            char fontName[] = "fixed";
518            RNA3D->cGraphics->InitMainFont(fontName);
519        }
520    }
521}
Note: See TracBrowser for help on using the repository browser.