"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "layer1/CGO.cpp" between
pymol-open-source-2.2.0.tar.gz and pymol-open-source-2.3.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.

CGO.cpp  (pymol-open-source-2.2.0):CGO.cpp  (pymol-open-source-2.3.0)
skipping to change at line 100 skipping to change at line 100
(val < minimum) ? minimum : (val < minimum) ? minimum :
(val > maximum) ? maximum : val; (val > maximum) ? maximum : val;
} }
#if defined(_PYMOL_IOS) && !defined(_WEBGL) #if defined(_PYMOL_IOS) && !defined(_WEBGL)
extern "C" void firePyMOLLimitationWarning(); extern "C" void firePyMOLLimitationWarning();
#define CHECK_GL_ERROR_OK(printstr) \ #define CHECK_GL_ERROR_OK(printstr) \
if ((err = glGetError())!=0 || I->G->Interrupt != 0){ \ if ((err = glGetError())!=0 || I->G->Interrupt != 0){ \
if (err) \ if (err) \
PRINTFB(I->G, FB_CGO, FB_Errors) printstr, err ENDFB(I->G); \ PRINTFB(I->G, FB_CGO, FB_Errors) printstr, err ENDFB(I->G); \
ok = false; \
} }
#else #else
#define CHECK_GL_ERROR_OK(printstr) \ #define CHECK_GL_ERROR_OK(printstr) \
if ((err = glGetError()) != 0){ \ if ((err = glGetError()) != 0){ \
PRINTFB(I->G, FB_CGO, FB_Errors) printstr, err ENDFB(I->G); \ PRINTFB(I->G, FB_CGO, FB_Errors) printstr, err ENDFB(I->G); \
ok = false; \
} }
#endif #endif
struct _CCGORenderer { struct _CCGORenderer {
PyMOLGlobals *G; PyMOLGlobals *G;
RenderInfo *info; RenderInfo *info;
Rep *rep; Rep *rep;
const float *color; const float *color;
float alpha; float alpha;
short sphere_quality; short sphere_quality;
skipping to change at line 142 skipping to change at line 140
{ {
p->context = (*context); p->context = (*context);
p->src.index = idx; p->src.index = idx;
p->src.bond = bnd; // actually holds state information p->src.bond = bnd; // actually holds state information
if (cgo) { if (cgo) {
cgo->current_pick_color_index = idx; cgo->current_pick_color_index = idx;
cgo->current_pick_color_bond = bnd; cgo->current_pick_color_bond = bnd;
} }
} }
bool AssignNewPickColor(CGO *cgo, unsigned int &i, Picking ** pick, PickContext * context, unsigned char *color, unsigned int index, int bond){ bool AssignNewPickColor(CGO *cgo, unsigned int &i, std::vector<Picking>* pick, P ickContext * context, unsigned char *color, unsigned int index, int bond){
i++; i++;
if(!((*pick)[0].src.bond & 1)) { if(!(pick->begin()->src.bond & 1)) {
/* pass 1 - low order bits */ /* pass 1 - low order bits */
color[0] = (uchar)((i & 0xF) << 4); color[0] = (uchar)((i & 0xF) << 4);
color[1] = (uchar)((i & 0xF0) | 0x8); color[1] = (uchar)((i & 0xF0) | 0x8);
color[2] = (uchar)((i & 0xF00) >> 4); color[2] = (uchar)((i & 0xF00) >> 4);
VLACheck((*pick), Picking, i); if (pick->size() <= i) {
set_current_pick_color(cgo, (*pick) + i, context, index, bond); pick->resize((i + 1) * 3 / 2); // grow by 50%
}
set_current_pick_color(cgo, pick->data() + i, context, index, bond);
} else { } else {
int j = i >> 12; int j = i >> 12;
color[0] = (uchar)((j & 0xF) << 4); color[0] = (uchar)((j & 0xF) << 4);
color[1] = (uchar)((j & 0xF0) | 0x8); color[1] = (uchar)((j & 0xF0) | 0x8);
color[2] = (uchar)((j & 0xF00) >> 4); color[2] = (uchar)((j & 0xF00) >> 4);
} }
color[3] = 255; color[3] = 255;
return true; return true;
} }
skipping to change at line 272 skipping to change at line 272
fsizeof<cgo::draw::line>(), fsizeof<cgo::draw::line>(),
fsizeof<cgo::draw::splitline>(), fsizeof<cgo::draw::splitline>(),
fsizeof<cgo::draw::custom>(), fsizeof<cgo::draw::custom>(),
fsizeof<cgo::draw::vertex_attribute_3f>(), fsizeof<cgo::draw::vertex_attribute_3f>(),
fsizeof<cgo::draw::vertex_attribute_4ub>(), fsizeof<cgo::draw::vertex_attribute_4ub>(),
fsizeof<cgo::draw::vertex_attribute_1f>(), fsizeof<cgo::draw::vertex_attribute_1f>(),
fsizeof<cgo::draw::mask_attribute_if_picking>(), fsizeof<cgo::draw::mask_attribute_if_picking>(),
fsizeof<cgo::draw::bind_vbo_for_picking>(), fsizeof<cgo::draw::bind_vbo_for_picking>(),
CGO_VERTEX_BEGIN_LINE_STRIP_SZ, CGO_INTERPOLATED_SZ, CGO_VERTEX_CROSS_SZ, CGO_VERTEX_BEGIN_LINE_STRIP_SZ, CGO_INTERPOLATED_SZ, CGO_VERTEX_CROSS_SZ,
fsizeof<cgo::draw::vertex_attribute_4ub_if_picking>(), fsizeof<cgo::draw::vertex_attribute_4ub_if_picking>(),
fsizeof<cgo::draw::custom_cylinder_alpha>(),
CGO_NULL_SZ CGO_NULL_SZ
}; };
typedef void CGO_op(CCGORenderer * I, float **); typedef void CGO_op(CCGORenderer * I, float **);
typedef CGO_op *CGO_op_fn; typedef CGO_op *CGO_op_fn;
static float *CGO_add(CGO * I, int c); static float *CGO_add(CGO * I, int c);
static float *CGO_size(CGO * I, int sz); static float *CGO_size(CGO * I, int sz);
static int CGOSimpleCylinder(CGO * I, float *v1, float *v2, float tube_size, flo static int CGOSimpleCylinder(CGO * I, const float *v1, const float *v2, const fl
at *c1, oat tube_size, const float *c1,
float *c2, bool interp, int cap1, int cap2, const float *c2, float a1, const float a2, const bo
Pickable *pickcolor2 = NULL, bool stick_round_nub = ol interp, const int cap1, const int cap2,
false); const Pickable *pickcolor2 = nullptr, const bool st
ick_round_nub = false);
template<typename CylinderT>
static int CGOSimpleCylinder(CGO * I, const CylinderT &cyl, const float a1, cons
t float a2, const bool interp, const int cap1,
const int cap2, const Pickable *pickcolor2 = nullpt
r, const bool stick_round_nub = false);
static int CGOSimpleEllipsoid(CGO * I, float *v, float vdw, float *n0, float *n1 , static int CGOSimpleEllipsoid(CGO * I, float *v, float vdw, float *n0, float *n1 ,
float *n2); float *n2);
static int CGOSimpleQuadric(CGO * I, float *v, float vdw, float *q); static int CGOSimpleQuadric(CGO * I, float *v, float vdw, float *q);
static int CGOSimpleSphere(CGO * I, float *v, float vdw, short sphere_quality); static int CGOSimpleSphere(CGO * I, float *v, float vdw, short sphere_quality);
static int CGOSimpleCone(CGO * I, float *v1, float *v2, float r1, float r2, floa t *c1, static int CGOSimpleCone(CGO * I, float *v1, float *v2, float r1, float r2, floa t *c1,
float *c2, int cap1, int cap2); float *c2, int cap1, int cap2);
/* /*
* Inverse function of CGOArrayFromPyListInPlace * Inverse function of CGOArrayFromPyListInPlace
* *
skipping to change at line 1348 skipping to change at line 1352
/* stick_quality needs to match *every* CGO? */ /* stick_quality needs to match *every* CGO? */
nEdge = SettingGetGlobal_i(I->G, cSetting_stick_quality); nEdge = SettingGetGlobal_i(I->G, cSetting_stick_quality);
while((op = (CGO_MASK & CGO_read_int(pc)))) { while((op = (CGO_MASK & CGO_read_int(pc)))) {
switch (op) { switch (op) {
case CGO_CYLINDER: case CGO_CYLINDER:
case CGO_CONE: case CGO_CONE:
case CGO_SAUSAGE: case CGO_SAUSAGE:
case CGO_CUSTOM_CYLINDER: case CGO_CUSTOM_CYLINDER:
case CGO_CUSTOM_CYLINDER_ALPHA:
fc += 3 * (3 + (nEdge + 1) * 9) + 9; fc += 3 * (3 + (nEdge + 1) * 9) + 9;
break; break;
case CGO_ELLIPSOID: case CGO_ELLIPSOID:
case CGO_QUADRIC: case CGO_QUADRIC:
case CGO_SPHERE: case CGO_SPHERE:
fc += (sp->NVertTot * 6) + (sp->NStrip * 3) + 3; fc += (sp->NVertTot * 6) + (sp->NStrip * 3) + 3;
break; break;
case CGO_DRAW_ARRAYS: case CGO_DRAW_ARRAYS:
{ {
cgo::draw::arrays * sp = reinterpret_cast<decltype(sp)>(pc); cgo::draw::arrays * sp = reinterpret_cast<decltype(sp)>(pc);
skipping to change at line 1662 skipping to change at line 1667
} else { } else {
nverts+=4; nverts+=4;
} }
} }
break; break;
} }
} }
if (nverts>0 && !err){ if (nverts>0 && !err){
int pl = 0, plc = 0, pla = 0; int pl = 0, plc = 0, pla = 0;
float *vertexVals; float *vertexVals;
float *normalVals, *colorVals = 0, *nxtVals = 0, *pickColorVals = 0, *a ccessibilityVals = 0; float *normalVals = 0, *colorVals = 0, *nxtVals = 0, *pickColorVals = 0 , *accessibilityVals = 0;
short notHaveValue = 0, nxtn = 3; short notHaveValue = 0, nxtn = 3;
if (hasFirstAlpha || hasFirstColor){ if (hasFirstAlpha || hasFirstColor){
if (hasFirstAlpha){ if (hasFirstAlpha){
CGOAlpha(cgo, firstAlpha); CGOAlpha(cgo, firstAlpha);
} }
if (hasFirstColor){ if (hasFirstColor){
CGOColorv(cgo, firstColor); CGOColorv(cgo, firstColor);
} }
} }
nxtVals = vertexVals = cgo->add<cgo::draw::arrays>(mode, damode, nverts ); nxtVals = vertexVals = cgo->add<cgo::draw::arrays>(mode, damode, nverts );
skipping to change at line 1801 skipping to change at line 1806
pl+=3; plc+=4; pla++; pl+=3; plc+=4; pla++;
} }
break; break;
case CGO_VERTEX: case CGO_VERTEX:
CGOAddVertexToDrawArrays(cgo, pl, plc, pla, pc, notHaveValue, vert exVals, CGOAddVertexToDrawArrays(cgo, pl, plc, pla, pc, notHaveValue, vert exVals,
normalVals, colorVals, pickColorVals, acc essibilityVals); normalVals, colorVals, pickColorVals, acc essibilityVals);
pl+=3; plc+=4; pla++; pl+=3; plc+=4; pla++;
notHaveValue = damode; notHaveValue = damode;
break; break;
case CGO_ALPHA: case CGO_ALPHA:
// in case we're before CGO_COLOR
cgo->alpha = *pc; cgo->alpha = *pc;
if (colorVals) {
// in case we're after CGO_COLOR
colorVals[plc + 3] = *pc;
}
break;
} }
} }
} }
} }
break; break;
case CGO_PICK_COLOR: case CGO_PICK_COLOR:
cgo->current_pick_color_index = CGO_get_uint(pc); cgo->current_pick_color_index = CGO_get_uint(pc);
cgo->current_pick_color_bond = CGO_get_int(pc + 1); cgo->current_pick_color_bond = CGO_get_int(pc + 1);
cgo->add_to_cgo(op, pc); cgo->add_to_cgo(op, pc);
break; break;
skipping to change at line 2338 skipping to change at line 2349
BufferDataDesc bufData = BufferDataDesc bufData =
{ { "a_Vertex", GL_FLOAT, 3, sizeof(float) * num_total_vertices_points * 3 , vertexVals, GL_FALSE } }; { { "a_Vertex", GL_FLOAT, 3, sizeof(float) * num_total_vertices_points * 3 , vertexVals, GL_FALSE } };
if (has_normals){ if (has_normals){
bufData.push_back( { "a_Normal", ntp, 3, (size_t)(num_total_vertices_ points * nsz), normalVals, nnorm } ); bufData.push_back( { "a_Normal", ntp, 3, (size_t)(num_total_vertices_ points * nsz), normalVals, nnorm } );
} }
if (has_colors){ if (has_colors){
bufData.push_back( { "a_Color", ctp, 4, sizeof(float) * num_total_ve rtices_points * csz, colorVals, cnorm } ); bufData.push_back( { "a_Color", ctp, 4, sizeof(float) * num_total_ve rtices_points * csz, colorVals, cnorm } );
} }
ok = vbo->bufferData((BufferDataDesc)bufData); ok = vbo->bufferData(std::move(bufData));
if (ok && has_colors){ if (ok && has_colors){
arrays |= CGO_COLOR_ARRAY; arrays |= CGO_COLOR_ARRAY;
} }
size_t vboid = vbo->get_hash_id(); size_t vboid = vbo->get_hash_id();
if (ok){ if (ok){
float *newPickColorVals ; float *newPickColorVals ;
if (addshaders) if (addshaders)
skipping to change at line 2868 skipping to change at line 2879
{ { "a_Vertex", GL_FLOAT, 3, sizeof(float) * num_total_indexes * 3, vert exVals, GL_FALSE } }; { { "a_Vertex", GL_FLOAT, 3, sizeof(float) * num_total_indexes * 3, vert exVals, GL_FALSE } };
if (has_normals){ if (has_normals){
bufData.push_back( { "a_Normal", ntp, VERTEX_NORMAL_SIZE, (size_t)( num_total_indexes * nsz), normalVals, nnorm } ); bufData.push_back( { "a_Normal", ntp, VERTEX_NORMAL_SIZE, (size_t)( num_total_indexes * nsz), normalVals, nnorm } );
} }
if (has_colors){ if (has_colors){
bufData.push_back( { "a_Color", ctp, 4, sizeof(float) * num_total_ indexes * csz, colorVals, cnorm } ); bufData.push_back( { "a_Color", ctp, 4, sizeof(float) * num_total_ indexes * csz, colorVals, cnorm } );
} }
if (has_accessibility){ if (has_accessibility){
bufData.push_back( { "a_Accessibility", GL_FLOAT, 1, sizeof(float) * num _total_indexes, accessibilityVals, GL_FALSE } ); bufData.push_back( { "a_Accessibility", GL_FLOAT, 1, sizeof(float) * num _total_indexes, accessibilityVals, GL_FALSE } );
} }
ok = vbo->bufferData((BufferDataDesc)bufData); ok = vbo->bufferData(std::move(bufData));
size_t vboid = vbo->get_hash_id(); size_t vboid = vbo->get_hash_id();
// picking VBO: generate a buffer twice the size needed, for each picking pass // picking VBO: generate a buffer twice the size needed, for each picking pass
VertexBuffer * pickvbo = I->G->ShaderMgr->newGPUBuffer<VertexBuffer>(Verte xBuffer::SEQUENTIAL, GL_DYNAMIC_DRAW); VertexBuffer * pickvbo = I->G->ShaderMgr->newGPUBuffer<VertexBuffer>(Verte xBuffer::SEQUENTIAL, GL_DYNAMIC_DRAW);
ok = pickvbo->bufferData({ ok = pickvbo->bufferData({
BufferDesc( "a_Color", GL_UNSIGNED_BYTE, 4, sizeof(float) * num_total_ indexes, 0, GL_TRUE ), BufferDesc( "a_Color", GL_UNSIGNED_BYTE, 4, sizeof(float) * num_total_ indexes, 0, GL_TRUE ),
BufferDesc( "a_Color", GL_UNSIGNED_BYTE, 4, sizeof(float) * num_total_ indexes, 0, GL_TRUE ) BufferDesc( "a_Color", GL_UNSIGNED_BYTE, 4, sizeof(float) * num_total_ indexes, 0, GL_TRUE )
}); });
size_t pickvboid = pickvbo->get_hash_id(); size_t pickvboid = pickvbo->get_hash_id();
skipping to change at line 3119 skipping to change at line 3130
VertexBuffer * vbo = I->G->ShaderMgr->newGPUBuffer<VertexBuffer>(VertexBuf fer::SEQUENTIAL); VertexBuffer * vbo = I->G->ShaderMgr->newGPUBuffer<VertexBuffer>(VertexBuf fer::SEQUENTIAL);
BufferDataDesc bufData = BufferDataDesc bufData =
{ { "a_Vertex", GL_FLOAT, 3, sizeof(float) * num_total_indexes_lines * 3 , vertexVals, GL_FALSE } }; { { "a_Vertex", GL_FLOAT, 3, sizeof(float) * num_total_indexes_lines * 3 , vertexVals, GL_FALSE } };
if (has_normals){ if (has_normals){
bufData.push_back( { "a_Normal", ntp, VERTEX_NORMAL_SIZE, (size_t)( num_total_indexes_lines * nsz), normalVals, nnorm } ); bufData.push_back( { "a_Normal", ntp, VERTEX_NORMAL_SIZE, (size_t)( num_total_indexes_lines * nsz), normalVals, nnorm } );
} }
if (has_color){ if (has_color){
bufData.push_back( { "a_Color", ctp, 4, sizeof(float) * num_total_ indexes_lines * csz, colorVals, cnorm } ); bufData.push_back( { "a_Color", ctp, 4, sizeof(float) * num_total_ indexes_lines * csz, colorVals, cnorm } );
} }
ok = vbo->bufferData((BufferDataDesc)bufData); ok = vbo->bufferData(std::move(bufData));
size_t vboid = vbo->get_hash_id(); size_t vboid = vbo->get_hash_id();
// picking VBO: generate a buffer twice the size needed, for each picking pass // picking VBO: generate a buffer twice the size needed, for each picking pass
VertexBuffer * pickvbo = I->G->ShaderMgr->newGPUBuffer<VertexBuffer>(Verte xBuffer::SEQUENTIAL, GL_DYNAMIC_DRAW); VertexBuffer * pickvbo = I->G->ShaderMgr->newGPUBuffer<VertexBuffer>(Verte xBuffer::SEQUENTIAL, GL_DYNAMIC_DRAW);
ok &= pickvbo->bufferData({ ok &= pickvbo->bufferData({
BufferDesc( "a_Color", GL_UNSIGNED_BYTE, 4, sizeof(float) * num_total_ indexes_lines, 0, GL_TRUE ), BufferDesc( "a_Color", GL_UNSIGNED_BYTE, 4, sizeof(float) * num_total_ indexes_lines, 0, GL_TRUE ),
BufferDesc( "a_Color", GL_UNSIGNED_BYTE, 4, sizeof(float) * num_total_ indexes_lines, 0, GL_TRUE ) BufferDesc( "a_Color", GL_UNSIGNED_BYTE, 4, sizeof(float) * num_total_ indexes_lines, 0, GL_TRUE )
}); });
size_t pickvboid = pickvbo->get_hash_id(); size_t pickvboid = pickvbo->get_hash_id();
skipping to change at line 4133 skipping to change at line 4144
case CGO_PICK_COLOR: case CGO_PICK_COLOR:
CGOPickColor(cgo, CGO_get_uint(pc), CGO_get_int(pc + 1)); CGOPickColor(cgo, CGO_get_uint(pc), CGO_get_int(pc + 1));
break; break;
case CGO_SHADER_CYLINDER: case CGO_SHADER_CYLINDER:
{ {
float v2[3]; float v2[3];
int cap = CGO_get_int(pc + 7); int cap = CGO_get_int(pc + 7);
int fcap = (cap & 1) ? ((cap & cCylShaderCap1RoundBit) ? 2 : 1) : 0; int fcap = (cap & 1) ? ((cap & cCylShaderCap1RoundBit) ? 2 : 1) : 0;
int bcap = (cap & 2) ? ((cap & cCylShaderCap2RoundBit) ? 2 : 1) : 0; int bcap = (cap & 2) ? ((cap & cCylShaderCap2RoundBit) ? 2 : 1) : 0;
add3f(pc, pc + 3, v2); add3f(pc, pc + 3, v2);
ok &= CGOSimpleCylinder(cgo, pc, v2, *(pc + 6), 0, 0, (cap & cCylShaderI ok &= CGOSimpleCylinder(cgo, pc, v2, *(pc + 6), 0, 0, cgo->alpha, cgo->a
nterpColor), lpha, (cap & cCylShaderInterpColor),
fcap, bcap, NULL, stick_round_nub); fcap, bcap, nullptr, stick_round_nub);
} }
break; break;
case CGO_SHADER_CYLINDER_WITH_2ND_COLOR: case CGO_SHADER_CYLINDER_WITH_2ND_COLOR:
{ {
auto cyl = reinterpret_cast<cgo::draw::shadercylinder2ndcolor*>(pc);
float v1[3]; float v1[3];
int cap = CGO_get_int(pc + 7); int cap = cyl->cap;
int fcap = (cap & 1) ? ((cap & cCylShaderCap1RoundBit) ? 2 : 1) : 0; int fcap = (cap & 1) ? ((cap & cCylShaderCap1RoundBit) ? 2 : 1) : 0;
int bcap = (cap & 2) ? ((cap & cCylShaderCap2RoundBit) ? 2 : 1) : 0; int bcap = (cap & 2) ? ((cap & cCylShaderCap2RoundBit) ? 2 : 1) : 0;
Pickable pickcolor2 = { CGO_get_uint(pc + 11), CGO_get_int(pc + 12) }; Pickable pickcolor2 = { cyl->pick_color_index, cyl->pick_color_bond };
float color1[3] = { cgo->color[0], cgo->color[1], cgo->color[2] }; float color1[3] = { cgo->color[0], cgo->color[1], cgo->color[2] };
add3f(pc, pc + 3, v1); add3f(pc, pc + 3, v1);
float mid[3]; float mid[3];
mult3f(pc + 3, .5f, mid); mult3f(cyl->axis, .5f, mid);
add3f(pc, mid, mid); add3f(cyl->origin, mid, mid);
if (cap & cCylShaderInterpColor){ if (cap & cCylShaderInterpColor){
ok &= CGOSimpleCylinder(cgo, pc, v1, *(pc + 6), color1, pc+8, true, bc ap, fcap, &pickcolor2, stick_round_nub); ok &= CGOSimpleCylinder(cgo, cyl->origin, v1, cyl->tube_size, color1, cyl->color2, cyl->alpha, cyl->alpha, true, bcap, fcap, &pickcolor2, stick_round_ nub);
} else { } else {
ok &= CGOColorv(cgo, color1); ok &= CGOColorv(cgo, color1);
ok &= CGOSimpleCylinder(cgo, pc, mid, *(pc + 6), color1, NULL, false, ok &= CGOSimpleCylinder(cgo, cyl->origin, mid, cyl->tube_size, color1,
fcap, 0, NULL, stick_round_nub); NULL, cyl->alpha, cyl->alpha, false, fcap, 0, nullptr, stick_round_nub);
ok &= CGOColorv(cgo, pc+8); ok &= CGOColorv(cgo, cyl->color2);
ok &= CGOPickColor(cgo, pickcolor2.index, pickcolor2.bond); ok &= CGOPickColor(cgo, pickcolor2.index, pickcolor2.bond);
ok &= CGOSimpleCylinder(cgo, mid, v1, *(pc + 6), pc+8, NULL, false, 0, bcap, NULL, stick_round_nub); ok &= CGOSimpleCylinder(cgo, mid, v1, cyl->tube_size, cyl->color2, NUL L, cyl->alpha, cyl->alpha, false, 0, bcap, nullptr, stick_round_nub);
} }
} }
break; break;
case CGO_CYLINDER: case CGO_CYLINDER:
ok &= CGOSimpleCylinder(cgo, pc, pc + 3, *(pc + 6), pc + 7, pc + 10, true, {
1, 1, NULL, stick_round_nub); auto cyl = reinterpret_cast<cgo::draw::cylinder*>(pc);
ok &= CGOSimpleCylinder(cgo, *cyl, cgo->alpha, cgo->alpha, true, 1, 1, n
ullptr, stick_round_nub);
}
break; break;
case CGO_CONE: case CGO_CONE:
ok &= CGOSimpleCone(cgo, pc, pc + 3, *(pc + 6), *(pc + 7), pc + 8, pc + 11 , ok &= CGOSimpleCone(cgo, pc, pc + 3, *(pc + 6), *(pc + 7), pc + 8, pc + 11 ,
(int) *(pc + 14), (int) *(pc + 15)); (int) *(pc + 14), (int) *(pc + 15));
break; break;
case CGO_SAUSAGE: case CGO_SAUSAGE:
ok &= CGOSimpleCylinder(cgo, pc, pc + 3, *(pc + 6), pc + 7, pc + 10, true, 2, 2, NULL, stick_round_nub); ok &= CGOSimpleCylinder(cgo, pc, pc + 3, *(pc + 6), pc + 7, pc + 10, cgo-> alpha, cgo->alpha, true, 2, 2, nullptr, stick_round_nub);
break; break;
case CGO_CUSTOM_CYLINDER: case CGO_CUSTOM_CYLINDER:
ok &= CGOSimpleCylinder(cgo, pc, pc + 3, *(pc + 6), pc + 7, pc + 10, true, {
(int) *(pc + 13), auto cyl = reinterpret_cast<cgo::draw::custom_cylinder*>(pc);
(int) *(pc + 14), NULL, stick_round_nub); ok &= CGOSimpleCylinder(cgo, *cyl, cgo->alpha, cgo->alpha, true, cyl->ca
p1, cyl->cap2, nullptr, stick_round_nub);
}
break;
case CGO_CUSTOM_CYLINDER_ALPHA:
{
auto cyl = reinterpret_cast<cgo::draw::custom_cylinder_alpha*>(pc);
ok &= CGOSimpleCylinder(cgo, *cyl, cyl->color1[3], cyl->color2[3], true,
cyl->cap1, cyl->cap2, nullptr, stick_round_nub);
}
break; break;
case CGO_SPHERE: case CGO_SPHERE:
ok &= CGOSimpleSphere(cgo, pc, *(pc + 3), sphere_quality); ok &= CGOSimpleSphere(cgo, pc, *(pc + 3), sphere_quality);
break; break;
case CGO_ELLIPSOID: case CGO_ELLIPSOID:
ok &= CGOSimpleEllipsoid(cgo, pc, *(pc + 3), pc + 4, pc + 7, pc + 10); ok &= CGOSimpleEllipsoid(cgo, pc, *(pc + 3), pc + 4, pc + 7, pc + 10);
break; break;
case CGO_QUADRIC: case CGO_QUADRIC:
ok &= CGOSimpleQuadric(cgo, pc, *(pc + 3), pc + 4); ok &= CGOSimpleQuadric(cgo, pc, *(pc + 3), pc + 4);
break; break;
skipping to change at line 4262 skipping to change at line 4285
} }
default: default:
break; break;
} }
sz = CGO_sz[op]; sz = CGO_sz[op];
pc += sz; pc += sz;
} }
if (nverts>0 && !err){ if (nverts>0 && !err){
int pl = 0, plc = 0, pla = 0; int pl = 0, plc = 0, pla = 0;
float *vertexVals, *tmp_ptr; float *vertexVals, *tmp_ptr;
float *normalVals, *colorVals = 0, *nxtVals = 0, *pickColorVals = 0, *a ccessibilityVals = 0; float *normalVals = 0, *colorVals = 0, *nxtVals = 0, *pickColorVals = 0 , *accessibilityVals = 0;
short notHaveValue = 0, nxtn = 3; short notHaveValue = 0, nxtn = 3;
if (hasFirstAlpha || hasFirstColor){ if (hasFirstAlpha || hasFirstColor){
if (hasFirstAlpha){ if (hasFirstAlpha){
CGOAlpha(cgo, firstAlpha); CGOAlpha(cgo, firstAlpha);
} }
if (hasFirstColor){ if (hasFirstColor){
CGOColorv(cgo, firstColor); CGOColorv(cgo, firstColor);
} }
} }
nxtVals = vertexVals = cgo->add<cgo::draw::arrays>(mode, damode, nverts ); nxtVals = vertexVals = cgo->add<cgo::draw::arrays>(mode, damode, nverts );
skipping to change at line 4360 skipping to change at line 4383
plc += 4; plc += 4;
pla++; pla++;
if (pla >= nverts) // anything past the last vertex is ignored if (pla >= nverts) // anything past the last vertex is ignored
skiptoend = true; skiptoend = true;
notHaveValue = damode; notHaveValue = damode;
break; break;
case CGO_END: case CGO_END:
end = 1; end = 1;
break; break;
case CGO_ALPHA: case CGO_ALPHA:
// in case we're before CGO_COLOR
cgo->alpha = *pc; cgo->alpha = *pc;
if (colorVals) {
// in case we're after CGO_COLOR
colorVals[plc + 3] = *pc;
}
break;
default: default:
break; break;
} }
sz = CGO_sz[op]; sz = CGO_sz[op];
pc += sz; pc += sz;
} }
save_pc = pc; save_pc = pc;
} else { } else {
save_pc = origpc; save_pc = origpc;
} }
skipping to change at line 4424 skipping to change at line 4453
case CGO_PICK_COLOR: case CGO_PICK_COLOR:
CGOPickColor(cgo, CGO_get_uint(pc), CGO_get_int(pc + 1)); CGOPickColor(cgo, CGO_get_uint(pc), CGO_get_int(pc + 1));
break; break;
case CGO_SHADER_CYLINDER: case CGO_SHADER_CYLINDER:
{ {
float v2[3]; float v2[3];
int cap = CGO_get_int(pc + 7); int cap = CGO_get_int(pc + 7);
int fcap = (cap & 1) ? ((cap & cCylShaderCap1RoundBit) ? 2 : 1) : 0; int fcap = (cap & 1) ? ((cap & cCylShaderCap1RoundBit) ? 2 : 1) : 0;
int bcap = (cap & 2) ? ((cap & cCylShaderCap2RoundBit) ? 2 : 1) : 0; int bcap = (cap & 2) ? ((cap & cCylShaderCap2RoundBit) ? 2 : 1) : 0;
add3f(pc, pc + 3, v2); add3f(pc, pc + 3, v2);
ok &= CGOSimpleCylinder(cgo, pc, v2, *(pc + 6), 0, 0, (cap & cCylShaderI ok &= CGOSimpleCylinder(cgo, pc, v2, *(pc + 6), 0, 0, cgo->alpha, cgo->a
nterpColor), lpha, (cap & cCylShaderInterpColor),
fcap, bcap, NULL, stick_round_nub); fcap, bcap, nullptr, stick_round_nub);
} }
break; break;
case CGO_SHADER_CYLINDER_WITH_2ND_COLOR: case CGO_SHADER_CYLINDER_WITH_2ND_COLOR:
{ {
auto cyl = reinterpret_cast<cgo::draw::shadercylinder2ndcolor*>(pc);
float v1[3]; float v1[3];
int cap = CGO_get_int(pc + 7); int cap = cyl->cap;
int fcap = (cap & 1) ? ((cap & cCylShaderCap1RoundBit) ? 2 : 1) : 0; int fcap = (cap & 1) ? ((cap & cCylShaderCap1RoundBit) ? 2 : 1) : 0;
int bcap = (cap & 2) ? ((cap & cCylShaderCap2RoundBit) ? 2 : 1) : 0; int bcap = (cap & 2) ? ((cap & cCylShaderCap2RoundBit) ? 2 : 1) : 0;
Pickable pickcolor2 = { CGO_get_uint(pc + 11), CGO_get_int(pc + 12) }; Pickable pickcolor2 = { cyl->pick_color_index, cyl->pick_color_bond };
float color1[3] = { cgo->color[0], cgo->color[1], cgo->color[2] }; float color1[3] = { cgo->color[0], cgo->color[1], cgo->color[2] };
add3f(pc, pc + 3, v1); add3f(cyl->origin, cyl->axis, v1);
float mid[3]; float mid[3];
mult3f(pc + 3, .5f, mid); mult3f(cyl->axis, .5f, mid);
add3f(pc, mid, mid); add3f(cyl->origin, mid, mid);
if (cap & cCylShaderInterpColor){ if (cap & cCylShaderInterpColor){
ok &= CGOSimpleCylinder(cgo, pc, v1, *(pc + 6), color1, pc+8, true, bc ap, fcap, &pickcolor2, stick_round_nub); ok &= CGOSimpleCylinder(cgo, cyl->origin, v1, cyl->tube_size, color1, cyl->color2, cyl->alpha, cyl->alpha, true, bcap, fcap, &pickcolor2, stick_round_ nub);
} else { } else {
ok &= CGOColorv(cgo, color1); ok &= CGOColorv(cgo, color1);
ok &= CGOSimpleCylinder(cgo, pc, mid, *(pc + 6), color1, NULL, false, ok &= CGOSimpleCylinder(cgo, cyl->origin, mid, cyl->tube_size, color1,
fcap, 0, NULL, stick_round_nub); NULL, cyl->alpha, cyl->alpha, false, fcap, 0, NULL, stick_round_nub);
ok &= CGOColorv(cgo, pc+8); ok &= CGOColorv(cgo, cyl->color2);
ok &= CGOPickColor(cgo, pickcolor2.index, pickcolor2.bond); ok &= CGOPickColor(cgo, pickcolor2.index, pickcolor2.bond);
ok &= CGOSimpleCylinder(cgo, mid, v1, *(pc + 6), pc+8, NULL, false, 0, bcap, NULL, stick_round_nub); ok &= CGOSimpleCylinder(cgo, mid, v1, cyl->tube_size, cyl->color2, NUL L, cyl->alpha, cyl->alpha, false, 0, bcap, NULL, stick_round_nub);
} }
} }
break; break;
case CGO_CYLINDER: case CGO_CYLINDER:
ok &= CGOSimpleCylinder(cgo, pc, pc + 3, *(pc + 6), pc + 7, pc + 10, true, {
1, 1, NULL, stick_round_nub); auto cyl = reinterpret_cast<cgo::draw::cylinder*>(pc);
ok &= CGOSimpleCylinder(cgo, *cyl, cgo->alpha, cgo->alpha, true, 1, 1, n
ullptr, stick_round_nub);
}
break; break;
case CGO_CONE: case CGO_CONE:
ok &= CGOSimpleCone(cgo, pc, pc + 3, *(pc + 6), *(pc + 7), pc + 8, pc + 11 , ok &= CGOSimpleCone(cgo, pc, pc + 3, *(pc + 6), *(pc + 7), pc + 8, pc + 11 ,
(int) *(pc + 14), (int) *(pc + 15)); (int) *(pc + 14), (int) *(pc + 15));
break; break;
case CGO_SAUSAGE: case CGO_SAUSAGE:
ok &= CGOSimpleCylinder(cgo, pc, pc + 3, *(pc + 6), pc + 7, pc + 10, true, 2, 2, NULL, stick_round_nub); ok &= CGOSimpleCylinder(cgo, pc, pc + 3, *(pc + 6), pc + 7, pc + 10, cgo-> alpha, cgo->alpha, true, 2, 2, nullptr, stick_round_nub);
break; break;
case CGO_CUSTOM_CYLINDER: case CGO_CUSTOM_CYLINDER:
ok &= CGOSimpleCylinder(cgo, pc, pc + 3, *(pc + 6), pc + 7, pc + 10, true, {
(int) *(pc + 13), auto cyl = reinterpret_cast<cgo::draw::custom_cylinder*>(pc);
(int) *(pc + 14), NULL, stick_round_nub); ok &= CGOSimpleCylinder(cgo, *cyl, cgo->alpha, cgo->alpha, true, cyl->ca
p1, cyl->cap2, nullptr, stick_round_nub);
}
break;
case CGO_CUSTOM_CYLINDER_ALPHA:
{
auto cyl = reinterpret_cast<cgo::draw::custom_cylinder_alpha*>(pc);
ok &= CGOSimpleCylinder(cgo, *cyl, cyl->color1[3], cyl->color2[3], true,
cyl->cap1, cyl->cap2, nullptr, stick_round_nub);
}
break; break;
case CGO_SPHERE: case CGO_SPHERE:
ok &= CGOSimpleSphere(cgo, pc, *(pc + 3), sphere_quality); ok &= CGOSimpleSphere(cgo, pc, *(pc + 3), sphere_quality);
break; break;
case CGO_ELLIPSOID: case CGO_ELLIPSOID:
ok &= CGOSimpleEllipsoid(cgo, pc, *(pc + 3), pc + 4, pc + 7, pc + 10); ok &= CGOSimpleEllipsoid(cgo, pc, *(pc + 3), pc + 4, pc + 7, pc + 10);
break; break;
case CGO_QUADRIC: case CGO_QUADRIC:
ok &= CGOSimpleQuadric(cgo, pc, *(pc + 3), pc + 4); ok &= CGOSimpleQuadric(cgo, pc, *(pc + 3), pc + 4);
break; break;
skipping to change at line 4662 skipping to change at line 4703
{ { CGO_DRAW_LABEL, 4, FLOAT3_TO_FLOAT3, offsetof(cgo::draw::label, sc reen_max), 0 } }; { { CGO_DRAW_LABEL, 4, FLOAT3_TO_FLOAT3, offsetof(cgo::draw::label, sc reen_max), 0 } };
AttribDataOp text_extent_op = AttribDataOp text_extent_op =
{ { CGO_DRAW_LABEL, 5, FLOAT2_TO_FLOAT2, offsetof(cgo::draw::label, te xt_extent), 0 } }; { { CGO_DRAW_LABEL, 5, FLOAT2_TO_FLOAT2, offsetof(cgo::draw::label, te xt_extent), 0 } };
AttribDataOp relative_mode_op = AttribDataOp relative_mode_op =
{ { CGO_DRAW_LABEL, 6, FLOAT_TO_FLOAT, offsetof(cgo::draw::label, re lative_mode), 0 } }; { { CGO_DRAW_LABEL, 6, FLOAT_TO_FLOAT, offsetof(cgo::draw::label, re lative_mode), 0 } };
AttribDataOp target_pos_op = AttribDataOp target_pos_op =
{ { CGO_DRAW_LABEL, 7, FLOAT3_TO_FLOAT3, offsetof(cgo::draw::label, ta rget_pos), 6 } }; { { CGO_DRAW_LABEL, 7, FLOAT3_TO_FLOAT3, offsetof(cgo::draw::label, ta rget_pos), 6 } };
AttribDataDesc attrDesc = { { "attr_worldpos", GL_FLOAT, 3, GL_FALSE, world_pos_op }, AttribDataDesc attrDesc = { { "attr_worldpos", GL_FLOAT, 3, GL_FALSE, world_pos_op },
{ "attr_targetpos", GL_FLOAT, 3, GL_FALSE, target_pos_op }, { "attr_targetpos", GL_FLOAT, 3, GL_FALSE, target_pos_op },
{ "attr_screenoffset", GL_FLOAT, 3, GL_FALSE, screen_offset_op }, { "attr_screenoffset", GL_FLOAT, 3, GL_FALSE, screen_min_op },
{ "attr_texcoords", GL_FLOAT, 2, GL_FALSE, text_extent_op }, { "attr_texcoords", GL_FLOAT, 2, GL_FALSE, text_extent_op },
{ "attr_screenworldoffset", GL_FLOAT, 3, GL_FALSE, screen_offset_op }, { "attr_screenworldoffset", GL_FLOAT, 3, GL_FALSE, screen_offset_op },
{ "attr_relative_mode", GL_FLOAT, 1, GL_FALSE, relative_mode_op } }; { "attr_relative_mode", GL_FLOAT, 1, GL_FALSE, relative_mode_op } };
auto ComputeScreenValues = [](void * varData, const float * pc, void * screenD ata, int idx) { auto ComputeScreenValues = [](void * varData, const float * pc, void * screenD ata, int idx) {
auto sp = reinterpret_cast<const cgo::draw::label *>(pc); auto sp = reinterpret_cast<const cgo::draw::label *>(pc);
const vec3 & smin = sp->screen_min; const vec3 & smin = sp->screen_min;
const vec3 & smax = sp->screen_max; const vec3 & smax = sp->screen_max;
float * v = reinterpret_cast<float *>(varData); float * v = reinterpret_cast<float *>(varData);
switch (idx) { switch (idx) {
skipping to change at line 5131 skipping to change at line 5172
check_extent(pc, 0); check_extent(pc, 0);
break; break;
case CGO_SPHERE: case CGO_SPHERE:
case CGO_ELLIPSOID: case CGO_ELLIPSOID:
check_extent(pc, *(pc + 3)); check_extent(pc, *(pc + 3));
break; break;
case CGO_CYLINDER: case CGO_CYLINDER:
case CGO_CONE: case CGO_CONE:
case CGO_SAUSAGE: case CGO_SAUSAGE:
case CGO_CUSTOM_CYLINDER: case CGO_CUSTOM_CYLINDER:
case CGO_CUSTOM_CYLINDER_ALPHA:
check_extent(pc, *(pc + 6)); check_extent(pc, *(pc + 6));
check_extent(pc + 3, *(pc + 6)); check_extent(pc + 3, *(pc + 6));
break; break;
case CGO_TRIANGLE: case CGO_TRIANGLE:
check_extent(pc, 0); check_extent(pc, 0);
check_extent(pc + 3, 0); check_extent(pc + 3, 0);
check_extent(pc + 6, 0); check_extent(pc + 6, 0);
break; break;
case CGO_DRAW_ARRAYS: case CGO_DRAW_ARRAYS:
{ {
skipping to change at line 5208 skipping to change at line 5250
while((op = (CGO_MASK & CGO_read_int(pc)))) { while((op = (CGO_MASK & CGO_read_int(pc)))) {
switch (op) { switch (op) {
case CGO_NORMAL: case CGO_NORMAL:
case CGO_SPHERE: case CGO_SPHERE:
case CGO_ELLIPSOID: case CGO_ELLIPSOID:
case CGO_CYLINDER: case CGO_CYLINDER:
case CGO_CONE: case CGO_CONE:
case CGO_SAUSAGE: case CGO_SAUSAGE:
case CGO_CUSTOM_CYLINDER: case CGO_CUSTOM_CYLINDER:
case CGO_CUSTOM_CYLINDER_ALPHA:
result |= 1; result |= 1;
break; break;
case CGO_DRAW_ARRAYS: case CGO_DRAW_ARRAYS:
{ {
cgo::draw::arrays * sp = reinterpret_cast<decltype(sp)>(pc); cgo::draw::arrays * sp = reinterpret_cast<decltype(sp)>(pc);
if (sp->arraybits & CGO_NORMAL_ARRAY){ if (sp->arraybits & CGO_NORMAL_ARRAY){
result |= 1; result |= 1;
} }
} }
break; break;
skipping to change at line 5607 skipping to change at line 5650
break; break;
case CGO_QUADRIC: case CGO_QUADRIC:
ray->color3fv(c0); ray->color3fv(c0);
ok &= CGORenderQuadricRay(ray, pc, *(pc + 3), pc + 4); ok &= CGORenderQuadricRay(ray, pc, *(pc + 3), pc + 4);
break; break;
case CGO_CONE: case CGO_CONE:
ok &= ray->cone3fv(pc, pc + 3, *(pc + 6), *(pc + 7), pc + 8, pc + 11, ok &= ray->cone3fv(pc, pc + 3, *(pc + 6), *(pc + 7), pc + 8, pc + 11,
(int) *(pc + 14), (int) *(pc + 15)); (int) *(pc + 14), (int) *(pc + 15));
break; break;
case CGO_CUSTOM_CYLINDER: case CGO_CUSTOM_CYLINDER:
ok &= ray->customCylinder3fv(pc, pc + 3, *(pc + 6), pc + 7, pc + 10, {
(int) *(pc + 13), (int) *(pc + 14)); auto cyl = reinterpret_cast<cgo::draw::custom_cylinder*>(pc);
ok &= ray->customCylinder3fv(*cyl);
}
break;
case CGO_CUSTOM_CYLINDER_ALPHA:
{
auto cyl = reinterpret_cast<cgo::draw::custom_cylinder_alpha*>(pc);
ok &= ray->customCylinderAlpha3fv(*cyl);
}
break; break;
case CGO_SHADER_CYLINDER: case CGO_SHADER_CYLINDER:
{ {
float p2[3]; float p2[3];
int cap = CGO_get_int(pc + 7); int cap = CGO_get_int(pc + 7);
int cap1 = cap & 1 ? ( (cap & cCylShaderCap1RoundBit) ? 2 : 1 ) : 0; int cap1 = cap & 1 ? ( (cap & cCylShaderCap1RoundBit) ? 2 : 1 ) : 0;
int cap2 = cap & 2 ? ( (cap & cCylShaderCap2RoundBit) ? 2 : 1 ) : 0; int cap2 = cap & 2 ? ( (cap & cCylShaderCap2RoundBit) ? 2 : 1 ) : 0;
add3f(pc, pc + 3, p2); add3f(pc, pc + 3, p2);
ok &= ray->customCylinder3fv(pc, p2, *(pc + 6), ray->CurColor, ray->CurC olor, ok &= ray->customCylinder3fv(pc, p2, *(pc + 6), ray->CurColor, ray->CurC olor,
cap1, cap2); cap1, cap2);
} }
break; break;
case CGO_SHADER_CYLINDER_WITH_2ND_COLOR: case CGO_SHADER_CYLINDER_WITH_2ND_COLOR:
{ {
auto cyl = reinterpret_cast<cgo::draw::shadercylinder2ndcolor*>(pc);
float v1[3]; float v1[3];
int cap = CGO_get_int(pc + 7); int cap = cyl->cap;
int fcap = (cap & 1) ? ((cap & cCylShaderCap1RoundBit) ? 2 : 1) : 0; int fcap = (cap & 1) ? ((cap & cCylShaderCap1RoundBit) ? 2 : 1) : 0;
int bcap = (cap & 2) ? ((cap & cCylShaderCap2RoundBit) ? 2 : 1) : 0; int bcap = (cap & 2) ? ((cap & cCylShaderCap2RoundBit) ? 2 : 1) : 0;
int colorinterp = cap & cCylShaderInterpColor; int colorinterp = cap & cCylShaderInterpColor;
const float *color1 = c0; const float *color1 = c0;
const float *color2 = pc + 8; const float *color2 = cyl->color2;
add3f(pc, pc + 3, v1); add3f(cyl->origin, cyl->axis, v1);
if (colorinterp || equal3f(color1, color2)) { if (colorinterp || equal3f(color1, color2)) {
ok &= ray->customCylinder3fv(pc, v1, *(pc + 6), color1, color2, fcap, bcap); ok &= ray->customCylinder3fv(pc, v1, cyl->tube_size, color1, color2, f cap, bcap, cyl->alpha, cyl->alpha);
} else { } else {
float mid[3]; float mid[3];
mult3f(pc + 3, .5f, mid); mult3f(cyl->axis, .5f, mid);
add3f(pc, mid, mid); add3f(cyl->origin, mid, mid);
ray->color3fv(c0); ray->color3fv(c0);
ok &= ray->customCylinder3fv(pc, mid, *(pc + 6), color1, color1, fcap, ok &= ray->customCylinder3fv(cyl->origin, mid, cyl->tube_size, color1,
0); color1, fcap, 0, cyl->alpha, cyl->alpha);
ray->color3fv(pc+8); ray->color3fv(cyl->color2);
ok &= ray->customCylinder3fv(mid, v1, *(pc + 6), color2, color2, 0, bc ok &= ray->customCylinder3fv(mid, v1, cyl->tube_size, color2, color2,
ap); 0, bcap, cyl->alpha, cyl->alpha);
} }
} }
break; break;
case CGO_CYLINDER: case CGO_CYLINDER:
ok &= ray->cylinder3fv(pc, pc + 3, *(pc + 6), pc + 7, pc + 10); {
auto *cyl = reinterpret_cast<cgo::draw::cylinder*>(pc);
ok &= ray->cylinder3fv(*cyl);
}
break; break;
case CGO_SAUSAGE: case CGO_SAUSAGE:
ok &= ray->sausage3fv(pc, pc + 3, *(pc + 6), pc + 7, pc + 10); ok &= ray->sausage3fv(pc, pc + 3, *(pc + 6), pc + 7, pc + 10);
break; break;
case CGO_TRIANGLE: case CGO_TRIANGLE:
ok &= ray->triangle3fv(pc, pc + 3, pc + 6, pc + 9, pc + 12, pc + 15, pc + 18, ok &= ray->triangle3fv(pc, pc + 3, pc + 6, pc + 9, pc + 12, pc + 15, pc + 18,
pc + 21, pc + 24); pc + 21, pc + 24);
break; break;
case CGO_DRAW_ARRAYS: case CGO_DRAW_ARRAYS:
{ {
skipping to change at line 5686 skipping to change at line 5741
offset += nverts * 3; offset += nverts * 3;
} }
vc = 0; vc = 0;
for (v=0, pl=0, plc=0; ok && v<nverts; v++, pl+=3, plc+=4){ for (v=0, pl=0, plc=0; ok && v<nverts; v++, pl+=3, plc+=4){
if (normalVals){ if (normalVals){
n0 = &normalVals[pl]; n0 = &normalVals[pl];
} }
if (colorVals){ if (colorVals){
c0 = &colorVals[plc]; c0 = &colorVals[plc];
ray->color3fv(c0); ray->color3fv(c0);
ray->transparentf(1.0f - c0[3]);
} }
if (vertexVals){ if (vertexVals){
v0 = &vertexVals[pl]; v0 = &vertexVals[pl];
} }
switch (mode){ switch (mode){
case GL_POINTS: case GL_POINTS:
ok &= ray->sphere3fv(v0, dotradius); ok &= ray->sphere3fv(v0, dotradius);
break; break;
case GL_LINES: case GL_LINES:
if(vc & 0x1) if(vc & 0x1)
skipping to change at line 5865 skipping to change at line 5921
if (I->isPicking){ if (I->isPicking){
if (no_split_for_pick){ if (no_split_for_pick){
glVertex3fv(splitline->vertex1); glVertex3fv(splitline->vertex1);
glVertex3fv(splitline->vertex2); glVertex3fv(splitline->vertex2);
} else { } else {
float h[3]; float h[3];
average3f(splitline->vertex1, splitline->vertex2, h); average3f(splitline->vertex1, splitline->vertex2, h);
glVertex3fv(splitline->vertex1); glVertex3fv(splitline->vertex1);
glVertex3fv(h); glVertex3fv(h);
unsigned char col[4]; unsigned char col[4];
Picking **pick = I->info->pick; auto pick = I->info->pick;
AssignNewPickColor(NULL, (*pick)[0].src.index, pick, &I->rep->context, c ol, AssignNewPickColor(NULL, (*pick)[0].src.index, pick, &I->rep->context, c ol,
splitline->index, splitline->bond); splitline->index, splitline->bond);
glColor4ubv(col); glColor4ubv(col);
glVertex3fv(h); glVertex3fv(h);
glVertex3fv(splitline->vertex2); glVertex3fv(splitline->vertex2);
} }
} else if (interpolation || equal_colors){ } else if (interpolation || equal_colors){
glVertex3fv(splitline->vertex1); glVertex3fv(splitline->vertex1);
if (!equal_colors) if (!equal_colors)
glColor4ub(splitline->color2[0], splitline->color2[1], splitline->color2 [2], CLIP_COLOR_VALUE(I->alpha)); glColor4ub(splitline->color2[0], splitline->color2[1], splitline->color2 [2], CLIP_COLOR_VALUE(I->alpha));
skipping to change at line 5979 skipping to change at line 6035
if (arrays & CGO_COLOR_ARRAY) if (arrays & CGO_COLOR_ARRAY)
glDisableVertexAttribArray(VERTEX_COLOR); glDisableVertexAttribArray(VERTEX_COLOR);
} }
if (arrays & CGO_VERTEX_ARRAY) glDisableVertexAttribArray(VERTEX_POS); if (arrays & CGO_VERTEX_ARRAY) glDisableVertexAttribArray(VERTEX_POS);
if (arrays & CGO_NORMAL_ARRAY) glDisableVertexAttribArray(VERTEX_NORMAL); if (arrays & CGO_NORMAL_ARRAY) glDisableVertexAttribArray(VERTEX_NORMAL);
#ifndef PURE_OPENGL_ES_2 #ifndef PURE_OPENGL_ES_2
} else { } else {
int pl, pla, plc; int pl, pla, plc;
float *vertexVals; float *vertexVals = nullptr;
float *colorVals = 0, *normalVals = 0, *tmp_ptr, alpha ; float *colorVals = 0, *normalVals = 0, *tmp_ptr, alpha ;
uchar *pickColorVals = 0, *tmp_pc_ptr; uchar *pickColorVals = 0, *tmp_pc_ptr;
alpha = I->alpha; alpha = I->alpha;
if (arrays & CGO_VERTEX_ARRAY){ if (arrays & CGO_VERTEX_ARRAY){
vertexVals = data; vertexVals = data;
data += nverts*3; data += nverts*3;
} }
if (arrays & CGO_NORMAL_ARRAY){ if (arrays & CGO_NORMAL_ARRAY){
normalVals = data; normalVals = data;
data += nverts*3; data += nverts*3;
skipping to change at line 6040 skipping to change at line 6096
if (vertexVals){ if (vertexVals){
tmp_ptr = &vertexVals[pla]; tmp_ptr = &vertexVals[pla];
glVertex3fv(&vertexVals[pla]); glVertex3fv(&vertexVals[pla]);
} }
} }
glEnd(); glEnd();
} }
#endif #endif
} }
static
void TransparentInfoSortIX(PyMOLGlobals * G, float *sum, float *z_value, void TransparentInfoSortIX(PyMOLGlobals * G, float *sum, float *z_value,
int *ix, int n_tri, int *sort_mem, int t_mode); int *ix, int n_tri, int *sort_mem, int t_mode);
static
void CGOReorderIndicesWithTransparentInfo(PyMOLGlobals * G, int nindices, void CGOReorderIndicesWithTransparentInfo(PyMOLGlobals * G, int nindices,
size_t vbuf, int n_tri, int *ix, size_t vbuf, int n_tri, int *ix,
GL_C_INT_TYPE *vertexIndicesOriginal, GL_C_INT_TYPE *vertexIndicesOriginal,
GL_C_INT_TYPE *vertexIndices); GL_C_INT_TYPE *vertexIndices);
static void CGO_gl_draw_buffers_indexed(CCGORenderer * I, float **pc){ static void CGO_gl_draw_buffers_indexed(CCGORenderer * I, float **pc){
cgo::draw::buffers_indexed * sp = reinterpret_cast<decltype(sp)>(*pc); cgo::draw::buffers_indexed * sp = reinterpret_cast<decltype(sp)>(*pc);
int mode = sp->mode, nindices = sp->nindices, int mode = sp->mode, nindices = sp->nindices,
nverts = sp->nverts, n_data = sp->n_data; nverts = sp->nverts, n_data = sp->n_data;
size_t vboid = sp->vboid, iboid = sp->iboid; size_t vboid = sp->vboid, iboid = sp->iboid;
VertexBuffer * vbo = I->G->ShaderMgr->getGPUBuffer<VertexBuffer>(vboid); VertexBuffer * vbo = I->G->ShaderMgr->getGPUBuffer<VertexBuffer>(vboid);
IndexBuffer * ibo = I->G->ShaderMgr->getGPUBuffer<IndexBuffer>(iboid); IndexBuffer * ibo = I->G->ShaderMgr->getGPUBuffer<IndexBuffer>(iboid);
int ok = true;
GLenum err ; GLenum err ;
CHECK_GL_ERROR_OK("beginning of CGO_gl_draw_buffers_indexed err=%d\n"); CHECK_GL_ERROR_OK("beginning of CGO_gl_draw_buffers_indexed err=%d\n");
auto shaderPrg = I->G->ShaderMgr->Get_Current_Shader(); auto shaderPrg = I->G->ShaderMgr->Get_Current_Shader();
if (!shaderPrg){ if (!shaderPrg){
*pc += fsizeof<cgo::draw::buffers_not_indexed>(); *pc += fsizeof<cgo::draw::buffers_not_indexed>();
return; return;
} }
skipping to change at line 6416 skipping to change at line 6473
cgo::draw::connectors * sp = reinterpret_cast<decltype(sp)>(*pc); cgo::draw::connectors * sp = reinterpret_cast<decltype(sp)>(*pc);
GLenum mode = GL_LINES; GLenum mode = GL_LINES;
int factor = 2; int factor = 2;
float lineWidth; float lineWidth;
if (I->isPicking){ if (I->isPicking){
return; return;
} }
{ {
GLenum err ; GLenum err ;
int ok = true;
CHECK_GL_ERROR_OK("ERROR: CGO_gl_draw_connectors begin returns err=%d\n"); CHECK_GL_ERROR_OK("ERROR: CGO_gl_draw_connectors begin returns err=%d\n");
} }
if (use_geometry_shaders){ if (use_geometry_shaders){
mode = GL_POINTS; mode = GL_POINTS;
factor = 1; factor = 1;
} else { } else {
factor = 4; factor = 4;
} }
auto shaderPrg = I->G->ShaderMgr->Get_Current_Shader(); auto shaderPrg = I->G->ShaderMgr->Get_Current_Shader();
skipping to change at line 6460 skipping to change at line 6516
#endif #endif
VertexBuffer * vbo = I->G->ShaderMgr->getGPUBuffer<VertexBuffer>(sp->vboid); VertexBuffer * vbo = I->G->ShaderMgr->getGPUBuffer<VertexBuffer>(sp->vboid);
if (!vbo) if (!vbo)
return; return;
vbo->bind(shaderPrg->id); vbo->bind(shaderPrg->id);
glDrawArrays(mode, 0, sp->nconnectors*factor); glDrawArrays(mode, 0, sp->nconnectors*factor);
vbo->unbind(); vbo->unbind();
{ {
GLenum err ; GLenum err ;
int ok = true;
CHECK_GL_ERROR_OK("ERROR: CGO_gl_draw_connectors end returns err=%d\n"); CHECK_GL_ERROR_OK("ERROR: CGO_gl_draw_connectors end returns err=%d\n");
} }
} }
static void CGO_gl_draw_textures(CCGORenderer * I, float **pc) { static void CGO_gl_draw_textures(CCGORenderer * I, float **pc) {
cgo::draw::textures * sp = reinterpret_cast<decltype(sp)>(*pc); cgo::draw::textures * sp = reinterpret_cast<decltype(sp)>(*pc);
int ntextures = sp->ntextures; int ntextures = sp->ntextures;
VertexBuffer * vbo = I->G->ShaderMgr->getGPUBuffer<VertexBuffer>(sp->vboid); VertexBuffer * vbo = I->G->ShaderMgr->getGPUBuffer<VertexBuffer>(sp->vboid);
CShaderPrg * shaderPrg; CShaderPrg * shaderPrg;
int attr_pickcolor = 0; int attr_pickcolor = 0;
skipping to change at line 6921 skipping to change at line 6976
case LINEWIDTH_FOR_LINES: case LINEWIDTH_FOR_LINES:
{ {
if (!use_shaders){ if (!use_shaders){
glEnd(); glEnd();
glLineWidth(argval); glLineWidth(argval);
glBegin(GL_LINES); glBegin(GL_LINES);
} }
} }
break; break;
case LINE_LIGHTING: case LINE_LIGHTING:
if(!SettingGetGlobal_b(I->G, cSetting_use_shaders)){ if (!I->isPicking && !SettingGetGlobal_b(I->G, cSetting_use_shaders)) {
if (!I->info->line_lighting){ if (!I->info->line_lighting){
bool enableLighting = (int)argval; bool enableLighting = (int)argval;
if (enableLighting) if (enableLighting)
glEnable(GL_LIGHTING); glEnable(GL_LIGHTING);
else else
glDisable(GL_LIGHTING); glDisable(GL_LIGHTING);
} }
} }
break; break;
case SPHERE_MODE_OPS: case SPHERE_MODE_OPS:
skipping to change at line 7400 skipping to change at line 7455
color[3] = 0; color[3] = 0;
} }
void SetUCColorToZero_16bit(uchar *color){ void SetUCColorToZero_16bit(uchar *color){
color[0] = 0; color[0] = 0;
color[1] = 0; color[1] = 0;
color[2] = 0; color[2] = 0;
color[3] = 255; color[3] = 255;
} }
#if 0
static static
void SetUCColorToPrev(uchar *color){ void SetUCColorToPrev(uchar *color){
color[0] = color[-4]; color[0] = color[-4];
color[1] = color[-3]; color[1] = color[-3];
color[2] = color[-2]; color[2] = color[-2];
color[3] = color[-1]; color[3] = color[-1];
} }
static static
void SetUCColorToPrev8(uchar *color){ void SetUCColorToPrev8(uchar *color){
color[0] = color[-8]; color[0] = color[-8];
color[1] = color[-7]; color[1] = color[-7];
color[2] = color[-6]; color[2] = color[-6];
color[3] = color[-5]; color[3] = color[-5];
} }
#endif
static static
void SetUCColorToPrevN(int n, uchar *color){ void SetUCColorToPrevN(int n, uchar *color){
color[0] = color[-n*4]; color[0] = color[-n*4];
color[1] = color[-n*4+1]; color[1] = color[-n*4+1];
color[2] = color[-n*4+2]; color[2] = color[-n*4+2];
color[3] = color[-n*4+3]; color[3] = color[-n*4+3];
} }
static static
skipping to change at line 7456 skipping to change at line 7513
return; return;
if (!I->c) if (!I->c)
return; return;
int op; int op;
CCGORenderer *R = G->CGORenderer; CCGORenderer *R = G->CGORenderer;
unsigned int i, j; unsigned int i, j;
bool pickable = (!I->no_pick) && bool pickable = (!I->no_pick) &&
SettingGet_b(G, set1, set2, cSetting_pickable); SettingGet_b(G, set1, set2, cSetting_pickable);
Picking ** pick = info->pick; auto pick = info->pick;
bool use_shaders = SettingGetGlobal_b(G, cSetting_use_shaders); bool use_shaders = SettingGetGlobal_b(G, cSetting_use_shaders);
bool reset_colors = !use_shaders || ((*pick)[0].src.bond & 2); bool reset_colors = !use_shaders || (pick->begin()->src.bond & 2);
R->use_shader = I->use_shader; R->use_shader = I->use_shader;
R->isPicking = true; R->isPicking = true;
R->picking_32bit = info->picking_32bit; R->picking_32bit = info->picking_32bit;
R->pick_mode = (*pick)[0].src.bond & 1; R->pick_mode = pick->begin()->src.bond & 1;
R->set1 = set1; R->set1 = set1;
R->set2 = set2; R->set2 = set2;
R->info = info; R->info = info;
R->rep = rep; R->rep = rep;
i = (*pick)[0].src.index; i = pick->begin()->src.index;
#ifndef _WEBGL #ifndef _WEBGL
glLineWidth(SettingGet_f(G, set1, set2, cSetting_cgo_line_width)); glLineWidth(SettingGet_f(G, set1, set2, cSetting_cgo_line_width));
#endif #endif
for (float *pc = I->op; for (float *pc = I->op;
(op = (CGO_MASK & CGO_read_int(pc))); (op = (CGO_MASK & CGO_read_int(pc)));
pc += CGO_sz[op]) { pc += CGO_sz[op]) {
switch (op) { switch (op) {
case CGO_COLOR: case CGO_COLOR:
continue; continue;
case CGO_PICK_COLOR: case CGO_PICK_COLOR:
if (reset_colors){ // only if picking info is invalid if (reset_colors){ // only if picking info is invalid
unsigned char col[4]; unsigned char col[4];
AssignNewPickColor(I, i, pick, context, col, CGO_get_uint(pc), AssignNewPickColor(I, i, pick, context, col, CGO_get_uint(pc),
pickable ? CGO_get_int(pc + 1) : cPickableNoPick); pickable ? CGO_get_int(pc + 1) : cPickableNoPick);
(*pick)[0].src.index = i; pick->begin()->src.index = i;
#ifndef PURE_OPENGL_ES_2 #ifndef PURE_OPENGL_ES_2
if (!I->use_shader){ if (!I->use_shader){
glColor4ubv(col); glColor4ubv(col);
} }
#endif #endif
} }
continue; continue;
case CGO_DRAW_ARRAYS: case CGO_DRAW_ARRAYS:
{ {
skipping to change at line 7525 skipping to change at line 7582
if (bnd == cPickableNoPick){ if (bnd == cPickableNoPick){
info->setUCColorToZero(pickColorValsUC + (v * 4)); info->setUCColorToZero(pickColorValsUC + (v * 4));
continue; continue;
} }
i++; i++;
if(!R->pick_mode) { if(!R->pick_mode) {
idx = pickColorVals[v * 2]; idx = pickColorVals[v * 2];
VLACheck((*pick), Picking, i); if (pick->size() <= i) {
set_current_pick_color(I, (*pick) + i, context, idx, bnd); pick->resize((i + 1) * 3 / 2); // grow by 50%
}
set_current_pick_color(I, pick->data() + i, context, idx, bnd);
j = i; j = i;
} else { } else {
j = i >> 12; j = i >> 12;
} }
info->setUCColorFromIndex(pickColorValsUC + (v * 4), j); info->setUCColorFromIndex(pickColorValsUC + (v * 4), j);
} }
} }
} }
break; break;
skipping to change at line 7552 skipping to change at line 7611
case CGO_DRAW_SPHERE_BUFFERS: case CGO_DRAW_SPHERE_BUFFERS:
case CGO_DRAW_CYLINDER_BUFFERS: case CGO_DRAW_CYLINDER_BUFFERS:
case CGO_DRAW_CUSTOM: case CGO_DRAW_CUSTOM:
{ {
int pickcolors_are_set = true; int pickcolors_are_set = true;
int *pickcolors_are_set_ptr = get_pickcolorsset_ptr(op, pc); int *pickcolors_are_set_ptr = get_pickcolorsset_ptr(op, pc);
if (!pickcolors_are_set_ptr) if (!pickcolors_are_set_ptr)
pickcolors_are_set_ptr = &pickcolors_are_set; pickcolors_are_set_ptr = &pickcolors_are_set;
if (reset_colors || !*pickcolors_are_set_ptr){ // only if picking info is invalid if (reset_colors || !*pickcolors_are_set_ptr){ // only if picking info is invalid
int nverts, nvertsperfrag = 1, v, pl, bnd = cPickableNoPick, pbnd = int nverts = 0;
cPickableNoPick, chg = 0; int nvertsperfrag = 1;
int v, pl;
int bnd = cPickableNoPick, pbnd = cPickableNoPick;
int chg = 0;
unsigned int idx = 0, pidx = 0; unsigned int idx = 0, pidx = 0;
int srcp; int srcp;
float *pca; float *pca = nullptr;
int *pickDataSrc ; int *pickDataSrc ;
uchar *pickColorDestUC = NULL; uchar *pickColorDestUC = NULL;
bool free_pick_color_dest = false; bool free_pick_color_dest = false;
int destOffset = 0, bufsizemult = 1; int destOffset = 0, bufsizemult = 1;
size_t pickvbo = 0; size_t pickvbo = 0;
switch (op){ switch (op){
case CGO_DRAW_CUSTOM: case CGO_DRAW_CUSTOM:
{ {
cgo::draw::custom * sp = reinterpret_cast<decltype(sp)>(pc); cgo::draw::custom * sp = reinterpret_cast<decltype(sp)>(pc);
nverts = sp->nverts; nverts = sp->nverts;
skipping to change at line 7691 skipping to change at line 7754
if (bnd == cPickableNoPick){ if (bnd == cPickableNoPick){
info->setUCColorToZero(&pickColorDestUC[pl+ploffset]); info->setUCColorToZero(&pickColorDestUC[pl+ploffset]);
continue; continue;
} }
chg = idx != pidx || bnd != pbnd; chg = idx != pidx || bnd != pbnd;
if (chg) if (chg)
i++; i++;
if(!R->pick_mode) { if(!R->pick_mode) {
j = i; j = i;
if (chg){ if (chg){
VLACheck((*pick), Picking, i); if (pick->size() <= i) {
set_current_pick_color(I, (*pick) + i, context, idx, bnd pick->resize((i + 1) * 3 / 2);
); }
set_current_pick_color(I, pick->data() + i, context, idx
, bnd);
} }
} else { } else {
j = i >> 12; j = i >> 12;
} }
info->setUCColorFromIndex(&pickColorDestUC[pl+ploffset], j); info->setUCColorFromIndex(&pickColorDestUC[pl+ploffset], j);
} }
} }
} }
} }
skipping to change at line 7850 skipping to change at line 7915
case CGO_TRIANGLE: case CGO_TRIANGLE:
CGOAlphaTriangle(info->alpha_cgo, CGOAlphaTriangle(info->alpha_cgo,
pc, pc + 3, pc + 6, pc + 9, pc + 12, pc + 15, pc + 18, pc, pc + 3, pc + 6, pc + 9, pc + 12, pc + 15, pc + 18,
pc + 21, pc + 24, R->alpha, R->alpha, R->alpha, f alse); pc + 21, pc + 24, R->alpha, R->alpha, R->alpha, f alse);
break; break;
case CGO_DRAW_ARRAYS: case CGO_DRAW_ARRAYS:
{ {
cgo::draw::arrays * sp = reinterpret_cast<decltype(sp)>(pc); cgo::draw::arrays * sp = reinterpret_cast<decltype(sp)>(pc);
int mode = sp->mode, arrays = sp->arraybits, nverts = sp->nverts; int mode = sp->mode, arrays = sp->arraybits, nverts = sp->nverts;
float *vertexVals = 0, *nxtVals = 0, *colorVals = 0, *normalVals; float *vertexVals = 0, *nxtVals = 0, *colorVals = 0, *normalVals;
float *vertexVals_tmp = 0, *colorVals_tmp = 0, *normalVals_tmp; float *vertexVals_tmp = 0, *colorVals_tmp = 0, *normalVals_tmp = 0;
int step; int step;
short nxtn = 3; short nxtn = 3;
nxtVals = vertexVals = vertexVals_tmp = sp->floatdata; nxtVals = vertexVals = vertexVals_tmp = sp->floatdata;
if (arrays & CGO_NORMAL_ARRAY){ if (arrays & CGO_NORMAL_ARRAY){
nxtVals = normalVals = normalVals_tmp = vertexVals + (nxtn*nver ts); nxtVals = normalVals = normalVals_tmp = vertexVals + (nxtn*nver ts);
} }
if (arrays & CGO_COLOR_ARRAY){ if (arrays & CGO_COLOR_ARRAY){
nxtVals = colorVals = colorVals_tmp = nxtVals + (nxtn*nverts); nxtVals = colorVals = colorVals_tmp = nxtVals + (nxtn*nverts);
nxtn = 4; nxtn = 4;
} }
skipping to change at line 8375 skipping to change at line 8440
CGOVertexv(I, vertex); CGOVertexv(I, vertex);
z3 = z2; z3 = z2;
} }
} }
} }
CGOEnd(I); CGOEnd(I);
} }
static int CGOSimpleCylinder(CGO * I, float *v1, float *v2, float tube_size, flo static int CGOSimpleCylinder(CGO * I, const float *v1, const float *v2, const fl
at *c1, oat tube_size,
float *c2, bool interp, int cap1, int cap2, const float *c1, const float *c2, const float alpha
Pickable *pickcolor2, bool stick_round_nub) 1,
const float alpha2, const bool interp, const int ca
p1, const int cap2,
const Pickable *pickcolor2, const bool stick_round_
nub)
{ {
#define MAX_EDGE 50 #define MAX_EDGE 50
float d[3], t[3], p0[3], p1[3], p2[3], vv1[3], vv2[3], v_buf[9], *v; float d[3], t[3], p0[3], p1[3], p2[3], vv1[3], vv2[3], v_buf[9], *v;
float x[MAX_EDGE + 1], y[MAX_EDGE + 1]; float x[MAX_EDGE + 1], y[MAX_EDGE + 1];
float overlap; float overlap;
float nub; float nub;
bool colorFlag, interpColorFlag; bool colorFlag, interpColorFlag;
int nEdge; int nEdge;
int c; int c;
int ok = true; int ok = true;
float midcolor[3]; float midcolor[3];
float midalpha{alpha1};
Pickable pickcolor[2]; Pickable pickcolor[2];
pickcolor[0].index = I->current_pick_color_index; pickcolor[0].index = I->current_pick_color_index;
pickcolor[0].bond = I->current_pick_color_bond; pickcolor[0].bond = I->current_pick_color_bond;
if (pickcolor2){ if (pickcolor2){
pickcolor[1].index = pickcolor2->index; pickcolor[1].index = pickcolor2->index;
pickcolor[1].bond = pickcolor2->bond; pickcolor[1].bond = pickcolor2->bond;
} else { } else {
pickcolor[1].index = pickcolor[0].index; pickcolor[1].index = pickcolor[0].index;
pickcolor[1].bond = pickcolor[0].bond; pickcolor[1].bond = pickcolor[0].bond;
} }
v = v_buf; v = v_buf;
nEdge = SettingGetGlobal_i(I->G, cSetting_stick_quality); nEdge = SettingGetGlobal_i(I->G, cSetting_stick_quality);
overlap = tube_size * SettingGetGlobal_f(I->G, cSetting_stick_overlap); overlap = tube_size * SettingGetGlobal_f(I->G, cSetting_stick_overlap);
nub = tube_size * SettingGetGlobal_f(I->G, cSetting_stick_nub); nub = tube_size * SettingGetGlobal_f(I->G, cSetting_stick_nub);
if(nEdge > MAX_EDGE) if(nEdge > MAX_EDGE)
nEdge = MAX_EDGE; nEdge = MAX_EDGE;
subdivide(nEdge, x, y); subdivide(nEdge, x, y);
colorFlag = (c1 != c2) && c2; colorFlag = (c1 != c2) && c2;
colorFlag |= alpha1 != alpha2;
interpColorFlag = c2 && interp && pickcolor2; interpColorFlag = c2 && interp && pickcolor2;
if (interpColorFlag){ if (interpColorFlag){
average3f(c1, c2, midcolor); average3f(c1, c2, midcolor);
midalpha = (alpha1 + alpha2) / 2.0f;
} }
/* direction vector */ /* direction vector */
p0[0] = (v2[0] - v1[0]); p0[0] = (v2[0] - v1[0]);
p0[1] = (v2[1] - v1[1]); p0[1] = (v2[1] - v1[1]);
p0[2] = (v2[2] - v1[2]); p0[2] = (v2[2] - v1[2]);
normalize3f(p0); normalize3f(p0);
if(cap1 == cCylCapRound && !stick_round_nub) { if(cap1 == cCylCapRound && !stick_round_nub) {
skipping to change at line 8476 skipping to change at line 8545
v[4] = vv1[1] + v[1] * tube_size; v[4] = vv1[1] + v[1] * tube_size;
v[5] = vv1[2] + v[2] * tube_size; v[5] = vv1[2] + v[2] * tube_size;
v[6] = v[3] + d[0]; v[6] = v[3] + d[0];
v[7] = v[4] + d[1]; v[7] = v[4] + d[1];
v[8] = v[5] + d[2]; v[8] = v[5] + d[2];
ok &= CGONormalv(I, v); ok &= CGONormalv(I, v);
if(ok && (colorFlag || interpColorFlag) ){ if(ok && (colorFlag || interpColorFlag) ){
ok &= CGOColorv(I, c1); ok &= CGOColorv(I, c1);
ok &= CGOAlpha(I, alpha1);
} }
if (ok) if (ok)
ok &= CGOVertexv(I, v + 3); ok &= CGOVertexv(I, v + 3);
if (ok && interpColorFlag){ if (ok && interpColorFlag){
ok &= CGOColorv(I, midcolor); ok &= CGOColorv(I, midcolor);
ok &= CGOAlpha(I, midalpha);
} else if(ok && colorFlag && !pickcolor2){ } else if(ok && colorFlag && !pickcolor2){
ok &= CGOColorv(I, c2); ok &= CGOColorv(I, c2);
ok &= CGOAlpha(I, alpha2);
} }
if (ok) if (ok)
ok &= CGOVertexv(I, v + 6); ok &= CGOVertexv(I, v + 6);
} }
if (ok) if (ok)
ok &= CGOEnd(I); ok &= CGOEnd(I);
if (pickcolor2){ if (pickcolor2){
ok &= CGOColorv(I, c2); ok &= CGOColorv(I, c2);
ok &= CGOAlpha(I, alpha2);
CGOPickColor(I, pickcolor2->index, pickcolor2->bond); CGOPickColor(I, pickcolor2->index, pickcolor2->bond);
if (ok) if (ok)
ok &= CGOBegin(I, GL_TRIANGLE_STRIP); ok &= CGOBegin(I, GL_TRIANGLE_STRIP);
for(c = nEdge; ok && c >= 0; c--) { for(c = nEdge; ok && c >= 0; c--) {
v[0] = p1[0] * x[c] + p2[0] * y[c]; v[0] = p1[0] * x[c] + p2[0] * y[c];
v[1] = p1[1] * x[c] + p2[1] * y[c]; v[1] = p1[1] * x[c] + p2[1] * y[c];
v[2] = p1[2] * x[c] + p2[2] * y[c]; v[2] = p1[2] * x[c] + p2[2] * y[c];
v[3] = vv1[0] + v[0] * tube_size + d[0]; v[3] = vv1[0] + v[0] * tube_size + d[0];
v[4] = vv1[1] + v[1] * tube_size + d[1]; v[4] = vv1[1] + v[1] * tube_size + d[1];
v[5] = vv1[2] + v[2] * tube_size + d[2]; v[5] = vv1[2] + v[2] * tube_size + d[2];
v[6] = v[3] + d[0]; v[6] = v[3] + d[0];
v[7] = v[4] + d[1]; v[7] = v[4] + d[1];
v[8] = v[5] + d[2]; v[8] = v[5] + d[2];
ok &= CGONormalv(I, v); ok &= CGONormalv(I, v);
if (ok && interpColorFlag) if (ok && interpColorFlag){
ok &= CGOColorv(I, midcolor); ok &= CGOColorv(I, midcolor);
ok &= CGOAlpha(I, midalpha);
}
if (ok) if (ok)
ok &= CGOVertexv(I, v + 3); ok &= CGOVertexv(I, v + 3);
if (ok && interpColorFlag){ if (ok && interpColorFlag){
ok &= CGOColorv(I, c2); ok &= CGOColorv(I, c2);
ok &= CGOAlpha(I, alpha2);
} }
if (ok) if (ok)
ok &= CGOVertexv(I, v + 6); ok &= CGOVertexv(I, v + 6);
} }
if (ok) if (ok)
ok &= CGOEnd(I); ok &= CGOEnd(I);
} }
if(ok && cap1) { if(ok && cap1) {
if(ok && colorFlag && c1){ if(ok && colorFlag && c1){
ok &= CGOColorv(I, c1); ok &= CGOColorv(I, c1);
ok &= CGOAlpha(I, alpha1);
} }
if (pickcolor2) if (pickcolor2)
CGOPickColor(I, pickcolor[0].index, pickcolor[0].bond); CGOPickColor(I, pickcolor[0].index, pickcolor[0].bond);
if(stick_round_nub && cap1 == cCylCapRound) { if(stick_round_nub && cap1 == cCylCapRound) {
CGORoundNub(I, v1, p0, p1, p2, -1, nEdge, tube_size); CGORoundNub(I, v1, p0, p1, p2, -1, nEdge, tube_size);
} else { } else {
v[0] = -p0[0]; v[0] = -p0[0];
v[1] = -p0[1]; v[1] = -p0[1];
v[2] = -p0[2]; v[2] = -p0[2];
skipping to change at line 8572 skipping to change at line 8649
ok &= CGOVertexv(I, v + 3); ok &= CGOVertexv(I, v + 3);
} }
if (ok) if (ok)
ok &= CGOEnd(I); ok &= CGOEnd(I);
} }
} }
if(ok && cap2) { if(ok && cap2) {
if(ok && colorFlag && c2){ if(ok && colorFlag && c2){
ok &= CGOColorv(I, c2); ok &= CGOColorv(I, c2);
ok &= CGOAlpha(I, alpha2);
} }
if (pickcolor2) if (pickcolor2)
CGOPickColor(I, pickcolor2->index, pickcolor2->bond); CGOPickColor(I, pickcolor2->index, pickcolor2->bond);
if(stick_round_nub && cap2 == cCylCapRound) { if(stick_round_nub && cap2 == cCylCapRound) {
CGORoundNub(I, v2, p0, p1, p2, 1, nEdge, tube_size); CGORoundNub(I, v2, p0, p1, p2, 1, nEdge, tube_size);
} else { } else {
v[0] = p0[0]; v[0] = p0[0];
v[1] = p0[1]; v[1] = p0[1];
v[2] = p0[2]; v[2] = p0[2];
skipping to change at line 8617 skipping to change at line 8695
ok &= CGONormalv(I, v); ok &= CGONormalv(I, v);
if (ok) if (ok)
ok &= CGOVertexv(I, v + 3); ok &= CGOVertexv(I, v + 3);
} }
if (ok) ok &= CGOEnd(I); if (ok) ok &= CGOEnd(I);
} }
} }
return ok; return ok;
} }
template <typename CylinderT>
static int CGOSimpleCylinder(CGO* I, const CylinderT& cyl, const float a1,
const float a2, const bool interp, const int cap1, const int cap2,
const Pickable* pickcolor2, const bool stick_round_nub)
{
return CGOSimpleCylinder(I, cyl.vertex1, cyl.vertex2, cyl.radius, cyl.color1,
cyl.color2, a1, a2, interp, cap1, cap2, pickcolor2, stick_round_nub);
}
static int CGOSimpleCone(CGO * I, float *v1, float *v2, float r1, float r2, static int CGOSimpleCone(CGO * I, float *v1, float *v2, float r1, float r2,
float *c1, float *c2, int cap1, int cap2) float *c1, float *c2, int cap1, int cap2)
{ {
#define MAX_EDGE 50 #define MAX_EDGE 50
float d[3], t[3], p0[3], p1[3], p2[3], vv1[3], vv2[3], v_buf[9], *v; float d[3], t[3], p0[3], p1[3], p2[3], vv1[3], vv2[3], v_buf[9], *v;
float x[MAX_EDGE + 1], y[MAX_EDGE + 1], edge_normal[3 * (MAX_EDGE + 1)]; float x[MAX_EDGE + 1], y[MAX_EDGE + 1], edge_normal[3 * (MAX_EDGE + 1)];
int colorFlag; int colorFlag;
int nEdge; int nEdge;
int c; int c;
skipping to change at line 9019 skipping to change at line 9106
} }
} }
return ret; return ret;
} }
bool CGOFilterOutCylinderOperationsInto(const CGO *I, CGO *cgo){ bool CGOFilterOutCylinderOperationsInto(const CGO *I, CGO *cgo){
static std::set<int> optypes = { CGO_SHADER_CYLINDER, static std::set<int> optypes = { CGO_SHADER_CYLINDER,
CGO_SHADER_CYLINDER_WITH_2ND_COLOR, CGO_SHADER_CYLINDER_WITH_2ND_COLOR,
CGO_SAUSAGE, CGO_SAUSAGE,
CGO_CYLINDER, CGO_CYLINDER,
CGO_CUSTOM_CYLINDER }; CGO_CUSTOM_CYLINDER,
CGO_CUSTOM_CYLINDER_ALPHA };
return CGOFilterOutOperationsOfTypeN(I, cgo, optypes); return CGOFilterOutOperationsOfTypeN(I, cgo, optypes);
} }
bool CGOHasCylinderOperations(const CGO *I){ bool CGOHasCylinderOperations(const CGO *I){
static std::set<int> optypes = { CGO_SHADER_CYLINDER, static std::set<int> optypes = { CGO_SHADER_CYLINDER,
CGO_SHADER_CYLINDER_WITH_2ND_COLOR, CGO_SHADER_CYLINDER_WITH_2ND_COLOR,
CGO_SAUSAGE, CGO_SAUSAGE,
CGO_CYLINDER, CGO_CYLINDER,
CGO_CUSTOM_CYLINDER }; CGO_CUSTOM_CYLINDER,
CGO_CUSTOM_CYLINDER_ALPHA };
return CGOHasOperationsOfTypeN(I, optypes); return CGOHasOperationsOfTypeN(I, optypes);
} }
bool CGOHasSphereOperations(const CGO *I){ bool CGOHasSphereOperations(const CGO *I){
static std::set<int> optypes = { CGO_SPHERE }; static std::set<int> optypes = { CGO_SPHERE };
return CGOHasOperationsOfTypeN(I, optypes); return CGOHasOperationsOfTypeN(I, optypes);
} }
bool CGOCheckWhetherToFree(PyMOLGlobals * G, CGO *I){ bool CGOCheckWhetherToFree(PyMOLGlobals * G, CGO *I){
if (I->use_shader){ if (I->use_shader){
skipping to change at line 9964 skipping to change at line 10053
* triangles. * triangles.
* *
* I: primitive CGO * I: primitive CGO
* return: new primitive CGO with normals on triangles * return: new primitive CGO with normals on triangles
*/ */
CGO *CGOGenerateNormalsForTriangles(const CGO * I){ CGO *CGOGenerateNormalsForTriangles(const CGO * I){
auto G = I->G; auto G = I->G;
auto cgo = CGONewSized(G, I->c); auto cgo = CGONewSized(G, I->c);
float vertices[3][3]; float vertices[3][3];
float current_color[3], colors[3][3]; float current_color[3] = {0.f, 0.f, 0.f}, colors[3][3];
float current_normal[3]; float current_normal[3];
float current_alpha, alphas[3]; float current_alpha = 0, alphas[3];
bool has_alpha = false; bool has_alpha = false;
bool has_color = false; bool has_color = false;
int mode = 0; int mode = 0;
bool inside_begin_triangles = false; bool inside_begin_triangles = false;
int current_i; int current_i = 0;
int vertex_count; int vertex_count = 0;
bool flip; bool flip = false;
bool emit; bool emit;
const int * indices;
const int indices_regular[] = {0, 1, 2}; const int indices_regular[] = {0, 1, 2};
const int indices_flipped[] = {0, 2, 1}; const int indices_flipped[] = {0, 2, 1};
for (auto it = I->begin(); !it.is_stop(); ++it) { for (auto it = I->begin(); !it.is_stop(); ++it) {
auto pc = it.data(); auto pc = it.data();
auto op = it.op_code(); auto op = it.op_code();
if (op == CGO_BEGIN) { if (op == CGO_BEGIN) {
mode = *reinterpret_cast<const int*>(pc); mode = *reinterpret_cast<const int*>(pc);
switch (mode) { switch (mode) {
case GL_TRIANGLE_STRIP: case GL_TRIANGLE_STRIP:
case GL_TRIANGLE_FAN: case GL_TRIANGLE_FAN:
case GL_TRIANGLES: case GL_TRIANGLES:
current_i = 0; current_i = 0;
vertex_count = 0; vertex_count = 0;
flip = false; flip = false;
indices = indices_regular;
inside_begin_triangles = true; inside_begin_triangles = true;
CGOBegin(cgo, GL_TRIANGLES); CGOBegin(cgo, GL_TRIANGLES);
continue; // for-loop, no add_to_cgo continue; // for-loop, no add_to_cgo
} }
inside_begin_triangles = false; inside_begin_triangles = false;
} else if (op == CGO_END) { } else if (op == CGO_END) {
inside_begin_triangles = false; inside_begin_triangles = false;
} }
skipping to change at line 10037 skipping to change at line 10124
case GL_TRIANGLE_FAN: case GL_TRIANGLE_FAN:
current_i = ((vertex_count + 1) % 2) + 1; current_i = ((vertex_count + 1) % 2) + 1;
emit = (vertex_count > 2); emit = (vertex_count > 2);
break; break;
default: default:
current_i = vertex_count % 3; current_i = vertex_count % 3;
emit = (current_i == 0); emit = (current_i == 0);
} }
if (emit) { if (emit) {
auto * indices = flip ? indices_flipped : indices_regular;
if (mode != GL_TRIANGLES) { if (mode != GL_TRIANGLES) {
indices = flip ? indices_flipped : indices_regular;
flip = !flip; flip = !flip;
} }
CalculateTriangleNormal(vertices[0], CalculateTriangleNormal(vertices[0],
vertices[indices[1]], vertices[indices[1]],
vertices[indices[2]], current_normal); vertices[indices[2]], current_normal);
CGONormalv(cgo, current_normal); CGONormalv(cgo, current_normal);
for (int j = 0; j < 3; ++j) { for (int j = 0; j < 3; ++j) {
skipping to change at line 10348 skipping to change at line 10436
cgo->current_pick_color_index = CGO_get_uint(pc); cgo->current_pick_color_index = CGO_get_uint(pc);
cgo->current_pick_color_bond = CGO_get_int(pc + 1); cgo->current_pick_color_bond = CGO_get_int(pc + 1);
CGOPickColor(cgo, cgo->current_pick_color_index, cgo->current_pick_color_b ond); CGOPickColor(cgo, cgo->current_pick_color_index, cgo->current_pick_color_b ond);
break; break;
case CGO_SHADER_CYLINDER: case CGO_SHADER_CYLINDER:
case CGO_SHADER_CYLINDER_WITH_2ND_COLOR: case CGO_SHADER_CYLINDER_WITH_2ND_COLOR:
case CGO_CYLINDER: case CGO_CYLINDER:
case CGO_CONE: case CGO_CONE:
case CGO_SAUSAGE: case CGO_SAUSAGE:
case CGO_CUSTOM_CYLINDER: case CGO_CUSTOM_CYLINDER:
case CGO_CUSTOM_CYLINDER_ALPHA:
case CGO_END: case CGO_END:
case CGO_VERTEX: case CGO_VERTEX:
case CGO_BEGIN: case CGO_BEGIN:
case CGO_ELLIPSOID: case CGO_ELLIPSOID:
case CGO_QUADRIC: case CGO_QUADRIC:
case CGO_DRAW_BUFFERS_INDEXED: case CGO_DRAW_BUFFERS_INDEXED:
case CGO_DRAW_BUFFERS_NOT_INDEXED: case CGO_DRAW_BUFFERS_NOT_INDEXED:
case CGO_DRAW_SPHERE_BUFFERS: case CGO_DRAW_SPHERE_BUFFERS:
case CGO_DRAW_CYLINDER_BUFFERS: case CGO_DRAW_CYLINDER_BUFFERS:
case CGO_DRAW_LABELS: case CGO_DRAW_LABELS:
skipping to change at line 10570 skipping to change at line 10659
pc += CGO_sz[op]; pc += CGO_sz[op];
} }
cgo->use_shader = I->use_shader; cgo->use_shader = I->use_shader;
if (cgo->use_shader){ if (cgo->use_shader){
cgo->cgo_shader_ub_color = SettingGetGlobal_i(cgo->G, cSetting_cgo_shader_ub _color); cgo->cgo_shader_ub_color = SettingGetGlobal_i(cgo->G, cSetting_cgo_shader_ub _color);
cgo->cgo_shader_ub_normal = SettingGetGlobal_i(cgo->G, cSetting_cgo_shader_u b_normal); cgo->cgo_shader_ub_normal = SettingGetGlobal_i(cgo->G, cSetting_cgo_shader_u b_normal);
} }
if (nLines){ if (nLines){
int ok = 1;
int err = 0; int err = 0;
glGenBuffers(1, &glbuff); glGenBuffers(1, &glbuff);
glBindBuffer(GL_ARRAY_BUFFER, glbuff); glBindBuffer(GL_ARRAY_BUFFER, glbuff);
glBufferData(GL_ARRAY_BUFFER, line_counter * 6 * 8 * sizeof(float), buffer_s tart, GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, line_counter * 6 * 8 * sizeof(float), buffer_s tart, GL_STATIC_DRAW);
free(buffer_start); free(buffer_start);
CHECK_GL_ERROR_OK("ERROR: CGOConvertLinesToTriangleStrips() glBindBuffer ret urns err=%d\n"); CHECK_GL_ERROR_OK("ERROR: CGOConvertLinesToTriangleStrips() glBindBuffer ret urns err=%d\n");
if (addshaders) if (addshaders)
CGOEnable(cgo, GL_TRILINES_SHADER); CGOEnable(cgo, GL_TRILINES_SHADER);
pc = CGO_add(cgo, CGO_DRAW_TRILINES_HEADER); pc = CGO_add(cgo, CGO_DRAW_TRILINES_HEADER);
skipping to change at line 10690 skipping to change at line 10778
case UINT_INT_TO_PICK_DATA: case UINT_INT_TO_PICK_DATA:
{ {
float *pcf = (float*)pc; float *pcf = (float*)pc;
unsigned int index = CGO_get_uint(pcf); unsigned int index = CGO_get_uint(pcf);
int bond = CGO_get_int(pcf+1); int bond = CGO_get_int(pcf+1);
CGO_put_uint(ord * 2 + pick_data, index); CGO_put_uint(ord * 2 + pick_data, index);
CGO_put_int(ord * 2 + pick_data + 1, bond); CGO_put_int(ord * 2 + pick_data + 1, bond);
has_pick_colorBS |= (1 << ord) ; has_pick_colorBS |= (1 << ord) ;
} }
break; break;
case FLOAT4_TO_UB4:
{
auto dataPtrUB = (unsigned char *)dataPtr;
float *pcf = (float*)pc;
dataPtrUB[0] = CLIP_COLOR_VALUE(pcf[0]);
dataPtrUB[1] = CLIP_COLOR_VALUE(pcf[1]);
dataPtrUB[2] = CLIP_COLOR_VALUE(pcf[2]);
dataPtrUB[3] = CLIP_COLOR_VALUE(pcf[3]);
}
break;
case CYL_CAP_TO_CAP: case CYL_CAP_TO_CAP:
{ {
unsigned char *dataPtrUB = (unsigned char *)dataPtr; unsigned char *dataPtrUB = (unsigned char *)dataPtr;
dataPtrUB[0] = *pc; dataPtrUB[0] = *pc;
} }
break; break;
case CYL_CAPS_ARE_ROUND: case CYL_CAPS_ARE_ROUND:
{ {
unsigned char *dataPtrUB = (unsigned char *)dataPtr; unsigned char *dataPtrUB = (unsigned char *)dataPtr;
dataPtrUB[0] = cCylShaderBothCapsRound | cCylShaderInterpColor; dataPtrUB[0] = cCylShaderBothCapsRound | cCylShaderInterpColor;
skipping to change at line 10893 skipping to change at line 10991
} }
} }
has_picking = allAttrIdxUsed & (1 << attrIdx); // has_picking if the last bit is set has_picking = allAttrIdxUsed & (1 << attrIdx); // has_picking if the last bit is set
if (allAttrIdxUsed != totAttrIdx){ if (allAttrIdxUsed != totAttrIdx){
// go through any attributes that aren't used: // go through any attributes that aren't used:
// - add associated vertex_attribute type (if default_value is set) // - add associated vertex_attribute type (if default_value is set)
// - remove attribute from attrData description so that it isn't included in VBO // - remove attribute from attrData description so that it isn't included in VBO
AttribDataDesc attrDataNew; AttribDataDesc attrDataNew;
for (auto idx = 0; idx < attrIdx; ++idx){ for (auto idx = 0; idx < attrIdx; ++idx){
if (!attrData[idx].repeat_value && (!allAttrIdxUsed & (1 << idx))){ if (!attrData[idx].repeat_value && !(allAttrIdxUsed & (1 << idx))) {
// attribute not used, need to create glVertexAttrib // attribute not used, need to create glVertexAttrib
if (attrData[idx].default_value){ if (attrData[idx].default_value){
// need to add glVertexAttrib CGO OP // need to add glVertexAttrib CGO OP
int attr_lookup_idx = I->G->ShaderMgr->GetAttributeUID(attrData[idx].a ttr_name); int attr_lookup_idx = I->G->ShaderMgr->GetAttributeUID(attrData[idx].a ttr_name);
switch (attrData[idx].type_size){ switch (attrData[idx].type_size){
case GL_FLOAT: case GL_FLOAT:
switch (attrData[idx].type_dim){ switch (attrData[idx].type_dim){
case 1: case 1:
cgo->add<cgo::draw::vertex_attribute_1f>(attr_lookup_idx, *(float* )attrData[idx].default_value); cgo->add<cgo::draw::vertex_attribute_1f>(attr_lookup_idx, *(float* )attrData[idx].default_value);
break; break;
skipping to change at line 11272 skipping to change at line 11370
} }
pick_data += 2; pick_data += 2;
} }
} else { } else {
pick_data += pstride; pick_data += pstride;
} }
has_pick_colorBS = 0; has_pick_colorBS = 0;
if (!nvert && attrBS!=allAttrBS){ if (!nvert && attrBS!=allAttrBS){
// for the first vertex, all attributes should be set // for the first vertex, all attributes should be set
for (auto idx = 0; idx < attrData.size(); ++idx){ for (auto idx = 0; idx < attrData.size(); ++idx){
if (!attrBS & (1 << idx)){ if (!(attrBS & (1 << idx))) {
if (!attrData[idx].default_value){ if (!attrData[idx].default_value){
std::cerr << "WARNING: attribute #" << idx << " not set for fi std::cerr << "WARNING: attribute #" << idx <<
rst vertex and does not have default value: allAttrBS=" << allAttrBS << " attrBS " (" << attrData[idx].attr_name << ") not set for first"
=" << attrBS << std::endl; " vertex and does not have default value" << std::endl;
} }
} }
} }
} }
if (nvert && attrBS!=allAttrBS){ if (nvert && attrBS!=allAttrBS){
// for each vertex that hasn't been written for the current vertex, copy it from the previous vertex // for each vertex that hasn't been written for the current vertex, copy it from the previous vertex
for (auto idx = 0; idx < attrData.size(); ++idx){ for (auto idx = 0; idx < attrData.size(); ++idx){
if (!attrBS & (1 << idx)){ if (!(attrBS & (1 << idx))) {
copyAttributeForVertex(isInterleaved, nvert, attrData[idx], vert exDataSize, dataPtrs, attrOffset); copyAttributeForVertex(isInterleaved, nvert, attrData[idx], vert exDataSize, dataPtrs, attrOffset);
} }
} }
} }
attrBS = 0; attrBS = 0;
// creating new vertices, all attribute data should be copied into new vertex. // creating new vertices, all attribute data should be copied into new vertex.
for (int nxt = 0; nxt < attribOp->incr_vertices; ++nxt){ for (int nxt = 0; nxt < attribOp->incr_vertices; ++nxt){
/* for now, always copy values from previous */ /* for now, always copy values from previous */
++nvert; ++nvert;
skipping to change at line 11354 skipping to change at line 11454
/* Generate Pick Buffers with all pick attributes (if necessary) */ /* Generate Pick Buffers with all pick attributes (if necessary) */
if (pickvbo){ if (pickvbo){
BufferDataDesc pickBufferData; BufferDataDesc pickBufferData;
for (int i=0; i < npickcolattr; i++){ for (int i=0; i < npickcolattr; i++){
for (auto &pickDesc : pickData){ for (auto &pickDesc : pickData){
int pickSize = gl_sizeof(pickDesc.type_size) * pickDesc.type_dim; int pickSize = gl_sizeof(pickDesc.type_size) * pickDesc.type_dim;
pickBufferData.push_back(BufferDesc(pickDesc.attr_name, pickDesc.type_si ze, pickBufferData.push_back(BufferDesc(pickDesc.attr_name, pickDesc.type_si ze,
pickDesc.type_dim, pickSize * nvert, NULL, pickDesc.data_norm)); pickDesc.type_dim, pickSize * nvert, NULL, pickDesc.data_norm));
} }
} }
pickvbo->bufferData(BufferDataDesc(pickBufferData)); pickvbo->bufferData(std::move(pickBufferData));
} }
/* Generate VBO Buffers with all pick attributes based on the VertexBuffer typ e SEPARATE/SEQUENTIAL/INTERLEAVED*/ /* Generate VBO Buffers with all pick attributes based on the VertexBuffer typ e SEPARATE/SEQUENTIAL/INTERLEAVED*/
BufferDataDesc bufferData; BufferDataDesc bufferData;
switch (layout){ switch (layout){
case VertexBuffer::SEPARATE: case VertexBuffer::SEPARATE:
case VertexBuffer::SEQUENTIAL: case VertexBuffer::SEQUENTIAL:
{ {
auto attrDataIt = attrData.begin(); auto attrDataIt = attrData.begin();
auto dataPtrIt = dataPtrs.begin(); auto dataPtrIt = dataPtrs.begin();
auto attrSizeIt = attrSizes.begin(); auto attrSizeIt = attrSizes.begin();
for (; attrDataIt!=attrData.end() && for (; attrDataIt!=attrData.end() &&
dataPtrIt!=dataPtrs.end() && dataPtrIt!=dataPtrs.end() &&
attrSizeIt!=attrSizes.end(); ++attrDataIt, ++dataPtrIt, ++attrSiz eIt){ attrSizeIt!=attrSizes.end(); ++attrDataIt, ++dataPtrIt, ++attrSiz eIt){
auto attrDesc = &(*attrDataIt); auto attrDesc = &(*attrDataIt);
auto dataPtr = *dataPtrIt; auto dataPtr = *dataPtrIt;
auto attrSize = *attrSizeIt; auto attrSize = *attrSizeIt;
bufferData.push_back(BufferDesc(attrDesc->attr_name, attrDesc->type_size , bufferData.push_back(BufferDesc(attrDesc->attr_name, attrDesc->type_size ,
attrDesc->type_dim, nvert * attrSize, da taPtr, attrDesc->data_norm)); attrDesc->type_dim, nvert * attrSize, da taPtr, attrDesc->data_norm));
} }
vbo->bufferData(BufferDataDesc(bufferData)); vbo->bufferData(std::move(bufferData));
break; break;
} }
break; break;
case VertexBuffer::INTERLEAVED: case VertexBuffer::INTERLEAVED:
{ {
auto attrDataIt = attrData.begin(); auto attrDataIt = attrData.begin();
auto attrOffsetIt = attrOffset.begin(); auto attrOffsetIt = attrOffset.begin();
for (; attrDataIt!=attrData.end() && attrOffsetIt!=attrOffset.end(); ++att rDataIt, ++attrOffsetIt){ for (; attrDataIt!=attrData.end() && attrOffsetIt!=attrOffset.end(); ++att rDataIt, ++attrOffsetIt){
auto attrDesc = &(*attrDataIt); auto attrDesc = &(*attrDataIt);
auto offset = *attrOffsetIt; auto offset = *attrOffsetIt;
bufferData.push_back(BufferDesc(attrDesc->attr_name, attrDesc->type_size , bufferData.push_back(BufferDesc(attrDesc->attr_name, attrDesc->type_size ,
attrDesc->type_dim, offset, attrDesc->da ta_norm)); attrDesc->type_dim, offset, attrDesc->da ta_norm));
} }
vbo->bufferData(BufferDataDesc(bufferData), (const void *)allData, vbo->bufferData(std::move(bufferData), (const void *)allData,
(size_t)(nvert*vertexDataSize), (size_t)vertexDataSize); (size_t)(nvert*vertexDataSize), (size_t)vertexDataSize);
break; break;
} }
} }
free(allData); free(allData);
CGOStop(cgo); CGOStop(cgo);
return cgo; return cgo;
} }
skipping to change at line 11461 skipping to change at line 11561
case cgo::draw::custom_cylinder::op_code: case cgo::draw::custom_cylinder::op_code:
{ {
auto cc = it.cast<cgo::draw::custom_cylinder>(); auto cc = it.cast<cgo::draw::custom_cylinder>();
int cap1 = (int) cc->cap1; int cap1 = (int) cc->cap1;
int cap2 = (int) cc->cap2; int cap2 = (int) cc->cap2;
cap_value = ((cap1 == 1) ? cCylShaderCap1Flat : (cap1 == 2) ? cCylShader Cap1Round : cCylCapNone) | cap_value = ((cap1 == 1) ? cCylShaderCap1Flat : (cap1 == 2) ? cCylShader Cap1Round : cCylCapNone) |
((cap2 == 1) ? cCylShaderCap2Flat : (cap2 == 2) ? cCylShader Cap2Round : cCylCapNone) | ((cap2 == 1) ? cCylShaderCap2Flat : (cap2 == 2) ? cCylShader Cap2Round : cCylCapNone) |
cCylShaderInterpColor; cCylShaderInterpColor;
} }
break; break;
case cgo::draw::custom_cylinder_alpha::op_code:
{
auto cc = it.cast<cgo::draw::custom_cylinder_alpha>();
int cap1 = (int) cc->cap1;
int cap2 = (int) cc->cap2;
cap_value = ((cap1 == 1) ? cCylShaderCap1Flat : (cap1 == 2) ? cCylShader
Cap1Round : cCylCapNone) |
((cap2 == 1) ? cCylShaderCap2Flat : (cap2 == 2) ? cCylShader
Cap2Round : cCylCapNone) |
cCylShaderInterpColor;
}
break;
default: default:
continue; continue;
} }
if (!cap_value_first_is_set) { if (!cap_value_first_is_set) {
cap_value_first = cap_value; cap_value_first = cap_value;
cap_value_first_is_set = true; cap_value_first_is_set = true;
} else if (cap_value != cap_value_first) { } else if (cap_value != cap_value_first) {
return false; return false;
} }
skipping to change at line 11839 skipping to change at line 11949
static unsigned char uv_bits[] = { 1, 3, 0, 3, 2, 1 }; static unsigned char uv_bits[] = { 1, 3, 0, 3, 2, 1 };
uvdesc->repeat_value = uv_bits; uvdesc->repeat_value = uv_bits;
addTo->add<cgo::draw::vertex_attribute_1f>(G->ShaderMgr->GetAttributeUID("a_in terpolate"), 0.f); addTo->add<cgo::draw::vertex_attribute_1f>(G->ShaderMgr->GetAttributeUID("a_in terpolate"), 0.f);
return CGOConvertToShader(I, attrDesc, pickDesc, GL_TRIANGLES, VertexBuffer::I NTERLEAVED); return CGOConvertToShader(I, attrDesc, pickDesc, GL_TRIANGLES, VertexBuffer::I NTERLEAVED);
} }
cgo::draw::shadercylinder2ndcolor::shadercylinder2ndcolor(CGO *I, const float *_ origin, cgo::draw::shadercylinder2ndcolor::shadercylinder2ndcolor(CGO *I, const float *_ origin,
const float *_axis, co nst float _tube_size, const float *_axis, co nst float _tube_size,
int _cap, const float int _cap, const float
*_color2, Pickable *pickcolor2) : *_color2, Pickable *pickcolor2,
tube_size(_tube_size) { const float _alpha) :
tube_size(_tube_size), alpha(_alpha) {
copy3f(_origin, origin); copy3f(_origin, origin);
copy3f(_axis, axis); copy3f(_axis, axis);
cap = _cap; cap = _cap;
copy3f(_color2, color2); copy3f(_color2, color2);
if (pickcolor2){ if (pickcolor2){
I->current_pick_color_index = pick_color_index = pickcolor2->index; I->current_pick_color_index = pick_color_index = pickcolor2->index;
I->current_pick_color_bond = pick_color_bond = pickcolor2->bond; I->current_pick_color_bond = pick_color_bond = pickcolor2->bond;
} else { } else {
pick_color_index = I->current_pick_color_index; pick_color_index = I->current_pick_color_index;
pick_color_bond = I->current_pick_color_bond; pick_color_bond = I->current_pick_color_bond;
skipping to change at line 11877 skipping to change at line 11988
CGO *CGOConvertShaderCylindersToCylinderShader(const CGO *I, CGO *addTo){ CGO *CGOConvertShaderCylindersToCylinderShader(const CGO *I, CGO *addTo){
/* Lines that pass in two vertices per line */ /* Lines that pass in two vertices per line */
PyMOLGlobals *G = I->G; PyMOLGlobals *G = I->G;
// TODO: NEED TO ADD: CGO_CUSTOM_CYLINDER and CGO_CYLINDER // TODO: NEED TO ADD: CGO_CUSTOM_CYLINDER and CGO_CYLINDER
AttribDataOp vertex1Ops = AttribDataOp vertex1Ops =
{ { CGO_SHADER_CYLINDER, 1, FLOAT3_TO_FLOAT3, offsetof( cgo::draw::shadercylinder, origin), 0 }, { { CGO_SHADER_CYLINDER, 1, FLOAT3_TO_FLOAT3, offsetof( cgo::draw::shadercylinder, origin), 0 },
{ CGO_SHADER_CYLINDER_WITH_2ND_COLOR, 1, FLOAT3_TO_FLOAT3, offsetof( cgo::draw::shadercylinder2ndcolor, origin), 0 }, { CGO_SHADER_CYLINDER_WITH_2ND_COLOR, 1, FLOAT3_TO_FLOAT3, offsetof( cgo::draw::shadercylinder2ndcolor, origin), 0 },
{ CGO_SAUSAGE, 1, FLOAT3_TO_FLOAT3, offsetof( cgo::draw::sausage, vertex1), 0 }, { CGO_SAUSAGE, 1, FLOAT3_TO_FLOAT3, offsetof( cgo::draw::sausage, vertex1), 0 },
{ CGO_CYLINDER, 1, FLOAT3_TO_FLOAT3, offsetof( cgo::draw::cylinder, vertex1), 0 }, { CGO_CYLINDER, 1, FLOAT3_TO_FLOAT3, offsetof( cgo::draw::cylinder, vertex1), 0 },
{ CGO_CUSTOM_CYLINDER, 1, FLOAT3_TO_FLOAT3, offsetof( { CGO_CUSTOM_CYLINDER, 1, FLOAT3_TO_FLOAT3, offsetof(
cgo::draw::custom_cylinder, vertex1), 0 } }; cgo::draw::custom_cylinder, vertex1), 0 },
{ CGO_CUSTOM_CYLINDER_ALPHA, 1, FLOAT3_TO_FLOAT3, offsetof(
cgo::draw::custom_cylinder_alpha, vertex1), 0 } };
AttribDataOp vertex2Ops = AttribDataOp vertex2Ops =
{ { CGO_SHADER_CYLINDER, 5, FLOAT3_TO_FLOAT3, offsetof( cgo::draw::shadercylinder, axis), 8 }, { { CGO_SHADER_CYLINDER, 5, FLOAT3_TO_FLOAT3, offsetof( cgo::draw::shadercylinder, axis), 8 },
{ CGO_SHADER_CYLINDER_WITH_2ND_COLOR, 6, FLOAT3_TO_FLOAT3, offsetof( cgo::draw::shadercylinder2ndcolor, axis), 8 }, { CGO_SHADER_CYLINDER_WITH_2ND_COLOR, 6, FLOAT3_TO_FLOAT3, offsetof( cgo::draw::shadercylinder2ndcolor, axis), 8 },
{ CGO_SAUSAGE, 6, FLOAT3_TO_FLOAT3, offsetof( cgo::draw::sausage, vertex2), 8 }, { CGO_SAUSAGE, 6, FLOAT3_TO_FLOAT3, offsetof( cgo::draw::sausage, vertex2), 8 },
{ CGO_CYLINDER, 6, FLOAT3_TO_FLOAT3, offsetof( cgo::draw::cylinder, vertex2), 8 }, { CGO_CYLINDER, 6, FLOAT3_TO_FLOAT3, offsetof( cgo::draw::cylinder, vertex2), 8 },
{ CGO_CUSTOM_CYLINDER, 6, FLOAT3_TO_FLOAT3, offsetof( { CGO_CUSTOM_CYLINDER, 6, FLOAT3_TO_FLOAT3, offsetof(
cgo::draw::custom_cylinder, vertex2), 8 } }; cgo::draw::custom_cylinder, vertex2), 8 },
{ CGO_CUSTOM_CYLINDER_ALPHA, 6, FLOAT3_TO_FLOAT3, offsetof(
cgo::draw::custom_cylinder_alpha, vertex2), 8 } };
static AttribDataOp colorOps = static AttribDataOp colorOps =
{ { CGO_COLOR, 0, FLOAT3_TO_UB3, 0 }, { { CGO_COLOR, 0, FLOAT3_TO_UB3, 0 },
{ CGO_ALPHA, 0, FLOAT1_TO_UB_4TH, 0 }, { CGO_ALPHA, 0, FLOAT1_TO_UB_4TH, 0 },
{ CGO_SAUSAGE, 4, FLOAT3_TO_UB3, offsetof( cgo::draw::sausage, color1) }, { CGO_SAUSAGE, 4, FLOAT3_TO_UB3, offsetof( cgo::draw::sausage, color1) },
{ CGO_CYLINDER, 4, FLOAT3_TO_UB3, offsetof( cgo::draw::cylinder, color1) }, { CGO_CYLINDER, 4, FLOAT3_TO_UB3, offsetof( cgo::draw::cylinder, color1) },
{ CGO_CUSTOM_CYLINDER, 4, FLOAT3_TO_UB3, offsetof( { CGO_CUSTOM_CYLINDER, 4, FLOAT3_TO_UB3, offsetof(
cgo::draw::custom_cylinder, color1) } }; cgo::draw::custom_cylinder, color1) },
{ CGO_CUSTOM_CYLINDER_ALPHA, 4, FLOAT4_TO_UB4, offsetof(
cgo::draw::custom_cylinder_alpha, color1) } };
static AttribDataOp color2Ops = static AttribDataOp color2Ops =
{ { CGO_COLOR, 1, FLOAT3_TO_UB3, 0 }, { { CGO_COLOR, 1, FLOAT3_TO_UB3, 0 },
{ CGO_ALPHA, 1, FLOAT1_TO_UB_4TH, 0 }, { CGO_ALPHA, 1, FLOAT1_TO_UB_4TH, 0 },
{ CGO_SHADER_CYLINDER_WITH_2ND_COLOR, 2, FLOAT3_TO_UB3, offsetof( cgo::draw::shadercylinder2ndcolor, color2) }, { CGO_SHADER_CYLINDER_WITH_2ND_COLOR, 2, FLOAT3_TO_UB3, offsetof( cgo::draw::shadercylinder2ndcolor, color2) },
{ CGO_SAUSAGE, 5, FLOAT3_TO_UB3, offsetof( cgo::draw::sausage, color2) }, { CGO_SAUSAGE, 5, FLOAT3_TO_UB3, offsetof( cgo::draw::sausage, color2) },
{ CGO_CYLINDER, 5, FLOAT3_TO_UB3, offsetof( cgo::draw::cylinder, color2) }, { CGO_CYLINDER, 5, FLOAT3_TO_UB3, offsetof( cgo::draw::cylinder, color2) },
{ CGO_CUSTOM_CYLINDER, 5, FLOAT3_TO_UB3, offsetof( { CGO_CUSTOM_CYLINDER, 5, FLOAT3_TO_UB3, offsetof(
cgo::draw::custom_cylinder, color2) } }; cgo::draw::custom_cylinder, color2) },
{ CGO_CUSTOM_CYLINDER_ALPHA, 5, FLOAT4_TO_UB4, offsetof(
cgo::draw::custom_cylinder_alpha, color2) } };
AttribDataOp radiusOps = AttribDataOp radiusOps =
{ { CGO_SHADER_CYLINDER, 2, FLOAT_TO_FLOAT, offsetof( cgo::draw::shadercylinder, tube_size), 0 }, { { CGO_SHADER_CYLINDER, 2, FLOAT_TO_FLOAT, offsetof( cgo::draw::shadercylinder, tube_size), 0 },
{ CGO_SHADER_CYLINDER_WITH_2ND_COLOR, 3, FLOAT_TO_FLOAT, offsetof( cgo::draw::shadercylinder2ndcolor, tube_size), 0 }, { CGO_SHADER_CYLINDER_WITH_2ND_COLOR, 3, FLOAT_TO_FLOAT, offsetof( cgo::draw::shadercylinder2ndcolor, tube_size), 0 },
{ CGO_SAUSAGE, 3, FLOAT_TO_FLOAT, offsetof( cgo::draw::sausage, radius), 0 }, { CGO_SAUSAGE, 3, FLOAT_TO_FLOAT, offsetof( cgo::draw::sausage, radius), 0 },
{ CGO_CYLINDER, 3, FLOAT_TO_FLOAT, offsetof( cgo::draw::cylinder, radius), 0 }, { CGO_CYLINDER, 3, FLOAT_TO_FLOAT, offsetof( cgo::draw::cylinder, radius), 0 },
{ CGO_CUSTOM_CYLINDER, 3, FLOAT_TO_FLOAT, offsetof( { CGO_CUSTOM_CYLINDER, 3, FLOAT_TO_FLOAT, offsetof(
cgo::draw::custom_cylinder, radius), 0 } }; cgo::draw::custom_cylinder, radius), 0 },
{ CGO_CUSTOM_CYLINDER_ALPHA, 3, FLOAT_TO_FLOAT, offsetof(
cgo::draw::custom_cylinder_alpha, radius), 0 } };
AttribDataDesc attrDesc = { { "attr_vertex1", GL_FLOAT, 3, GL_FALSE, v ertex1Ops }, AttribDataDesc attrDesc = { { "attr_vertex1", GL_FLOAT, 3, GL_FALSE, v ertex1Ops },
{ "attr_vertex2", GL_FLOAT, 3, GL_FALSE, v ertex2Ops }, { "attr_vertex2", GL_FLOAT, 3, GL_FALSE, v ertex2Ops },
{ "a_Color", GL_UNSIGNED_BYTE, 4, GL_TRUE, color Ops }, { "a_Color", GL_UNSIGNED_BYTE, 4, GL_TRUE, color Ops },
{ "a_Color2", GL_UNSIGNED_BYTE, 4, GL_TRUE, color 2Ops }, { "a_Color2", GL_UNSIGNED_BYTE, 4, GL_TRUE, color 2Ops },
{ "attr_radius", GL_FLOAT, 1, GL_FALSE, r adiusOps } }; { "attr_radius", GL_FLOAT, 1, GL_FALSE, r adiusOps } };
AttribDesc *fdesc; AttribDesc *fdesc;
static unsigned char cyl_flags[] = { 0, 4, 6, 2, 1, 5, 7, 3 }; // right(4)/up( 2)/out(1) static unsigned char cyl_flags[] = { 0, 4, 6, 2, 1, 5, 7, 3 }; // right(4)/up( 2)/out(1)
attrDesc[1].attrOps[0].funcDataConversions.push_back( { SetVertexFromOriginAxi sForCylinder, NULL, "attr_vertex2" } ); attrDesc[1].attrOps[0].funcDataConversions.push_back( { SetVertexFromOriginAxi sForCylinder, NULL, "attr_vertex2" } );
skipping to change at line 11945 skipping to change at line 12061
unsigned char cap_value = 0; unsigned char cap_value = 0;
if ((interp_same = CGOCheckShaderCylinderCapInfoIsSame(I, cap_value))){ if ((interp_same = CGOCheckShaderCylinderCapInfoIsSame(I, cap_value))){
addTo->add<cgo::draw::vertex_attribute_1f>(G->ShaderMgr->GetAttributeUID("a_ cap"), cap_value ); addTo->add<cgo::draw::vertex_attribute_1f>(G->ShaderMgr->GetAttributeUID("a_ cap"), cap_value );
} else { } else {
AttribDataOp interpOps = AttribDataOp interpOps =
{ { CGO_SHADER_CYLINDER, 3, CYL_CAP_TO_CAP, offsetof(c go::draw::shadercylinder, cap), 0 }, { { CGO_SHADER_CYLINDER, 3, CYL_CAP_TO_CAP, offsetof(c go::draw::shadercylinder, cap), 0 },
{ CGO_SHADER_CYLINDER_WITH_2ND_COLOR, 4, CYL_CAP_TO_CAP, offsetof(c go::draw::shadercylinder2ndcolor, cap), 0 }, { CGO_SHADER_CYLINDER_WITH_2ND_COLOR, 4, CYL_CAP_TO_CAP, offsetof(c go::draw::shadercylinder2ndcolor, cap), 0 },
{ CGO_SAUSAGE, 2, CYL_CAPS_ARE_ROUND, 0, 0 }, { CGO_SAUSAGE, 2, CYL_CAPS_ARE_ROUND, 0, 0 },
{ CGO_CYLINDER, 2, CYL_CAPS_ARE_FLAT, 0, 0 }, { CGO_CYLINDER, 2, CYL_CAPS_ARE_FLAT, 0, 0 },
{ CGO_CUSTOM_CYLINDER, 2, CYL_CAPS_ARE_CUSTOM, offsetof(c go::draw::custom_cylinder, cap1), 0 }, { CGO_CUSTOM_CYLINDER, 2, CYL_CAPS_ARE_CUSTOM, offsetof(c go::draw::custom_cylinder, cap1), 0 },
{ CGO_CUSTOM_CYLINDER_ALPHA, 2, CYL_CAPS_ARE_CUSTOM, offsetof(c go::draw::custom_cylinder_alpha, cap1), 0 },
}; };
attrDesc.push_back({ "a_cap", GL_UNSIGNED_BYTE, 1, GL_FALSE, interpOps } ); attrDesc.push_back({ "a_cap", GL_UNSIGNED_BYTE, 1, GL_FALSE, interpOps } );
} }
AttribDataOp extraPickColorOps = { { CGO_PICK_COLOR, 1, UINT_INT_TO_PICK_DATA, 0, 0 }, AttribDataOp extraPickColorOps = { { CGO_PICK_COLOR, 1, UINT_INT_TO_PICK_DATA, 0, 0 },
{ CGO_SHADER_CYLINDER_WITH_2ND_COLOR, 8, U INT_INT_TO_PICK_DATA, offsetof(cgo::draw::shadercylinder2ndcolor, pick_color_ind ex), 0 } }; { CGO_SHADER_CYLINDER_WITH_2ND_COLOR, 8, U INT_INT_TO_PICK_DATA, offsetof(cgo::draw::shadercylinder2ndcolor, pick_color_ind ex), 0 } };
AttribDataOp extraPickColor2Ops = { { CGO_PICK_COLOR, 2, UINT_INT_TO_PICK_DATA , 0, 0 }, AttribDataOp extraPickColor2Ops = { { CGO_PICK_COLOR, 2, UINT_INT_TO_PICK_DATA , 0, 0 },
{ CGO_SHADER_CYLINDER_WITH_2ND_COLOR, 5, UINT_INT_TO_PICK_DATA, offsetof(cgo::draw::shadercylinder2ndcolor, pick_color_in dex), 0 } }; { CGO_SHADER_CYLINDER_WITH_2ND_COLOR, 5, UINT_INT_TO_PICK_DATA, offsetof(cgo::draw::shadercylinder2ndcolor, pick_color_in dex), 0 } };
AttribDataDesc pickDesc = { { "a_Color", GL_UNSIGNED_BYTE, 4, GL_TRUE, extraP ickColorOps }, AttribDataDesc pickDesc = { { "a_Color", GL_UNSIGNED_BYTE, 4, GL_TRUE, extraP ickColorOps },
{ "a_Color2", GL_UNSIGNED_BYTE, 4, GL_TRUE, extraP ickColor2Ops }}; { "a_Color2", GL_UNSIGNED_BYTE, 4, GL_TRUE, extraP ickColor2Ops }};
 End of changes. 113 change blocks. 
126 lines changed or deleted 255 lines changed or added

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