in layer2/RepMesh.cpp [82:303]
static int RepMeshCGOGenerate(RepMesh * I, RenderInfo * info)
{
PyMOLGlobals *G = I->R.G;
float *v = I->V;
float *vc = I->VC;
int *n = I->N;
int ok = true;
short use_shader;
short mesh_as_cylinders;
int c;
short dot_as_spheres = I->mesh_type==1 && SettingGet_i(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_dot_as_spheres);
use_shader = SettingGetGlobal_b(G, cSetting_mesh_use_shader) &
SettingGetGlobal_b(G, cSetting_use_shaders);
mesh_as_cylinders = SettingGetGlobal_b(G, cSetting_render_as_cylinders) && SettingGetGlobal_b(G, cSetting_mesh_as_cylinders) && I->mesh_type!=1;
ok &= CGOResetNormal(I->shaderCGO, true);
#ifndef PURE_OPENGL_ES_2
int lighting =
SettingGet_i(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_mesh_lighting);
if(!lighting) {
if(!use_shader && !info->line_lighting){
CGODisable(I->shaderCGO, GL_LIGHTING);
}
}
#endif
if (ok){
switch (I->mesh_type) {
case 0:
ok &= CGOSpecial(I->shaderCGO, LINEWIDTH_DYNAMIC_MESH);
break;
case 1:
ok &= CGOSpecial(I->shaderCGO, POINTSIZE_DYNAMIC_DOT_WIDTH);
break;
}
}
ok &= CGOResetNormal(I->shaderCGO, false);
switch (I->mesh_type) {
case 0:
if(n) {
if (ok){
if(I->oneColorFlag) {
while(ok && *n) {
ok &= CGOColorv(I->shaderCGO, ColorGet(G, I->oneColor));
if (ok){
c = *(n++);
if (mesh_as_cylinders){
float *origin, axis[3];
for (; ok && c > 1; --c) {
origin = v;
v += 3;
axis[0] = v[0] - origin[0];
axis[1] = v[1] - origin[1];
axis[2] = v[2] - origin[2];
ok &= (bool)I->shaderCGO->add<cgo::draw::shadercylinder>(origin, axis, 1.f, 15);
}
if (c == 1) {
v += 3;
}
} else {
ok &= CGOBegin(I->shaderCGO, GL_LINE_STRIP);
ok &= CGONormal(I->shaderCGO, 0.f,0.f,1.f);
while(ok && c--) {
ok &= CGOVertexv(I->shaderCGO, v);
v += 3;
}
if (ok)
ok &= CGOEnd(I->shaderCGO);
}
}
}
} else {
while(ok && *n) {
c = *(n++);
if (mesh_as_cylinders){
float *origin, axis[3], *color;
for (; ok && c > 1; --c) {
ok &= CGOColorv(I->shaderCGO, vc);
color = vc;
origin = v;
vc += 3;
v += 3;
axis[0] = v[0] - origin[0];
axis[1] = v[1] - origin[1];
axis[2] = v[2] - origin[2];
if (*(color) != *(vc) || *(color+1) != *(vc+1) || *(color+2) != *(vc+2)){
ok &= (bool)I->shaderCGO->add<cgo::draw::shadercylinder2ndcolor>(I->shaderCGO, origin, axis, 1.f, 15, vc);
} else {
ok &= (bool)I->shaderCGO->add<cgo::draw::shadercylinder>(origin, axis, 1.f, 15);
}
}
if (c == 1) {
v += 3;
vc += 3;
}
} else {
ok &= CGOBegin(I->shaderCGO, GL_LINE_STRIP);
ok &= CGONormal(I->shaderCGO, 0.f,0.f,1.f);
while(ok && c--) {
ok &= CGOColorv(I->shaderCGO, vc);
vc += 3;
if (ok){
ok &= CGOVertexv(I->shaderCGO, v);
v += 3;
}
}
if (ok)
ok &= CGOEnd(I->shaderCGO);
}
}
}
}
}
break;
case 1:
#ifdef PURE_OPENGL_ES_2
/* TODO */
#else
glPointSize(SettingGet_f
(G, I->R.cs->Setting, I->R.obj->Setting, cSetting_dot_width));
#endif
if(ok && n) {
if(I->oneColorFlag) {
while(ok && *n) {
ok &= CGOColorv(I->shaderCGO, ColorGet(G, I->oneColor));
c = *(n++);
if (ok && !dot_as_spheres)
ok &= CGOBegin(I->shaderCGO, GL_POINTS);
while(ok && c--) {
if (dot_as_spheres)
ok &= CGOSphere(I->shaderCGO, v, 1.f);
else
ok &= CGOVertexv(I->shaderCGO, v);
v += 3;
}
if (ok && !dot_as_spheres)
ok &= CGOEnd(I->shaderCGO);
}
} else {
while(ok && *n) {
c = *(n++);
if (!dot_as_spheres)
ok &= CGOBegin(I->shaderCGO, GL_POINTS);
while(ok && c--) {
ok &= CGOColorv(I->shaderCGO, vc);
vc += 3;
if (ok){
if (dot_as_spheres)
ok &= CGOSphere(I->shaderCGO, v, 1.f);
else
ok &= CGOVertexv(I->shaderCGO, v);
}
v += 3;
}
if (!dot_as_spheres)
ok &= CGOEnd(I->shaderCGO);
}
}
}
break;
}
if (use_shader) {
if (ok){
CGO *convertcgo = NULL;
ok &= CGOStop(I->shaderCGO);
if (ok)
convertcgo = CGOCombineBeginEnd(I->shaderCGO, 0);
CHECKOK(ok, convertcgo);
CGOFree(I->shaderCGO);
I->shaderCGO = convertcgo;
convertcgo = NULL;
if (ok){
if (dot_as_spheres){
CGO *tmpCGO = CGONew(G);
if (ok) ok &= CGOEnable(tmpCGO, GL_SPHERE_SHADER);
if (ok) ok &= CGOSpecial(tmpCGO, DOTSIZE_WITH_SPHERESCALE);
convertcgo = CGOOptimizeSpheresToVBONonIndexedNoShader(I->shaderCGO,
CGO_BOUNDING_BOX_SZ + fsizeof<cgo::draw::sphere_buffers>() + 2);
if (ok) ok &= CGOAppendNoStop(tmpCGO, convertcgo);
if (ok) ok &= CGODisable(tmpCGO, GL_SPHERE_SHADER);
if (ok) ok &= CGOStop(tmpCGO);
CGOFreeWithoutVBOs(convertcgo);
convertcgo = tmpCGO;
convertcgo->use_shader = true;
} else {
if (mesh_as_cylinders){
CGO *tmpCGO = CGONew(G);
ok &= CGOEnable(tmpCGO, GL_CYLINDER_SHADER);
if (ok) ok &= CGOSpecial(tmpCGO, MESH_WIDTH_FOR_SURFACES);
convertcgo = CGOConvertShaderCylindersToCylinderShader(I->shaderCGO, tmpCGO);
if (ok) ok &= CGOAppendNoStop(tmpCGO, convertcgo);
if (ok) ok &= CGODisable(tmpCGO, GL_CYLINDER_SHADER);
if (ok) ok &= CGOStop(tmpCGO);
CGOFreeWithoutVBOs(convertcgo);
convertcgo = tmpCGO;
convertcgo->use_shader = convertcgo->has_draw_cylinder_buffers = true;
} else {
CGO *tmpCGO = CGONew(G);
if (ok) ok &= CGOEnable(tmpCGO, GL_DEFAULT_SHADER);
convertcgo = CGOOptimizeToVBONotIndexedNoShader(I->shaderCGO, 0);
if (ok) ok &= CGOAppendNoStop(tmpCGO, convertcgo);
if (ok) ok &= CGODisable(tmpCGO, GL_DEFAULT_SHADER);
if (ok) ok &= CGOStop(tmpCGO);
CGOFreeWithoutVBOs(convertcgo);
convertcgo = tmpCGO;
}
}
CHECKOK(ok, convertcgo);
}
if (convertcgo){
convertcgo->use_shader = true;
CGOFree(I->shaderCGO);
I->shaderCGO = convertcgo;
convertcgo = NULL;
}
}
}
return ok;
}