in layer2/RepLabel.cpp [1172:1503]
static void RepLabelRender(RepLabel * I, RenderInfo * info)
{
CRay *ray = info->ray;
auto pick = info->pick;
PyMOLGlobals *G = I->R.G;
float *v = I->V;
int c = I->N;
lexidx_t *l = I->L;
int font_id = SettingGet_i(G, I->R.cs->Setting, I->R.obj->Setting,
cSetting_label_font_id);
float font_size = SettingGet_f(G, I->R.cs->Setting, I->R.obj->Setting,
cSetting_label_size);
int float_text = SettingGet_i(G, I->R.cs->Setting, I->R.obj->Setting,
cSetting_float_labels);
if (!(ray || pick) && info->pass >= 0)
return;
if(I->R.MaxInvalid >= cRepInvRep){
return;
}
font_id = SettingCheckFontID(G, I->R.cs->Setting, I->R.obj->Setting, font_id);
if (I->shaderCGO && font_size < 0.f){
int size;
if (InvalidateShaderCGOIfTextureNeedsUpdate(G, font_size, I->texture_font_size, &size)){
CGOFree(I->shaderCGO);
I->texture_font_size = size;
}
}
if(ray) {
RepLabelRenderRay(I, info);
} else if(G->HaveGUI && G->ValidContext) {
if(pick) {
int pick_labels = SettingGet_b(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_pick_labels);
if (!pick_labels)
return;
if (I->shaderCGO){
if(float_text)
glDisable(GL_DEPTH_TEST);
CGORenderGLPicking(I->shaderCGO, info, &I->R.context, I->R.cs->Setting, I->R.obj->Setting);
if(float_text)
glEnable(GL_DEPTH_TEST);
return;
} else {
Pickable *p = I->R.P;
unsigned int i;
TextSetIsPicking(G, true);
SceneSetupGLPicking(G);
if(c) {
const char *st;
int screenwidth, screenheight;
if(float_text)
glDisable(GL_DEPTH_TEST);
if (!I->shaderCGO){
SceneGetWidthHeight(G, &screenwidth, &screenheight);
}
i = pick->begin()->src.index;
while(c--) {
if(*l) {
float xn[3], yn[3], tCenterPt[3], offpt[3];
short relativeMode = ((short)*(v + 15));
copy3f(v + 6, tCenterPt);
SceneGetCenter(G, offpt);
TextSetPosNColor(G, offpt, v);
SceneGetScaledAxes(G, I->R.obj, xn, yn);
if (!I->shaderCGO){
if (relativeMode & 2){ // label_relative_mode = 1
float tmp3f[3];
mult3f(xn, tCenterPt[0] * screenwidth/2.f, tmp3f);
add3f(tmp3f, offpt, offpt);
mult3f(yn, tCenterPt[1] * screenheight/2.f, tmp3f);
add3f(tmp3f, offpt, offpt);
copy3f(offpt, tCenterPt);
} else if (relativeMode & 4){ // label_relative_mode = 2
float tmp3f[3];
mult3f(xn, (tCenterPt[0] - (.5f * screenwidth)), tmp3f);
add3f(tmp3f, offpt, offpt);
mult3f(yn, (tCenterPt[1] - (.5f * screenheight)), tmp3f);
add3f(tmp3f, offpt, offpt);
copy3f(offpt, tCenterPt);
}
}
i++;
TextSetPosNColor(G, tCenterPt, v);
TextSetTargetPos(G, v + 3);
TextSetLabelBkgrdInfo(G, *(v + 16), *(v + 17), (v + 18));
if (p) {
p++;
AssignNewPickColor(NULL, i, pick, &I->R.context, TextGetColorUChar4uv(G), p->index, p->bond);
}
TextSetColorFromUColor(G);
st = LexStr(G, *l);
if (!TextRenderOpenGL(G, info, font_id, st, font_size, v + 12, false, (short)*(v + 15), 1, SHADERCGO)){
TextSetIsPicking(G, false);
return ;
}
}
l++;
v += 28;
}
if(float_text)
glEnable(GL_DEPTH_TEST);
(*pick)[0].src.index = i; /* pass the count */
}
TextSetIsPicking(G, false);
}
} else { // not pick or ray, render
if(c) {
const char *st;
short use_shader, has_connector = 0;
CGO *connectorCGO = NULL;
float *PmvMatrix = NULL;
int screenwidth, screenheight;
float xn[3] = { 1.0F, 0.0F, 0.0F };
float yn[3] = { 0.0F, 1.0F, 0.0F };
int pre_use_shaders = info->use_shaders;
Pickable *p = I->R.P;
use_shader = SettingGetGlobal_b(G, cSetting_use_shaders)
#ifdef _PYMOL_IOS
;
#else
&& G->ShaderMgr->GeometryShadersPresent();
#endif
info->use_shaders = use_shader;
if (use_shader){
if (!I->shaderCGO){
I->shaderCGO = CGONew(G);
I->shaderCGO->use_shader = true;
} else {
info->texture_font_size = I->texture_font_size;
if(float_text)
glDisable(GL_DEPTH_TEST);
CGORenderGL(I->shaderCGO, NULL, NULL, NULL, info, &I->R);
if(float_text)
glEnable(GL_DEPTH_TEST);
return;
}
} else {
CGOFree(I->shaderCGO);
#ifndef PURE_OPENGL_ES_2
if(!info->line_lighting)
glDisable(GL_LIGHTING);
#endif
}
TextSetOutlineColor(G, I->OutlineColor);
if (I->shaderCGO && c){
connectorCGO = CGONew(G);
CGOBegin(connectorCGO, GL_LINES);
}
if (!I->shaderCGO){
PmvMatrix = SceneGetPmvMatrix(G);
SceneGetWidthHeight(G, &screenwidth, &screenheight);
MatrixInvTransformC44fAs33f3f(PmvMatrix, xn, xn);
MatrixInvTransformC44fAs33f3f(PmvMatrix, yn, yn);
normalize3f(xn);
normalize3f(yn);
}
while(c--) {
if(*l) {
float tCenterPt[3], offpt[3];
short relativeMode = ((short)*(v + 15));
int draw_var = 127 & (int)*(v + 21);
copy3f(v + 6, tCenterPt);
SceneGetCenter(G, offpt);
TextSetPosNColor(G, offpt, v);
SceneGetScaledAxes(G, I->R.obj, xn, yn);
if (!I->shaderCGO){
if (relativeMode & 2){ // label_relative_mode = 1
float tmp3f[3];
mult3f(xn, tCenterPt[0] * screenwidth/2.f, tmp3f);
add3f(tmp3f, offpt, offpt);
mult3f(yn, tCenterPt[1] * screenheight/2.f, tmp3f);
add3f(tmp3f, offpt, offpt);
copy3f(offpt, tCenterPt);
} else if (relativeMode & 4){ // label_relative_mode = 2
float tmp3f[3];
mult3f(xn, (tCenterPt[0] - .5f * screenwidth), tmp3f);
add3f(tmp3f, offpt, offpt);
mult3f(yn, (tCenterPt[1] - .5f * screenheight), tmp3f);
add3f(tmp3f, offpt, offpt);
copy3f(offpt, tCenterPt);
}
}
if (p) {
p++;
if (I->shaderCGO)
CGOPickColor(I->shaderCGO, p->index, p->bond);
}
TextSetPosNColor(G, tCenterPt, v);
TextSetTargetPos(G, v + 3);
st = LexStr(G, *l);
TextSetLabelBkgrdInfo(G, *(v + 16), *(v + 17), (v + 18));
if (relativeMode & 8){ // label_z_target, adjust z to target
TextGetLabelPos(G)[0] = (SceneGetDepth(G, v+3) - .5) * 2.f;
TextSetLabelPosIsSet(G, 1);
} else if (relativeMode & 6){ // label_relative_mode 1 or 2, i.e., screen stabilized, adjust z
TextSetLabelPos(G, v+6);
TextSetLabelPosIsSet(G, 2);
#ifndef PURE_OPENGL_ES_2
glDisable(GL_FOG);
#endif
} else {
TextSetLabelPosIsSet(G, 0);
}
#ifndef PURE_OPENGL_ES_2
if (!use_shader)
glPushMatrix();
#endif
if (!TextRenderOpenGL(G, info, font_id, st, font_size, v + 12, (draw_var ? 1 : 0), (short)*(v + 15), use_shader, SHADERCGO)){
CGOFree(connectorCGO);
return;
}
if (draw_var){
float *RotMatrix = NULL;
float *screenWorldOffset = TextGetScreenWorldOffset(G);
float text_width = TextGetWidth(G), text_height = TextGetHeight(G);
float *indentFactor = TextGetIndentFactor(G);
RotMatrix = SceneGetMatrix(G);
if (I->shaderCGO){
CGODrawConnector(connectorCGO, v + 3, v + 6, text_width, text_height, indentFactor, screenWorldOffset, v + 9, ((short)*(v + 15)), draw_var, *(v + 22), (v + 23), *(v + 27) * font_size / text_height, *(v + 26)) ;
has_connector = 1;
} else {
#ifndef PURE_OPENGL_ES_2
RepLabelRenderBackgroundInImmediate(G, I, v, draw_var, tCenterPt, relativeMode, xn, yn, PmvMatrix, RotMatrix, screenwidth, screenheight, screenWorldOffset, indentFactor, text_width, text_height, font_size);
#endif
}
}
#ifdef PURE_OPENGL_ES_2
if (float_text && draw_var){
TextRenderOpenGL(G, info, font_id, st, font_size, v + 12, 1, (short)*(v + 15), 1, SHADERCGO);
}
#else
if (!use_shader){
glPopMatrix();
{
// for now, render text twice in immediate mode, some cards don't handle
// z-buffer offset properly, before, only did this when float_text && draw_var
glPushMatrix();
TextRenderOpenGL(G, info, font_id, st, font_size, v + 12, 1, (short)*(v + 15), 1, SHADERCGO);
glPopMatrix();
}
}
#endif
if (relativeMode & 6){ // label_relative_mode 1 or 2, i.e., screen stabilized, adjust z
#ifndef PURE_OPENGL_ES_2
glEnable(GL_FOG);
#endif
}
}
l++;
v += 28;
}
if (!has_connector){
CGOFree(connectorCGO);
}
if (connectorCGO){
CGOEnd(connectorCGO);
CGOStop(connectorCGO);
}
if (I->shaderCGO){
CGO *totalCGO = NULL;
CGO *labelCGO = NULL;
CGOStop(I->shaderCGO);
CGO * tmpCGO = CGONew(G);
CGOEnable(tmpCGO, GL_LABEL_SHADER);
CGOSpecial(tmpCGO, SET_LABEL_SCALE_UNIFORMS);
labelCGO = CGOConvertToLabelShader(I->shaderCGO, tmpCGO);
CGOAppendNoStop(tmpCGO, labelCGO);
CGOFreeWithoutVBOs(labelCGO);
labelCGO = tmpCGO;
if (!labelCGO) return;
CGOFree(I->shaderCGO);
if (connectorCGO){
CGO *tmpCGO = NULL;
tmpCGO = CGOOptimizeConnectors(connectorCGO, 0);
CGOFree(connectorCGO);
connectorCGO = tmpCGO;
// need to render connector/backgrounds first
totalCGO = CGONew(G);
CGOEnable(totalCGO, GL_LABEL_FLOAT_TEXT);
CGOEnable(totalCGO, GL_CONNECTOR_SHADER);
#ifndef PURE_OPENGL_ES_2
CGODisable(totalCGO, GL_LIGHTING);
#endif
CGOAppendNoStop(totalCGO, connectorCGO);
CGOFreeWithoutVBOs(connectorCGO);
CGODisable(totalCGO, GL_CONNECTOR_SHADER);
CGOAppendNoStop(totalCGO, labelCGO);
CGOFreeWithoutVBOs(labelCGO);
CGODisable(totalCGO, GL_LABEL_FLOAT_TEXT);
CGOStop(totalCGO);
} else {
totalCGO = CGONew(G);
CGOEnable(totalCGO, GL_LABEL_FLOAT_TEXT);
CGOAppendNoStop(totalCGO, labelCGO);
CGODisable(totalCGO, GL_LABEL_FLOAT_TEXT);
CGODisable(totalCGO, GL_LABEL_SHADER);
CGOStop(totalCGO);
CGOFreeWithoutVBOs(labelCGO);
}
I->shaderCGO = totalCGO;
if (I->shaderCGO){
I->shaderCGO->use_shader = true;
RepLabelRender(I, info);
return;
}
} else {
#ifndef PURE_OPENGL_ES_2
glEnable(GL_LIGHTING);
#endif
glEnable(GL_BLEND);
}
if(float_text)
glEnable(GL_DEPTH_TEST);
info->use_shaders = pre_use_shaders;
}
}
}
}