in layer1/Ortho.cpp [1489:1956]
void OrthoDoDraw(PyMOLGlobals * G, int render_mode)
{
COrtho *I = G->Ortho;
CGO *orthoCGO = NULL;
int x, y;
int l, lcount;
char *str;
int showLines;
int height;
int overlay, text;
int rightSceneMargin;
int internal_feedback;
int times = 1, origtimes = 0;
int double_pump = false;
const float *bg_color;
int skip_prompt = 0;
int render = false;
int internal_gui_mode = SettingGetGlobal_i(G, cSetting_internal_gui_mode);
int generate_shader_cgo = 0;
I->RenderMode = render_mode;
if(SettingGetGlobal_b(G, cSetting_seq_view)) {
SeqUpdate(G);
I->HaveSeqViewer = true;
} else if(I->HaveSeqViewer) {
SeqUpdate(G);
I->HaveSeqViewer = false;
}
if(SettingGet_i(G, NULL, NULL, cSetting_internal_prompt))
skip_prompt = 0;
else
skip_prompt = 1;
double_pump = SettingGet_i(G, NULL, NULL, cSetting_stereo_double_pump_mono);
bg_color = ColorGet(G, SettingGet_color(G, NULL, NULL, cSetting_bg_rgb));
I->OverlayColor[0] = 1.0F - bg_color[0];
I->OverlayColor[1] = 1.0F - bg_color[1];
I->OverlayColor[2] = 1.0F - bg_color[2];
if(diff3f(I->OverlayColor, bg_color) < 0.25)
zero3f(I->OverlayColor);
PRINTFD(G, FB_Ortho)
" OrthoDoDraw: entered.\n" ENDFD;
if(G->HaveGUI && G->ValidContext) {
#ifdef GL_FRAMEBUFFER_UNDEFINED
// prevents GL_INVALID_FRAMEBUFFER_OPERATION (0x0506) on macOS
// with external Monitor
if (glCheckFramebufferStatus &&
glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_UNDEFINED)
return;
#endif
if(Feedback(G, FB_OpenGL, FB_Debugging))
PyMOLCheckOpenGLErr("OrthoDoDraw checkpoint 0");
if(SettingGetGlobal_b(G, cSetting_internal_gui)) {
switch (SettingGetGlobal_i(G, cSetting_internal_gui_mode)) {
case 0:
rightSceneMargin = DIP2PIXEL(SettingGetGlobal_i(G, cSetting_internal_gui_width));
break;
default:
rightSceneMargin = 0;
break;
}
} else {
rightSceneMargin = 0;
}
internal_feedback = SettingGetGlobal_i(G, cSetting_internal_feedback);
overlay = OrthoGetOverlayStatus(G);
switch (overlay) {
case -1: /* auto overlay */
overlay = I->CurLine - I->AutoOverlayStopLine;
if(overlay < 0) {
overlay += (OrthoSaveLines + 1);
}
if(internal_feedback > 1) {
overlay -= (internal_feedback - 1);
}
if(overlay < 0)
overlay = 0;
break;
case 1: /* default -- user overlay_lines */
overlay = SettingGetGlobal_i(G, cSetting_overlay_lines);
break;
}
text = SettingGetGlobal_b(G, cSetting_text);
if(text)
overlay = 0;
if(overlay || (!text))
if(!SceneRenderCached(G))
render = true;
if(render_mode < 2) {
if(SceneMustDrawBoth(G)) {
OrthoDrawBuffer(G, GL_BACK_LEFT);
SceneGLClear(G, GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
OrthoDrawBuffer(G, GL_BACK_RIGHT);
SceneGLClear(G, GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
times = 2;
double_pump = true;
} else {
OrthoDrawBuffer(G, GL_BACK);
SceneGLClear(G, GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
times = 1;
double_pump = false;
}
} else {
times = 1;
double_pump = false;
}
I->DrawTime = -I->LastDraw;
I->LastDraw = UtilGetSeconds(G);
I->DrawTime += I->LastDraw;
ButModeSetRate(G, (float) I->DrawTime);
if(render && (render_mode < 2))
SceneRender(G, NULL, 0, 0, NULL, 0, 0, 0,
SettingGetGlobal_b(G, cSetting_image_copy_always));
else if (text){
bg_grad(G); // only render the background for text
}
SceneGLClearColor(0.0, 0.0, 0.0, 1.0);
origtimes = times;
while(times--) {
switch (times) {
case 1:
OrthoDrawBuffer(G, GL_BACK_LEFT);
break;
case 0:
if(double_pump) {
OrthoDrawBuffer(G, GL_BACK_RIGHT);
} else
OrthoDrawBuffer(G, GL_BACK);
break;
}
OrthoPushMatrix(G);
if (G->ShaderMgr->ShadersPresent()){
if(SettingGetGlobal_b(G, cSetting_internal_gui) &&
SettingGetGlobal_b(G, cSetting_use_shaders)){
CGO *orthoFastCGO = CGONew(G);
CGOFree(I->orthoFastCGO);
if (I->Blocks->recursiveFastDraw(orthoFastCGO)){
int ok = true;
CGO *expandedCGO;
CGOStop(orthoFastCGO);
expandedCGO = CGOExpandDrawTextures(orthoFastCGO, 0);
CHECKOK(ok, expandedCGO);
if (ok)
I->orthoFastCGO = CGOOptimizeScreenTexturesAndPolygons(expandedCGO, 0);
CHECKOK(ok, I->orthoFastCGO);
CGOFree(orthoFastCGO);
CGOFree(expandedCGO);
} else {
CGOFree(orthoFastCGO);
}
if (!I->orthoCGO){
orthoCGO = CGONew(G);
generate_shader_cgo = true;
} else {
OrthoRenderCGO(G);
OrthoPopMatrix(G);
continue;
}
}
}
x = I->X;
y = I->Y;
if(I->DrawText && internal_feedback) { /* moved to avoid conflict with menus */
Block *block = SceneGetBlock(G);
height = block->rect.bottom;
switch (internal_gui_mode) {
case 0:
if (generate_shader_cgo){
CGOColor(orthoCGO, 0.f, 0.f, 0.f);
CGOBegin(orthoCGO, GL_TRIANGLE_STRIP);
CGOVertex(orthoCGO, I->Width - rightSceneMargin, height - 1, 0.f);
CGOVertex(orthoCGO, I->Width - rightSceneMargin, 0, 0.f);
CGOVertex(orthoCGO, 0.f, height - 1,0.f);
CGOVertex(orthoCGO, 0.f, 0.f, 0.f);
CGOEnd(orthoCGO);
} else {
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex2i(I->Width - rightSceneMargin, height - 1);
glVertex2i(I->Width - rightSceneMargin, 0);
glVertex2i(0, 0);
glVertex2i(0, height - 1);
glEnd();
}
/* deliberate fall-through */
case 1:
if (generate_shader_cgo){
CGOColor(orthoCGO, 0.3f, 0.3f, 0.3f);
CGOBegin(orthoCGO, GL_TRIANGLE_STRIP);
CGOVertex(orthoCGO, 1 + I->Width - rightSceneMargin, height, 0.f);
CGOVertex(orthoCGO, 1 + I->Width - rightSceneMargin, height - 1, 0.f);
CGOVertex(orthoCGO, -1, height, 0.f);
CGOVertex(orthoCGO, -1, height - 1, 0.f);
CGOEnd(orthoCGO);
} else {
glColor3f(0.3, 0.3, 0.3);
glBegin(GL_LINES);
glVertex2i(1 + I->Width - rightSceneMargin, height - 1);
glVertex2i(-1, height - 1);
glEnd();
}
break;
}
}
PRINTFD(G, FB_Ortho)
" OrthoDoDraw: drawing blocks...\n" ENDFD;
if(SettingGetGlobal_b(G, cSetting_internal_gui)) {
int internal_gui_width = DIP2PIXEL(SettingGetGlobal_i(G, cSetting_internal_gui_width));
if(internal_gui_mode != 2) {
if (generate_shader_cgo){
CGOColor(orthoCGO, 0.3f, 0.3f, 0.3f);
CGOBegin(orthoCGO, GL_TRIANGLE_STRIP);
CGOVertex(orthoCGO, I->Width - internal_gui_width, 0.f, 0.f);
CGOVertex(orthoCGO, I->Width - internal_gui_width + 1.f, 0.f, 0.f);
CGOVertex(orthoCGO, I->Width - internal_gui_width, I->Height, 0.f);
CGOVertex(orthoCGO, I->Width - internal_gui_width + 1.f, I->Height, 0.f);
CGOEnd(orthoCGO);
} else {
glColor3f(0.3, 0.3, 0.3);
glBegin(GL_LINES);
glVertex2i(I->Width - internal_gui_width, 0);
glVertex2i(I->Width - internal_gui_width, I->Height);
glEnd();
}
}
}
OrthoRestorePrompt(G);
if(I->DrawText) {
int adjust_at = 0;
/* now print the text */
lcount = 0;
x = cOrthoLeftMargin;
y = cOrthoBottomMargin + MovieGetPanelHeight(G);
#ifdef _PYMOL_SHARP3D
if(SceneGetStereo(G) && SettingGetGlobal_b(G, cSetting_overlay)) {
y += (7 * cOrthoLineHeight) / 10;
}
#endif
if(SettingGetGlobal_b(G, cSetting_text) || I->SplashFlag)
showLines = I->ShowLines;
else {
showLines = internal_feedback + overlay;
}
if(internal_feedback)
adjust_at = internal_feedback + 1;
l = (I->CurLine - (lcount + skip_prompt)) & OrthoSaveLines;
if (orthoCGO)
CGOColorv(orthoCGO, I->TextColor);
else
glColor3fv(I->TextColor);
while(l >= 0) {
lcount++;
if(lcount > showLines)
break;
if(lcount == adjust_at)
y += 4;
str = I->Line[l & OrthoSaveLines];
if(internal_gui_mode) {
TextSetColor(G, I->OverlayColor);
} else if(strncmp(str, I->Prompt, 6) == 0) {
if(lcount < adjust_at)
TextSetColor(G, I->TextColor);
else {
if(length3f(I->OverlayColor) < 0.5)
TextSetColor(G, I->OverlayColor);
else
TextSetColor(G, I->TextColor);
}
} else
TextSetColor(G, I->OverlayColor);
TextSetPos2i(G, x, y);
if(str) {
TextDrawStr(G, str ORTHOCGOARGVAR);
if((lcount == 1) && (I->InputFlag)) {
if(!skip_prompt) {
if(I->CursorChar >= 0) {
TextSetPos2i(G, x + cOrthoCharWidth * I->CursorChar, y);
}
TextDrawChar(G, '_' ORTHOCGOARGVAR);
}
}
}
l = (I->CurLine - (lcount + skip_prompt)) & OrthoSaveLines;
y = y + cOrthoLineHeight;
}
}
OrthoDrawWizardPrompt(G ORTHOCGOARGVAR);
if(SettingGetGlobal_b(G, cSetting_text) || I->SplashFlag) {
Block *block;
int active_tmp;
block = SeqGetBlock(G);
active_tmp = block->active;
block->active = false;
I->Blocks->recursiveDraw(orthoCGO);
block->active = active_tmp;
} else {
I->Blocks->recursiveDraw(orthoCGO);
}
PRINTFD(G, FB_Ortho)
" OrthoDoDraw: blocks drawn.\n" ENDFD;
if(I->LoopFlag) {
const float *vc = ColorGet(G, cColorFront);
if (generate_shader_cgo){
CGOColor(orthoCGO, vc[0], vc[1], vc[2]);
CGOBegin(orthoCGO, GL_TRIANGLE_STRIP);
CGOVertex(orthoCGO, I->LoopRect.left, I->LoopRect.bottom, 0.f);
CGOVertex(orthoCGO, I->LoopRect.left, I->LoopRect.top+1, 0.f);
CGOVertex(orthoCGO, I->LoopRect.left+1, I->LoopRect.bottom, 0.f);
CGOVertex(orthoCGO, I->LoopRect.left+1, I->LoopRect.top+1, 0.f);
CGOEnd(orthoCGO);
CGOBegin(orthoCGO, GL_TRIANGLE_STRIP);
CGOVertex(orthoCGO, I->LoopRect.left, I->LoopRect.top, 0.f);
CGOVertex(orthoCGO, I->LoopRect.left, I->LoopRect.top+1, 0.f);
CGOVertex(orthoCGO, I->LoopRect.right, I->LoopRect.top, 0.f);
CGOVertex(orthoCGO, I->LoopRect.right, I->LoopRect.top+1, 0.f);
CGOEnd(orthoCGO);
CGOBegin(orthoCGO, GL_TRIANGLE_STRIP);
CGOVertex(orthoCGO, I->LoopRect.right, I->LoopRect.bottom, 0.f);
CGOVertex(orthoCGO, I->LoopRect.right, I->LoopRect.top+1, 0.f);
CGOVertex(orthoCGO, I->LoopRect.right+1, I->LoopRect.bottom, 0.f);
CGOVertex(orthoCGO, I->LoopRect.right+1, I->LoopRect.top+1, 0.f);
CGOEnd(orthoCGO);
CGOBegin(orthoCGO, GL_TRIANGLE_STRIP);
CGOVertex(orthoCGO, I->LoopRect.left, I->LoopRect.bottom, 0.f);
CGOVertex(orthoCGO, I->LoopRect.left, I->LoopRect.bottom+1, 0.f);
CGOVertex(orthoCGO, I->LoopRect.right, I->LoopRect.bottom, 0.f);
CGOVertex(orthoCGO, I->LoopRect.right, I->LoopRect.bottom+1, 0.f);
CGOEnd(orthoCGO);
} else {
glColor3f(vc[0], vc[1], vc[2]);
glBegin(GL_LINE_LOOP);
glVertex2i(I->LoopRect.left, I->LoopRect.top);
glVertex2i(I->LoopRect.right, I->LoopRect.top);
glVertex2i(I->LoopRect.right, I->LoopRect.bottom);
glVertex2i(I->LoopRect.left, I->LoopRect.bottom);
glVertex2i(I->LoopRect.left, I->LoopRect.top);
glEnd();
}
}
/* BEGIN PROPRIETARY CODE SEGMENT (see disclaimer in "os_proprietary.h") */
#ifdef PYMOL_EVAL
OrthoDrawEvalMessage(G ORTHOCGOARGVAR);
#endif
#ifdef PYMOL_BETA
OrthoDrawBetaMessage(G);
#endif
#ifdef JYMOL_EVAL
OrthoDrawEvalMessage(G);
#endif
#ifdef PYMOL_EDU
OrthoDrawEduMessage(G);
#endif
#ifdef PYMOL_COLL
OrthoDrawCollMessage(G);
#endif
#ifdef AXPYMOL_EVAL
OrthoDrawAxMessage(G);
#endif
/* END PROPRIETARY CODE SEGMENT */
OrthoPopMatrix(G);
if(Feedback(G, FB_OpenGL, FB_Debugging))
PyMOLCheckOpenGLErr("OrthoDoDraw final checkpoint");
} /* while */
}
if (generate_shader_cgo){
int ok = true;
{
#ifdef SHOW_FONT_TEXTURE
/* This shows the font texture in the middle of the screen, we might want to debug it */
CGO *testOrthoCGO = orthoCGO;
// CGO *testOrthoCGO = CGONew(G);
float minx = 100.f, maxx = 612.f, miny = 100.f, maxy = 612.f;
short texcoord = true;
CGOAlpha(testOrthoCGO, .5f);
CGOColor(testOrthoCGO, 0.f, 0.f, 0.f);
CGOBegin(testOrthoCGO, GL_TRIANGLE_STRIP);
if (texcoord)
CGOTexCoord2f(testOrthoCGO, 1.f, 1.f);
CGOVertex(testOrthoCGO, maxx, maxy, 0.f);
if (texcoord)
CGOTexCoord2f(testOrthoCGO, 1.f, 0.f);
CGOVertex(testOrthoCGO, maxx, miny, 0.f);
if (texcoord)
CGOTexCoord2f(testOrthoCGO, 0.f, 1.f);
CGOVertex(testOrthoCGO, minx, maxy, 0.f);
if (texcoord)
CGOTexCoord2f(testOrthoCGO, 0.f, 0.f);
CGOVertex(testOrthoCGO, minx, miny, 0.f);
CGOEnd(testOrthoCGO);
CGOStop(testOrthoCGO);
#else
CGOStop(orthoCGO);
#endif
}
{
CGO *expandedCGO = CGOExpandDrawTextures(orthoCGO, 0);
CHECKOK(ok, expandedCGO);
if (ok)
I->orthoCGO = CGOOptimizeScreenTexturesAndPolygons(expandedCGO, 0);
CGOFree(orthoCGO);
CGOFree(expandedCGO);
while(origtimes--){
switch (origtimes){
case 1:
OrthoDrawBuffer(G, GL_BACK_LEFT);
break;
case 0:
if(double_pump) {
OrthoDrawBuffer(G, GL_BACK_RIGHT);
} else
OrthoDrawBuffer(G, GL_BACK);
break;
}
OrthoPushMatrix(G);
OrthoRenderCGO(G);
OrthoPopMatrix(G);
}
}
}
I->DirtyFlag = false;
PRINTFD(G, FB_Ortho)
" OrthoDoDraw: leaving...\n" ENDFD;
}