ObjectCGO.cpp (pymol-v2.1.0.tar.bz2) | : | ObjectCGO.cpp (pymol-open-source-2.2.0) | ||
---|---|---|---|---|
skipping to change at line 38 | skipping to change at line 38 | |||
#include"Scene.h" | #include"Scene.h" | |||
#include"Setting.h" | #include"Setting.h" | |||
#include"PConv.h" | #include"PConv.h" | |||
#include"main.h" | #include"main.h" | |||
#include"Color.h" | #include"Color.h" | |||
#include"VFont.h" | #include"VFont.h" | |||
#include"ShaderMgr.h" | #include"ShaderMgr.h" | |||
static PyObject *ObjectCGOStateAsPyList(ObjectCGOState * I) | static PyObject *ObjectCGOStateAsPyList(ObjectCGOState * I) | |||
{ | { | |||
PyObject *result = NULL; | PyObject *result = NULL; | |||
result = PyList_New(1); | result = PyList_New(1); | |||
if(I->ray) | if(I->origCGO) | |||
PyList_SetItem(result, 0, CGOAsPyList(I->ray)); | PyList_SetItem(result, 0, CGOAsPyList(I->origCGO)); | |||
else if(I->std) | ||||
PyList_SetItem(result, 0, CGOAsPyList(I->std)); | ||||
else | else | |||
PyList_SetItem(result, 0, PConvAutoNone(NULL)); | PyList_SetItem(result, 0, PConvAutoNone(NULL)); | |||
return (PConvAutoNone(result)); | return (PConvAutoNone(result)); | |||
} | } | |||
static PyObject *ObjectCGOAllStatesAsPyList(ObjectCGO * I) | static PyObject *ObjectCGOAllStatesAsPyList(ObjectCGO * I) | |||
{ | { | |||
PyObject *result = NULL; | PyObject *result = NULL; | |||
int a; | int a; | |||
skipping to change at line 75 | skipping to change at line 72 | |||
{ | { | |||
int ok = true; | int ok = true; | |||
int ll, pl = 0; | int ll, pl = 0; | |||
PyObject *tmp; | PyObject *tmp; | |||
if(ok) | if(ok) | |||
ok = (list != NULL); | ok = (list != NULL); | |||
if(ok) | if(ok) | |||
ok = PyList_Check(list); | ok = PyList_Check(list); | |||
if(ok) | if(ok) | |||
ll = PyList_Size(list); | ll = PyList_Size(list); | |||
CGOFree(I->origCGO); | ||||
/* TO SUPPORT BACKWARDS COMPATIBILITY... | /* TO SUPPORT BACKWARDS COMPATIBILITY... | |||
Always check ll when adding new PyList_GetItem's */ | Always check ll when adding new PyList_GetItem's */ | |||
if(ok && ll==2) { | if(ok && ll==2) { | |||
tmp = PyList_GetItem(list, 0); | tmp = PyList_GetItem(list, 0); | |||
if(tmp == Py_None) | if(tmp == Py_None) | |||
I->std = NULL; | I->origCGO = NULL; | |||
else | else { | |||
ok = ((I->std = CGONewFromPyList(G, tmp, version)) != NULL); | ok = ((I->origCGO = CGONewFromPyList(G, tmp, version, 1)) != NULL); | |||
} | ||||
pl++; | pl++; | |||
} | } | |||
if(ok) { | if(ok && !I->origCGO) { | |||
tmp = PyList_GetItem(list, pl); | tmp = PyList_GetItem(list, pl); | |||
if(tmp == Py_None) | if(tmp == Py_None) | |||
I->ray = NULL; | I->origCGO = NULL; | |||
else | else { | |||
ok = ((I->ray = CGONewFromPyList(G, tmp, version)) != NULL); | ok = ((I->origCGO = CGONewFromPyList(G, tmp, version, 0)) != NULL); | |||
if (!I->std && I->ray){ | ||||
I->std = CGOSimplify(I->ray, 0); | ||||
} | } | |||
} | } | |||
return (ok); | return (ok); | |||
} | } | |||
static int ObjectCGOAllStatesFromPyList(ObjectCGO * I, PyObject * list, int vers ion) | static int ObjectCGOAllStatesFromPyList(ObjectCGO * I, PyObject * list, int vers ion) | |||
{ | { | |||
int ok = true; | int ok = true; | |||
int a; | int a; | |||
VLACheck(I->State, ObjectCGOState, I->NState); | VLACheck(I->State, ObjectCGOState, I->NState); | |||
skipping to change at line 167 | skipping to change at line 163 | |||
return (PConvAutoNone(result)); | return (PConvAutoNone(result)); | |||
} | } | |||
/*========================================================================*/ | /*========================================================================*/ | |||
void ObjectCGOFree(ObjectCGO * I) | void ObjectCGOFree(ObjectCGO * I) | |||
{ | { | |||
int a; | int a; | |||
for(a = 0; a < I->NState; a++) { | for(a = 0; a < I->NState; a++) { | |||
if(I->State[a].shaderCGO && I->State[a].std!=I->State[a].shaderCGO) | CGOFree(I->State[a].renderCGO); | |||
CGOFree(I->State[a].shaderCGO); | CGOFree(I->State[a].origCGO); | |||
if(I->State[a].std) | ||||
CGOFree(I->State[a].std); | ||||
if(I->State[a].ray) | ||||
CGOFree(I->State[a].ray); | ||||
} | } | |||
VLAFreeP(I->State); | VLAFreeP(I->State); | |||
ObjectPurge(&I->Obj); | ObjectPurge(&I->Obj); | |||
OOFreeP(I); | OOFreeP(I); | |||
} | } | |||
/*========================================================================*/ | /*========================================================================*/ | |||
void ObjectCGORecomputeExtent(ObjectCGO * I) | void ObjectCGORecomputeExtent(ObjectCGO * I) | |||
{ | { | |||
float mx[3], mn[3]; | float mx[3], mn[3]; | |||
int extent_flag = false; | int extent_flag = false; | |||
int a; | int a; | |||
int has_normals = 0; | int has_normals = 0; | |||
CGO *cgo; | CGO *cgo; | |||
for(a = 0; a < I->NState; a++){ | for(a = 0; a < I->NState; a++){ | |||
cgo = I->State[a].std; | cgo = I->State[a].origCGO; | |||
if (!cgo){ | if (!cgo){ | |||
cgo = I->State[a].shaderCGO; | cgo = I->State[a].renderCGO; | |||
} | } | |||
if(cgo) { | if(cgo) { | |||
if(CGOGetExtent(cgo, mn, mx)) { | if(CGOGetExtent(cgo, mn, mx)) { | |||
if(!extent_flag) { | if(!extent_flag) { | |||
extent_flag = true; | extent_flag = true; | |||
copy3f(mx, I->Obj.ExtentMax); | copy3f(mx, I->Obj.ExtentMax); | |||
copy3f(mn, I->Obj.ExtentMin); | copy3f(mn, I->Obj.ExtentMin); | |||
} else { | } else { | |||
max3f(mx, I->Obj.ExtentMax, I->Obj.ExtentMax); | max3f(mx, I->Obj.ExtentMax, I->Obj.ExtentMax); | |||
min3f(mn, I->Obj.ExtentMin, I->Obj.ExtentMin); | min3f(mn, I->Obj.ExtentMin, I->Obj.ExtentMin); | |||
skipping to change at line 222 | skipping to change at line 214 | |||
} | } | |||
/*========================================================================*/ | /*========================================================================*/ | |||
static void ObjectCGOInvalidate(ObjectCGO * I, int rep, int level, int state) | static void ObjectCGOInvalidate(ObjectCGO * I, int rep, int level, int state) | |||
{ | { | |||
ObjectCGOState *sobj = NULL; | ObjectCGOState *sobj = NULL; | |||
if(state < 0) { | if(state < 0) { | |||
int a; | int a; | |||
for(a = 0; a < I->NState; a++) { | for(a = 0; a < I->NState; a++) { | |||
I->State[a].valid = false; | ||||
sobj = I->State + a; | sobj = I->State + a; | |||
if (sobj->shaderCGO){ | if (sobj->renderCGO){ | |||
CGOFree(sobj->shaderCGO); | CGOFree(sobj->renderCGO); | |||
sobj->shaderCGO = 0; | sobj->renderCGO = 0; | |||
} | } | |||
} | } | |||
} else { | } else { | |||
if((state >= 0) && (state < I->NState)) { | if((state >= 0) && (state < I->NState)) { | |||
I->State[state].valid = false; | ||||
sobj = I->State + state; | sobj = I->State + state; | |||
if (sobj->shaderCGO){ | if (sobj->renderCGO){ | |||
CGOFree(sobj->shaderCGO); | CGOFree(sobj->renderCGO); | |||
sobj->shaderCGO = 0; | sobj->renderCGO = 0; | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
/*========================================================================*/ | /*========================================================================*/ | |||
static void ObjectCGOUpdate(ObjectCGO * I) | static void ObjectCGOUpdate(ObjectCGO * I) | |||
{ | { | |||
int a; | int a; | |||
for(a = 0; a < I->NState; a++) { | for(a = 0; a < I->NState; a++) { | |||
ObjectCGOState *ocs = I->State + a; | ObjectCGOState *ocs = I->State + a; | |||
if (ocs->shaderCGO){ | if (ocs->renderCGO){ | |||
CGOFree(ocs->shaderCGO); | CGOFree(ocs->renderCGO); | |||
ocs->shaderCGO = 0; | ocs->renderCGO = 0; | |||
} | ||||
if(!ocs->valid) { | ||||
if(ocs->std && ocs->ray) { | ||||
int est = CGOCheckComplex(ocs->ray); | ||||
if(est) { | ||||
if(ocs->std) | ||||
CGOFree(ocs->std); | ||||
ocs->std = CGOSimplify(ocs->ray, est); | ||||
} | ||||
} | ||||
ocs->valid = true; | ||||
} | } | |||
} | } | |||
SceneInvalidate(I->Obj.G); /* needed ? */ | SceneInvalidate(I->Obj.G); /* needed ? */ | |||
} | } | |||
/*========================================================================*/ | /*========================================================================*/ | |||
static int ObjectCGOGetNState(ObjectCGO * I) | static int ObjectCGOGetNState(ObjectCGO * I) | |||
{ | { | |||
return (I->NState); | return (I->NState); | |||
} | } | |||
static void ObjectCGORenderState(PyMOLGlobals * G, int pass, CRay *ray, Picking | ||||
**pick, ObjectCGO * I, RenderInfo * info, ObjectCGOState *sobj, const float *col | ||||
or, ObjectGadgetRamp *ramp, int use_shader, bool cgo_lighting){ | ||||
if(ray) { | ||||
if(sobj) { | ||||
if(sobj->origCGO){ | ||||
CGO *cgo = sobj->origCGO, *cgo_copy = NULL; | ||||
if (cgo_lighting && CGOHasAnyTriangleVerticesWithoutNormals(cgo)) { | ||||
cgo = cgo_copy = CGOGenerateNormalsForTriangles(cgo); | ||||
} | ||||
CGORenderRay(cgo, ray, info, color, ramp, I->Obj.Setting, NULL); | ||||
CGOFree(cgo_copy); | ||||
} | ||||
} | ||||
} else if(G->HaveGUI && G->ValidContext && pass) { | ||||
if(pick) { // no picking yet | ||||
} else { | ||||
bool pass_is_opaque = (pass > 0); | ||||
if(sobj && ((sobj->hasTransparency ^ pass_is_opaque) || (sobj->hasOpaque = | ||||
= pass_is_opaque))){ | ||||
{ | ||||
CShaderPrg *shaderPrg; | ||||
int two_sided_lighting = SettingGet_i(G, I->Obj.Setting, NULL, cSetting | ||||
_two_sided_lighting); | ||||
bool backface_cull = SettingGet_i(G, I->Obj.Setting, NULL, cSetting_ba | ||||
ckface_cull); | ||||
if (two_sided_lighting<0){ | ||||
two_sided_lighting = !cgo_lighting; | ||||
} | ||||
two_sided_lighting &= cgo_lighting; // only set two_sided_lighting if | ||||
cgo_lighting is set | ||||
#ifndef PURE_OPENGL_ES_2 | ||||
if (cgo_lighting){ | ||||
glEnable(GL_LIGHTING); | ||||
} else { | ||||
glDisable(GL_LIGHTING); | ||||
} | ||||
if (two_sided_lighting){ | ||||
if (use_shader) | ||||
glEnable(GL_VERTEX_PROGRAM_TWO_SIDE); | ||||
GLLIGHTMODELI(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); | ||||
} else { | ||||
if (use_shader) | ||||
glDisable(GL_VERTEX_PROGRAM_TWO_SIDE); | ||||
GLLIGHTMODELI(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); | ||||
} | ||||
#endif | ||||
if (backface_cull){ | ||||
glCullFace(GL_BACK); | ||||
glEnable(GL_CULL_FACE); | ||||
} | ||||
if (use_shader){ | ||||
shaderPrg = G->ShaderMgr->Enable_DefaultShader(info->pass); | ||||
if (!shaderPrg) return; | ||||
shaderPrg->SetLightingEnabled(cgo_lighting); | ||||
shaderPrg->Set1i("two_sided_lighting_enabled", two_sided_lighting); | ||||
sobj->renderCGO->use_shader = use_shader; | ||||
sobj->renderCGO->debug = SettingGetGlobal_i(G, cSetting_cgo_debug); | ||||
CGORenderGL(sobj->renderCGO, color, I->Obj.Setting, NULL, info, NULL) | ||||
; | ||||
shaderPrg->Disable(); | ||||
} else { | ||||
sobj->renderCGO->use_shader = use_shader; | ||||
sobj->renderCGO->debug = SettingGetGlobal_i(G, cSetting_cgo_debug); | ||||
CGORenderGL(sobj->renderCGO, color, I->Obj.Setting, NULL, info, NULL) | ||||
; | ||||
} | ||||
if (backface_cull){ | ||||
glDisable(GL_CULL_FACE); | ||||
} | ||||
#ifndef PURE_OPENGL_ES_2 | ||||
if (two_sided_lighting){ | ||||
if (use_shader) | ||||
glDisable(GL_VERTEX_PROGRAM_TWO_SIDE); | ||||
GLLIGHTMODELI(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); | ||||
} | ||||
if (!cgo_lighting){ | ||||
glEnable(GL_LIGHTING); | ||||
} | ||||
#endif | ||||
} | ||||
} | ||||
} | ||||
} | ||||
} | ||||
static void ObjectCGOGenerateCGO(PyMOLGlobals * G, ObjectCGO * I, ObjectCGOState | ||||
*sobj, bool use_shader, bool cgo_lighting, const float *color, ObjectGadgetRamp | ||||
*ramp, int state) | ||||
{ | ||||
if (sobj->renderCGO && | ||||
((use_shader ^ sobj->renderWithShaders) || | ||||
(cgo_lighting ^ sobj->cgo_lighting))){ | ||||
// if renderWithShaders doesn't match use_shader, clear CGO and re-generate | ||||
CGOFree(sobj->renderCGO); | ||||
sobj->renderCGO = 0; | ||||
} | ||||
if (!sobj->renderCGO){ | ||||
CGO *convertcgo = NULL; | ||||
float colorWithA[4]; | ||||
short someLinesWithoutNormals = 0; | ||||
CGO *preOpt = NULL; | ||||
if (color){ | ||||
colorWithA[0] = color[0]; colorWithA[1] = color[1]; colorWithA[2] = color[ | ||||
2]; | ||||
} else { | ||||
colorWithA[0] = 1.f; colorWithA[1] = 1.f; colorWithA[2] = 1.f; | ||||
} | ||||
colorWithA[3] = 1.f - SettingGet_f(G, I->Obj.Setting, NULL, cSetting_cgo_tra | ||||
nsparency); | ||||
preOpt = sobj->origCGO; | ||||
bool hasTransparency = (colorWithA[3] < 1.f || CGOHasTransparency(preOpt)); | ||||
bool hasOpaque = (colorWithA[3] == 1.f || CGOHasOpaque(preOpt)); | ||||
CGO *allCylinders = NULL; | ||||
CGO *allSpheres = NULL; | ||||
{ | ||||
CGO *convertcgo = NULL; | ||||
bool freePreOpt = false; | ||||
if (cgo_lighting){ | ||||
if (CGOHasAnyTriangleVerticesWithoutNormals(preOpt)){ | ||||
// we only need normals if cgo_lighting is on | ||||
preOpt = CGOGenerateNormalsForTriangles(preOpt); | ||||
freePreOpt = true; | ||||
} | ||||
someLinesWithoutNormals = CGOHasAnyLineVerticesWithoutNormals(preOpt); | ||||
if (!use_shader && someLinesWithoutNormals){ | ||||
// if some lines without normals, turn lighting off on lines | ||||
CGO *preOpt2 = preOpt; | ||||
preOpt->use_shader = use_shader; | ||||
preOpt = CGOTurnLightingOnLinesOff(preOpt); | ||||
CGOStop(preOpt); | ||||
if (freePreOpt){ | ||||
CGOFree(preOpt2); | ||||
} | ||||
freePreOpt = true; | ||||
} | ||||
} | ||||
convertcgo = CGONew(G); | ||||
CGOColorv(convertcgo, colorWithA); | ||||
CGOAlpha(convertcgo, colorWithA[3]); | ||||
CGOAppend(convertcgo, preOpt); | ||||
if (freePreOpt){ | ||||
CGOFree(preOpt); | ||||
} | ||||
if (use_shader){ | ||||
bool t_mode_3 = SettingGetGlobal_i(G, cSetting_transparency_mode)==3; | ||||
if ((t_mode_3 || !hasTransparency) | ||||
&& G->ShaderMgr->Get_DefaultSphereShader(0) | ||||
&& G->ShaderMgr->Get_CylinderShader(0)) | ||||
{ | ||||
if (CGOHasCylinderOperations(convertcgo)){ | ||||
CGO *newCGO = NULL; | ||||
allCylinders = CGONew(G); | ||||
CGOEnable(allCylinders, GL_CYLINDER_SHADER); | ||||
newCGO = CGOConvertShaderCylindersToCylinderShader(convertcgo, allCy | ||||
linders); | ||||
CGOAppendNoStop(allCylinders, newCGO); | ||||
CGOFreeWithoutVBOs(newCGO); | ||||
CGODisable(allCylinders, GL_CYLINDER_SHADER); | ||||
CGOStop(allCylinders); | ||||
CGO *allButCylinders = CGONew(G); | ||||
CGOFilterOutCylinderOperationsInto(convertcgo, allButCylinders); | ||||
CGOStop(allButCylinders); | ||||
CGOFree(convertcgo); | ||||
convertcgo = allButCylinders; | ||||
} | ||||
if (CGOHasOperationsOfType(convertcgo, CGO_SPHERE)){ | ||||
CGO *allButSpheres = CGONew(G); | ||||
allSpheres = CGOOptimizeSpheresToVBONonIndexed(convertcgo, 0, true, | ||||
allButSpheres); | ||||
if (allSpheres){ | ||||
CGOFree(convertcgo); | ||||
CGOStop(allButSpheres); | ||||
convertcgo = allButSpheres; | ||||
} else { | ||||
CGOFree(allButSpheres); | ||||
} | ||||
} | ||||
preOpt = CGOSimplify(convertcgo, 0); | ||||
} else { | ||||
preOpt = CGOSimplifyNoCompress(convertcgo, 0) ; | ||||
} | ||||
} else { | ||||
preOpt = CGOSimplifyNoCompress(convertcgo, 0) ; | ||||
} | ||||
CGOFree(convertcgo); | ||||
} | ||||
if (ramp){ | ||||
convertcgo = CGOColorByRamp(G, preOpt, ramp, state, I->Obj.Setting); | ||||
CGOFree(preOpt); | ||||
preOpt = convertcgo; | ||||
} | ||||
if (use_shader){ | ||||
if(preOpt && preOpt->has_begin_end){ | ||||
CGO *convertcgo = CGOCombineBeginEnd(preOpt, 0); | ||||
CGOFree(preOpt); | ||||
preOpt = convertcgo; | ||||
} | ||||
sobj->hasTransparency = hasTransparency; | ||||
sobj->hasOpaque = hasOpaque; | ||||
convertcgo = CGOOptimizeToVBOIndexedWithColorEmbedTransparentInfo(preOpt, | ||||
0, colorWithA, false); | ||||
if (someLinesWithoutNormals){ | ||||
// if some lines without normals, turn lighting off on lines | ||||
convertcgo->use_shader = use_shader; | ||||
CGO *convertcgo2 = CGOTurnLightingOnLinesOff(convertcgo); | ||||
CGOStop(convertcgo2); | ||||
CGOFreeWithoutVBOs(convertcgo); | ||||
convertcgo = convertcgo2; | ||||
} | ||||
if (allCylinders){ | ||||
CGOAppendNoStop(convertcgo, allCylinders); | ||||
CGOFreeWithoutVBOs(allCylinders); | ||||
} | ||||
if (allSpheres){ | ||||
CGOAppendNoStop(convertcgo, allSpheres); | ||||
CGOFreeWithoutVBOs(allSpheres); | ||||
} | ||||
CGOStop(convertcgo); | ||||
sobj->renderCGO = convertcgo; | ||||
} else { | ||||
unsigned char hasTrans = CGOHasTransparency(preOpt); | ||||
CGOFree(convertcgo); | ||||
if (hasTrans){ | ||||
CGO *convertcgo ; | ||||
convertcgo = CGOConvertTrianglesToAlpha(preOpt); | ||||
sobj->renderCGO = convertcgo; | ||||
sobj->renderCGO->render_alpha = 2; | ||||
} else { | ||||
sobj->renderCGO = CGOSimplify(preOpt, 0); // copy, for now | ||||
} | ||||
sobj->hasTransparency = hasTrans; | ||||
sobj->hasOpaque = CGOHasOpaque(preOpt); | ||||
} | ||||
CGOFree(preOpt); | ||||
sobj->renderWithShaders = use_shader; | ||||
sobj->cgo_lighting = cgo_lighting; | ||||
} | ||||
} | ||||
/*========================================================================*/ | /*========================================================================*/ | |||
static void ObjectCGORender(ObjectCGO * I, RenderInfo * info) | static void ObjectCGORender(ObjectCGO * I, RenderInfo * info) | |||
{ | { | |||
PyMOLGlobals *G = I->Obj.G; | PyMOLGlobals *G = I->Obj.G; | |||
int state = info->state; | int state = info->state; | |||
CRay *ray = info->ray; | CRay *ray = info->ray; | |||
Picking **pick = info->pick; | Picking **pick = info->pick; | |||
int pass = info->pass; | int pass = info->pass; | |||
ObjectCGOState *sobj = NULL; | ObjectCGOState *sobj = NULL; | |||
float *color; | const float *color = NULL; | |||
int use_shader = 0; | bool use_shader = false, cgo_lighting = false; | |||
ObjectGadgetRamp *ramp = NULL; | ||||
use_shader = SettingGetGlobal_b(G, cSetting_cgo_use_shader) & | use_shader = SettingGetGlobal_b(G, cSetting_cgo_use_shader) & | |||
SettingGetGlobal_b(G, cSetting_use_shaders) & | SettingGetGlobal_b(G, cSetting_use_shaders); | |||
!SettingGetGlobal_b(G, cSetting_transparency_global_sort); | cgo_lighting = SettingGet_i(G, I->Obj.Setting, NULL, cSetting_cgo_lighting); | |||
ObjectPrepareContext(&I->Obj, ray); | ||||
ObjectPrepareContext(&I->Obj, info); | ||||
ramp = ColorGetRamp(G, I->Obj.Color); | ||||
color = ColorGet(G, I->Obj.Color); | color = ColorGet(G, I->Obj.Color); | |||
if(!I->State) | if(!I->State) | |||
return; | return; | |||
if((pass == 1) || info->ray) { | if(pass || info->ray) { | |||
if((I->Obj.visRep & cRepCGOBit)) { | if((I->Obj.visRep & cRepCGOBit)) { | |||
for(StateIterator iter(G, I->Obj.Setting, state, I->NState); iter.next();) { | for(StateIterator iter(G, I->Obj.Setting, state, I->NState); iter.next();) { | |||
sobj = I->State + iter.state; | sobj = I->State + iter.state; | |||
if (use_shader){ | if (!sobj->origCGO) | |||
if (!sobj->shaderCGO && sobj->std){ | continue; | |||
float colorWithA[4]; | if (!ray) | |||
if (color){ | ObjectCGOGenerateCGO(G, I, sobj, use_shader, cgo_lighting, color, ramp | |||
colorWithA[0] = color[0]; colorWithA[1] = color[1]; colorWithA[2] = | , iter.state); | |||
color[2]; | ObjectCGORenderState(G, pass, ray, pick, I, info, sobj, color, ramp, use_ | |||
} else { | shader, cgo_lighting); | |||
colorWithA[0] = 1.f; colorWithA[1] = 1.f; colorWithA[2] = 1.f; | ||||
} | ||||
colorWithA[3] = 1.f - SettingGet_f(G, I->Obj.Setting, NULL, cSetting_ | ||||
cgo_transparency); | ||||
{ | ||||
CGO *convertcgo = NULL; | ||||
if(sobj->std && sobj->std->has_begin_end){ | ||||
convertcgo = CGOCombineBeginEnd(sobj->std, 0); | ||||
CGOFree(sobj->std); | ||||
sobj->std = convertcgo; | ||||
} | ||||
} | ||||
if (CGOHasCylinderOperations(sobj->std)){ | ||||
sobj->shaderCGO = CGOOptimizeGLSLCylindersToVBOIndexedNoColor(sobj- | ||||
>std, 0); | ||||
// sobj->shaderCGO->enable_shaders = true; | ||||
} else { | ||||
sobj->shaderCGO = CGOOptimizeToVBOIndexedWithColor(sobj->std, 0, co | ||||
lorWithA); | ||||
} | ||||
} | ||||
} else if (sobj->shaderCGO){ | ||||
CGOFree(sobj->shaderCGO); | ||||
sobj->shaderCGO = 0; | ||||
} | ||||
if(ray) { | ||||
if(sobj) { | ||||
int try_std = false; | ||||
if(sobj->ray){ | ||||
int rayok = CGORenderRay(sobj->ray, ray, color, I->Obj.Setting, NU | ||||
LL); | ||||
if (!rayok){ | ||||
CGOFree(sobj->ray); | ||||
sobj->ray = NULL; | ||||
try_std = true; | ||||
} | ||||
} else { | ||||
try_std = true; | ||||
} | ||||
if (try_std && sobj->std){ | ||||
int rayok = CGORenderRay(sobj->std, ray, color, I->Obj.Setting, NU | ||||
LL); | ||||
if (!rayok){ | ||||
CGOFree(sobj->std); | ||||
sobj->std = NULL; | ||||
} | ||||
} | ||||
} | ||||
} else if(G->HaveGUI && G->ValidContext) { | ||||
if(pick) { | ||||
} else { | ||||
if(sobj) | ||||
if(sobj->std){ | ||||
CShaderPrg *shaderPrg; | ||||
int cgo_lighting, two_sided_lighting; | ||||
cgo_lighting = SettingGet_i(G, I->Obj.Setting, NULL, cSetting_cgo | ||||
_lighting); | ||||
two_sided_lighting = SettingGet_i(G, I->Obj.Setting, NULL, cSetti | ||||
ng_two_sided_lighting); | ||||
if (two_sided_lighting<0){ | ||||
two_sided_lighting = SceneGetTwoSidedLighting(G); | ||||
} | ||||
if (use_shader){ | ||||
shaderPrg = CShaderPrg_Enable_DefaultShader(G); | ||||
if (!shaderPrg) return; | ||||
CShaderPrg_SetLightingEnabled(shaderPrg, cgo_lighting); | ||||
CShaderPrg_Set1i(shaderPrg, "two_sided_lighting_enabled", two_s | ||||
ided_lighting); | ||||
sobj->shaderCGO->use_shader = use_shader; | ||||
sobj->shaderCGO->debug = SettingGetGlobal_i(G, cSetting_cgo_deb | ||||
ug); | ||||
CGORenderGL(sobj->shaderCGO, color, I->Obj.Setting, NULL, info, | ||||
NULL); | ||||
CShaderPrg_Disable(shaderPrg); | ||||
} else { | ||||
sobj->std->use_shader = use_shader; | ||||
sobj->std->debug = SettingGetGlobal_i(G, cSetting_cgo_debug); | ||||
if (cgo_lighting){ | ||||
glEnable(GL_LIGHTING); | ||||
} else { | ||||
glDisable(GL_LIGHTING); | ||||
} | ||||
if (two_sided_lighting){ | ||||
glEnable(GL_VERTEX_PROGRAM_TWO_SIDE); | ||||
} else { | ||||
glDisable(GL_VERTEX_PROGRAM_TWO_SIDE); | ||||
} | ||||
CGORenderGL(sobj->std, color, I->Obj.Setting, NULL, info, NULL) | ||||
; | ||||
if (SceneGetTwoSidedLighting(G)){ | ||||
glEnable(GL_VERTEX_PROGRAM_TWO_SIDE); | ||||
} else { | ||||
glDisable(GL_VERTEX_PROGRAM_TWO_SIDE); | ||||
} | ||||
if (!cgo_lighting){ | ||||
glEnable(GL_LIGHTING); | ||||
} | ||||
} | ||||
} | ||||
} | ||||
} | ||||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
/*========================================================================*/ | /*========================================================================*/ | |||
ObjectCGO *ObjectCGONew(PyMOLGlobals * G) | ObjectCGO *ObjectCGONew(PyMOLGlobals * G) | |||
{ | { | |||
OOAlloc(G, ObjectCGO); | OOAlloc(G, ObjectCGO); | |||
skipping to change at line 478 | skipping to change at line 596 | |||
} | } | |||
} | } | |||
} | } | |||
return (cgo); | return (cgo); | |||
} | } | |||
/*========================================================================*/ | /*========================================================================*/ | |||
ObjectCGO *ObjectCGOFromCGO(PyMOLGlobals * G, ObjectCGO * obj, CGO * cgo, int st ate) | ObjectCGO *ObjectCGOFromCGO(PyMOLGlobals * G, ObjectCGO * obj, CGO * cgo, int st ate) | |||
{ | { | |||
ObjectCGO *I = NULL; | ObjectCGO *I = NULL; | |||
int est = 0; | ||||
if(obj) { | if(obj) { | |||
if(obj->Obj.type != cObjectCGO) /* TODO: handle this */ | if(obj->Obj.type != cObjectCGO) /* TODO: handle this */ | |||
obj = NULL; | obj = NULL; | |||
} | } | |||
if(!obj) { | if(!obj) { | |||
I = ObjectCGONew(G); | I = ObjectCGONew(G); | |||
} else { | } else { | |||
I = obj; | I = obj; | |||
} | } | |||
if(state < 0) | if(state < 0) | |||
state = I->NState; | state = I->NState; | |||
if(I->NState <= state) { | if(I->NState <= state) { | |||
VLACheck(I->State, ObjectCGOState, state); | VLACheck(I->State, ObjectCGOState, state); | |||
I->NState = state + 1; | I->NState = state + 1; | |||
} | } | |||
if(I->State[state].shaderCGO && I->State[state].std!=I->State[state].shaderCGO | CGOFree(I->State[state].renderCGO); | |||
) { | CGOFree(I->State[state].origCGO); | |||
CGOFree(I->State[state].shaderCGO); | I->State[state].origCGO = cgo; | |||
I->State[state].shaderCGO = 0; | ||||
} | ||||
if(I->State[state].std) { | ||||
CGOFree(I->State[state].std); | ||||
} | ||||
if(I->State[state].ray) { | ||||
CGOFree(I->State[state].ray); | ||||
} | ||||
if (cgo) | ||||
est = CGOCheckComplex(cgo); | ||||
if(est) { | ||||
I->State[state].ray = cgo; | ||||
I->State[state].std = CGOSimplify(cgo, est); | ||||
} else { | ||||
I->State[state].std = cgo; | ||||
} | ||||
I->State[state].valid = true; | ||||
if(I) { | if(I) { | |||
ObjectCGORecomputeExtent(I); | ObjectCGORecomputeExtent(I); | |||
} | } | |||
SceneChanged(G); | SceneChanged(G); | |||
SceneCountFrames(G); | SceneCountFrames(G); | |||
return (I); | return (I); | |||
} | } | |||
/*========================================================================*/ | /*========================================================================*/ | |||
skipping to change at line 536 | skipping to change at line 637 | |||
ObjectCGO *ObjectCGONewVFontTest(PyMOLGlobals * G, const char *text, float *pos) | ObjectCGO *ObjectCGONewVFontTest(PyMOLGlobals * G, const char *text, float *pos) | |||
{ | { | |||
ObjectCGO *I = NULL; | ObjectCGO *I = NULL; | |||
int font_id; | int font_id; | |||
CGO *cgo = NULL; | CGO *cgo = NULL; | |||
float scale[2] = { 1.0, 1.0 }; | float scale[2] = { 1.0, 1.0 }; | |||
font_id = VFontLoad(G, 1, 1, 1, true); | font_id = VFontLoad(G, 1, 1, 1, true); | |||
cgo = CGONew(G); | cgo = CGONew(G); | |||
VFontWriteToCGO(G, font_id, cgo, text, pos, scale, NULL); | VFontWriteToCGO(G, font_id, cgo, text, pos, scale, NULL, NULL); | |||
I = ObjectCGOFromCGO(G, NULL, cgo, 0); | I = ObjectCGOFromCGO(G, NULL, cgo, 0); | |||
return (I); | return (I); | |||
} | } | |||
/*========================================================================*/ | /*========================================================================*/ | |||
ObjectCGO *ObjectCGODefine(PyMOLGlobals * G, ObjectCGO * obj, PyObject * pycgo, int state) | ObjectCGO *ObjectCGODefine(PyMOLGlobals * G, ObjectCGO * obj, PyObject * pycgo, int state) | |||
{ /* assumes blocked interpreter */ | { /* assumes blocked interpreter */ | |||
ObjectCGO *I = NULL; | ObjectCGO *I = NULL; | |||
skipping to change at line 566 | skipping to change at line 667 | |||
} else { | } else { | |||
I = obj; | I = obj; | |||
} | } | |||
if(state < 0) | if(state < 0) | |||
state = I->NState; | state = I->NState; | |||
if(I->NState <= state) { | if(I->NState <= state) { | |||
VLACheck(I->State, ObjectCGOState, state); | VLACheck(I->State, ObjectCGOState, state); | |||
I->NState = state + 1; | I->NState = state + 1; | |||
} | } | |||
if(I->State[state].std) { | CGOFree(I->State[state].origCGO); | |||
CGOFree(I->State[state].std); | ||||
I->State[state].std = NULL; | ||||
} | ||||
if(I->State[state].ray) { | ||||
CGOFree(I->State[state].ray); | ||||
I->State[state].ray = NULL; | ||||
} | ||||
if(PyList_Check(pycgo)) { | if(PyList_Check(pycgo)) { | |||
if(PyList_Size(pycgo)) { | if(PyList_Size(pycgo)) { | |||
if(PyFloat_Check(PyList_GetItem(pycgo, 0))) { | if(PyFloat_Check(PyList_GetItem(pycgo, 0))) { | |||
cgo = ObjectCGOPyListFloatToCGO(G, pycgo); | cgo = ObjectCGOPyListFloatToCGO(G, pycgo); | |||
if(cgo) { | if(cgo) { | |||
est = CGOCheckForText(cgo); | est = CGOCheckForText(cgo); | |||
if(est) { | if(est) { | |||
CGOPreloadFonts(cgo); | CGOPreloadFonts(cgo); | |||
font_cgo = CGODrawText(cgo, est, NULL); | font_cgo = CGODrawText(cgo, est, NULL); | |||
CGOFree(cgo); | CGOFree(cgo); | |||
cgo = font_cgo; | cgo = font_cgo; | |||
} | } | |||
est = CGOCheckComplex(cgo); | est = CGOCheckComplex(cgo); | |||
I->State[state].ray = cgo; | I->State[state].origCGO = cgo; | |||
I->State[state].std = CGOSimplify(cgo, est); | ||||
I->State[state].valid = true; | ||||
} else { | } else { | |||
ErrMessage(G, "ObjectCGO", "could not parse CGO List."); | ErrMessage(G, "ObjectCGO", "could not parse CGO List."); | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
if(I) { | if(I) { | |||
ObjectCGORecomputeExtent(I); | ObjectCGORecomputeExtent(I); | |||
} | } | |||
SceneChanged(G); | SceneChanged(G); | |||
skipping to change at line 627 | skipping to change at line 720 | |||
I = ObjectCGONew(G); | I = ObjectCGONew(G); | |||
} else { | } else { | |||
I = obj; | I = obj; | |||
} | } | |||
if(state < 0) | if(state < 0) | |||
state = I->NState; | state = I->NState; | |||
if(I->NState <= state) { | if(I->NState <= state) { | |||
VLACheck(I->State, ObjectCGOState, state); | VLACheck(I->State, ObjectCGOState, state); | |||
I->NState = state + 1; | I->NState = state + 1; | |||
} | } | |||
if(I->State[state].shaderCGO && I->State[state].std!=I->State[state].shaderCGO | ||||
) { | CGOFree(I->State[state].renderCGO); | |||
CGOFree(I->State[state].shaderCGO); | CGOFree(I->State[state].origCGO); | |||
I->State[state].shaderCGO = 0; | ||||
} | ||||
if(I->State[state].std) { | ||||
CGOFree(I->State[state].std); | ||||
} | ||||
if(I->State[state].ray) { | ||||
CGOFree(I->State[state].ray); | ||||
} | ||||
cgo = ObjectCGOFloatArrayToCGO(G, array, size, quiet); | cgo = ObjectCGOFloatArrayToCGO(G, array, size, quiet); | |||
if(cgo) { | if(cgo) { | |||
est = CGOCheckForText(cgo); | est = CGOCheckForText(cgo); | |||
if(est) { | if(est) { | |||
CGOPreloadFonts(cgo); | CGOPreloadFonts(cgo); | |||
font_cgo = CGODrawText(cgo, est, NULL); | font_cgo = CGODrawText(cgo, est, NULL); | |||
CGOFree(cgo); | CGOFree(cgo); | |||
cgo = font_cgo; | cgo = font_cgo; | |||
} | } | |||
est = CGOCheckComplex(cgo); | est = CGOCheckComplex(cgo); | |||
if(est) { | I->State[state].origCGO = cgo; | |||
I->State[state].ray = cgo; | ||||
I->State[state].std = CGOSimplify(cgo, est); | ||||
} else { | ||||
I->State[state].std = cgo; | ||||
} | ||||
I->State[state].valid = true; | ||||
} else if(!quiet) { | } else if(!quiet) { | |||
ErrMessage(G, "ObjectCGO", "could not parse CGO."); | ErrMessage(G, "ObjectCGO", "could not parse CGO."); | |||
} | } | |||
if(I) { | if(I) { | |||
ObjectCGORecomputeExtent(I); | ObjectCGORecomputeExtent(I); | |||
} | } | |||
SceneChanged(G); | SceneChanged(G); | |||
SceneCountFrames(G); | SceneCountFrames(G); | |||
return (I); | return (I); | |||
} | } | |||
End of changes. 28 change blocks. | ||||
211 lines changed or deleted | 295 lines changed or added |