static int RepMeshCGOGenerate()

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;
}