"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "layer2/ObjectVolume.cpp" between
pymol-v2.1.0.tar.bz2 and pymol-open-source-2.2.0.tar.gz

About: PyMOL is a Python-enhanced molecular graphics tool. It excels at 3D visualization of proteins, small molecules, density, surfaces, and trajectories. It also includes molecular editing, ray tracing, and movies. Open Source version.

ObjectVolume.cpp  (pymol-v2.1.0.tar.bz2):ObjectVolume.cpp  (pymol-open-source-2.2.0)
skipping to change at line 312 skipping to change at line 312
* Does actually NOT free the instance, only it's fields. * Does actually NOT free the instance, only it's fields.
*/ */
static void ObjectVolumeStateFree(ObjectVolumeState * vs) static void ObjectVolumeStateFree(ObjectVolumeState * vs)
{ {
// the instance is only "Active" when it has been initialized. Never free // the instance is only "Active" when it has been initialized. Never free
// uninitialized instances. // uninitialized instances.
if(!vs->Active) if(!vs->Active)
return; return;
ObjectStatePurge(&vs->State); ObjectStatePurge(&vs->State);
if(vs->State.G->HaveGUI) { if(vs->State.G->HaveGUI) {
glDeleteTextures(3, (const GLuint *) vs->textures); vs->State.G->ShaderMgr->freeGPUBuffers(vs->textures, 3);
} }
if(vs->Field) { if(vs->Field) {
IsosurfFieldFree(vs->State.G, vs->Field); IsosurfFieldFree(vs->State.G, vs->Field);
vs->Field = NULL; vs->Field = NULL;
} }
FieldFreeP(vs->carvemask); FieldFreeP(vs->carvemask);
VLAFreeP(vs->AtomVertex); VLAFreeP(vs->AtomVertex);
if (vs->Ramp) if (vs->Ramp)
FreeP(vs->Ramp); FreeP(vs->Ramp);
vs->Active = false; vs->Active = false;
skipping to change at line 504 skipping to change at line 504
vs->ResurfaceFlag = false; vs->ResurfaceFlag = false;
if(vs->Field) { if(vs->Field) {
field = vs->Field; field = vs->Field;
} else if(oms->Field) { } else if(oms->Field) {
field = oms->Field; field = oms->Field;
} else { } else {
field = NULL; field = NULL;
} }
if(field) { if(field) {
float *min_ext, *max_ext;
float tmp_min[3], tmp_max[3];
if(MatrixInvTransformExtentsR44d3f(vs->State.Matrix,
vs->ExtentMin, vs->ExtentMax,
tmp_min, tmp_max)) {
min_ext = tmp_min;
max_ext = tmp_max;
} else {
min_ext = vs->ExtentMin;
max_ext = vs->ExtentMax;
}
// get bounds and dimension data from field // get bounds and dimension data from field
copy3(field->data->dim, vs->dim); copy3(field->data->dim, vs->dim);
IsofieldGetCorners(G, field, vs->Corner); IsofieldGetCorners(G, field, vs->Corner);
// transform corners by state matrix // transform corners by state matrix
if(vs->State.Matrix) { if(vs->State.Matrix) {
for(i = 0; i < 8; i++) for(i = 0; i < 8; i++)
transform44d3f(vs->State.Matrix, transform44d3f(vs->State.Matrix,
vs->Corner + 3 * i, vs->Corner + 3 * i,
vs->Corner + 3 * i); vs->Corner + 3 * i);
skipping to change at line 684 skipping to change at line 672
12, 15, 15, 21, 21, 18, 18, 12, 12, 15, 15, 21, 21, 18, 18, 12,
0, 12, 3, 15, 9, 21, 6, 18 0, 12, 3, 15, 9, 21, 6, 18
}; };
glBegin(GL_LINES); glBegin(GL_LINES);
for(i = 0; i < 8 * 3; i++) for(i = 0; i < 8 * 3; i++)
glVertex3fv(corner + ci[i]); glVertex3fv(corner + ci[i]);
glEnd(); glEnd();
#endif #endif
} }
static GLuint createColorTexture(const float *colors, const int count) static size_t createColorTexture(PyMOLGlobals * G, const float *colors, const in t count)
{ {
GLuint texname = 0; size_t texname = 0;
#ifndef PURE_OPENGL_ES_2 #ifndef PURE_OPENGL_ES_2
auto tex = G->ShaderMgr->newGPUBuffer<textureBuffer_t>(
glGenTextures(1, &texname); tex::format::RGBA,
glBindTexture(GL_TEXTURE_1D, texname); tex::data_type::FLOAT,
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, count, 0, GL_RGBA, GL_FLOAT, colors); tex::filter::LINEAR,
tex::filter::LINEAR,
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); tex::wrap::CLAMP
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); );
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP ); tex->texture_data_1D(count, colors);
texname = tex->get_hash_id();
#endif #endif
return texname; return texname;
} }
#ifndef PURE_OPENGL_ES_2 static size_t createPreintegrationTexture(PyMOLGlobals * G, const float *Table,
/* const int count)
* Generate, bind and set parameters for a 3D volume texture
*/
static GLuint tex3dGenBind()
{ {
GLuint texname = 0; float factor, tmp1[4];
Vector4f *sat = Alloc(Vector4f, count + 1);
int i, sb, sf, lookupindex = 0;
GLfloat *lookupImg = Alloc(GLfloat, count * count * 4);
glGenTextures(1, &texname); memset(sat[0], 0, sizeof(sat[0]));
glBindTexture(GL_TEXTURE_3D, texname);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // summed area table
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); for (i = 0; i < count; i++) {
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP); tmp1[3] = Table[i * 4 + 3];
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); scale3f(Table + i * 4, tmp1[3], tmp1);
add4f(tmp1, sat[i], sat[i + 1]);
}
return texname; // make quadratic lookup table
for (sb = 0; sb < count; sb++) {
for (sf = 0; sf < count; sf++) {
GLfloat col[4];
int smin, smax;
if (sb < sf) { smin=sb; smax=sf; } else { smin=sf; smax=sb; }
if (sat[smax + 1][3] != sat[smin][3]) {
factor = 1.f / (sat[smax + 1][3] - sat[smin][3]);
for (i = 0; i < 3; i++)
col[i] = (sat[smax + 1][i] - sat[smin][i]) * factor;
col[3] = 1. / (factor * (smax + 1 - smin));
} else {
for (i = 0; i < 4; i++)
col[i] = 0.f;
}
for (i = 0; i < 4; i++)
lookupImg[lookupindex++] = clamp(col[i], 0., 1.);
}
}
// upload texture
auto tex = G->ShaderMgr->newGPUBuffer<textureBuffer_t>(
tex::format::RGBA,
tex::data_type::FLOAT,
tex::filter::NEAREST,
tex::filter::NEAREST,
tex::wrap::CLAMP_TO_EDGE,
tex::wrap::CLAMP_TO_EDGE
);
tex->texture_data_2D(count, count, lookupImg);
mfree(sat);
mfree(lookupImg);
return tex->get_hash_id();
} }
#endif
static void ObjectVolumeRender(ObjectVolume * I, RenderInfo * info) static void ObjectVolumeRender(ObjectVolume * I, RenderInfo * info)
{ {
#ifndef PURE_OPENGL_ES_2 #ifndef PURE_OPENGL_ES_2
PyMOLGlobals *G = I->Obj.G; PyMOLGlobals *G = I->Obj.G;
int state = info->state; int state = info->state;
CRay *ray = info->ray;
int pass = info->pass; int pass = info->pass;
int a = 0; int a = 0;
ObjectVolumeState *vs = NULL; ObjectVolumeState *vs = NULL;
float volume_layers = SettingGet_f(I->Obj.G, I->Obj.Setting, NULL, cSetting_v olume_layers); float volume_layers = SettingGet_f(I->Obj.G, I->Obj.Setting, NULL, cSetting_v olume_layers);
short volume_mode = SettingGetGlobal_i(G, cSetting_volume_mode);
short ortho = SettingGetGlobal_i(G, cSetting_ortho);
/* make this a setting? */ /* make this a setting? */
GLint alpha_func; GLint alpha_func;
GLfloat alpha_ref; GLfloat alpha_ref;
float tex_corner[24]; float tex_corner[24];
float *corner; float *corner;
const float *ttt; const float *ttt;
float zaxis[3]; float zaxis[3];
float points[36], tex_coords[36]; float points[36], tex_coords[36];
int n_points; int n_points;
float d, sliceRange, sliceDelta; float d, sliceRange, sliceDelta;
float origin[3]; float origin[3];
CShaderPrg *shaderPrg; CShaderPrg *shaderPrg;
bool volume_t = 0;
if(info->pick || pass != -1) if(info->pick || pass != -1)
return; return;
if(!G->HaveGUI || !G->ValidContext) if(!G->HaveGUI || !G->ValidContext)
return; return;
/* bail if no shaders */ /* bail if no shaders */
if (G && !(CShaderMgr_ShadersPresent(G->ShaderMgr))) if (G && !(G->ShaderMgr->ShadersPresent()))
return; return;
if (info->pass < 0){
volume_t = SettingGetGlobal_i(G, cSetting_transparency_mode) == 3;
}
// ViewElem/TTT Matrix // ViewElem/TTT Matrix
ObjectPrepareContext(&I->Obj, ray); ObjectPrepareContext(&I->Obj, info);
for(a = 0; a < I->NState; ++a) { for(a = 0; a < I->NState; ++a) {
if(state < 0 || state == a) { if(state < 0 || state == a) {
vs = I->State + a; vs = I->State + a;
} else if(a == 0 && I->NState == 1 && SettingGetGlobal_b(G, cSetting_static_ singletons)) { } else if(a == 0 && I->NState == 1 && SettingGetGlobal_b(G, cSetting_static_ singletons)) {
vs = I->State; vs = I->State;
} else { } else {
continue; continue;
} }
skipping to change at line 799 skipping to change at line 831
float * colors = ObjectVolumeStateGetColors(G, vs, volume_nColors, &vs->ra mp_min, &vs->ramp_range); float * colors = ObjectVolumeStateGetColors(G, vs, volume_nColors, &vs->ra mp_min, &vs->ramp_range);
if(!colors) if(!colors)
continue; continue;
// volume_layers default is 256, adjust alpha to maintain integrated // volume_layers default is 256, adjust alpha to maintain integrated
// opacity with different layer numbers // opacity with different layer numbers
ColorsAdjustAlpha(colors, volume_nColors, 256. / volume_layers); ColorsAdjustAlpha(colors, volume_nColors, 256. / volume_layers);
if (vs->textures[1]) { if (vs->textures[1]) {
glDeleteTextures(1, (const GLuint *) &vs->textures[1]); G->ShaderMgr->freeGPUBuffer(vs->textures[1]);
} }
{ vs->textures[1] =
vs->textures[1] = createColorTexture(colors, volume_nColors); #ifdef _PYMOL_IP_EXTRAS
} #endif
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); createColorTexture(G, colors, volume_nColors);
tex::env(tex::env_name::ENV_MODE, tex::env_param::REPLACE);
mfree(colors); mfree(colors);
vs->RecolorFlag = false; vs->RecolorFlag = false;
} }
// upload map data texture // upload map data texture
if (!vs->textures[0] || vs->RefreshFlag) { if (!vs->textures[0] || vs->RefreshFlag) {
int volume_bit_depth; tex::data_type volume_bit_depth;
CField * field = ObjectVolumeStateGetField(vs); CField * field = ObjectVolumeStateGetField(vs);
if(!field) { if(!field) {
PRINTFB(G, FB_ObjectVolume, FB_Errors) PRINTFB(G, FB_ObjectVolume, FB_Errors)
" ObjectVolumeRender-Error: Could not get field data.\n" ENDFB(G); " ObjectVolumeRender-Error: Could not get field data.\n" ENDFB(G);
return; return;
} }
volume_bit_depth = SettingGet_i(G, I->Obj.Setting, NULL, cSetting_volume_b int volume_bit_val = SettingGet_i(G, I->Obj.Setting, NULL, cSetting_volume
it_depth); _bit_depth);
volume_bit_depth = (volume_bit_depth < 17) ? GL_R16F : GL_R32F; volume_bit_depth = (volume_bit_val < 17) ? tex::data_type::HALF_FLOAT : te
x::data_type::FLOAT;
/* BEGIN PROPRIETARY CODE SEGMENT (see disclaimer in "os_proprietary.h") */ /* BEGIN PROPRIETARY CODE SEGMENT (see disclaimer in "os_proprietary.h") */
#ifdef WIN32 #if 0
glTexImage3D = getTexImage3D(); glTexImage3D = getTexImage3D();
if (! glTexImage3D) { if (! glTexImage3D) {
PRINTFB(G, FB_ObjectVolume, FB_Errors) PRINTFB(G, FB_ObjectVolume, FB_Errors)
" ObjectVolumeRender-Error: Could not bind the glActiveTexture or glTe xImage3D function.\n" " ObjectVolumeRender-Error: Could not bind the glActiveTexture or glTe xImage3D function.\n"
ENDFB(G); ENDFB(G);
return; return;
} }
#endif #endif
/* END PROPRIETARY CODE SEGMENT (see disclaimer in "os_proprietary.h") */ /* END PROPRIETARY CODE SEGMENT (see disclaimer in "os_proprietary.h") */
if (vs->textures[0]) { if (vs->textures[0]) {
glDeleteTextures(1, (const GLuint *) &vs->textures[0]); G->ShaderMgr->freeGPUBuffer(vs->textures[0]);
vs->textures[0] = 0; vs->textures[0] = 0;
} }
if (vs->textures[2]) { if (vs->textures[2]) {
glDeleteTextures(1, (const GLuint *) &vs->textures[2]); G->ShaderMgr->freeGPUBuffer(vs->textures[2]);
vs->textures[2] = 0; vs->textures[2] = 0;
} }
auto tex3dGenBind = [](PyMOLGlobals * G, tex::data_type dtype) -> size_t {
auto texture = G->ShaderMgr->newGPUBuffer<textureBuffer_t>(
tex::format::R,
dtype,
tex::filter::LINEAR,
tex::filter::LINEAR,
tex::wrap::CLAMP,
tex::wrap::CLAMP,
tex::wrap::CLAMP
);
tex::env(tex::env_name::ENV_MODE, tex::env_param::REPLACE);
return texture->get_hash_id();
};
// Create a 3D texture // Create a 3D texture
vs->textures[0] = tex3dGenBind(); vs->textures[0] = tex3dGenBind(G, volume_bit_depth);
glTexImage3D(GL_TEXTURE_3D, 0, volume_bit_depth, auto t0 = G->ShaderMgr->getGPUBuffer<textureBuffer_t>(vs->textures[0]);
field->dim[2], field->dim[1], field->dim[0], 0, t0->texture_data_3D(field->dim[2], field->dim[1], field->dim[0], field->da
GL_RED, GL_FLOAT, field->data); ta);
// Create 3D carve mask texture // Create 3D carve mask texture
if(vs->carvemask) { if(vs->carvemask) {
vs->textures[2] = tex3dGenBind(); vs->textures[2] = tex3dGenBind(G, tex::data_type::UBYTE);
glTexImage3D(GL_TEXTURE_3D, 0, GL_R8, auto t2 = G->ShaderMgr->getGPUBuffer<textureBuffer_t>(vs->textures[2]);
vs->carvemask->dim[2], vs->carvemask->dim[1], vs->carvemask->dim[0], t2->texture_data_3D(
0, vs->carvemask->dim[2],
GL_RED, GL_UNSIGNED_BYTE, vs->carvemask->data); vs->carvemask->dim[1],
vs->carvemask->dim[0],
vs->carvemask->data
);
// not needed anymore, data now in texture memory // not needed anymore, data now in texture memory
FieldFreeP(vs->carvemask); FieldFreeP(vs->carvemask);
} }
vs->RefreshFlag = false; vs->RefreshFlag = false;
} }
// render volume // render volume
if((I->Obj.visRep & cRepVolumeBit)) { if((I->Obj.visRep & cRepVolumeBit)) {
skipping to change at line 900 skipping to change at line 950
MatrixTransformC44fAs33f3f(ttt, zaxis, zaxis); MatrixTransformC44fAs33f3f(ttt, zaxis, zaxis);
// determine number of slices based on max extent // determine number of slices based on max extent
// and slice option // and slice option
sliceRange = 0.5*sqrt(2.0) * sliceRange = 0.5*sqrt(2.0) *
std::max(std::max(fabs(corner[21]-corner[0]), fabs(corner[22]-corner[1]) ), std::max(std::max(fabs(corner[21]-corner[0]), fabs(corner[22]-corner[1]) ),
fabs(corner[23]-corner[2])); fabs(corner[23]-corner[2]));
sliceDelta = (sliceRange / volume_layers); sliceDelta = (sliceRange / volume_layers);
// load shader // load shader
shaderPrg = CShaderMgr_GetShaderPrg(G->ShaderMgr, "volume"); shaderPrg = G->ShaderMgr->GetShaderPrg(volume_t ? "volume_t" : "volume");
CShaderPrg_Enable(shaderPrg); if (!shaderPrg)
CShaderPrg_Set1i(shaderPrg, "volumeTex", 0); return;
CShaderPrg_Set1i(shaderPrg, "colorTex", 1); shaderPrg->Enable();
CShaderPrg_Set1i(shaderPrg, "carvemask", 5); shaderPrg->Set_Stereo_And_AnaglyphMode();
CShaderPrg_Set1i(shaderPrg, "carvemaskFlag", vs->textures[2] != 0); shaderPrg->Set1i("volumeTex", 0);
CShaderPrg_Set1f(shaderPrg, "volumeScale", 1.0 / vs->ramp_range); shaderPrg->Set1i("colorTex1D", 1);
CShaderPrg_Set1f(shaderPrg, "volumeBias", (-vs->ramp_min) / vs->ramp_range shaderPrg->Set1i("colorTex2D", 1);
); shaderPrg->Set1i("carvemask", 5);
shaderPrg->Set1i("carvemaskFlag", vs->textures[2] != 0);
shaderPrg->Set1f("volumeScale", 1.0 / vs->ramp_range);
shaderPrg->Set1f("volumeBias", (-vs->ramp_min) / vs->ramp_range);
// for pre-integrated rendering
#ifdef _PYMOL_IP_EXTRAS
#endif
// background and fog stuff // background and fog stuff
{ {
float fog[4]; shaderPrg->SetBgUniforms();
int bg_gradient = SettingGet_b(G, NULL, NULL, cSetting_bg_gradient);
const char * bg_image_filename = SettingGet_s(G, NULL, NULL, cSetting_bg
_image_filename);
CShaderPrg_Set1f(shaderPrg, "fogIsSolidColor", bg_gradient || (bg_image_
filename && bg_image_filename[0]) ? 0.f : 1.f);
CShaderPrg_Set3fv(shaderPrg, "fogSolidColor", ColorGet(G, SettingGet_col
or(G, NULL, NULL, cSetting_bg_rgb)));
CShaderPrg_SetFogUniforms(G, shaderPrg);
CShaderPrg_Set1f(shaderPrg, "fog_enabled", SettingGetGlobal_b(G, cSettin
g_depth_cue) ? 1.f : 0.f);
glActiveTexture(GL_TEXTURE4);
glBindTexture(GL_TEXTURE_2D, OrthoGetBackgroundTextureID(G));
if (!(shaderPrg->uniform_set & 4)){
CShaderPrg_Set1i(shaderPrg, "bgTextureMap", 4);
shaderPrg->uniform_set |= 4;
}
SceneSetFog(G, fog);
} }
// bind color ramp and map data textures // bind color ramp and map data textures
glActiveTexture(GL_TEXTURE1); glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_1D, vs->textures[1]); G->ShaderMgr->bindGPUBuffer(vs->textures[1]);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_3D, vs->textures[0]); G->ShaderMgr->bindGPUBuffer(vs->textures[0]);
if (vs->textures[2]) { if (vs->textures[2]) {
glActiveTexture(GL_TEXTURE5); glActiveTexture(GL_TEXTURE5);
glBindTexture(GL_TEXTURE_3D, vs->textures[2]); G->ShaderMgr->bindGPUBuffer(vs->textures[2]);
} }
// alpha: everything passes // alpha: everything passes
// Not sure if we really need to restore this // Not sure if we really need to restore this
glGetIntegerv(GL_ALPHA_TEST_FUNC, &alpha_func); glGetIntegerv(GL_ALPHA_TEST_FUNC, &alpha_func);
glGetFloatv(GL_ALPHA_TEST_REF, &alpha_ref); glGetFloatv(GL_ALPHA_TEST_REF, &alpha_ref);
glAlphaFunc(GL_ALWAYS, 0.0); glAlphaFunc(GL_ALWAYS, 0.0);
// don't write to the depth buffer // don't write to the depth buffer
GLboolean depth_writemask; GLboolean depth_writemask;
glGetBooleanv(GL_DEPTH_WRITEMASK, &depth_writemask); glGetBooleanv(GL_DEPTH_WRITEMASK, &depth_writemask);
if (depth_writemask) if (depth_writemask)
glDepthMask(GL_FALSE); glDepthMask(GL_FALSE);
// This is setting used for PyMOL, but just to be on a safe side
// we set glBlendFunct explicitely here
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Cheap hack, should be replaced with non-immediate calls // Cheap hack, should be replaced with non-immediate calls
glFlush(); glFlush();
glFinish(); glFinish();
// draw slices // draw slices
{ {
int i, cornerindices[] = { int i, cornerindices[] = {
0, 3, 3, 9, 9, 6, 6, 0, 0, 3, 3, 9, 9, 6, 6, 0,
12, 15, 15, 21, 21, 18, 18, 12, 12, 15, 15, 21, 21, 18, 18, 12,
0, 12, 3, 15, 9, 21, 6, 18 0, 12, 3, 15, 9, 21, 6, 18
skipping to change at line 981 skipping to change at line 1020
for(i = 0; i < 24; i += 2) { for(i = 0; i < 24; i += 2) {
int j = cornerindices[i], k = cornerindices[i + 1]; int j = cornerindices[i], k = cornerindices[i + 1];
n_points += ObjectVolumeAddSlicePoint( n_points += ObjectVolumeAddSlicePoint(
corner + j, corner + k, zaxis, d, points + n_points, corner + j, corner + k, zaxis, d, points + n_points,
tex_corner + j, tex_corner + k, tex_coords + n_points, origin); tex_corner + j, tex_corner + k, tex_coords + n_points, origin);
} }
ObjectVolumeDrawSlice(points, tex_coords, n_points/3, zaxis); ObjectVolumeDrawSlice(points, tex_coords, n_points/3, zaxis);
} }
} }
CShaderPrg_Disable(shaderPrg); shaderPrg->Disable();
// restore // restore
if (depth_writemask) if (depth_writemask)
glDepthMask(GL_TRUE); glDepthMask(GL_TRUE);
glAlphaFunc(alpha_func, alpha_ref); glAlphaFunc(alpha_func, alpha_ref);
} }
glEnable(GL_LIGHTING); glEnable(GL_LIGHTING);
} }
#endif #endif
 End of changes. 34 change blocks. 
100 lines changed or deleted 136 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)