"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "layer1/CGO.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.

CGO.cpp  (pymol-v2.1.0.tar.bz2):CGO.cpp  (pymol-open-source-2.2.0)
skipping to change at line 37 skipping to change at line 37
#include"Setting.h" #include"Setting.h"
#include"Sphere.h" #include"Sphere.h"
#include"PConv.h" #include"PConv.h"
#include"GadgetSet.h" #include"GadgetSet.h"
#include"VFont.h" #include"VFont.h"
#include"P.h" #include"P.h"
#include"PyMOLGlobals.h" #include"PyMOLGlobals.h"
#include"Ray.h" #include"Ray.h"
#include"Util.h" #include"Util.h"
#include"Scene.h" #include"Scene.h"
#include"ScenePicking.h"
#include"Matrix.h" #include"Matrix.h"
#include"ShaderMgr.h" #include"ShaderMgr.h"
#include"CoordSet.h" #include"CoordSet.h"
#include"Rep.h" #include"Rep.h"
#include"Vector.h"
#include"ObjectGadgetRamp.h"
#include"Triangle.h"
#if defined(_PYMOL_IOS) && !defined(_WEBGL)
#define ALIGN_VBOS_TO_4_BYTE_ARRAYS
#define VAR_FOR_NORMAL plc
#define VAR_FOR_NORMAL_CNT_PLUS + (cnt / 3)
#define VERTEX_NORMAL_SIZE 4
#else
#define VAR_FOR_NORMAL pl #define VAR_FOR_NORMAL pl
#define VERTEX_NORMAL_SIZE 3 #define VERTEX_NORMAL_SIZE 3
#define VAR_FOR_NORMAL_CNT_PLUS #define VAR_FOR_NORMAL_CNT_PLUS
#endif
#define VALUES_PER_IMPOSTER_SPACE_COORD 1
#if defined(PURE_OPENGL_ES_2)
#define VERTICES_PER_SPHERE 6
#else
#define VERTICES_PER_SPHERE 4
#endif
#if defined(_PYMOL_IOS) && !defined(_WEBGL)
#define NUM_VERTICES_PER_CYLINDER 4
#define NUM_TOTAL_VERTICES_PER_CYLINDER 6
#else
#define NUM_VERTICES_PER_CYLINDER 8
#define NUM_TOTAL_VERTICES_PER_CYLINDER 36
#endif
#ifdef PURE_OPENGL_ES_2
#define glVertexAttrib4ubv(loc, data) glVertexAttrib4f(loc, \
(data)[0] / 255.f, (data)[1] / 255.f, (data)[2] / 255.f, (data)[3] / 255.f);
#endif
#include <iostream>
#include <algorithm>
using namespace std;
#define MAX_INDICES_FOR_IOS 65536
#define CLIP_COLOR_VALUE(cv) (uchar)((cv>1.f) ? 255 : (cv < 0.f) ? 0 : pymol_r const float g_ones4f[4] = {1.f, 1.f, 1.f, 1.f};
oundf(cv * 255) )
#define CLIP_NORMAL_VALUE(cv) (uchar)((cv>1.f) ? 127 : (cv < -1.f) ? -128 : py
mol_roundf(((cv + 1.f)/2.f) * 255) - 128 )
template <typename T>
inline T CLAMPVALUE(T val, T minimum, T maximum) {
return
(val < minimum) ? minimum :
(val > maximum) ? maximum : val;
}
#if defined(_PYMOL_IOS) && !defined(_WEBGL)
extern "C" void firePyMOLLimitationWarning();
#define CHECK_GL_ERROR_OK(printstr) \
if ((err = glGetError())!=0 || I->G->Interrupt != 0){ \
if (err) \
PRINTFB(I->G, FB_CGO, FB_Errors) printstr, err ENDFB(I->G); \
ok = false; \
}
#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
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 isPicking; short sphere_quality;
short use_shader; bool isPicking;
short debug; bool pick_mode; // bit 1 of (*pick)[0].src.bond 0 - first pass, 1 - second pas
short enable_shaders; s
bool use_shader; // OpenGL 1.4+, e.g., glEnableVertexAttribArray() (on) vs. gl
EnableClientState() (off)
bool debug;
bool picking_32bit;
CSetting *set1, *set2; CSetting *set1, *set2;
}; };
static
void set_current_pick_color(
CGO * cgo,
Picking * p,
const PickContext * context,
unsigned int idx,
int bnd)
{
p->context = (*context);
p->src.index = idx;
p->src.bond = bnd; // actually holds state information
if (cgo) {
cgo->current_pick_color_index = idx;
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){
i++;
if(!((*pick)[0].src.bond & 1)) {
/* pass 1 - low order bits */
color[0] = (uchar)((i & 0xF) << 4);
color[1] = (uchar)((i & 0xF0) | 0x8);
color[2] = (uchar)((i & 0xF00) >> 4);
VLACheck((*pick), Picking, i);
set_current_pick_color(cgo, (*pick) + i, context, index, bond);
} else {
int j = i >> 12;
color[0] = (uchar)((j & 0xF) << 4);
color[1] = (uchar)((j & 0xF0) | 0x8);
color[2] = (uchar)((j & 0xF00) >> 4);
}
color[3] = 255;
return true;
}
static
int CGOConvertDebugMode(int debug, int modeArg){ int CGOConvertDebugMode(int debug, int modeArg){
int mode = modeArg; int mode = modeArg;
if (debug==1){ if (debug==1){
switch (mode){ switch (mode){
case GL_TRIANGLES: case GL_TRIANGLES:
mode = GL_LINES; mode = GL_LINES;
break; break;
case GL_TRIANGLE_STRIP: case GL_TRIANGLE_STRIP:
mode = GL_LINE_STRIP; mode = GL_LINE_STRIP;
break; break;
skipping to change at line 118 skipping to change at line 213
CGO_NULL_SZ, CGO_NULL_SZ,
CGO_BEGIN_SZ, CGO_BEGIN_SZ,
CGO_END_SZ, CGO_END_SZ,
CGO_VERTEX_SZ, CGO_VERTEX_SZ,
CGO_NORMAL_SZ, CGO_NORMAL_SZ,
CGO_COLOR_SZ, CGO_COLOR_SZ,
CGO_SPHERE_SZ, CGO_SPHERE_SZ,
CGO_TRIANGLE_SZ, CGO_TRIANGLE_SZ,
CGO_CYLINDER_SZ, fsizeof<cgo::draw::cylinder>(),
CGO_LINEWIDTH_SZ, CGO_LINEWIDTH_SZ,
CGO_WIDTHSCALE_SZ, CGO_WIDTHSCALE_SZ,
CGO_ENABLE_SZ, CGO_ENABLE_SZ,
CGO_DISABLE_SZ, CGO_DISABLE_SZ,
CGO_SAUSAGE_SZ, fsizeof<cgo::draw::sausage>(),
CGO_CUSTOM_CYLINDER_SZ, fsizeof<cgo::draw::custom_cylinder>(),
CGO_DOTWIDTH_SZ, CGO_DOTWIDTH_SZ,
CGO_ALPHA_TRIANGLE_SZ, CGO_ALPHA_TRIANGLE_SZ,
CGO_ELLIPSOID_SZ, CGO_ELLIPSOID_SZ,
CGO_FONT_SZ, CGO_FONT_SZ,
CGO_FONT_SCALE_SZ, CGO_FONT_SCALE_SZ,
CGO_FONT_VERTEX_SZ, CGO_FONT_VERTEX_SZ,
CGO_FONT_AXES_SZ, CGO_FONT_AXES_SZ,
CGO_CHAR_SZ, CGO_CHAR_SZ,
CGO_INDENT_SZ, CGO_INDENT_SZ,
CGO_ALPHA_SZ, CGO_ALPHA_SZ,
CGO_QUADRIC_SZ, CGO_QUADRIC_SZ,
CGO_CONE_SZ, CGO_CONE_SZ,
CGO_DRAW_ARRAYS_SZ, fsizeof<cgo::draw::arrays>(),
CGO_NULL_SZ, CGO_NULL_SZ,
CGO_RESET_NORMAL_SZ, CGO_RESET_NORMAL_SZ,
CGO_PICK_COLOR_SZ, CGO_PICK_COLOR_SZ,
CGO_DRAW_BUFFERS_SZ, CGO_NULL_SZ, // CGO_DRAW_BUFFERS_SZ no longer used
CGO_DRAW_BUFFERS_INDEXED_SZ, fsizeof<cgo::draw::buffers_indexed>(),
CGO_BOUNDING_BOX_SZ, CGO_BOUNDING_BOX_SZ,
CGO_DRAW_BUFFERS_NOT_INDEXED_SZ, fsizeof<cgo::draw::buffers_not_indexed>(),
CGO_LINEWIDTH_SPECIAL_SZ, CGO_SPECIAL_SZ,
CGO_DRAW_CYLINDER_BUFFERS_SZ, fsizeof<cgo::draw::cylinder_buffers>(),
CGO_SHADER_CYLINDER_SZ, fsizeof<cgo::draw::shadercylinder>(),
CGO_SHADER_CYLINDER_WITH_2ND_COLOR_SZ, fsizeof<cgo::draw::shadercylinder2ndcolor>(),
CGO_DRAW_SPHERE_BUFFERS_SZ, fsizeof<cgo::draw::sphere_buffers>(),
CGO_ACCESSIBILITY_SZ, CGO_ACCESSIBILITY_SZ,
CGO_DRAW_TEXTURE_SZ, CGO_DRAW_TEXTURE_SZ,
CGO_DRAW_TEXTURES_SZ, fsizeof<cgo::draw::textures>(),
CGO_DRAW_SCREEN_TEXTURES_AND_POLYGONS_SZ, fsizeof<cgo::draw::screen_textures>(),
CGO_TEX_COORD_SZ, CGO_TEX_COORD_SZ,
CGO_DRAW_LABEL_SZ, fsizeof<cgo::draw::label>(),
CGO_DRAW_LABELS_SZ, fsizeof<cgo::draw::labels>(),
CGO_NULL_SZ, CGO_NULL_SZ, CGO_DRAW_CONNECTOR_SZ,
CGO_NULL_SZ, CGO_NULL_SZ, CGO_NULL_SZ, CGO_NULL_SZ, CGO_NULL_SZ, CGO_NULL fsizeof<cgo::draw::connectors>(),
_SZ, CGO_NULL_SZ, CGO_NULL_SZ, CGO_DRAW_TRILINES_SZ, CGO_UNIFORM3F_SZ,
CGO_NULL_SZ, CGO_NULL_SZ, CGO_NULL_SZ, CGO_NULL_SZ, CGO_NULL_SZ, CGO_NULL CGO_SPECIAL_WITH_ARG_SZ,
_SZ, CGO_NULL_SZ fsizeof<cgo::draw::line>(),
fsizeof<cgo::draw::splitline>(),
fsizeof<cgo::draw::custom>(),
fsizeof<cgo::draw::vertex_attribute_3f>(),
fsizeof<cgo::draw::vertex_attribute_4ub>(),
fsizeof<cgo::draw::vertex_attribute_1f>(),
fsizeof<cgo::draw::mask_attribute_if_picking>(),
fsizeof<cgo::draw::bind_vbo_for_picking>(),
CGO_VERTEX_BEGIN_LINE_STRIP_SZ, CGO_INTERPOLATED_SZ, CGO_VERTEX_CROSS_SZ,
fsizeof<cgo::draw::vertex_attribute_4ub_if_picking>(),
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 at *c1, static int CGOSimpleCylinder(CGO * I, float *v1, float *v2, float tube_size, flo at *c1,
float *c2, int cap1, int cap2); float *c2, bool interp, int cap1, int cap2,
Pickable *pickcolor2 = NULL, 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); 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);
#ifndef _PYMOL_NOPY /*
* Inverse function of CGOArrayFromPyListInPlace
static PyObject *CGOArrayAsPyList(CGO * I) *
* I: (input) Primitive CGO (may contain CGO_DRAW_ARRAYS)
*
* Return: All-float Python list primitive CGO
*/
static PyObject *CGOArrayAsPyList(const CGO * I)
{ {
std::vector<float> flat;
flat.reserve(I->c);
float *pc = I->op; for (auto it = I->begin(); !it.is_stop(); ++it) {
int op; auto op = it.op_code();
int i; auto pc = it.data();
int cc; auto sz = CGO_sz[op];
PyObject *result = NULL;
result = PyList_New(I->c); flat.push_back(op);
i = 0; switch (op) {
if(I->c) { case CGO_BEGIN:
while((op = (CGO_MASK & CGO_read_int(pc)))) { case CGO_ENABLE:
PyList_SetItem(result, i++, PyFloat_FromDouble((float) op)); case CGO_DISABLE:
cc = CGO_sz[op]; case CGO_SPECIAL:
switch (op) { /* now convert any instructions with int argumen // first member int
ts */ flat.push_back(*reinterpret_cast<const int*>(pc));
case CGO_BEGIN: ++pc;
case CGO_ENABLE: --sz;
case CGO_DISABLE: break;
case CGO_LINEWIDTH_SPECIAL: case CGO_DRAW_ARRAYS:
PyList_SetItem(result, i++, PyFloat_FromDouble((float) CGO_read_int(pc)) {
); auto sp = reinterpret_cast<const cgo::draw::arrays*>(pc);
cc--; flat.push_back(sp->mode);
break; flat.push_back(sp->arraybits);
case CGO_DRAW_ARRAYS: flat.push_back(sp->narrays); // (redundant)
{ flat.push_back(sp->nverts);
int narrays = CGO_get_int(pc + 2), nverts = CGO_get_int(pc + 3), floatl pc = sp->get_data();
ength = narrays*nverts; sz = sp->get_data_length();
cc = floatlength ;
PyList_SetItem(result, i++, PyFloat_FromDouble((float) CGO_read_int(pc)
));
PyList_SetItem(result, i++, PyFloat_FromDouble((float) CGO_read_int(pc)
));
PyList_SetItem(result, i++, PyFloat_FromDouble((float) CGO_read_int(pc)
));
PyList_SetItem(result, i++, PyFloat_FromDouble((float) CGO_read_int(pc)
));
}
} }
if(cc > 0) }
while(cc--) {
PyList_SetItem(result, i++, PyFloat_FromDouble(*(pc++))); // float members
} for(; sz; --sz) {
flat.push_back(*(pc++));
} }
} }
while(i < I->c) {
PyList_SetItem(result, i++, PyFloat_FromDouble((float) CGO_STOP)); return PConvToPyObject(flat);
}
return (result);
} }
#endif
PyObject *CGOAsPyList(CGO * I) PyObject *CGOAsPyList(CGO * I)
{ {
#ifdef _PYMOL_NOPY
return NULL;
#else
PyObject *result; PyObject *result;
result = PyList_New(2); result = PyList_New(2);
PyList_SetItem(result, 0, PyInt_FromLong(I->c)); PyObject *list = CGOArrayAsPyList(I);
PyList_SetItem(result, 1, CGOArrayAsPyList(I)); PyList_SetItem(result, 0, PyInt_FromLong(PyList_Size(list)));
PyList_SetItem(result, 1, list);
return (result); return (result);
#endif
} }
#ifndef _PYMOL_NOPY static float CPythonVal_PyFloat_AsDouble_From_List(void * G, PyObject * list, si
ze_t i) {
float out;
PConvPyFloatToFloat(PyList_GetItem(list, i), &out);
return out;
}
/*
* Inverse function of CGOArrayAsPyList
*
* list: (input) All-float Python list primitive CGO (may contain CGO_DRAW_ARRAY
S)
* I: (output) empty CGO
*/
static int CGOArrayFromPyListInPlace(PyObject * list, CGO * I) static int CGOArrayFromPyListInPlace(PyObject * list, CGO * I)
{ {
int a; // sanity check
int c = I->c; if (!list || !PyList_Check(list))
int cc = 0; return false;
int ok = true;
float *pc;
int sz, op;
int l;
if(!list) {
ok = false;
} else if(!PyList_Check(list)) {
ok = false;
} else {
l = PyList_Size(list);
if(l != I->c)
ok = false;
}
if(ok) {
pc = I->op;
while(c > 0) { #define GET_FLOAT(i) ((float) CPythonVal_PyFloat_AsDouble_From_List(I->G, list,
op = (int) PyFloat_AsDouble(PyList_GetItem(list, cc++)); i))
op = op & CGO_MASK; #define GET_INT(i) ((int) CPythonVal_PyFloat_AsDouble_From_List(I->G, list,
c--; i))
sz = CGO_sz[op];
CGO_write_int(pc, op); for (int i = 0, l = PyList_Size(list); i < l;) {
ok = true; int op = CGO_MASK & GET_INT(i++);
switch (op) { int sz = CGO_sz[op];
case CGO_END: float * fdata = I->add_to_buffer(sz + 1);
case CGO_VERTEX: CGO_write_int(fdata, op);
case CGO_BEGIN:
I->has_begin_end = true; switch (op) {
} case CGO_STOP:
switch (op) { /* now convert any instructions with int argumen // don't increment size for null terminator
ts */ I->c -= 1;
case CGO_BEGIN: return true;
case CGO_ENABLE: case CGO_BEGIN:
case CGO_DISABLE: I->has_begin_end = true;
CGO_write_int(pc, (int) PyFloat_AsDouble(PyList_GetItem(list, cc++))); case CGO_ENABLE:
c--; case CGO_DISABLE:
sz--; case CGO_SPECIAL:
break; // first member int
case CGO_DRAW_ARRAYS: CGO_write_int(fdata, GET_INT(i++));
{ sz--;
int arrays, narrays, nverts; break;
CGO_write_int(pc, (int) PyFloat_AsDouble(PyList_GetItem(list, cc++))); case CGO_DRAW_ARRAYS:
CGO_write_int(pc, arrays = (int) PyFloat_AsDouble(PyList_GetItem(list, {
cc++))); // has abstract superclass, need to be constructed!
CGO_write_int(pc, narrays = (int) PyFloat_AsDouble(PyList_GetItem(list, auto sp = new (fdata) cgo::draw::arrays(
cc++))); GET_INT(i),
CGO_write_int(pc, nverts = (int) PyFloat_AsDouble(PyList_GetItem(list, GET_INT(i + 1),
cc++))); GET_INT(i + 3));
c -= 4;
sz = narrays*nverts; // sanity check
} int narrays_check = GET_INT(i + 2);
break; if (sp->narrays != narrays_check) {
} PRINTFB(I->G, FB_CGO, FB_Warnings)
" CGO-Warning: narrays mismatch: %d != %d\n",
sp->narrays, narrays_check ENDFB(I->G);
}
for(a = 0; a < sz; a++) { // data
*(pc++) = (float) PyFloat_AsDouble(PyList_GetItem(list, cc++)); sz = sp->get_data_length();
c--; sp->floatdata = fdata = I->allocate_in_data_heap(sz);
i += 4;
} }
break;
}
// float members
for(; sz; --sz) {
*(fdata++) = GET_FLOAT(i++);
} }
} }
return (ok);
#undef GET_FLOAT
#undef GET_INT
return true;
} }
#endif
CGO *CGONewFromPyList(PyMOLGlobals * G, PyObject * list, int version) CGO *CGONewFromPyList(PyMOLGlobals * G, PyObject * list, int version, bool shoul dCombine)
{ {
int ok = true; int ok = true;
int ll; auto I = CGONew(G);
OOCalloc(G, CGO);
I->G = G;
I->op = NULL;
I->i_start = 0;
I->debug = 0;
I->has_begin_end = false;
I->has_draw_buffers = false;
I->has_draw_cylinder_buffers = false;
I->has_draw_sphere_buffers = false;
I->enable_shaders = 0;
I->no_pick = 0;
if(ok) if(ok)
ok = (list != NULL); ok = (list != NULL);
if(ok) if(ok)
ok = PyList_Check(list); ok = PyList_Check(list);
if(ok)
ll = PyList_Size(list);
/* TO ENABLE BACKWARDS COMPATIBILITY... /* TO ENABLE BACKWARDS COMPATIBILITY...
Always check ll when adding new PyList_GetItem's */ Always check ll when adding new PyList_GetItem's */
if(ok)
ok = PConvPyIntToInt(PyList_GetItem(list, 0), &I->c);
if(ok){
ok = ((I->op = VLAlloc(float, I->c + 1)) != NULL);
}
if((version > 0) && (version <= 86)) { if((version > 0) && (version <= 86)) {
if(ok) if(ok)
ok = PConvPyIntToInt(PyList_GetItem(list, 0), &I->c);
if(ok)
VLACheck(I->op, float, I->c);
if(ok)
ok = PConvPyListToFloatArrayInPlace(PyList_GetItem(list, 1), I->op, I->c); ok = PConvPyListToFloatArrayInPlace(PyList_GetItem(list, 1), I->op, I->c);
} else { } else {
if(ok) if(ok)
ok = CGOArrayFromPyListInPlace(PyList_GetItem(list, 1), I); ok = CGOArrayFromPyListInPlace(PyList_GetItem(list, 1), I);
} }
if(!ok) { if(!ok) {
CGOFree(I); CGOFree(I);
I = NULL;
} }
{ {
CGO *cgo = NULL; CGO *cgo = NULL;
if (I && I->has_begin_end){ if (shouldCombine && I && I->has_begin_end){
cgo = CGOCombineBeginEnd(I, 0); cgo = CGOCombineBeginEnd(I, 0);
CGOFree(I); CGOFree(I);
} else { } else {
cgo = I; cgo = I;
} }
return cgo; return cgo;
} }
} }
CGO *CGONew(PyMOLGlobals * G) CGO *CGONew(PyMOLGlobals * G, int size)
{
OOCalloc(G, CGO);
I->G = G;
I->op = VLAlloc(float, 33);
I->i_start = 0;
I->alpha = 1.f;
I->has_begin_end = false;
I->has_draw_buffers = false;
I->has_draw_cylinder_buffers = false;
I->normal[0] = 0.f; I->normal[1] = 0.f; I->normal[2] = 1.f;
I->color[0] = 0.f; I->color[1] = 0.f; I->color[2] = 1.f;
I->pickColor[0] = 0; I->pickColor[1] = 0; I->pickColor[2] = 0; I->pickColor[3]
= 255;
I->current_accessibility = 1.f;
I->enable_shaders = 0;
I->no_pick = 0;
I->current_pick_color_index = 0;
I->current_pick_color_bond = cPickableNoPick;
return (I);
}
CGO *CGONewSized(PyMOLGlobals * G, int size)
{ {
OOCalloc(G, CGO); auto I = new CGO();
I->G = G; I->G = G;
I->op = VLAlloc(float, size + 32); I->op = VLACalloc(float, size + 32);
I->i_start = 0; #ifdef _PYMOL_IOS
I->alpha = 1.f; if (!I->op){
I->has_begin_end = false; delete I;
I->has_draw_buffers = false; return NULL;
I->has_draw_cylinder_buffers = false; }
#endif
I->normal[0] = 0.f; I->normal[1] = 0.f; I->normal[2] = 1.f; I->normal[0] = 0.f; I->normal[1] = 0.f; I->normal[2] = 1.f;
I->color[0] = 0.f; I->color[1] = 0.f; I->color[2] = 1.f; I->color[0] = 0.f; I->color[1] = 0.f; I->color[2] = 1.f;
I->pickColor[0] = 0; I->pickColor[1] = 0; I->pickColor[2] = 0; I->pickColor[3] = 255; I->pickColor[0] = 0; I->pickColor[1] = 0; I->pickColor[2] = 0; I->pickColor[3] = 255;
I->current_accessibility = 1.f; I->cgo_shader_ub_color = SettingGetGlobal_i(G, cSetting_cgo_shader_ub_color);
I->enable_shaders = 0; I->cgo_shader_ub_normal = SettingGetGlobal_i(G, cSetting_cgo_shader_ub_normal)
I->no_pick = 0; ;
I->current_pick_color_index = 0;
I->current_pick_color_bond = cPickableNoPick;
return (I); return (I);
} }
void CGOSetUseShader(CGO *I, int use_shader){ void CGOSetUseShader(CGO *I, int use_shader){
I->use_shader = use_shader; I->use_shader = use_shader;
if (use_shader){ if (use_shader){
I->cgo_shader_ub_color = SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_col or); I->cgo_shader_ub_color = SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_col or);
I->cgo_shader_ub_normal = SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_no rmal); I->cgo_shader_ub_normal = SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_no rmal);
} else { } else {
I->cgo_shader_ub_color = 0; I->cgo_shader_ub_color = 0;
skipping to change at line 428 skipping to change at line 507
I->alpha = 1.f; I->alpha = 1.f;
I->has_begin_end = false; I->has_begin_end = false;
I->has_draw_buffers = false; I->has_draw_buffers = false;
I->has_draw_cylinder_buffers = false; I->has_draw_cylinder_buffers = false;
I->normal[0] = 0.f; I->normal[1] = 0.f; I->normal[2] = 1.f; I->normal[0] = 0.f; I->normal[1] = 0.f; I->normal[2] = 1.f;
I->color[0] = 0.f; I->color[1] = 0.f; I->color[2] = 1.f; I->color[0] = 0.f; I->color[1] = 0.f; I->color[2] = 1.f;
I->pickColor[0] = 0; I->pickColor[1] = 0; I->pickColor[2] = 0; I->pickColor[3] = 255; I->pickColor[0] = 0; I->pickColor[1] = 0; I->pickColor[2] = 0; I->pickColor[3] = 255;
I->current_accessibility = 1.f; I->current_accessibility = 1.f;
} }
void CGOFreeWithoutVBOs(CGO * I){ void CGOFree(CGO * &I, bool withVBOs)
CGOFreeImpl(I, 0);
}
void CGOFree(CGO * &I){
CGOFreeImpl(I, 1);
I = NULL;
}
void CGOFreeImpl(CGO * I, short withVBOs)
{ {
if(I) { if(I) {
if (withVBOs && I->has_draw_buffers){ if (withVBOs && I->has_draw_buffers){
CGOFreeVBOs(I); CGOFreeStruct(I, true);
} else {
CGOFreeStruct(I, false);
} }
if(I->i_start) { if(I->i_start) {
FreeP(I->i_start); FreeP(I->i_start);
} }
VLAFreeP(I->op); VLAFreeP(I->op);
DeleteP(I);
} }
OOFreeP(I);
} }
static float *CGO_add(CGO * I, int c) static float *CGO_add(CGO * I, int c)
{ {
float *at; float *at;
VLACheck(I->op, float, I->c + c); VLACheck(I->op, float, I->c + c);
if (!I->op){ if (!I->op){
return NULL; return NULL;
} }
at = I->op + I->c; at = I->op + I->c;
I->c += c; I->c += c;
return (at); return (at);
} }
float *CGO_add_GLfloat(CGO * I, int c)
{
GLfloat *at;
VLACheck(I->op, GLfloat, I->c + c);
if (!I->op){
return NULL;
}
at = I->op + I->c;
I->c += c;
return (at);
}
static float *CGO_size(CGO * I, int sz) static float *CGO_size(CGO * I, int sz)
{ {
float *at; float *at;
VLASize(I->op, float, sz); VLASize(I->op, float, sz);
if (!I->op){ if (!I->op){
return NULL; return NULL;
} }
at = I->op + I->c; at = I->op + I->c;
I->c = sz; I->c = sz;
return (at); return (at);
} }
/*===== Object Creation Routines =======*/ /*===== Object Creation Routines =======*/
int CGOFromFloatArray(CGO * I, const float *src, int len) int CGOFromFloatArray(CGO * I, const float *src, int len)
{ {
int op, iarg; int op, iarg;
int c;
int ok; int ok;
int all_ok = true; int all_ok = true;
int bad_entry = 0; int bad_entry = 0;
int sz; int sz;
int a; int a;
int cc = 0; int cc = 0;
float val; float val;
float *pc, *save_pc, *tf; float *pc, *save_pc, *tf;
VLACheck(I->op, float, I->c + len + 32); VLACheck(I->op, float, I->c + len + 32);
save_pc = I->op + I->c; save_pc = I->op + I->c;
while(len-- > 0) { while(len-- > 0) {
cc++; cc++;
c = 1;
op = CGO_MASK & ((int) (*(src++))); op = CGO_MASK & ((int) (*(src++)));
sz = CGO_sz[op]; sz = CGO_sz[op];
if(len < sz) if(len < sz)
break; /* discard short instruction */ break; /* discard short instruction */
len -= sz; len -= sz;
pc = save_pc; pc = save_pc;
CGO_write_int(pc, op); CGO_write_int(pc, op);
ok = true; ok = true;
for(a = 0; a < sz; a++) { for(a = 0; a < sz; a++) {
cc++; cc++;
skipping to change at line 535 skipping to change at line 593
switch (op) { switch (op) {
case CGO_END: case CGO_END:
case CGO_VERTEX: case CGO_VERTEX:
case CGO_BEGIN: case CGO_BEGIN:
I->has_begin_end = true; I->has_begin_end = true;
} }
switch (op) { /* now convert any instructions with int argumen ts */ switch (op) { /* now convert any instructions with int argumen ts */
case CGO_BEGIN: case CGO_BEGIN:
case CGO_ENABLE: case CGO_ENABLE:
case CGO_DISABLE: case CGO_DISABLE:
case CGO_LINEWIDTH_SPECIAL: case CGO_SPECIAL:
tf = save_pc + 1; tf = save_pc + 1;
iarg = (int) *(tf); iarg = (int) *(tf);
CGO_write_int(tf, iarg); CGO_write_int(tf, iarg);
break; break;
} }
save_pc = pc; save_pc = pc;
I->c += sz + 1; I->c += sz + 1;
} else { /* discard illegal instructions */ } else { /* discard illegal instructions */
if(all_ok) if(all_ok)
bad_entry = cc; bad_entry = cc;
all_ok = false; all_ok = false;
} }
} }
return (bad_entry); return (bad_entry);
} }
int CGOBegin(CGO * I, int mode) int CGOBegin(CGO * I, int mode)
{ {
float *pc = CGO_add(I, 2); float *pc = CGO_add(I, CGO_BEGIN_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_BEGIN); CGO_write_int(pc, CGO_BEGIN);
CGO_write_int(pc, mode); CGO_write_int(pc, mode);
I->has_begin_end = true; I->has_begin_end = true;
I->texture[0] = 0.f; I->texture[0] = 0.f;
I->texture[1] = 0.f; I->texture[1] = 0.f;
return true; return true;
} }
int CGOEnd(CGO * I) int CGOEnd(CGO * I)
{ {
float *pc = CGO_add(I, 1); float *pc = CGO_add(I, CGO_END_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_END); CGO_write_int(pc, CGO_END);
I->has_begin_end = true; I->has_begin_end = true;
return true; return true;
} }
int CGOEnable(CGO * I, int mode) int CGOEnable(CGO * I, int mode)
{ {
float *pc = CGO_add(I, 2); float *pc = CGO_add(I, CGO_ENABLE_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_ENABLE); CGO_write_int(pc, CGO_ENABLE);
CGO_write_int(pc, mode); CGO_write_int(pc, mode);
return true; return true;
} }
int CGODisable(CGO * I, int mode) int CGODisable(CGO * I, int mode)
{ {
float *pc = CGO_add(I, 2); float *pc = CGO_add(I, CGO_DISABLE_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_DISABLE); CGO_write_int(pc, CGO_DISABLE);
CGO_write_int(pc, mode); CGO_write_int(pc, mode);
return true; return true;
} }
int CGOLinewidth(CGO * I, float v) int CGOLinewidth(CGO * I, float v)
{ {
float *pc = CGO_add(I, 2); float *pc = CGO_add(I, CGO_LINEWIDTH_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_LINEWIDTH); CGO_write_int(pc, CGO_LINEWIDTH);
*(pc++) = v; *(pc++) = v;
return true; return true;
} }
int CGOLinewidthSpecial(CGO * I, int v) /*
* implements special-case operations inside a CGO
*
* v: lookup value defined for each special operation (see CGO.h)
*/
int CGOSpecial(CGO * I, int v)
{ {
float *pc = CGO_add(I, 2); float *pc = CGO_add(I, CGO_SPECIAL_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_LINEWIDTH_SPECIAL); CGO_write_int(pc, CGO_SPECIAL);
CGO_write_int(pc, v); CGO_write_int(pc, v);
return true; return true;
} }
int CGODotwidth(CGO * I, float v) /*
* implements special-case operations with an argument
* inside a CGO
*
* v: lookup value defined for each special operation (see CGO.h)
* argval : argument value
*/
int CGOSpecialWithArg(CGO * I, int v, float argval)
{ {
float *pc = CGO_add(I, 2); float *pc = CGO_add(I, CGO_SPECIAL_WITH_ARG_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_DOTWIDTH); CGO_write_int(pc, CGO_SPECIAL_WITH_ARG);
*(pc++) = v; CGO_write_int(pc, v);
*pc = argval;
return true; return true;
} }
GLfloat *CGODrawArrays(CGO *I, GLenum mode, short arrays, int nverts){ int CGODotwidth(CGO * I, float v)
int narrays = 0, floatlength; {
short bit; float *pc = CGO_add(I, CGO_DOTWIDTH_SZ + 1);
float *pc;
for (bit = 0; bit < 4; bit++){
if ((1 << bit) & arrays){
narrays+=3;
}
}
if (arrays & CGO_ACCESSIBILITY_ARRAY) narrays++;
if (arrays & CGO_COLOR_ARRAY) narrays++; //floatlength += nverts;
floatlength = narrays*nverts;
pc = CGO_add_GLfloat(I, floatlength + 5); /* 4 floats for color array, 3 float
s for every other array, 1 float for accessibility */
if (!pc) if (!pc)
return NULL; return false;
CGO_write_int(pc, CGO_DRAW_ARRAYS); CGO_write_int(pc, CGO_DOTWIDTH);
CGO_write_int(pc, mode); *(pc++) = v;
CGO_write_int(pc, arrays); return true;
CGO_write_int(pc, narrays);
CGO_write_int(pc, nverts);
return pc;
} }
int CGODrawBuffers(CGO *I, GLenum mode, short arrays, int nverts, uint *bufs){ /* CGOUniform3f - specifies a 3f uniform variable and
int narrays = 0; its value. This function returns the offset of where
short bit; these values are stored inside the CGO float array
so that they can be accessed and changed from outside
the CGO.
float *pc = CGO_add(I, 9); */
int CGOUniform3f(CGO *I, int uniform_id, const float *value){
float *pc = CGO_add(I, CGO_UNIFORM3F_SZ + 1);
if (!pc) if (!pc)
return false; return 0;
CGO_write_int(pc, CGO_DRAW_BUFFERS); CGO_write_int(pc, CGO_UNIFORM3F);
CGO_write_int(pc, mode); CGO_write_int(pc, uniform_id);
CGO_write_int(pc, arrays); copy3f(value, pc);
for (bit = 0; bit < 4; bit++){ return pc - I->op;
if ((1 << bit) & arrays){
narrays+=3;
}
}
if (arrays & CGO_ACCESSIBILITY_ARRAY) narrays++;
if (arrays & CGO_COLOR_ARRAY) narrays++; //floatlength += nverts;
CGO_write_int(pc, narrays);
CGO_write_int(pc, nverts);
for (bit = 0; bit<4; bit++){
CGO_write_int(pc, bufs[bit]);
}
return true;
} }
int CGOBoundingBox(CGO *I, float *min, float *max){
float *pc = CGO_add(I, 7); int CGOBoundingBox(CGO *I, const float *min, const float *max){
float *pc = CGO_add(I, CGO_BOUNDING_BOX_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_BOUNDING_BOX); CGO_write_int(pc, CGO_BOUNDING_BOX);
*(pc++) = *(min); *(pc++) = *(min);
*(pc++) = *(min+1); *(pc++) = *(min+1);
*(pc++) = *(min+2); *(pc++) = *(min+2);
*(pc++) = *(max); *(pc++) = *(max);
*(pc++) = *(max+1); *(pc++) = *(max+1);
*(pc++) = *(max+2); *(pc++) = *(max+2);
return true; return true;
} }
int CGOAccessibility(CGO * I, float a) int CGOAccessibility(CGO * I, float a)
{ {
float *pc = CGO_add(I, 2); float *pc = CGO_add(I, CGO_ACCESSIBILITY_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_ACCESSIBILITY); CGO_write_int(pc, CGO_ACCESSIBILITY);
*(pc++) = a; *(pc++) = a;
return true; return true;
} }
int CGODrawTexture(CGO *I, int texture_id, float *worldPos, float *screenMin, fl oat *screenMax, float *textExtent) int CGODrawTexture(CGO *I, int texture_id, float *worldPos, float *screenMin, fl oat *screenMax, float *textExtent)
{ {
float *pc = CGO_add(I, CGO_DRAW_TEXTURE_SZ + 1); float *pc = CGO_add(I, CGO_DRAW_TEXTURE_SZ + 1);
skipping to change at line 717 skipping to change at line 768
*(pc++) = screenMin[2]; *(pc++) = screenMin[2];
*(pc++) = screenMax[0]; *(pc++) = screenMax[0];
*(pc++) = screenMax[1]; *(pc++) = screenMax[1];
*(pc++) = screenMax[2]; *(pc++) = screenMax[2];
*(pc++) = textExtent[0]; *(pc++) = textExtent[0];
*(pc++) = textExtent[1]; *(pc++) = textExtent[1];
*(pc++) = textExtent[2]; *(pc++) = textExtent[2];
*(pc++) = textExtent[3]; *(pc++) = textExtent[3];
return true; return true;
} }
GLfloat *CGODrawTextures(CGO *I, int ntextures, uint *bufs)
int CGODrawConnector(CGO *I, float *targetPt3d, float *labelCenterPt3d, float te
xt_width, float text_height, float *indentFactor, float *screenWorldOffset, floa
t *connectorColor, short relativeMode, int draw_flags, float bkgrd_transp, float
*bkgrd_color, float rel_ext_length, float connectorWidth)
{ {
float *pc = CGO_add_GLfloat(I, ntextures * 18 + 5); /* 6 vertices per texture, first third for passed buffer, last 2 thirds for pick index and bond per vertex */ float *pc = CGO_add(I, CGO_DRAW_CONNECTOR_SZ + 1);
if (!pc) if (!pc)
return NULL; return false;
CGO_write_int(pc, CGO_DRAW_TEXTURES); CGO_write_int(pc, CGO_DRAW_CONNECTOR);
CGO_write_int(pc, ntextures); *(pc++) = targetPt3d[0];
CGO_write_int(pc, bufs[0]); *(pc++) = targetPt3d[1];
CGO_write_int(pc, bufs[1]); *(pc++) = targetPt3d[2];
CGO_write_int(pc, bufs[2]); *(pc++) = labelCenterPt3d[0];
return pc; *(pc++) = labelCenterPt3d[1];
*(pc++) = labelCenterPt3d[2];
*(pc++) = indentFactor[0];
*(pc++) = indentFactor[1];
*(pc++) = rel_ext_length; /* place for ext_length relative to height (i.e., te
xt_height which is total height */
*(pc++) = screenWorldOffset[0];
*(pc++) = screenWorldOffset[1];
*(pc++) = screenWorldOffset[2];
*(pc++) = text_width;
*(pc++) = text_height;
*(pc++) = connectorColor[0];
*(pc++) = connectorColor[1];
*(pc++) = connectorColor[2];
*(pc++) = (float)relativeMode;
*(pc++) = (float)draw_flags;
*(pc++) = bkgrd_color[0];
*(pc++) = bkgrd_color[1];
*(pc++) = bkgrd_color[2];
*(pc++) = bkgrd_transp;
*(pc++) = connectorWidth; // place for label_connector_width
return true;
} }
int CGODrawLabel(CGO *I, int texture_id, float *worldPos, float *screenWorldOffs et, float *screenMin, float *screenMax, float *textExtent) int CGODrawLabel(CGO *I, int texture_id, float *targetPos, float *worldPos, floa t *screenWorldOffset, float *screenMin, float *screenMax, float *textExtent, sho rt relativeMode)
{ {
float *pc = CGO_add(I, CGO_DRAW_LABEL_SZ + 1); float *pc = CGO_add(I, CGO_DRAW_LABEL_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_DRAW_LABEL); CGO_write_int(pc, CGO_DRAW_LABEL);
*(pc++) = worldPos[0]; *(pc++) = worldPos[0];
*(pc++) = worldPos[1]; *(pc++) = worldPos[1];
*(pc++) = worldPos[2]; *(pc++) = worldPos[2];
*(pc++) = screenWorldOffset[0]; *(pc++) = screenWorldOffset[0];
*(pc++) = screenWorldOffset[1]; *(pc++) = screenWorldOffset[1];
skipping to change at line 752 skipping to change at line 824
*(pc++) = screenMin[0]; *(pc++) = screenMin[0];
*(pc++) = screenMin[1]; *(pc++) = screenMin[1];
*(pc++) = screenMin[2]; *(pc++) = screenMin[2];
*(pc++) = screenMax[0]; *(pc++) = screenMax[0];
*(pc++) = screenMax[1]; *(pc++) = screenMax[1];
*(pc++) = screenMax[2]; *(pc++) = screenMax[2];
*(pc++) = textExtent[0]; *(pc++) = textExtent[0];
*(pc++) = textExtent[1]; *(pc++) = textExtent[1];
*(pc++) = textExtent[2]; *(pc++) = textExtent[2];
*(pc++) = textExtent[3]; *(pc++) = textExtent[3];
return true; *(pc++) = (float)relativeMode;
} *(pc++) = targetPos[0];
GLfloat *CGODrawLabels(CGO *I, int ntextures, uint *bufs) *(pc++) = targetPos[1];
{ *(pc++) = targetPos[2];
float *pc = CGO_add_GLfloat(I, ntextures * 18 + 6); /* 6 vertices per texture,
first third for passed buffer, last 2 thirds for pick index and bond per vertex
*/
if (!pc)
return NULL;
CGO_write_int(pc, CGO_DRAW_LABELS);
CGO_write_int(pc, ntextures);
CGO_write_int(pc, bufs[0]);
CGO_write_int(pc, bufs[1]);
CGO_write_int(pc, bufs[2]);
CGO_write_int(pc, bufs[3]);
I->has_draw_buffers = true;
return pc;
}
int CGODrawScreenTexturesAndPolygons(CGO *I, int nverts, uint *bufs)
{
float *pc = CGO_add(I, CGO_DRAW_SCREEN_TEXTURES_AND_POLYGONS_SZ + 1);
if (!pc)
return false;
CGO_write_int(pc, CGO_DRAW_SCREEN_TEXTURES_AND_POLYGONS);
CGO_write_int(pc, nverts);
CGO_write_int(pc, bufs[0]);
CGO_write_int(pc, bufs[1]);
CGO_write_int(pc, bufs[2]);
I->has_draw_buffers = true;
return true;
}
GLfloat *CGODrawBuffersIndexed(CGO *I, GLenum mode, short arrays, int nindices,
int nverts, uint *bufs){
int narrays = 0;
short bit;
float *pc = CGO_add_GLfloat(I, nverts*3 + 11); /* 3 floats for pick array, 1st
1/3 for color, 2/3 for atom/bond info */
if (!pc)
return NULL;
CGO_write_int(pc, CGO_DRAW_BUFFERS_INDEXED);
CGO_write_int(pc, mode);
CGO_write_int(pc, arrays);
for (bit = 0; bit < 4; bit++){
if ((1 << bit) & arrays){
narrays++;
}
}
if (arrays & CGO_ACCESSIBILITY_ARRAY) narrays++;
if (arrays & CGO_COLOR_ARRAY) narrays++; //floatlength += nverts;
CGO_write_int(pc, narrays);
CGO_write_int(pc, nindices);
CGO_write_int(pc, nverts);
for (bit = 0; bit<5; bit++){
CGO_write_int(pc, bufs[bit]);
}
I->has_draw_buffers = true;
return pc;
}
GLfloat *CGODrawBuffersNotIndexed(CGO *I, GLenum mode, short arrays, int nverts,
uint *bufs){
int narrays = 0;
short bit;
float *pc = CGO_add_GLfloat(I, nverts*3 + 9); /* 3 floats for pick array, 1st
1/3 for color, 2/3 for atom/bond info */
if (!pc)
return NULL;
CGO_write_int(pc, CGO_DRAW_BUFFERS_NOT_INDEXED);
CGO_write_int(pc, mode);
CGO_write_int(pc, arrays);
for (bit = 0; bit < 4; bit++){
if ((1 << bit) & arrays){
narrays++;
}
}
if (arrays & CGO_ACCESSIBILITY_ARRAY) narrays++;
if (arrays & CGO_COLOR_ARRAY) narrays++; //floatlength += nverts;
CGO_write_int(pc, narrays);
CGO_write_int(pc, nverts);
for (bit = 0; bit<4; bit++){
CGO_write_int(pc, bufs[bit]);
}
I->has_draw_buffers = true;
return pc;
}
int CGOShaderCylinder(CGO *I,
const float *origin,
const float *axis, float tube_size, int cap){
float *pc = CGO_add(I, 9);
if (!pc)
return false;
CGO_write_int(pc, CGO_SHADER_CYLINDER);
*(pc++) = *(origin);
*(pc++) = *(origin+1);
*(pc++) = *(origin+2);
*(pc++) = *(axis);
*(pc++) = *(axis+1);
*(pc++) = *(axis+2);
*(pc++) = tube_size;
CGO_write_int(pc, cap);
return true;
}
int CGOShaderCylinder2ndColor(CGO *I,
const float *origin,
const float *axis, float tube_size, int cap,
const float *color2){
float *pc = CGO_add(I, 12);
if (!pc)
return false;
CGO_write_int(pc, CGO_SHADER_CYLINDER_WITH_2ND_COLOR);
*(pc++) = *(origin);
*(pc++) = *(origin+1);
*(pc++) = *(origin+2);
*(pc++) = *(axis);
*(pc++) = *(axis+1);
*(pc++) = *(axis+2);
*(pc++) = tube_size;
CGO_write_int(pc, cap);
*(pc++) = *(color2);
*(pc++) = *(color2+1);
*(pc++) = *(color2+2);
return true;
}
int CGODrawCylinderBuffers(CGO *I, int num_cyl, int alpha, uint *bufs){
short bit;
float *pc = CGO_add(I, 8);
if (!pc)
return false;
CGO_write_int(pc, CGO_DRAW_CYLINDER_BUFFERS);
CGO_write_int(pc, num_cyl);
CGO_write_int(pc, alpha);
for (bit = 0; bit<5; bit++){
CGO_write_int(pc, bufs[bit]);
}
I->has_draw_buffers = true;
return true;
}
int CGODrawSphereBuffers(CGO *I, int num_spheres, int ub_flags, uint *bufs){
/* ub_flags are for whether the color and flags buffer are UB:
1 - color buffer is UB
2 - flags buffer is UB
*/
short bit;
float *pc = CGO_add(I, 6);
if (!pc)
return false;
CGO_write_int(pc, CGO_DRAW_SPHERE_BUFFERS);
CGO_write_int(pc, num_spheres);
CGO_write_int(pc, ub_flags);
for (bit = 0; bit<3; bit++){
CGO_write_int(pc, bufs[bit]);
}
I->has_draw_buffers = true;
return true; return true;
} }
int CGOCylinderv(CGO * I, int CGOConev(CGO * I,
const float *p1, const float *p1,
const float *p2, float r, const float *p2, float r1, float r2,
const float *c1, const float *c1,
const float *c2) const float *c2,
float cap1, float cap2)
{ {
float *pc = CGO_add(I, 14); float *pc = CGO_add(I, CGO_CONE_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_CYLINDER); CGO_write_int(pc, CGO_CONE);
*(pc++) = *(p1++); *(pc++) = *(p1++);
*(pc++) = *(p1++); *(pc++) = *(p1++);
*(pc++) = *(p1++); *(pc++) = *(p1++);
*(pc++) = *(p2++); *(pc++) = *(p2++);
*(pc++) = *(p2++); *(pc++) = *(p2++);
*(pc++) = *(p2++); *(pc++) = *(p2++);
*(pc++) = r; *(pc++) = r1;
*(pc++) = r2;
*(pc++) = *(c1++); *(pc++) = *(c1++);
*(pc++) = *(c1++); *(pc++) = *(c1++);
*(pc++) = *(c1++); *(pc++) = *(c1++);
*(pc++) = *(c2++); *(pc++) = *(c2++);
*(pc++) = *(c2++); *(pc++) = *(c2++);
*(pc++) = *(c2++); *(pc++) = *(c2++);
*(pc++) = cap1;
*(pc++) = cap2;
return true; return true;
} }
int CGOCustomCylinderv(CGO * I, void SetCGOPickColor(float *begPickColorVals, int nverts, int pl, unsigned int i
const float *p1, ndex, int bond){
const float *p2, float r, float *colorVals = begPickColorVals + nverts;
const float *c1, int pld = pl / 3;
const float *c2, /* Picking Color stores atom/bond info in the second 2/3rds of the array */
float cap1, float cap2) CGO_put_uint(colorVals + (pld*2), index);
CGO_put_int(colorVals + (pld*2) + 1, bond);
}
int CGOPickColor(CGO * I, unsigned int index, int bond)
{ {
float *pc = CGO_add(I, 16); // check if uchar is -1 since extrude does this for masked atoms
if (!pc) if (index == (unsigned int)-1){
return false; bond = cPickableNoPick;
CGO_write_int(pc, CGO_CUSTOM_CYLINDER); }
*(pc++) = *(p1++); if (I->current_pick_color_index==index &&
*(pc++) = *(p1++); I->current_pick_color_bond==bond)
*(pc++) = *(p1++); return true;
*(pc++) = *(p2++); float *pc = CGO_add(I, CGO_PICK_COLOR_SZ + 1);
*(pc++) = *(p2++);
*(pc++) = *(p2++);
*(pc++) = r;
*(pc++) = *(c1++);
*(pc++) = *(c1++);
*(pc++) = *(c1++);
*(pc++) = *(c2++);
*(pc++) = *(c2++);
*(pc++) = *(c2++);
*(pc++) = cap1;
*(pc++) = cap2;
return true;
}
int CGOConev(CGO * I,
const float *p1,
const float *p2, float r1, float r2,
const float *c1,
const float *c2,
float cap1, float cap2)
{
float *pc = CGO_add(I, 17);
if (!pc)
return false;
CGO_write_int(pc, CGO_CONE);
*(pc++) = *(p1++);
*(pc++) = *(p1++);
*(pc++) = *(p1++);
*(pc++) = *(p2++);
*(pc++) = *(p2++);
*(pc++) = *(p2++);
*(pc++) = r1;
*(pc++) = r2;
*(pc++) = *(c1++);
*(pc++) = *(c1++);
*(pc++) = *(c1++);
*(pc++) = *(c2++);
*(pc++) = *(c2++);
*(pc++) = *(c2++);
*(pc++) = cap1;
*(pc++) = cap2;
return true;
}
void SetCGOPickColor(float *begPickColorVals, int nverts, int pl, int index, int
bond){
float *colorVals = begPickColorVals + nverts;
int pld = pl / 3;
/* Picking Color stores atom/bond info in the second 2/3rds of the array */
CGO_put_int(colorVals + (pld*2), index);
CGO_put_int(colorVals + (pld*2) + 1, bond);
}
int CGOPickColor(CGO * I, int index, int bond)
{
float *pc = CGO_add(I, 3);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_PICK_COLOR); CGO_write_int(pc, CGO_PICK_COLOR);
CGO_write_int(pc, index); CGO_write_uint(pc, index);
CGO_write_int(pc, bond); CGO_write_int(pc, bond);
I->current_pick_color_index = index; I->current_pick_color_index = index;
I->current_pick_color_bond = bond; I->current_pick_color_bond = bond;
return true; return true;
} }
int CGOAlpha(CGO * I, float alpha) int CGOAlpha(CGO * I, float alpha)
{ {
float *pc = CGO_add(I, 2); float *pc = CGO_add(I, CGO_ALPHA_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_ALPHA); CGO_write_int(pc, CGO_ALPHA);
*(pc++) = alpha; *(pc++) = alpha;
I->alpha = alpha; I->alpha = alpha;
return true; return true;
} }
int CGOSphere(CGO * I, const float *v1, float r) int CGOSphere(CGO * I, const float *v1, float r)
{ {
float *pc = CGO_add(I, 5); float *pc = CGO_add(I, CGO_SPHERE_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_SPHERE); CGO_write_int(pc, CGO_SPHERE);
*(pc++) = *(v1++); *(pc++) = *(v1++);
*(pc++) = *(v1++); *(pc++) = *(v1++);
*(pc++) = *(v1++); *(pc++) = *(v1++);
*(pc++) = r; *(pc++) = r;
return true; return true;
} }
int CGOEllipsoid(CGO * I, const float *v1, float r, int CGOEllipsoid(CGO * I, const float *v1, float r,
const float *n1, const float *n1,
const float *n2, const float *n2,
const float *n3) const float *n3)
{ {
float *pc = CGO_add(I, 14); float *pc = CGO_add(I, CGO_ELLIPSOID_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_ELLIPSOID); CGO_write_int(pc, CGO_ELLIPSOID);
*(pc++) = *(v1++); *(pc++) = *(v1++);
*(pc++) = *(v1++); *(pc++) = *(v1++);
*(pc++) = *(v1++); *(pc++) = *(v1++);
*(pc++) = r; *(pc++) = r;
*(pc++) = *(n1++); *(pc++) = *(n1++);
*(pc++) = *(n1++); *(pc++) = *(n1++);
skipping to change at line 1067 skipping to change at line 940
*(pc++) = *(n2++); *(pc++) = *(n2++);
*(pc++) = *(n2++); *(pc++) = *(n2++);
*(pc++) = *(n3++); *(pc++) = *(n3++);
*(pc++) = *(n3++); *(pc++) = *(n3++);
*(pc++) = *(n3++); *(pc++) = *(n3++);
return true; return true;
} }
int CGOQuadric(CGO * I, const float *v, float r, const float *q) int CGOQuadric(CGO * I, const float *v, float r, const float *q)
{ {
float *pc = CGO_add(I, 15); float *pc = CGO_add(I, CGO_QUADRIC_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_QUADRIC); CGO_write_int(pc, CGO_QUADRIC);
*(pc++) = *(v++); *(pc++) = *(v++);
*(pc++) = *(v++); *(pc++) = *(v++);
*(pc++) = *(v++); *(pc++) = *(v++);
*(pc++) = r; *(pc++) = r;
*(pc++) = *(q++); *(pc++) = *(q++);
skipping to change at line 1091 skipping to change at line 964
*(pc++) = *(q++); *(pc++) = *(q++);
*(pc++) = *(q++); *(pc++) = *(q++);
*(pc++) = *(q++); *(pc++) = *(q++);
*(pc++) = *(q++); *(pc++) = *(q++);
*(pc++) = *(q++); *(pc++) = *(q++);
*(pc++) = *(q++); *(pc++) = *(q++);
return true; return true;
} }
int CGOSausage(CGO * I, const float *v1, const float *v2, float r, const float *
c1, const float *c2)
{
float *pc = CGO_add(I, 14);
if (!pc)
return false;
CGO_write_int(pc, CGO_SAUSAGE);
*(pc++) = *(v1++);
*(pc++) = *(v1++);
*(pc++) = *(v1++);
*(pc++) = *(v2++);
*(pc++) = *(v2++);
*(pc++) = *(v2++);
*(pc++) = r;
*(pc++) = *(c1++);
*(pc++) = *(c1++);
*(pc++) = *(c1++);
*(pc++) = *(c2++);
*(pc++) = *(c2++);
*(pc++) = *(c2++);
return true;
}
void CGOSetZVector(CGO * I, float z0, float z1, float z2) void CGOSetZVector(CGO * I, float z0, float z1, float z2)
{ {
I->z_flag = true; I->z_flag = true;
I->z_vector[0] = z0; I->z_vector[0] = z0;
I->z_vector[1] = z1; I->z_vector[1] = z1;
I->z_vector[2] = z2; I->z_vector[2] = z2;
I->z_min = FLT_MAX; I->z_min = FLT_MAX;
I->z_max = -FLT_MAX; I->z_max = -FLT_MAX;
} }
skipping to change at line 1138 skipping to change at line 989
const float *n1, const float *n2, const float *n3, const float *n1, const float *n2, const float *n3,
const float *c1, const float *c2, const float *c3, const float *c1, const float *c2, const float *c3,
float a1, float a2, float a3, int reverse) float a1, float a2, float a3, int reverse)
{ {
if(v1 && v2 && v3) { if(v1 && v2 && v3) {
float *pc = CGO_add(I, CGO_ALPHA_TRIANGLE_SZ + 1); float *pc = CGO_add(I, CGO_ALPHA_TRIANGLE_SZ + 1);
float z = _0; float z = _0;
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_ALPHA_TRIANGLE); CGO_write_int(pc, CGO_ALPHA_TRIANGLE);
CGO_write_int(pc, 0); CGO_write_int(pc, 0); // this is the place for the next triangle in the bin
*(pc++) = (v1[0] + v2[0] + v3[0]) * one_third; *(pc++) = (v1[0] + v2[0] + v3[0]) * one_third;
*(pc++) = (v1[1] + v2[1] + v3[1]) * one_third; *(pc++) = (v1[1] + v2[1] + v3[1]) * one_third;
*(pc++) = (v1[2] + v2[2] + v3[2]) * one_third; *(pc++) = (v1[2] + v2[2] + v3[2]) * one_third;
if(I->z_flag) { if(I->z_flag) {
float *zv = I->z_vector; float *zv = I->z_vector;
z = pc[-3] * zv[0] + pc[-2] * zv[1] + pc[-1] * zv[2]; z = pc[-3] * zv[0] + pc[-2] * zv[1] + pc[-1] * zv[2];
if(z > I->z_max) if(z > I->z_max)
I->z_max = z; I->z_max = z;
if(z < I->z_min) if(z < I->z_min)
I->z_min = z; I->z_min = z;
skipping to change at line 1220 skipping to change at line 1071
*(pc++) = *(c3++); *(pc++) = *(c3++);
*(pc++) = *(c3++); *(pc++) = *(c3++);
*(pc++) = *(c3++); *(pc++) = *(c3++);
*(pc++) = a3; *(pc++) = a3;
} }
return true; return true;
} }
int CGOVertex(CGO * I, float v1, float v2, float v3) int CGOVertex(CGO * I, float v1, float v2, float v3)
{ {
float *pc = CGO_add(I, 4); float *pc = CGO_add(I, CGO_VERTEX_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_VERTEX); CGO_write_int(pc, CGO_VERTEX);
*(pc++) = v1; *(pc++) = v1;
*(pc++) = v2; *(pc++) = v2;
*(pc++) = v3; *(pc++) = v3;
return true; return true;
} }
int CGOVertexv(CGO * I, const float *v) int CGOVertexv(CGO * I, const float *v)
{ {
float *pc = CGO_add(I, 4); float *pc = CGO_add(I, CGO_VERTEX_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_VERTEX); CGO_write_int(pc, CGO_VERTEX);
*(pc++) = *(v++); *(pc++) = *(v++);
*(pc++) = *(v++); *(pc++) = *(v++);
*(pc++) = *(v++); *(pc++) = *(v++);
return true; return true;
} }
int CGOVertexBeginLineStripv(CGO * I, const float *v)
{
float *pc = CGO_add(I, CGO_VERTEX_BEGIN_LINE_STRIP_SZ + 1);
if (!pc)
return false;
CGO_write_int(pc, CGO_VERTEX_BEGIN_LINE_STRIP);
*(pc++) = *(v++);
*(pc++) = *(v++);
*(pc++) = *(v++);
return true;
}
int CGOVertexCrossv(CGO * I, const float *v)
{
float *pc = CGO_add(I, CGO_VERTEX_CROSS_SZ + 1);
if (!pc)
return false;
CGO_write_int(pc, CGO_VERTEX_CROSS);
*(pc++) = *(v++);
*(pc++) = *(v++);
*(pc++) = *(v++);
return true;
}
int CGOInterpolated(CGO * I, const bool interp)
{
float *pc = CGO_add(I, CGO_INTERPOLATED_SZ + 1);
if (!pc)
return false;
CGO_write_int(pc, CGO_INTERPOLATED);
*(pc++) = interp ? 1.f : 0.f;
I->interpolated = interp;
return true;
}
int CGOColor(CGO * I, float v1, float v2, float v3) int CGOColor(CGO * I, float v1, float v2, float v3)
{ {
float *pc = CGO_add(I, 4); float *pc = CGO_add(I, CGO_COLOR_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_COLOR); CGO_write_int(pc, CGO_COLOR);
*(pc++) = v1; *(pc++) = v1;
*(pc++) = v2; *(pc++) = v2;
*(pc++) = v3; *(pc++) = v3;
I->color[0] = v1; I->color[0] = v1;
I->color[1] = v2; I->color[1] = v2;
I->color[2] = v3; I->color[2] = v3;
return true; return true;
} }
int CGOColorv(CGO * I, const float *v) int CGOColorv(CGO * I, const float *v)
{ {
return CGOColor(I, v[0], v[1], v[2]); return CGOColor(I, v[0], v[1], v[2]);
} }
int CGOTexCoord2f(CGO * I, float v1, float v2){ int CGOTexCoord2f(CGO * I, float v1, float v2){
float *pc = CGO_add(I, 3); float *pc = CGO_add(I, CGO_TEX_COORD_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_TEX_COORD); CGO_write_int(pc, CGO_TEX_COORD);
*(pc++) = v1; *(pc++) = v1;
*(pc++) = v2; *(pc++) = v2;
I->texture[0] = v1; I->texture[0] = v1;
I->texture[1] = v2; I->texture[1] = v2;
return true; return true;
} }
int CGOTexCoord2fv(CGO * I, float *v){
return CGOTexCoord2f(I, v[0], v[1]);
}
int CGONormal(CGO * I, float v1, float v2, float v3) int CGONormal(CGO * I, float v1, float v2, float v3)
{ {
float *pc = CGO_add(I, 4); float *pc = CGO_add(I, CGO_NORMAL_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_NORMAL); CGO_write_int(pc, CGO_NORMAL);
*(pc++) = v1; *(pc++) = v1;
*(pc++) = v2; *(pc++) = v2;
*(pc++) = v3; *(pc++) = v3;
I->normal[0] = v1; I->normal[0] = v1;
I->normal[1] = v2; I->normal[1] = v2;
I->normal[2] = v3; I->normal[2] = v3;
return true; return true;
} }
int CGOResetNormal(CGO * I, int mode) int CGOResetNormal(CGO * I, int mode)
{ {
float *pc = CGO_add(I, 2); float *pc = CGO_add(I, CGO_RESET_NORMAL_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_RESET_NORMAL); CGO_write_int(pc, CGO_RESET_NORMAL);
CGO_write_int(pc, mode); CGO_write_int(pc, mode);
SceneGetResetNormal(I->G, I->normal, mode); SceneGetResetNormal(I->G, I->normal, mode);
return true; return true;
} }
int CGOFontVertexv(CGO * I, const float *v) int CGOFontVertexv(CGO * I, const float *v)
{ {
float *pc = CGO_add(I, 4); float *pc = CGO_add(I, CGO_FONT_VERTEX_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_FONT_VERTEX); CGO_write_int(pc, CGO_FONT_VERTEX);
*(pc++) = *(v++); *(pc++) = *(v++);
*(pc++) = *(v++); *(pc++) = *(v++);
*(pc++) = *(v++); *(pc++) = *(v++);
return true; return true;
} }
int CGOFontVertex(CGO * I, float x, float y, float z) int CGOFontVertex(CGO * I, float x, float y, float z)
{ {
float *pc = CGO_add(I, 4); float *pc = CGO_add(I, CGO_FONT_VERTEX_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_FONT_VERTEX); CGO_write_int(pc, CGO_FONT_VERTEX);
*(pc++) = x; *(pc++) = x;
*(pc++) = y; *(pc++) = y;
*(pc++) = z; *(pc++) = z;
return true; return true;
} }
int CGOFontScale(CGO * I, float v1, float v2) int CGOFontScale(CGO * I, float v1, float v2)
{ {
float *pc = CGO_add(I, 3); float *pc = CGO_add(I, CGO_FONT_SCALE_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_FONT_SCALE); CGO_write_int(pc, CGO_FONT_SCALE);
*(pc++) = v1; *(pc++) = v1;
*(pc++) = v2; *(pc++) = v2;
return true; return true;
} }
int CGOChar(CGO * I, char c) int CGOChar(CGO * I, char c)
{ {
float *pc = CGO_add(I, 2); float *pc = CGO_add(I, CGO_CHAR_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_CHAR); CGO_write_int(pc, CGO_CHAR);
*(pc++) = (float) c; *(pc++) = (float) c;
return true; return true;
} }
int CGOIndent(CGO * I, char c, float dir) int CGOIndent(CGO * I, char c, float dir)
{ {
float *pc = CGO_add(I, 3); float *pc = CGO_add(I, CGO_INDENT_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_INDENT); CGO_write_int(pc, CGO_INDENT);
*(pc++) = (float) c; *(pc++) = (float) c;
*(pc++) = dir; *(pc++) = dir;
return true; return true;
} }
int CGOWrite(CGO * I, const char *str) int CGOWrite(CGO * I, const char *str)
{ {
float *pc; float *pc;
while(*str) { while(*str) {
pc = CGO_add(I, 2); pc = CGO_add(I, CGO_CHAR_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_CHAR); CGO_write_int(pc, CGO_CHAR);
*(pc++) = (float) *(str++); *(pc++) = (float) *(str++);
} }
return true; return true;
} }
int CGOWriteLeft(CGO * I, const char *str) int CGOWriteLeft(CGO * I, const char *str)
{ {
float *pc; float *pc;
const char *s = str; const char *s = str;
while(*s) { while(*s) {
pc = CGO_add(I, 3); pc = CGO_add(I, CGO_INDENT_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_INDENT); CGO_write_int(pc, CGO_INDENT);
*(pc++) = (float) *(s++); *(pc++) = (float) *(s++);
*(pc++) = -1.0F; *(pc++) = -1.0F;
} }
s = str; s = str;
while(*s) { while(*s) {
pc = CGO_add(I, 2); pc = CGO_add(I, CGO_CHAR_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_CHAR); CGO_write_int(pc, CGO_CHAR);
*(pc++) = (float) *(s++); *(pc++) = (float) *(s++);
} }
return true; return true;
} }
int CGOWriteIndent(CGO * I, const char *str, float indent) int CGOWriteIndent(CGO * I, const char *str, float indent)
{ {
float *pc; float *pc;
const char *s = str; const char *s = str;
while(*s) { while(*s) {
pc = CGO_add(I, 3); pc = CGO_add(I, CGO_INDENT_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_INDENT); CGO_write_int(pc, CGO_INDENT);
*(pc++) = (float) *(s++); *(pc++) = (float) *(s++);
*(pc++) = indent; *(pc++) = indent;
} }
s = str; s = str;
while(*s) { while(*s) {
pc = CGO_add(I, 2); pc = CGO_add(I, CGO_CHAR_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_CHAR); CGO_write_int(pc, CGO_CHAR);
*(pc++) = (float) *(s++); *(pc++) = (float) *(s++);
} }
return true; return true;
} }
int CGONormalv(CGO * I, const float *v) int CGONormalv(CGO * I, const float *v)
{ {
float *pc = CGO_add(I, 4); float *pc = CGO_add(I, CGO_NORMAL_SZ + 1);
if (!pc) if (!pc)
return false; return false;
CGO_write_int(pc, CGO_NORMAL); CGO_write_int(pc, CGO_NORMAL);
*(pc++) = *(v++); *(pc++) = *(v++);
*(pc++) = *(v++); *(pc++) = *(v++);
*(pc++) = *(v++); *(pc++) = *(v++);
return true; return true;
} }
/*
* Add a null terminator to the CGO buffer, but don't increment
* the size variable (CGO::c).
*/
int CGOStop(CGO * I) int CGOStop(CGO * I)
{ {
/* add enough zeros to prevent overrun in the event of corruption #define CGO_STOP_ZEROS 1
* (include more zeros than the longest instruction in the compiler
* although this is wasteful, it does prevent crashes...
*/
#define CGO_STOP_ZEROS 16
float *pc = CGO_size(I, I->c + CGO_STOP_ZEROS); float *pc = CGO_size(I, I->c + CGO_STOP_ZEROS);
if (!pc) if (!pc)
return false; return false;
UtilZeroMem(pc, sizeof(float) * CGO_STOP_ZEROS); UtilZeroMem(pc, sizeof(float) * CGO_STOP_ZEROS);
I->c -= CGO_STOP_ZEROS;
return true; return true;
} }
int CGOCheckComplex(CGO * I) int CGOCheckComplex(CGO * I)
{ {
float *pc = I->op; float *pc = I->op;
int fc = 0; int fc = 0;
int nEdge; int nEdge;
int op; int op;
SphereRec *sp; SphereRec *sp;
skipping to change at line 1476 skipping to change at line 1357
case CGO_CUSTOM_CYLINDER: case CGO_CUSTOM_CYLINDER:
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:
{ {
int narrays = CGO_get_int(pc + 2), nverts = CGO_get_int(pc + 3), floatlen cgo::draw::arrays * sp = reinterpret_cast<decltype(sp)>(pc);
gth = narrays*nverts; fc += sp->nverts;
fc += nverts;
pc += floatlength + 4 ;
} }
break; break;
case CGO_DRAW_BUFFERS_INDEXED: case CGO_DRAW_BUFFERS_INDEXED:
{ {
int mode = CGO_get_int(pc), nverts = CGO_get_int(pc + 4), nindices = CGO_ cgo::draw::buffers_indexed * sp = reinterpret_cast<decltype(sp)>(pc);
get_int(pc + 3); switch(sp->mode){
switch(mode){
case GL_TRIANGLES: case GL_TRIANGLES:
fc += nindices / 3; fc += sp->nindices / 3;
break; break;
case GL_LINES: case GL_LINES:
fc += nindices / 2; fc += sp->nindices / 2;
break; break;
} }
pc += nverts*3 + 10 ;
} }
break; break;
case CGO_DRAW_BUFFERS_NOT_INDEXED: case CGO_DRAW_BUFFERS_NOT_INDEXED:
{ {
int mode = CGO_get_int(pc), nverts = CGO_get_int(pc + 3); cgo::draw::buffers_not_indexed * sp = reinterpret_cast<decltype(sp)>(pc)
switch(mode){ ;
switch(sp->mode){
case GL_TRIANGLES: case GL_TRIANGLES:
fc += nverts / 3; fc += sp->nverts / 3;
break; break;
case GL_LINES: case GL_LINES:
fc += nverts / 2; fc += sp->nverts / 2;
break; break;
} }
pc += nverts*3 + 8 ; }
break;
case CGO_DRAW_SPHERE_BUFFERS:
{
cgo::draw::sphere_buffers * sp = reinterpret_cast<decltype(sp)>(pc);
fc += sp->num_spheres * VERTICES_PER_SPHERE;
}
break;
case CGO_DRAW_CYLINDER_BUFFERS:
{
cgo::draw::cylinder_buffers * sp = reinterpret_cast<decltype(sp)>(pc);
fc += sp->num_cyl * NUM_VERTICES_PER_CYLINDER;
} }
break; break;
} }
pc += CGO_sz[op]; pc += CGO_sz[op];
} }
return (fc); return (fc);
} }
int CGOPreloadFonts(CGO * I) int CGOPreloadFonts(CGO * I)
{ {
skipping to change at line 1538 skipping to change at line 1428
ok = ok && (VFontLoad(I->G, 1.0, 1, 1, true)); ok = ok && (VFontLoad(I->G, 1.0, 1, 1, true));
font_seen = true; font_seen = true;
break; break;
case CGO_CHAR: case CGO_CHAR:
if(!font_seen) { if(!font_seen) {
font_id = VFontLoad(I->G, 1.0, 1, 1, true); font_id = VFontLoad(I->G, 1.0, 1, 1, true);
ok = ok && font_id; ok = ok && font_id;
font_seen = true; font_seen = true;
} }
break; break;
case CGO_DRAW_ARRAYS:
{
int narrays = CGO_get_int(pc + 2), nverts = CGO_get_int(pc + 3), floatlen
gth = narrays*nverts;
pc += floatlength + 4 ;
}
break;
case CGO_DRAW_BUFFERS_INDEXED:
{
int nverts = CGO_get_int(pc + 4);
pc += nverts*3 + 10 ;
}
break;
case CGO_DRAW_BUFFERS_NOT_INDEXED:
{
int nverts = CGO_get_int(pc + 3);
pc += nverts*3 + 8 ;
}
break;
case CGO_DRAW_TEXTURES:
{
int ntextures = CGO_get_int(pc);
pc += ntextures * 18 + 4;
}
case CGO_DRAW_LABELS:
{
int nlabels = CGO_get_int(pc);
pc += nlabels * 18 + 5;
}
break;
} }
pc += CGO_sz[op]; pc += CGO_sz[op];
} }
if(blocked) if(blocked)
PUnblock(I->G); PUnblock(I->G);
return (ok); return (ok);
} }
int CGOCheckForText(CGO * I) int CGOCheckForText(CGO * I)
{ {
skipping to change at line 1595 skipping to change at line 1456
case CGO_FONT_SCALE: case CGO_FONT_SCALE:
fc++; fc++;
break; break;
case CGO_INDENT: case CGO_INDENT:
case CGO_FONT_VERTEX: case CGO_FONT_VERTEX:
fc++; fc++;
break; break;
case CGO_CHAR: case CGO_CHAR:
fc += 3 + 2 * 3 * 10; /* est 10 lines per char */ fc += 3 + 2 * 3 * 10; /* est 10 lines per char */
break; break;
case CGO_DRAW_ARRAYS:
{
int narrays = CGO_get_int(pc + 2), nverts = CGO_get_int(pc + 3), floatlen
gth = narrays*nverts;
pc += floatlength + 4 ;
}
break;
case CGO_DRAW_BUFFERS_INDEXED:
{
int nverts = CGO_get_int(pc + 4);
pc += nverts*3 + 10 ;
}
break;
case CGO_DRAW_BUFFERS_NOT_INDEXED:
{
int nverts = CGO_get_int(pc + 3);
pc += nverts*3 + 8 ;
}
break;
case CGO_DRAW_TEXTURES:
{
int ntextures = CGO_get_int(pc);
pc += ntextures * 18 + 4;
}
break;
case CGO_DRAW_LABELS:
{
int nlabels = CGO_get_int(pc);
pc += nlabels * 18 + 5;
}
break;
} }
pc += CGO_sz[op]; pc += CGO_sz[op];
} }
PRINTFD(I->G, FB_CGO) PRINTFD(I->G, FB_CGO)
" CGOCheckForText-Debug: %d\n", fc ENDFD; " CGOCheckForText-Debug: %d\n", fc ENDFD;
return (fc); return (fc);
} }
CGO *CGODrawText(CGO * I, int est, float *camera) CGO *CGODrawText(CGO * I, int est, float *camera)
{ /* assumes blocked intepreter */ { /* assumes blocked intepreter */
CGO *cgo; CGO *cgo;
float *pc = I->op; float *pc = I->op;
float *nc;
int op; int op;
float *save_pc; float *save_pc;
int sz;
int font_id = 0; int font_id = 0;
char text[2] = " "; char text[2] = " ";
float pos[] = { 0.0F, 0.0F, 0.0F }; float pos[] = { 0.0F, 0.0F, 0.0F };
float axes[] = { 1.0F, 0.0F, 0.0F, float axes[] = { 1.0F, 0.0F, 0.0F,
0.0F, 1.0F, 0.0F, 0.0F, 1.0F, 0.0F,
0.0F, 0.0F, 1.0F 0.0F, 0.0F, 1.0F
}; };
float scale[2] = { 1.0, 1.0 }; float scale[2] = { 1.0, 1.0 };
cgo = CGONewSized(I->G, I->c + est); cgo = CGONewSized(I->G, I->c + est);
skipping to change at line 1677 skipping to change at line 1505
break; break;
case CGO_INDENT: case CGO_INDENT:
text[0] = (unsigned char) *pc; text[0] = (unsigned char) *pc;
VFontIndent(I->G, font_id, text, pos, scale, axes, pc[1]); VFontIndent(I->G, font_id, text, pos, scale, axes, pc[1]);
break; break;
case CGO_CHAR: case CGO_CHAR:
if(!font_id) { if(!font_id) {
font_id = VFontLoad(I->G, 1.0, 1, 1, false); font_id = VFontLoad(I->G, 1.0, 1, 1, false);
} }
text[0] = (unsigned char) *pc; text[0] = (unsigned char) *pc;
VFontWriteToCGO(I->G, font_id, cgo, text, pos, scale, axes); VFontWriteToCGO(I->G, font_id, cgo, text, pos, scale, axes, cgo->color);
break;
case CGO_DRAW_ARRAYS:
{
int narrays = CGO_get_int(pc + 2), nverts = CGO_get_int(pc + 3), tsz;
sz = narrays*nverts + 4 ;
tsz = sz;
nc = CGO_add(cgo, sz + 1);
*(nc++) = *(pc - 1);
while(sz--)
*(nc++) = *(pc++);
save_pc += tsz ;
}
break;
case CGO_DRAW_BUFFERS_INDEXED:
{
int nverts = CGO_get_int(pc + 4), tsz;
sz = nverts*3 + 10 ;
tsz = sz;
nc = CGO_add(cgo, sz + 1);
*(nc++) = *(pc - 1);
while(sz--)
*(nc++) = *(pc++);
save_pc += tsz ;
}
break;
case CGO_DRAW_TEXTURES:
{
int ntextures = CGO_get_int(pc), tsz;
sz = ntextures * 18 + 4;
tsz = sz;
nc = CGO_add(cgo, sz + 1);
*(nc++) = *(pc - 1);
while(sz--)
*(nc++) = *(pc++);
save_pc += tsz ;
}
break;
case CGO_DRAW_LABELS:
{
int nlabels = CGO_get_int(pc), tsz;
sz = nlabels * 18 + 5;
tsz = sz;
nc = CGO_add(cgo, sz + 1);
*(nc++) = *(pc - 1);
while(sz--)
*(nc++) = *(pc++);
save_pc += tsz ;
}
break;
case CGO_DRAW_BUFFERS_NOT_INDEXED:
{
int nverts = CGO_get_int(pc + 3), tsz;
sz = nverts*3 + 8 ;
tsz = sz;
nc = CGO_add(cgo, sz + 1);
*(nc++) = *(pc - 1);
while(sz--)
*(nc++) = *(pc++);
save_pc += tsz ;
}
break; break;
case CGO_COLOR:
cgo->color[0] = *pc; cgo->color[1] = *(pc + 1); cgo->color[2] = *(pc + 2);
default: default:
sz = CGO_sz[op]; cgo->add_to_cgo(op, pc);
nc = CGO_add(cgo, sz + 1);
*(nc++) = *(pc - 1);
while(sz--)
*(nc++) = *(pc++);
} }
pc = save_pc; pc = save_pc;
pc += CGO_sz[op]; pc += CGO_sz[op];
} }
CGOStop(cgo); CGOStop(cgo);
if (cgo && cgo->has_begin_end){ if (cgo && cgo->has_begin_end){
/* this is mainly for VFontWriteToCGO() that still creates CGOBegin/CGOEnd * / /* this is mainly for VFontWriteToCGO() that still creates CGOBegin/CGOEnd * /
if(cgo && cgo->has_begin_end){ if(cgo && cgo->has_begin_end){
CGO *convertcgo = NULL; CGO *convertcgo = NULL;
convertcgo = CGOCombineBeginEnd(cgo, 0); convertcgo = CGOCombineBeginEnd(cgo, 0);
CGOFree(cgo); CGOFree(cgo);
cgo = convertcgo; cgo = convertcgo;
} }
} }
return (cgo); return (cgo);
} }
static
void CGOAddVertexToDrawArrays(CGO *cgo, int pl, int plc, int pla, const float *v
ertex,
short notHaveValue, float *vertexVals, float *norm
alVals,
float *colorVals, float *pickColorVals, float *acc
essibilityVals){
float *tmp_ptr;
if (notHaveValue & CGO_NORMAL_ARRAY){
if (pl){
tmp_ptr = &normalVals[pl-3];
copy3f(tmp_ptr, &normalVals[pl]);
} else {
copy3f(cgo->normal, &normalVals[pl]);
}
}
if (notHaveValue & CGO_COLOR_ARRAY){
if (plc){
tmp_ptr = &colorVals[plc-4];
copy4f(tmp_ptr, &colorVals[plc]);
} else {
copy3f(&colorVals[plc], cgo->color);
colorVals[plc+3] = cgo->alpha;
}
}
if (pickColorVals){
CGO_put_uint(pickColorVals + pla * 2, cgo->current_pick_color_index);
CGO_put_int(pickColorVals + pla * 2 + 1, cgo->current_pick_color_bond);
}
if (accessibilityVals){
accessibilityVals[pla] = cgo->current_accessibility;
}
copy3f(vertex, &vertexVals[pl]);
}
bool CGOCombineBeginEnd(CGO ** I, bool do_not_split_lines) { bool CGOCombineBeginEnd(CGO ** I, bool do_not_split_lines) {
CGO *cgo = CGOCombineBeginEnd(*I, 0); CGO *cgo = CGOCombineBeginEnd(*I, 0, do_not_split_lines);
CGOFree(*I); CGOFree(*I);
*I = cgo; *I = cgo;
return (cgo != NULL); return (cgo != NULL);
} }
CGO *CGOCombineBeginEnd(const CGO * I, int est) CGO *CGOCombineBeginEnd(const CGO * I, int est, bool do_not_split_lines)
{ {
CGO *cgo; CGO *cgo;
float *nc;
int op;
float *save_pc;
int sz;
int ok = true; int ok = true;
if (!I) if (!I)
return NULL; return NULL;
auto pc = I->op;
cgo = CGONewSized(I->G, 0); cgo = CGONewSized(I->G, 0);
ok &= cgo ? true : false; ok &= cgo ? true : false;
while(ok && (op = (CGO_MASK & CGO_read_int(pc)))) { for (auto it = I->begin(); ok && !it.is_stop(); ++it) {
save_pc = pc; auto pc = it.data();
switch (op) { int op = it.op_code();
case CGO_DRAW_ARRAYS:
{
int mode = CGO_get_int(pc), arrays = CGO_get_int(pc + 1), narrays = CGO_g
et_int(pc + 2), nverts = CGO_get_int(pc + 3);
GLfloat *vals = CGODrawArrays(cgo, mode, arrays, nverts);
int nvals = narrays*nverts, onvals ;
ok &= vals ? true : false; switch (op) {
if (ok){
onvals = nvals;
pc += 4;
while(nvals--)
*(vals++) = *(pc++);
save_pc += onvals + 4 ;
}
}
break;
case CGO_END: case CGO_END:
case CGO_VERTEX: case CGO_VERTEX:
PRINTFB(I->G, FB_CGO, FB_Warnings) PRINTFB(I->G, FB_CGO, FB_Warnings)
" CGOCombineBeginEnd: op=0x%02x encountered without CGO_BEGIN\n", op " CGOCombineBeginEnd: op=0x%02x encountered without CGO_BEGIN\n", op
ENDFB(I->G); ENDFB(I->G);
break; break;
case CGO_BEGIN: case CGO_BEGIN:
{ {
float *origpc = pc;
float firstColor[3], firstAlpha; float firstColor[3], firstAlpha;
char hasFirstColor = 0, hasFirstAlpha = 0; char hasFirstColor = 0, hasFirstAlpha = 0;
int nverts = 0, damode = CGO_VERTEX_ARRAY, err = 0; int nverts = 0, damode = CGO_VERTEX_ARRAY, err = 0;
int end = 0;
// read int argument of the BEGIN operation // read int argument of the BEGIN operation
int mode = CGO_read_int(pc); int mode = CGO_get_int(it.data());
++it;
// first iteration over BEGIN/END block (consumes 'it')
while(ok && !err && !end && (op = (CGO_MASK & CGO_read_int(pc)))) { // we want to iterate twice over the BEGIN/END block
switch (op) { auto it2 = it;
// first iteration over BEGIN/END block (consumes 'it')
for (; !err && it != CGO_END; ++it) {
auto pc = it.data();
switch (it.op_code()) {
case CGO_DRAW_ARRAYS: case CGO_DRAW_ARRAYS:
case CGO_STOP: case CGO_STOP:
PRINTFB(I->G, FB_CGO, FB_Errors) PRINTFB(I->G, FB_CGO, FB_Errors)
" CGO-Error: CGOCombineBeginEnd: invalid op=0x%02x inside BEGIN/END \n", " CGO-Error: CGOCombineBeginEnd: invalid op=0x%02x inside BEGIN/END \n",
op ENDFB(I->G); it.op_code() ENDFB(I->G);
err = true; err = true;
continue; continue;
case CGO_NORMAL: case CGO_NORMAL:
damode |= CGO_NORMAL_ARRAY; damode |= CGO_NORMAL_ARRAY;
break; break;
case CGO_COLOR: case CGO_COLOR:
if (!nverts){ if (!nverts){
hasFirstColor = 1; hasFirstColor = 1;
copy3f(pc, firstColor); copy3f(pc, firstColor);
} else { } else {
skipping to change at line 1852 skipping to change at line 1634
break; break;
case CGO_PICK_COLOR: case CGO_PICK_COLOR:
damode |= CGO_PICK_COLOR_ARRAY; damode |= CGO_PICK_COLOR_ARRAY;
break; break;
case CGO_ACCESSIBILITY: case CGO_ACCESSIBILITY:
damode |= CGO_ACCESSIBILITY_ARRAY; damode |= CGO_ACCESSIBILITY_ARRAY;
break; break;
case CGO_VERTEX: case CGO_VERTEX:
nverts++; nverts++;
break; break;
case CGO_END:
end = 1;
break;
case CGO_ALPHA: case CGO_ALPHA:
cgo->alpha = *pc; cgo->alpha = *pc;
if (!nverts){ if (!nverts){
hasFirstAlpha = 1; hasFirstAlpha = 1;
firstAlpha = cgo->alpha; firstAlpha = cgo->alpha;
} else { } else {
hasFirstAlpha = 0; hasFirstAlpha = 0;
damode |= CGO_COLOR_ARRAY; damode |= CGO_COLOR_ARRAY;
} }
default: break;
break; case CGO_LINE:
nverts+=2;
break;
case CGO_SPLITLINE:
{
auto splitline = reinterpret_cast<const cgo::draw::splitline *>(pc
);
if (do_not_split_lines || (splitline->flags & cgo::draw::splitline
::equal_colors)){
nverts+=2;
} else {
nverts+=4;
}
}
break;
} }
sz = CGO_sz[op];
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; float *vertexVals;
float *tmp_ptr;
float *normalVals, *colorVals = 0, *nxtVals = 0, *pickColorVals = 0, *a ccessibilityVals = 0; float *normalVals, *colorVals = 0, *nxtVals = 0, *pickColorVals = 0, *a ccessibilityVals = 0;
uchar *pickColorValsUC;
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 = CGODrawArrays(cgo, mode, damode, nverts); nxtVals = vertexVals = cgo->add<cgo::draw::arrays>(mode, damode, nverts );
ok &= vertexVals ? true : false; ok &= vertexVals ? true : false;
if (!ok) if (!ok)
continue; continue;
if (damode & CGO_NORMAL_ARRAY){ if (damode & CGO_NORMAL_ARRAY){
nxtVals = normalVals = vertexVals + (nxtn*nverts); nxtVals = normalVals = vertexVals + (nxtn*nverts);
nxtn = 3; nxtn = 3;
} }
if (damode & CGO_COLOR_ARRAY){ if (damode & CGO_COLOR_ARRAY){
nxtVals = colorVals = nxtVals + (nxtn*nverts); nxtVals = colorVals = nxtVals + (nxtn*nverts);
nxtn = 4; nxtn = 4;
} }
if (damode & CGO_PICK_COLOR_ARRAY){ if (damode & CGO_PICK_COLOR_ARRAY){
nxtVals = nxtVals + (nxtn*nverts); nxtVals = nxtVals + (nxtn*nverts);
pickColorVals = nxtVals + nverts; pickColorVals = nxtVals + nverts;
pickColorValsUC = (uchar*)nxtVals;
nxtn = 3; nxtn = 3;
} }
if (damode & CGO_ACCESSIBILITY_ARRAY){ if (damode & CGO_ACCESSIBILITY_ARRAY){
nxtVals = nxtVals + (nxtn*nverts); nxtVals = nxtVals + (nxtn*nverts);
accessibilityVals = nxtVals; accessibilityVals = nxtVals;
nxtn = 1; nxtn = 1;
} }
pc = origpc + 1;
notHaveValue = damode; notHaveValue = damode;
end = 0;
// second iteration (with copy of iterator, doesn't consume 'it') // second iteration (with copy of iterator, doesn't consume 'it')
while(ok && !err && !end && (op = (CGO_MASK & CGO_read_int(pc)))) { for (; ok && it2 != CGO_END; ++it2) {
switch (op) { auto pc = it2.data();
switch (it2.op_code()) {
case CGO_NORMAL: case CGO_NORMAL:
copy3f(pc, &normalVals[pl]); copy3f(pc, &normalVals[pl]);
notHaveValue &= ~CGO_NORMAL_ARRAY; notHaveValue &= ~CGO_NORMAL_ARRAY;
break; break;
case CGO_COLOR: case CGO_COLOR:
if (colorVals){ if (colorVals){
copy3f(pc, &colorVals[plc]); copy3f(pc, &colorVals[plc]);
colorVals[plc+3] = cgo->alpha; colorVals[plc+3] = cgo->alpha;
notHaveValue &= ~CGO_COLOR_ARRAY; notHaveValue &= ~CGO_COLOR_ARRAY;
} }
copy3f(pc, cgo->color);
break; break;
case CGO_PICK_COLOR: case CGO_PICK_COLOR:
/* TODO need to move uchar and index/bond separately into pickColor cgo->current_pick_color_index = CGO_get_uint(pc);
Vals */
CGO_put_int(&pickColorVals[pla * 2], CGO_get_int(pc));
CGO_put_int(&pickColorVals[pla * 2 + 1], CGO_get_int(pc+1));
cgo->current_pick_color_index = CGO_get_int(pc);
cgo->current_pick_color_bond = CGO_get_int(pc + 1); cgo->current_pick_color_bond = CGO_get_int(pc + 1);
notHaveValue &= ~CGO_PICK_COLOR_ARRAY; notHaveValue &= ~CGO_PICK_COLOR_ARRAY;
break; break;
case CGO_ACCESSIBILITY: case CGO_ACCESSIBILITY:
cgo->current_accessibility = pc[0]; cgo->current_accessibility = pc[0];
break; break;
case CGO_SPLITLINE:
{
auto splitline = reinterpret_cast<const cgo::draw::splitline *>(
pc);
float color2[] = { CONVERT_COLOR_VALUE(splitline->color2[0]),
CONVERT_COLOR_VALUE(splitline->color2[1]),
CONVERT_COLOR_VALUE(splitline->color2[2]) };
if (do_not_split_lines || (splitline->flags & cgo::draw::splitli
ne::equal_colors)){
CGOAddVertexToDrawArrays(cgo, pl, plc, pla, splitline->vertex1
, notHaveValue, vertexVals,
normalVals, colorVals, pickColorVals,
accessibilityVals);
pl+=3; plc+=4; pla++;
notHaveValue = damode;
if (!(splitline->flags & cgo::draw::splitline::equal_colors)){
if (colorVals){
copy3f(color2, &colorVals[plc]);
colorVals[plc+3] = cgo->alpha;
notHaveValue = notHaveValue & ~CGO_COLOR_ARRAY;
}
copy3f(color2, cgo->color);
}
if (pickColorVals){
cgo->current_pick_color_index = splitline->index;
cgo->current_pick_color_bond = splitline->bond;
notHaveValue = notHaveValue & ~CGO_PICK_COLOR_ARRAY;
}
CGOAddVertexToDrawArrays(cgo, pl, plc, pla, splitline->vertex2
, notHaveValue, vertexVals,
normalVals, colorVals, pickColorVals,
accessibilityVals);
pl+=3; plc+=4; pla++;
notHaveValue = damode;
} else {
float mid[3];
add3f(splitline->vertex1, splitline->vertex2, mid);
mult3f(mid, .5f, mid);
CGOAddVertexToDrawArrays(cgo, pl, plc, pla, splitline->vertex1
, notHaveValue, vertexVals,
normalVals, colorVals, pickColorVals,
accessibilityVals);
notHaveValue = damode;
pl+=3; plc+=4; pla++;
CGOAddVertexToDrawArrays(cgo, pl, plc, pla, mid, notHaveValue,
vertexVals,
normalVals, colorVals, pickColorVals,
accessibilityVals);
pl+=3; plc+=4; pla++;
if (colorVals){
copy3f(color2, &colorVals[plc]);
colorVals[plc+3] = cgo->alpha;
notHaveValue = notHaveValue & ~CGO_COLOR_ARRAY;
}
copy3f(color2, cgo->color);
if (pickColorVals){
cgo->current_pick_color_index = splitline->index;
cgo->current_pick_color_bond = splitline->bond;
notHaveValue = notHaveValue & ~CGO_PICK_COLOR_ARRAY;
}
CGOAddVertexToDrawArrays(cgo, pl, plc, pla, mid, notHaveValue,
vertexVals,
normalVals, colorVals, pickColorVals,
accessibilityVals);
notHaveValue = damode;
pl+=3; plc+=4; pla++;
CGOAddVertexToDrawArrays(cgo, pl, plc, pla, splitline->vertex2
, notHaveValue, vertexVals,
normalVals, colorVals, pickColorVals,
accessibilityVals);
pl+=3; plc+=4; pla++;
notHaveValue = damode;
}
}
break;
case CGO_LINE:
{
auto line = reinterpret_cast<const cgo::draw::line *>(pc);
CGOAddVertexToDrawArrays(cgo, pl, plc, pla, line->vertex1, notHa
veValue, vertexVals,
normalVals, colorVals, pickColorVals, a
ccessibilityVals);
pl+=3; plc+=4; pla++;
notHaveValue = damode;
CGOAddVertexToDrawArrays(cgo, pl, plc, pla, line->vertex2, notHa
veValue, vertexVals,
normalVals, colorVals, pickColorVals, a
ccessibilityVals);
pl+=3; plc+=4; pla++;
}
break;
case CGO_VERTEX: case CGO_VERTEX:
if (notHaveValue & CGO_NORMAL_ARRAY){ CGOAddVertexToDrawArrays(cgo, pl, plc, pla, pc, notHaveValue, vert
tmp_ptr = &normalVals[pl-3]; exVals,
normalVals[pl] = tmp_ptr[0]; normalVals[pl+1] = tmp_ptr[1]; norma normalVals, colorVals, pickColorVals, acc
lVals[pl+2] = tmp_ptr[2]; essibilityVals);
} pl+=3; plc+=4; pla++;
if (notHaveValue & CGO_COLOR_ARRAY){
tmp_ptr = &colorVals[plc-4];
colorVals[plc] = tmp_ptr[0]; colorVals[plc+1] = tmp_ptr[1];
colorVals[plc+2] = tmp_ptr[2]; colorVals[plc+3] = tmp_ptr[3];
}
if (notHaveValue & CGO_PICK_COLOR_ARRAY){
CGO_put_int(pickColorVals + pla * 2, cgo->current_pick_color_inde
x);
CGO_put_int(pickColorVals + pla * 2 + 1, cgo->current_pick_color_
bond);
}
if (accessibilityVals){
accessibilityVals[pla] = cgo->current_accessibility;
}
vertexVals[pl++] = pc[0]; vertexVals[pl++] = pc[1]; vertexVals[pl++
] = pc[2];
plc+=4;
pla++;
notHaveValue = damode; notHaveValue = damode;
break; break;
case CGO_END:
end = 1;
break;
case CGO_ALPHA: case CGO_ALPHA:
cgo->alpha = *pc; cgo->alpha = *pc;
default:
break;
} }
sz = CGO_sz[op];
pc += sz;
} }
} }
save_pc = pc;
op = CGO_NULL;
} }
break; break;
case CGO_PICK_COLOR:
cgo->current_pick_color_index = CGO_get_uint(pc);
cgo->current_pick_color_bond = CGO_get_int(pc + 1);
cgo->add_to_cgo(op, pc);
break;
case CGO_ALPHA: case CGO_ALPHA:
cgo->alpha = *pc; cgo->alpha = *pc;
default: default:
sz = CGO_sz[op]; cgo->add_to_cgo(op, pc);
nc = CGO_add(cgo, sz + 1);
ok &= nc ? true : false;
if (!ok)
break;
*(nc++) = *(pc - 1);
while(sz--)
*(nc++) = *(pc++);
} }
pc = save_pc;
pc += CGO_sz[op];
} }
if (ok){ if (ok){
ok &= CGOStop(cgo); ok &= CGOStop(cgo);
if (ok){ if (ok){
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_shade r_ub_normal); cgo->cgo_shader_ub_normal = SettingGetGlobal_i(cgo->G, cSetting_cgo_shade r_ub_normal);
} }
} }
} }
if (!ok){ if (!ok){
CGOFree(cgo); CGOFree(cgo);
} }
return (cgo); return (cgo);
} }
void CGOFreeVBOs(CGO *I){ void CGOFreeVBOs(CGO * I) {
CGOFreeStruct(I, true);
}
void CGOFreeStruct(CGO *I, bool freevbos){
float *pc = I->op; float *pc = I->op;
int op = 0; int op = 0;
float *save_pc = NULL;
int numbufs = 0, bufoffset;
while((op = (CGO_MASK & CGO_read_int(pc)))) { while((op = (CGO_MASK & CGO_read_int(pc)))) {
save_pc = pc;
numbufs = 0;
bufoffset = 0;
switch (op) { switch (op) {
case CGO_DRAW_TRILINES:
{
int buf = CGO_get_int(pc + 1);
if (freevbos)
I->G->ShaderMgr->AddVBOToFree(buf);
}
break;
case CGO_DRAW_CUSTOM:
{
cgo::draw::custom * sp = reinterpret_cast<decltype(sp)>(pc);
if (freevbos) {
I->G->ShaderMgr->freeGPUBuffer(sp->vboid);
I->G->ShaderMgr->freeGPUBuffer(sp->iboid);
I->G->ShaderMgr->freeGPUBuffer(sp->pickvboid);
}
}
break;
case CGO_DRAW_SPHERE_BUFFERS: case CGO_DRAW_SPHERE_BUFFERS:
numbufs = 3; {
bufoffset = 2; cgo::draw::sphere_buffers * sp = reinterpret_cast<decltype(sp)>(pc);
case CGO_DRAW_LABELS: if (freevbos) {
if (!numbufs){ I->G->ShaderMgr->freeGPUBuffer(sp->vboid);
numbufs = 4; I->G->ShaderMgr->freeGPUBuffer(sp->pickvboid);
bufoffset = 1;
} }
}
break;
case CGO_DRAW_LABELS:
{
cgo::draw::labels * sp;
sp = reinterpret_cast<decltype(sp)>(pc);
if (freevbos) {
I->G->ShaderMgr->freeGPUBuffer(sp->vboid);
I->G->ShaderMgr->freeGPUBuffer(sp->pickvboid);
}
}
break;
case CGO_DRAW_TEXTURES: case CGO_DRAW_TEXTURES:
{
cgo::draw::textures * sp = reinterpret_cast<decltype(sp)>(pc);
if (freevbos)
I->G->ShaderMgr->freeGPUBuffer(sp->vboid);
}
break;
case CGO_DRAW_SCREEN_TEXTURES_AND_POLYGONS: case CGO_DRAW_SCREEN_TEXTURES_AND_POLYGONS:
if (!numbufs){ {
numbufs = 3; cgo::draw::screen_textures * sp;
bufoffset = 1; sp = reinterpret_cast<decltype(sp)>(pc);
} if (freevbos)
I->G->ShaderMgr->freeGPUBuffer(sp->vboid);
}
break;
case CGO_DRAW_CYLINDER_BUFFERS: case CGO_DRAW_CYLINDER_BUFFERS:
if (!numbufs){ {
numbufs = 5; cgo::draw::cylinder_buffers * sp = reinterpret_cast<decltype(sp)>(pc);
bufoffset = 2; if (freevbos) {
} I->G->ShaderMgr->freeGPUBuffer(sp->vboid);
case CGO_DRAW_BUFFERS: I->G->ShaderMgr->freeGPUBuffer(sp->iboid);
if (!numbufs){ I->G->ShaderMgr->freeGPUBuffer(sp->pickvboid);
numbufs = 4;
bufoffset = 4;
} }
}
break;
case CGO_DRAW_BUFFERS_NOT_INDEXED: case CGO_DRAW_BUFFERS_NOT_INDEXED:
if (!numbufs){ {
numbufs = 4; cgo::draw::buffers_not_indexed * sp;
bufoffset = 4; sp = reinterpret_cast<decltype(sp)>(pc);
if (freevbos) {
I->G->ShaderMgr->freeGPUBuffer(sp->vboid);
I->G->ShaderMgr->freeGPUBuffer(sp->pickvboid);
} }
}
break;
case CGO_DRAW_BUFFERS_INDEXED: case CGO_DRAW_BUFFERS_INDEXED:
if (!numbufs){ {
numbufs = 5; cgo::draw::buffers_indexed * sp = reinterpret_cast<decltype(sp)>(pc);
bufoffset = 5; if (freevbos) {
} I->G->ShaderMgr->freeGPUBuffers({ sp->vboid, sp->iboid, sp->pickvboid })
{ ;
int i, buf;
for (i=0; i<numbufs; i++){
buf = CGO_get_int(pc+bufoffset+i);
if (buf){
CShaderMgr_AddVBOToFree(I->G->ShaderMgr, buf);
}
}
switch (op){
case CGO_DRAW_BUFFERS_INDEXED:
{
int nverts = CGO_get_int(pc + 4);
pc += nverts*3 + 10;
save_pc += nverts*3 + 10 ;
}
break;
case CGO_DRAW_BUFFERS_NOT_INDEXED:
{
int nverts = CGO_get_int(pc + 3);
pc += nverts*3 + 8;
save_pc += nverts*3 + 8 ;
}
break;
case CGO_DRAW_TEXTURES:
{
int ntextures = CGO_get_int(pc);
pc += ntextures * 18 + 4;
save_pc += ntextures * 18 + 4;
}
break;
case CGO_DRAW_LABELS:
{
int nlabels = CGO_get_int(pc);
pc += nlabels * 18 + 5;
save_pc += nlabels * 18 + 5;
}
break;
}
}
break;
case CGO_DRAW_ARRAYS:
{
int narrays = CGO_get_int(pc + 2), nverts = CGO_get_int(pc + 3);
int nvals = narrays*nverts;
pc += nvals + 4;
save_pc += nvals + 4 ;
} }
break; }
break;
case CGO_DRAW_CONNECTORS:
{
cgo::draw::connectors * sp;
sp = reinterpret_cast<decltype(sp)>(pc);
if (freevbos)
I->G->ShaderMgr->freeGPUBuffer(sp->vboid);
}
break;
default: default:
break; break;
} }
pc = save_pc;
pc += CGO_sz[op]; pc += CGO_sz[op];
} }
} }
#define set_min_max(mn, mx, pt) { \ #define set_min_max(mn, mx, pt) { \
if (mn[0]>*pt) mn[0] = *pt; \ if (mn[0]>*pt) mn[0] = *pt; \
if (mn[1]>*(pt+1)) mn[1] = *(pt+1); \ if (mn[1]>*(pt+1)) mn[1] = *(pt+1); \
if (mn[2]>*(pt+2)) mn[2] = *(pt+2); \ if (mn[2]>*(pt+2)) mn[2] = *(pt+2); \
if (mx[0]<*pt) mx[0] = *pt; \ if (mx[0]<*pt) mx[0] = *pt; \
if (mx[1]<*(pt+1)) mx[1] = *(pt+1); \ if (mx[1]<*(pt+1)) mx[1] = *(pt+1); \
if (mx[2]<*(pt+2)) mx[2] = *(pt+2);} if (mx[2]<*(pt+2)) mx[2] = *(pt+2);}
void CGOCountNumVertices(CGO *I, int *num_total_vertices, int *num_total_indexes , static void CGOCountNumVertices(const CGO *I, int *num_total_vertices, int *num_ total_indexes,
int *num_total_vertices_lines, int *num_total_indexes_li nes, int *num_total_vertices_lines, int *num_total_indexes_li nes,
int *num_total_vertices_points); int *num_total_vertices_points);
void CGOCountNumVerticesDEBUG(CGO *I){ void CGOCountNumVerticesDEBUG(const CGO *I){
int num_total_vertices=0, num_total_indexes=0, num_total_vertices_lines=0, num _total_indexes_lines=0, num_total_vertices_points=0; int num_total_vertices=0, num_total_indexes=0, num_total_vertices_lines=0, num _total_indexes_lines=0, num_total_vertices_points=0;
CGOCountNumVertices(I, &num_total_vertices, &num_total_indexes, &num_total_ver tices_lines, &num_total_indexes_lines, &num_total_vertices_points); CGOCountNumVertices(I, &num_total_vertices, &num_total_indexes, &num_total_ver tices_lines, &num_total_indexes_lines, &num_total_vertices_points);
printf("CGOCountNumVerticesDEBUG: num_total_vertices=%d num_total_indexes=%d n um_total_vertices_lines=%d num_total_indexes_lines=%d num_total_vertices_points= %d\n", num_total_vertices, num_total_indexes, num_total_vertices_lines, num_tota l_indexes_lines, num_total_vertices_points); printf("CGOCountNumVerticesDEBUG: num_total_vertices=%d num_total_indexes=%d n um_total_vertices_lines=%d num_total_indexes_lines=%d num_total_vertices_points= %d\n", num_total_vertices, num_total_indexes, num_total_vertices_lines, num_tota l_indexes_lines, num_total_vertices_points);
} }
void CGOCountNumVertices(CGO *I, int *num_total_vertices, int *num_total_indexes , static void CGOCountNumVertices(const CGO *I, int *num_total_vertices, int *num_ total_indexes,
int *num_total_vertices_lines, int *num_total_indexes_li nes, int *num_total_vertices_lines, int *num_total_indexes_li nes,
int *num_total_vertices_points){ int *num_total_vertices_points){
float *pc = I->op; float *pc = I->op;
int op = 0; int op = 0;
float *save_pc = NULL;
int verts_skipped = 0; int verts_skipped = 0;
short err = 0; short err = 0;
while((op = (CGO_MASK & CGO_read_int(pc)))) { while((op = (CGO_MASK & CGO_read_int(pc)))) {
save_pc = pc;
err = 0; err = 0;
switch (op) { switch (op) {
case CGO_DRAW_ARRAYS: case CGO_DRAW_ARRAYS:
{ {
int mode = CGO_get_int(pc), narrays = CGO_get_int(pc + 2), nverts = CGO_g et_int(pc + 3); cgo::draw::arrays * sp = reinterpret_cast<decltype(sp)>(pc);
short shouldCompress = false, shouldCompressLines = false, shouldCompress Points = false; short shouldCompress = false, shouldCompressLines = false, shouldCompress Points = false;
switch(mode){ switch(sp->mode){
case GL_TRIANGLE_FAN: case GL_TRIANGLE_FAN:
case GL_TRIANGLE_STRIP: case GL_TRIANGLE_STRIP:
case GL_TRIANGLES: case GL_TRIANGLES:
shouldCompress = true; shouldCompress = true;
break; break;
case GL_LINES: case GL_LINES:
case GL_LINE_STRIP: case GL_LINE_STRIP:
case GL_LINE_LOOP: case GL_LINE_LOOP:
shouldCompressLines = true; shouldCompressLines = true;
break; break;
case GL_POINTS: case GL_POINTS:
shouldCompressPoints = true; shouldCompressPoints = true;
break; break;
default: default:
break; break;
} }
if (!shouldCompress && !shouldCompressLines && !shouldCompressPoints){ if (!shouldCompress && !shouldCompressLines && !shouldCompressPoints){
verts_skipped += nverts; verts_skipped += sp->nverts;
{
int narrays = CGO_get_int(pc + 2), nverts = CGO_get_int(pc + 3);
int nvals = narrays*nverts, onvals ;
onvals = nvals;
pc += 4;
save_pc += onvals + 4 ;
}
} else if (shouldCompressLines) { } else if (shouldCompressLines) {
int nvals = narrays*nverts ; *num_total_vertices_lines += sp->nverts;
pc += nvals + 4; switch(sp->mode){
save_pc += nvals + 4 ;
*num_total_vertices_lines += nverts;
switch(mode){
case GL_LINE_LOOP: case GL_LINE_LOOP:
*num_total_indexes_lines += 2 * nverts; *num_total_indexes_lines += 2 * sp->nverts;
break; break;
case GL_LINE_STRIP: case GL_LINE_STRIP:
*num_total_indexes_lines += 2 * (nverts - 1); *num_total_indexes_lines += 2 * (sp->nverts - 1);
break; break;
case GL_LINES: case GL_LINES:
*num_total_indexes_lines += nverts; *num_total_indexes_lines += sp->nverts;
break; break;
} }
} else if (shouldCompress){ } else if (shouldCompress){
int nvals = narrays*nverts ; *num_total_vertices += sp->nverts;
pc += nvals + 4; switch(sp->mode){
save_pc += nvals + 4 ;
*num_total_vertices += nverts;
switch(mode){
case GL_TRIANGLE_FAN: case GL_TRIANGLE_FAN:
*num_total_indexes += 3 * (nverts - 2); *num_total_indexes += 3 * (sp->nverts - 2);
break; break;
case GL_TRIANGLE_STRIP: case GL_TRIANGLE_STRIP:
*num_total_indexes += 3 * (nverts - 2); *num_total_indexes += 3 * (sp->nverts - 2);
break; break;
case GL_TRIANGLES: case GL_TRIANGLES:
*num_total_indexes += nverts; *num_total_indexes += sp->nverts;
break; break;
} }
} else if (shouldCompressPoints){ } else if (shouldCompressPoints){
int nvals = narrays*nverts ; *num_total_vertices_points += sp->nverts;
pc += nvals + 4;
save_pc += nvals + 4 ;
*num_total_vertices_points += nverts;
} }
} }
break; break;
case CGO_END: case CGO_END:
if (!err){ if (!err){
PRINTFB(I->G, FB_CGO, FB_Warnings) " CGOCountNumVertices: CGO_END encount ered, should call CGOCombineBeginEnd before CGOCountNumVertices\n" ENDFB(I->G); PRINTFB(I->G, FB_CGO, FB_Warnings) " CGOCountNumVertices: CGO_END encount ered, should call CGOCombineBeginEnd before CGOCountNumVertices\n" ENDFB(I->G);
err = true; err = true;
} }
case CGO_VERTEX: case CGO_VERTEX:
if (!err){ if (!err){
PRINTFB(I->G, FB_CGO, FB_Warnings) " CGOCountNumVertices: CGO_VERTEX enco untered, should call CGOCombineBeginEnd before CGOCountNumVertices\n" ENDFB(I->G ); PRINTFB(I->G, FB_CGO, FB_Warnings) " CGOCountNumVertices: CGO_VERTEX enco untered, should call CGOCombineBeginEnd before CGOCountNumVertices\n" ENDFB(I->G );
err = true; err = true;
} }
case CGO_BEGIN: case CGO_BEGIN:
if (!err){ if (!err){
PRINTFB(I->G, FB_CGO, FB_Warnings) " CGOCountNumVertices: CGO_BEGIN encou ntered, should call CGOCombineBeginEnd before CGOCountNumVertices\n" ENDFB(I->G) ; PRINTFB(I->G, FB_CGO, FB_Warnings) " CGOCountNumVertices: CGO_BEGIN encou ntered, should call CGOCombineBeginEnd before CGOCountNumVertices\n" ENDFB(I->G) ;
err = true; err = true;
} }
case CGO_ALPHA:
I->alpha = *pc;
default: default:
break; break;
} }
pc = save_pc;
pc += CGO_sz[op]; pc += CGO_sz[op];
} }
} }
void CGOCountNumVerticesForScreen(CGO *I, int *num_total_vertices, int *num_tota l_indexes){ static void CGOCountNumVerticesForScreen(const CGO *I, int *num_total_vertices, int *num_total_indexes){
float *pc = I->op; float *pc = I->op;
int op = 0; int op = 0;
float *save_pc = NULL; float *save_pc = NULL;
short err = 0; short err = 0;
*num_total_vertices = 0; *num_total_vertices = 0;
*num_total_indexes = 0; *num_total_indexes = 0;
while((op = (CGO_MASK & CGO_read_int(pc)))) { while((op = (CGO_MASK & CGO_read_int(pc)))!=0) {
save_pc = pc; save_pc = pc;
err = 0; err = 0;
switch (op) { switch (op) {
case CGO_DRAW_ARRAYS: case CGO_DRAW_ARRAYS:
if (!err){ if (!err){
PRINTFB(I->G, FB_CGO, FB_Warnings) " CGOCountNumVerticesForScreen:CGO_DRA W_ARRAYS encountered, should not call CGOCombineBeginEnd before CGOCountNumVerti cesForScreen\n" ENDFB(I->G); PRINTFB(I->G, FB_CGO, FB_Warnings) " CGOCountNumVerticesForScreen:CGO_DRA W_ARRAYS encountered, should not call CGOCombineBeginEnd before CGOCountNumVerti cesForScreen\n" ENDFB(I->G);
err = true; err = true;
} }
break; break;
case CGO_BEGIN: case CGO_BEGIN:
{ {
int nverts = 0, err = 0, end = 0; int nverts = 0, err = 0, end = 0;
int mode = CGO_read_int(pc); int mode = CGO_read_int(pc);
int sz; int sz;
while(!err && !end && ((op = (CGO_MASK & CGO_read_int(pc))))) { while(!err && !end && (op = (CGO_MASK & CGO_read_int(pc)))) {
switch (op) { switch (op) {
case CGO_DRAW_ARRAYS: case CGO_DRAW_ARRAYS:
PRINTFB(I->G, FB_CGO, FB_Warnings) " CGOSimplify: CGO_DRAW_ARRAYS enc ountered inside CGO_BEGIN/CGO_END\n" ENDFB(I->G); PRINTFB(I->G, FB_CGO, FB_Warnings) " CGOSimplify: CGO_DRAW_ARRAYS enc ountered inside CGO_BEGIN/CGO_END\n" ENDFB(I->G);
err = true; err = true;
continue; continue;
case CGO_VERTEX: case CGO_VERTEX:
nverts++; nverts++;
break; break;
case CGO_END: case CGO_END:
end = 1; end = 1;
skipping to change at line 2306 skipping to change at line 2114
err = true; err = true;
} }
default: default:
break; break;
} }
pc = save_pc; pc = save_pc;
pc += CGO_sz[op]; pc += CGO_sz[op];
} }
} }
void SetVertexValuesForVBO(PyMOLGlobals * G, CGO *cgo, int arrays, int pl, int p static
lc, int cnt, int incr, float *vertexValsDA, float *normalValsDA, float *colorVal void SetVertexValuesForVBO(PyMOLGlobals * G, CGO *cgo, int pl, int plc, int cnt,
sDA, float *pickColorValsDA, int incr,
float *vertexVals, uchar *normalValsC, float *normalVa float *vertexValsDA, float *normalValsDA,
ls, uchar *colorValsUC, float *colorVals, float *pickColorVals, float *accessibi float *colorValsDA, float *pickColorValsDA,
lityVals, float *accessibilityValsDA){ float *vertexVals, uchar *normalValsC,
float *normalVals, uchar *colorValsUC, float *colorVa
ls,
float *pickColorVals,
float *accessibilityVals=NULL, float *accessibilityVa
lsDA=NULL){
int pl2 = pl + 1, pl3 = pl + 2; int pl2 = pl + 1, pl3 = pl + 2;
int pln1 = VAR_FOR_NORMAL, pln2 = VAR_FOR_NORMAL + 1, pln3 = VAR_FOR_NORMAL + 2; int pln1 = VAR_FOR_NORMAL, pln2 = VAR_FOR_NORMAL + 1, pln3 = VAR_FOR_NORMAL + 2;
int plc2 = plc + 1, plc3 = plc + 2, plc4 = plc + 3; int plc2 = plc + 1, plc3 = plc + 2, plc4 = plc + 3;
int c, c2, c3; int c, c2, c3;
int cc, cc2, cc3, cc4; int cc, cc2, cc3, cc4;
int pcc = incr * 2, pcco = cnt * 2; int pcc = incr * 2, pcco = cnt * 2;
c = cnt * 3; c2 = c + 1; c3 = c + 2; c = cnt * 3; c2 = c + 1; c3 = c + 2;
cc = cnt * 4; cc2 = cc + 1; cc3 = cc + 2; cc4 = cc + 3; cc = cnt * 4; cc2 = cc + 1; cc3 = cc + 2; cc4 = cc + 3;
vertexVals[pl] = vertexValsDA[c]; vertexVals[pl2] = vertexValsDA[c2]; vertexVa ls[pl3] = vertexValsDA[c3]; vertexVals[pl] = vertexValsDA[c]; vertexVals[pl2] = vertexValsDA[c2]; vertexVa ls[pl3] = vertexValsDA[c3];
if (SettingGetGlobal_i(G, cSetting_cgo_shader_ub_normal)){
if (normalValsC){ if (normalValsC){
if (arrays & CGO_NORMAL_ARRAY){ if (normalValsDA){
normalValsC[pln1] = CLIP_NORMAL_VALUE(normalValsDA[c]); normalValsC[pln2] = CLIP_NORMAL_VALUE(normalValsDA[c2]); normalValsC[pln3] = CLIP_NORMAL_VALUE(no rmalValsDA[c3]); normalValsC[pln1] = CLIP_NORMAL_VALUE(normalValsDA[c]); normalValsC[pln2] = CLIP_NORMAL_VALUE(normalValsDA[c2]); normalValsC[pln3] = CLIP_NORMAL_VALUE(no rmalValsDA[c3]);
} else { } else {
normalValsC[pln1] = CLIP_NORMAL_VALUE(cgo->normal[0]); normalValsC[pln2] = CLIP_NORMAL_VALUE(cgo->normal[1]); normalValsC[pln3] = CLIP_NORMAL_VALUE(cgo-> normal[2]); normalValsC[pln1] = CLIP_NORMAL_VALUE(cgo->normal[0]); normalValsC[pln2] = CLIP_NORMAL_VALUE(cgo->normal[1]); normalValsC[pln3] = CLIP_NORMAL_VALUE(cgo-> normal[2]);
} }
}
#ifdef ALIGN_VBOS_TO_4_BYTE_ARRAYS #ifdef ALIGN_VBOS_TO_4_BYTE_ARRAYS
normalValsC[pln3+1] = 127; normalValsC[pln3+1] = 127;
#endif #endif
} else { } else {
if (normalVals){ if (normalValsDA){
if (arrays & CGO_NORMAL_ARRAY){
normalVals[pln1] = normalValsDA[c]; normalVals[pln2] = normalValsDA[c2]; normalVals[pln3] = normalValsDA[c3]; normalVals[pln1] = normalValsDA[c]; normalVals[pln2] = normalValsDA[c2]; normalVals[pln3] = normalValsDA[c3];
} else { } else {
normalVals[pln1] = cgo->normal[0]; normalVals[pln2] = cgo->normal[1]; nor malVals[pln3] = cgo->normal[2]; normalVals[pln1] = cgo->normal[0]; normalVals[pln2] = cgo->normal[1]; nor malVals[pln3] = cgo->normal[2];
} }
}
} }
if (SettingGetGlobal_i(G, cSetting_cgo_shader_ub_color)){
if (arrays & CGO_COLOR_ARRAY){ if (colorValsUC){
if (colorValsDA){
colorValsUC[plc] = CLIP_COLOR_VALUE(colorValsDA[cc]); colorValsUC[plc2] = CLIP_COLOR_VALUE(colorValsDA[cc2]); colorValsUC[plc] = CLIP_COLOR_VALUE(colorValsDA[cc]); colorValsUC[plc2] = CLIP_COLOR_VALUE(colorValsDA[cc2]);
colorValsUC[plc3] = CLIP_COLOR_VALUE(colorValsDA[cc3]); colorValsUC[plc4] = CLIP_COLOR_VALUE(colorValsDA[cc4]); colorValsUC[plc3] = CLIP_COLOR_VALUE(colorValsDA[cc3]); colorValsUC[plc4] = CLIP_COLOR_VALUE(colorValsDA[cc4]);
} else { } else {
colorValsUC[plc] = CLIP_COLOR_VALUE(cgo->color[0]); colorValsUC[plc2] = CL IP_COLOR_VALUE(cgo->color[1]); colorValsUC[plc] = CLIP_COLOR_VALUE(cgo->color[0]); colorValsUC[plc2] = CL IP_COLOR_VALUE(cgo->color[1]);
colorValsUC[plc3] = CLIP_COLOR_VALUE(cgo->color[2]); colorValsUC[plc4] = C LIP_COLOR_VALUE(cgo->alpha); colorValsUC[plc3] = CLIP_COLOR_VALUE(cgo->color[2]); colorValsUC[plc4] = C LIP_COLOR_VALUE(cgo->alpha);
} }
} else { } else {
if (arrays & CGO_COLOR_ARRAY){ if (colorValsDA){
colorVals[plc] = colorValsDA[cc]; colorVals[plc2] = colorValsDA[cc2]; colorVals[plc] = colorValsDA[cc]; colorVals[plc2] = colorValsDA[cc2];
colorVals[plc3] = colorValsDA[cc3]; colorVals[plc4] = colorValsDA[cc4]; colorVals[plc3] = colorValsDA[cc3]; colorVals[plc4] = colorValsDA[cc4];
} else { } else {
colorVals[plc] = cgo->color[0]; colorVals[plc2] = cgo->color[1]; colorVals[plc] = cgo->color[0]; colorVals[plc2] = cgo->color[1];
colorVals[plc3] = cgo->color[2]; colorVals[plc4] = cgo->alpha; colorVals[plc3] = cgo->color[2]; colorVals[plc4] = cgo->alpha;
} }
} }
if (arrays & CGO_PICK_COLOR_ARRAY){ if (pickColorValsDA){
cgo->current_pick_color_index = CGO_get_int(pickColorValsDA + pcco); cgo->current_pick_color_index = CGO_get_uint(pickColorValsDA + pcco);
cgo->current_pick_color_bond = CGO_get_int(pickColorValsDA + pcco + 1); cgo->current_pick_color_bond = CGO_get_int(pickColorValsDA + pcco + 1);
} }
CGO_put_int(pickColorVals + pcc, cgo->current_pick_color_index); CGO_put_uint(pickColorVals + pcc, cgo->current_pick_color_index);
CGO_put_int(pickColorVals + pcc + 1, cgo->current_pick_color_bond); CGO_put_int(pickColorVals + pcc + 1, cgo->current_pick_color_bond);
if (arrays & CGO_ACCESSIBILITY_ARRAY){ if (accessibilityValsDA){
accessibilityVals[pl/3] = accessibilityValsDA[cnt]; accessibilityVals[pl/3] = accessibilityValsDA[cnt];
} }
} }
int OptimizePointsToVBO(CGO *I, CGO *cgo, int num_total_vertices_points, float * min, float *max, short *has_draw_buffer){ static int OptimizePointsToVBO(const CGO *I, CGO *cgo, int num_total_vertices_po ints, float *min, float *max, short *has_draw_buffer, bool addshaders){
float *vertexVals = 0, *colorVals = 0, *normalVals = 0; float *vertexVals = 0, *colorVals = 0, *normalVals = 0;
float *pickColorVals; float *pickColorVals;
int pl = 0, plc = 0, idxpl = 0, vpl = 0, tot, nxtn; int pl = 0, plc = 0, idxpl = 0, vpl = 0, tot, nxtn;
uchar *colorValsUC = 0; uchar *colorValsUC = 0;
uchar *normalValsC = 0; uchar *normalValsC = 0;
int numbufs = 0, bufoffset = 0; bool has_normals = false, has_colors = false;
short has_normals = 0, has_colors = 0;
float *pc = I->op; float *pc = I->op;
int op; int op;
float *save_pc; float *save_pc;
short err = 0;
int ok = true; int ok = true;
cgo->alpha = 1.f; cgo->alpha = 1.f;
cgo->color[0] = 1.f; cgo->color[1] = 1.f; cgo->color[2] = 1.f; cgo->color[0] = 1.f; cgo->color[1] = 1.f; cgo->color[2] = 1.f;
tot = num_total_vertices_points * (3 * 5) ; tot = num_total_vertices_points * (3 * 5) ;
// tot = num_total_indexes * (3 * 3 + 2) ; // tot = num_total_indexes * (3 * 3 + 2) ;
/* NOTE/TODO: Not sure why 3*5 needs to be used, but 3*3+2, which is the /* NOTE/TODO: Not sure why 3*5 needs to be used, but 3*3+2, which is the
correct length, crashes in glBufferData */ correct length, crashes in glBufferData */
vertexVals = Alloc(float, tot); vertexVals = Alloc(float, tot);
skipping to change at line 2408 skipping to change at line 2219
colorVals = normalVals + nxtn * num_total_vertices_points; colorVals = normalVals + nxtn * num_total_vertices_points;
if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_color)){ if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_color)){
colorValsUC = (uchar*) colorVals; colorValsUC = (uchar*) colorVals;
nxtn = 1; nxtn = 1;
} else { } else {
nxtn = 4; nxtn = 4;
} }
pickColorVals = (colorVals + nxtn * num_total_vertices_points); pickColorVals = (colorVals + nxtn * num_total_vertices_points);
while(ok && (op = (CGO_MASK & CGO_read_int(pc)))) { while(ok && (op = (CGO_MASK & CGO_read_int(pc)))) {
save_pc = pc; save_pc = pc;
err = 0;
numbufs = 0;
switch (op) { switch (op) {
case CGO_BOUNDING_BOX: case CGO_BOUNDING_BOX:
{
float *nc, *newpc = pc;
int sz;
sz = CGO_sz[op];
nc = CGO_add(cgo, sz + 1);
*(nc++) = *(pc - 1);
while(sz--)
*(nc++) = *(newpc++);
}
break;
case CGO_DRAW_SPHERE_BUFFERS: case CGO_DRAW_SPHERE_BUFFERS:
numbufs = 3;
bufoffset = 2;
case CGO_DRAW_LABELS: case CGO_DRAW_LABELS:
if (!numbufs){
numbufs = 4;
bufoffset = 1;
}
case CGO_DRAW_TEXTURES: case CGO_DRAW_TEXTURES:
case CGO_DRAW_SCREEN_TEXTURES_AND_POLYGONS: case CGO_DRAW_SCREEN_TEXTURES_AND_POLYGONS:
if (!numbufs){
numbufs = 3;
bufoffset = 1;
}
case CGO_DRAW_CYLINDER_BUFFERS: case CGO_DRAW_CYLINDER_BUFFERS:
if (!numbufs){
numbufs = 5;
bufoffset = 2;
}
case CGO_DRAW_BUFFERS:
if (!numbufs){
numbufs = 4;
bufoffset = 4;
}
case CGO_DRAW_BUFFERS_NOT_INDEXED: case CGO_DRAW_BUFFERS_NOT_INDEXED:
if (!numbufs){
numbufs = 4;
bufoffset = 4;
}
case CGO_DRAW_BUFFERS_INDEXED: case CGO_DRAW_BUFFERS_INDEXED:
if (!numbufs){ PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: OptimizePointsToVBO used with uns
numbufs = 5; upported CGO ops" ENDFB(I->G);
bufoffset = 5; return 0;
}
{
int i, sz;
float *nc, *newpc = pc;
sz = CGO_sz[op];
nc = CGO_add(cgo, sz + 1);
*(nc++) = *(pc - 1);
while(sz--)
*(nc++) = *(newpc++);
for (i=0; i<numbufs; i++){
*(pc+bufoffset+i) = 0;
}
}
break; break;
case CGO_NORMAL: case CGO_NORMAL:
cgo->normal[0] = *pc; cgo->normal[1] = *(pc + 1); cgo->normal[2] = *(pc + 2); cgo->normal[0] = *pc; cgo->normal[1] = *(pc + 1); cgo->normal[2] = *(pc + 2);
has_normals = 1; has_normals = true;
break; break;
case CGO_COLOR: case CGO_COLOR:
cgo->color[0] = *pc; cgo->color[1] = *(pc + 1); cgo->color[2] = *(pc + 2); cgo->color[0] = *pc; cgo->color[1] = *(pc + 1); cgo->color[2] = *(pc + 2);
has_colors = 1; has_colors = true;
break; break;
case CGO_ALPHA: case CGO_ALPHA:
cgo->alpha = *pc; cgo->alpha = *pc;
break; break;
case CGO_PICK_COLOR: case CGO_PICK_COLOR:
cgo->current_pick_color_index = CGO_get_int(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);
break; break;
case CGO_DRAW_ARRAYS: case CGO_DRAW_ARRAYS:
{ {
int mode = CGO_get_int(pc), arrays = CGO_get_int(pc + 1), narrays = CGO_g et_int(pc + 2), nverts = CGO_get_int(pc + 3); cgo::draw::arrays * sp = reinterpret_cast<decltype(sp)>(pc);
short shouldCompress = false; short shouldCompress = false;
switch(mode){ switch(sp->mode){
case GL_POINTS: case GL_POINTS:
shouldCompress = true; shouldCompress = true;
default: default:
break; break;
} }
/* TODO : DO WE NEED TO COMPENSATE FOR THIS? if (!has_normals && arr ays & CGO_NORMAL_ARRAY){ /* TODO : DO WE NEED TO COMPENSATE FOR THIS? if (!has_normals && arr ays & CGO_NORMAL_ARRAY){
arrays = arrays ^ CGO_NORMAL_ARRAY; arrays = arrays ^ CGO_NORMAL_ARRAY;
narrays -= 1; narrays -= 1;
}*/ }*/
if (shouldCompress){ if (shouldCompress){
int nvals = narrays*nverts, cnt, nxtn = 3 ,incr=0; int cnt, nxtn = 3 ,incr=0;
float *vertexValsDA = 0, *nxtVals = 0, *colorValsDA = 0, *normalValsDA float *vertexValsDA = NULL, *nxtVals = NULL, *colorValsDA = NULL, *norm
= 0; alValsDA = NULL;
float *pickColorValsDA, *pickColorValsTMP; float *pickColorValsDA = NULL, *pickColorValsTMP;
nxtVals = vertexValsDA = pc + 4; nxtVals = vertexValsDA = sp->floatdata;
for (cnt=0; cnt<nverts*3; cnt+=3){ for (cnt=0; cnt<sp->nverts*3; cnt+=3){
set_min_max(min, max, &vertexValsDA[cnt]); set_min_max(min, max, &vertexValsDA[cnt]);
} }
if (arrays & CGO_NORMAL_ARRAY){ if (sp->arraybits & CGO_NORMAL_ARRAY){
nxtVals = normalValsDA = vertexValsDA + (nxtn*nverts); has_normals = true;
} nxtVals = normalValsDA = vertexValsDA + (nxtn*sp->nverts);
if (arrays & CGO_COLOR_ARRAY){ }
has_colors = 1; if (sp->arraybits & CGO_COLOR_ARRAY){
nxtVals = colorValsDA = nxtVals + (nxtn*nverts); has_colors = true;
nxtVals = colorValsDA = nxtVals + (nxtn*sp->nverts);
nxtn = 4; nxtn = 4;
} }
if (arrays & CGO_PICK_COLOR_ARRAY){ if (sp->arraybits & CGO_PICK_COLOR_ARRAY){
nxtVals = nxtVals + (nxtn*nverts); nxtVals = nxtVals + (nxtn*sp->nverts);
pickColorValsDA = nxtVals + nverts; pickColorValsDA = nxtVals + sp->nverts;
nxtn = 3; nxtn = 3;
} }
pickColorValsTMP = pickColorVals + (idxpl * 2); pickColorValsTMP = pickColorVals + (idxpl * 2);
switch (mode){ switch (sp->mode){
case GL_POINTS: case GL_POINTS:
for (cnt = 0; cnt < nverts; cnt++){ for (cnt = 0; cnt < sp->nverts; cnt++){
SetVertexValuesForVBO(I->G, cgo, arrays, pl, plc, cnt, incr++, SetVertexValuesForVBO(I->G, cgo, pl, plc, cnt, incr++,
vertexValsDA, normalValsDA, colorValsDA, pick ColorValsDA, vertexValsDA, normalValsDA, colorValsDA, pick ColorValsDA,
vertexVals, normalValsC, normalVals, colorVal sUC, colorVals, vertexVals, normalValsC, normalVals, colorVal sUC, colorVals,
pickColorValsTMP, NULL, NULL); pickColorValsTMP);
idxpl++; pl += 3; plc += 4; idxpl++; pl += 3; plc += 4;
} }
break; break;
} }
vpl += nverts; vpl += sp->nverts;
}
pc += nvals + 4;
save_pc += nvals + 4 ;
} else {
{
int nvals = narrays*nverts ;
pc += nvals + 4;
save_pc += nvals + 4 ;
}
}
} }
break; break;
default: default:
break; break;
} }
pc = save_pc; pc = save_pc;
pc += CGO_sz[op]; pc += CGO_sz[op];
ok &= !I->G->Interrupt; ok &= !I->G->Interrupt;
} }
if (ok){ if (ok){
uint bufs[3] = {0, 0, 0 }, allbufs[4] = { 0, 0, 0, 0 };
short bufpl = 0;
GLenum err ;
short arrays = CGO_VERTEX_ARRAY | CGO_PICK_COLOR_ARRAY; short arrays = CGO_VERTEX_ARRAY | CGO_PICK_COLOR_ARRAY;
short nsz = 12;
GLenum ntp = GL_FLOAT;
bool nnorm = GL_FALSE;
if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_normal)){
nsz = 3;
ntp = GL_BYTE;
nnorm = GL_TRUE;
}
CHECK_GL_ERROR_OK("ERROR: OptimizePointsToVBO() BEFORE glGenBuffers returns short csz = 4;
err=%d\n"); GLenum ctp = GL_FLOAT;
if (ok){ bool cnorm = GL_FALSE;
glGenBuffers(3, bufs); if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_color)){
CHECK_GL_ERROR_OK("ERROR: OptimizePointsToVBO() glGenBuffers returns err=% csz = 1;
d\n"); ctp = GL_UNSIGNED_BYTE;
cnorm = GL_TRUE;
} }
if (ok){
glBindBuffer(GL_ARRAY_BUFFER, bufs[bufpl]); VertexBuffer * vbo = I->G->ShaderMgr->newGPUBuffer<VertexBuffer>();
CHECK_GL_ERROR_OK("ERROR: OptimizePointsToVBO() glBindBuffer returns err=%
d\n"); BufferDataDesc bufData =
{ { "a_Vertex", GL_FLOAT, 3, sizeof(float) * num_total_vertices_points * 3
, vertexVals, GL_FALSE } };
if (has_normals){
bufData.push_back( { "a_Normal", ntp, 3, (size_t)(num_total_vertices_
points * nsz), normalVals, nnorm } );
} }
if (ok && !glIsBuffer(bufs[bufpl])){ if (has_colors){
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: OptimizePointsToVBO() glGenBu bufData.push_back( { "a_Color", ctp, 4, sizeof(float) * num_total_ve
ffers created bad buffer bufpl=%d bufs[bufpl]=%d\n", bufpl, bufs[bufpl] ENDFB(I- rtices_points * csz, colorVals, cnorm } );
>G);
ok = false;
} else if (ok){
allbufs[0] = bufs[bufpl++];
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*num_total_vertices_points*3, v
ertexVals, GL_STATIC_DRAW);
CHECK_GL_ERROR_OK("ERROR: OptimizePointsToVBO() glBufferData returns err=%
d\n");
}
/* NO NORMALS IN POINTS */
if (!has_normals){
if (bufs[bufpl]){
if (glIsBuffer(bufs[bufpl])){
CShaderMgr_AddVBOToFree(I->G->ShaderMgr, bufs[bufpl]);
}
bufs[bufpl] = 0;
}
bufpl++;
} else if (ok){
glBindBuffer(GL_ARRAY_BUFFER, bufs[bufpl]);
CHECK_GL_ERROR_OK("ERROR: OptimizePointsToVBO() glBindBuffer returns err=%
d\n");
if (ok && !glIsBuffer(bufs[bufpl])){
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: OptimizePointsToVBO() glGenB
uffers created bad buffer bufpl=%d bufs[bufpl]=%d\n", bufpl, bufs[bufpl] ENDFB(I
->G);
ok = false;
} else if (ok){
short sz = 3;
allbufs[1] = bufs[bufpl++];
if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_normal)){
sz = 1;
}
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*num_total_vertices_points*sz,
normalVals, GL_STATIC_DRAW);
CHECK_GL_ERROR_OK("ERROR: OptimizePointsToVBO() glBufferData returns err=
%d\n");
}
} }
ok = vbo->bufferData((BufferDataDesc)bufData);
if (ok && has_colors){ if (ok && has_colors){
arrays |= CGO_COLOR_ARRAY; arrays |= CGO_COLOR_ARRAY;
glBindBuffer(GL_ARRAY_BUFFER, bufs[bufpl]);
CHECK_GL_ERROR_OK("ERROR: OptimizePointsToVBO() glBindBuffer returns err=%
d\n");
if (ok && !glIsBuffer(bufs[bufpl])){
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: OptimizePointsToVBO() glGenB
uffers created bad buffer bufpl=%d bufs[bufpl]=%d\n", bufpl, bufs[bufpl] ENDFB(I
->G);
ok = false;
} else if (ok){
short sz = 4;
allbufs[2] = bufs[bufpl++];
if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_color)){
sz = 1;
}
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*num_total_vertices_points*sz,
colorVals, GL_STATIC_DRAW);
CHECK_GL_ERROR_OK("ERROR: OptimizePointsToVBO() glBufferData returns err=
%d\n");
}
} else {
if (glIsBuffer(bufs[bufpl])){
CShaderMgr_AddVBOToFree(I->G->ShaderMgr, bufs[bufpl]);
}
bufs[bufpl++] = 0;
} }
size_t vboid = vbo->get_hash_id();
if (ok){ if (ok){
GLfloat *newPickColorVals ; float *newPickColorVals ;
newPickColorVals = CGODrawBuffersNotIndexed(cgo, GL_POINTS, arrays, num_to if (addshaders)
tal_vertices_points, allbufs); CGOEnable(cgo, GL_DEFAULT_SHADER);
newPickColorVals = cgo->add<cgo::draw::buffers_not_indexed>(GL_POINTS, arr
ays, num_total_vertices_points, vboid);
CHECKOK(ok, newPickColorVals); CHECKOK(ok, newPickColorVals);
if (ok && addshaders)
ok &= CGODisable(cgo, GL_DEFAULT_SHADER);
if (!newPickColorVals) if (!newPickColorVals)
CShaderMgr_AddVBOsToFree(I->G->ShaderMgr, bufs, 3); I->G->ShaderMgr->freeGPUBuffer(vboid);
if (ok) if (ok)
memcpy(newPickColorVals + num_total_vertices_points, pickColorVals, num_t otal_vertices_points * 2 * sizeof(float)); memcpy(newPickColorVals + num_total_vertices_points, pickColorVals, num_t otal_vertices_points * 2 * sizeof(float));
*has_draw_buffer = true; *has_draw_buffer = true;
} else { } else {
CShaderMgr_AddVBOsToFree(I->G->ShaderMgr, bufs, 3); I->G->ShaderMgr->freeGPUBuffer(vboid);
} }
} }
FreeP(vertexVals); FreeP(vertexVals);
return ok; return ok;
/* END GL_POINTS */ /* END GL_POINTS */
// printf("num_total_vertices_points=%d\n", num_total_vertices_points); // printf("num_total_vertices_points=%d\n", num_total_vertices_points);
} }
int CGOProcessCGOtoArrays(PyMOLGlobals * G, float *pcarg, CGO *cgo, CGO *addtocg static
o, float *min, float *max, int *ambient_occlusion, float *vertexVals, float *nor void FixPickColorsForLine(float *pick1, float *pick2){
malVals, uchar *normalValsC, float *colorVals, uchar *colorValsUC, float *pickCo unsigned int p1 = CGO_get_uint(pick1);
lorVals, float *accessibilityVals){ unsigned int p2 = CGO_get_uint(pick2);
int b1 = CGO_get_int(pick1 + 1);
int b2 = CGO_get_int(pick2 + 1);
if (p1 != p2 || b1 != b2){
// if the pick colors are different, then pick the first one
CGO_put_uint(pick1, p2);
CGO_put_int(pick1 + 1, b2);
}
}
static
void FixPickColorsForTriangle(float *pick1, float *pick2, float *pick3){
unsigned int p1 = CGO_get_uint(pick1);
unsigned int p2 = CGO_get_uint(pick2);
unsigned int p3 = CGO_get_uint(pick3);
int b1 = CGO_get_int(pick1 + 1);
int b2 = CGO_get_int(pick2 + 1);
int b3 = CGO_get_int(pick3 + 1);
if (p1 != p2 || p1 != p3 || p2 != p3 ||
b1 != b2 || b1 != b3 || b2 != b3){
// right now, if the pick colors are different, then pick majority, otherwis
e, pick first one
if (p1 == p2 && b1 == b2){
CGO_put_uint(pick3, p1);
CGO_put_int(pick3 + 1, b1);
} else if (p1 == p3 && b1 == b3){
CGO_put_uint(pick2, p1);
CGO_put_int(pick2 + 1, b1);
} else if (p2 == p3 && b2 == b3){
CGO_put_uint(pick1, p2);
CGO_put_int(pick1 + 1, b2);
} else {
CGO_put_uint(pick2, p1);
CGO_put_int(pick2 + 1, b1);
CGO_put_uint(pick3, p1);
CGO_put_int(pick3 + 1, b1);
}
}
}
static
int CGOProcessCGOtoArrays(PyMOLGlobals * G, float *pcarg, CGO *cgo, CGO *addtocg
o, float *min, float *max, int *ambient_occlusion, float *vertexVals, float *nor
malVals, uchar *normalValsC, float *colorVals, uchar *colorValsUC, float *pickCo
lorVals, float *accessibilityVals, bool &has_normals, bool &has_colors, bool &ha
s_accessibility){
float *pc = pcarg; float *pc = pcarg;
int op = 0; int op = 0;
float *save_pc = NULL; float *save_pc = NULL;
short err = 0;
int numbufs = 0, bufoffset = 0;
int idxpl = 0; int idxpl = 0;
int pl = 0, plc = 0, vpl = 0; int pl = 0, plc = 0, vpl = 0;
int ok = true; int ok = true;
while(ok && (op = (CGO_MASK & CGO_read_int(pc)))) { while(ok && (op = (CGO_MASK & CGO_read_int(pc)))) {
save_pc = pc; save_pc = pc;
err = 0;
numbufs = 0;
switch (op) { switch (op) {
case CGO_BOUNDING_BOX: case CGO_BOUNDING_BOX:
{ {
float *nc, *newpc = pc; float *newpc = pc;
int sz; if (addtocgo)
sz = CGO_sz[op]; addtocgo->add_to_cgo(op, newpc);
if (addtocgo){
nc = CGO_add(addtocgo, sz + 1);
ok &= nc ? true : false;
if (!ok){
break;
}
*(nc++) = *(pc - 1);
while(sz--)
*(nc++) = *(newpc++);
}
} }
break; break;
case CGO_DRAW_SPHERE_BUFFERS: case CGO_DRAW_SPHERE_BUFFERS:
numbufs = 3;
bufoffset = 2;
case CGO_DRAW_LABELS: case CGO_DRAW_LABELS:
if (!numbufs){
numbufs = 4;
bufoffset = 1;
}
case CGO_DRAW_TEXTURES: case CGO_DRAW_TEXTURES:
case CGO_DRAW_SCREEN_TEXTURES_AND_POLYGONS: case CGO_DRAW_SCREEN_TEXTURES_AND_POLYGONS:
if (!numbufs){
numbufs = 3;
bufoffset = 1;
}
case CGO_DRAW_CYLINDER_BUFFERS: case CGO_DRAW_CYLINDER_BUFFERS:
if (!numbufs){
numbufs = 5;
bufoffset = 2;
}
case CGO_DRAW_BUFFERS:
if (!numbufs){
numbufs = 4;
bufoffset = 4;
}
case CGO_DRAW_BUFFERS_NOT_INDEXED: case CGO_DRAW_BUFFERS_NOT_INDEXED:
if (!numbufs){
numbufs = 4;
bufoffset = 4;
}
case CGO_DRAW_BUFFERS_INDEXED: case CGO_DRAW_BUFFERS_INDEXED:
if (!numbufs){ {
numbufs = 5; float * newpc = pc;
bufoffset = 5; if (addtocgo)
} addtocgo->add_to_cgo(op, newpc);
}
{
int i, sz;
float *nc, *newpc = pc;
sz = CGO_sz[op];
if (addtocgo){
nc = CGO_add(addtocgo, sz + 1);
ok &= nc ? true : false;
if (!ok){
break;
}
*(nc++) = *(pc - 1);
while(sz--)
*(nc++) = *(newpc++);
}
for (i=0; i<numbufs; i++){
*(pc+bufoffset+i) = 0;
}
}
break; break;
case CGO_NORMAL: case CGO_NORMAL:
cgo->normal[0] = *pc; cgo->normal[1] = *(pc + 1); cgo->normal[2] = *(pc + 2); cgo->normal[0] = *pc; cgo->normal[1] = *(pc + 1); cgo->normal[2] = *(pc + 2);
has_normals = true;
break; break;
case CGO_COLOR: case CGO_COLOR:
cgo->color[0] = *pc; cgo->color[1] = *(pc + 1); cgo->color[2] = *(pc + 2); cgo->color[0] = *pc; cgo->color[1] = *(pc + 1); cgo->color[2] = *(pc + 2);
has_colors = true;
break; break;
case CGO_ALPHA: case CGO_ALPHA:
cgo->alpha = *pc; cgo->alpha = *pc;
break; break;
case CGO_ACCESSIBILITY: case CGO_ACCESSIBILITY:
cgo->current_accessibility = pc[0]; cgo->current_accessibility = pc[0];
has_accessibility = true;
break; break;
case CGO_PICK_COLOR: case CGO_PICK_COLOR:
cgo->current_pick_color_index = CGO_get_int(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);
break; break;
case CGO_DRAW_ARRAYS: case CGO_DRAW_ARRAYS:
{ {
int mode = CGO_get_int(pc), arrays = CGO_get_int(pc + 1), narrays = CGO_g et_int(pc + 2), nverts = CGO_get_int(pc + 3); cgo::draw::arrays * sp = reinterpret_cast<decltype(sp)>(pc);
short shouldCompress = false; short shouldCompress = false;
switch(mode){ switch(sp->mode){
case GL_TRIANGLE_FAN: case GL_TRIANGLE_FAN:
case GL_TRIANGLE_STRIP: case GL_TRIANGLE_STRIP:
case GL_TRIANGLES: case GL_TRIANGLES:
shouldCompress = true; shouldCompress = true;
default: default:
break; break;
} }
if (shouldCompress){ if (shouldCompress){
int nvals = narrays*nverts, cnt, nxtn = 3,incr=0; int cnt, nxtn = 3,incr=0;
float *vertexValsDA = 0, *nxtVals = 0, *colorValsDA = 0, *normalValsDA, float *vertexValsDA = NULL, *nxtVals = NULL, *colorValsDA = NULL, *norm
*accessibilityValsDA; alValsDA = NULL, *accessibilityValsDA = NULL;
float *pickColorValsDA, *pickColorValsTMP; float *pickColorValsDA = NULL, *pickColorValsTMP;
nxtVals = vertexValsDA = sp->floatdata;
nxtVals = vertexValsDA = pc + 4; for (cnt=0; cnt<sp->nverts*3; cnt+=3){
for (cnt=0; cnt<nverts*3; cnt+=3){
set_min_max(min, max, &vertexValsDA[cnt]); set_min_max(min, max, &vertexValsDA[cnt]);
} }
if (arrays & CGO_NORMAL_ARRAY){ if (sp->arraybits & CGO_NORMAL_ARRAY){
nxtVals = normalValsDA = vertexValsDA + (nxtn*nverts); nxtVals = normalValsDA = vertexValsDA + (nxtn*sp->nverts);
has_normals = true;
} }
if (arrays & CGO_COLOR_ARRAY){ if (sp->arraybits & CGO_COLOR_ARRAY){
nxtVals = colorValsDA = nxtVals + (nxtn*nverts); nxtVals = colorValsDA = nxtVals + (nxtn*sp->nverts);
nxtn = 4; nxtn = 4;
has_colors = true;
} }
if (arrays & CGO_PICK_COLOR_ARRAY){ if (sp->arraybits & CGO_PICK_COLOR_ARRAY){
nxtVals = nxtVals + (nxtn*nverts); nxtVals = nxtVals + (nxtn*sp->nverts);
pickColorValsDA = nxtVals + nverts; pickColorValsDA = nxtVals + sp->nverts;
nxtn = 3; nxtn = 3;
} }
pickColorValsTMP = pickColorVals + (idxpl * 2); pickColorValsTMP = pickColorVals + (idxpl * 2);
if (arrays & CGO_ACCESSIBILITY_ARRAY){ if (sp->arraybits & CGO_ACCESSIBILITY_ARRAY){
if (!(*ambient_occlusion) && incr){ if (!(*ambient_occlusion) && incr){
for (cnt=0; cnt<incr;cnt++){ for (cnt=0; cnt<incr;cnt++){
/* if ambient_occlusion, need to fill in the array */ /* if ambient_occlusion, need to fill in the array */
accessibilityVals[cnt] = 1.f; accessibilityVals[cnt] = 1.f;
} }
} }
(*ambient_occlusion) = 1; (*ambient_occlusion) = 1;
accessibilityValsDA = nxtVals + nxtn*nverts; accessibilityValsDA = nxtVals + nxtn*sp->nverts;
has_accessibility = true;
} else { } else {
if (*ambient_occlusion){ if (*ambient_occlusion){
for (cnt=incr; cnt<incr+nverts;cnt++){ for (cnt=incr; cnt<incr+sp->nverts;cnt++){
/* if ambient_occlusion, need to fill in the array */ /* if ambient_occlusion, need to fill in the array */
accessibilityVals[cnt] = 1.f; accessibilityVals[cnt] = 1.f;
} }
} }
} }
switch (mode){ switch (sp->mode){
case GL_TRIANGLES: case GL_TRIANGLES:
for (cnt = 0; ok && cnt < nverts; cnt++){ for (cnt = 0; ok && cnt < sp->nverts; cnt++){
SetVertexValuesForVBO(G, cgo, arrays, pl, plc, cnt, incr++, SetVertexValuesForVBO(G, cgo, pl, plc, cnt, incr++,
vertexValsDA, normalValsDA, colorValsDA, pick ColorValsDA, vertexValsDA, normalValsDA, colorValsDA, pick ColorValsDA,
vertexVals, normalValsC, normalVals, colorVal sUC, colorVals, vertexVals, normalValsC, normalVals, colorVal sUC, colorVals,
pickColorValsTMP, accessibilityVals, accessib ilityValsDA); pickColorValsTMP, accessibilityVals, accessib ilityValsDA);
if (incr && (incr % 3) == 0){
FixPickColorsForTriangle(pickColorValsTMP + (incr-3) * 2,
pickColorValsTMP + (incr-2) * 2,
pickColorValsTMP + (incr-1) * 2);
}
idxpl++; pl += 3; plc += 4; idxpl++; pl += 3; plc += 4;
ok &= !G->Interrupt; ok &= !G->Interrupt;
} }
break; break;
case GL_TRIANGLE_STRIP: case GL_TRIANGLE_STRIP:
for (cnt = 2; ok && cnt < nverts; cnt++){ {
SetVertexValuesForVBO(G, cgo, arrays, pl, plc, cnt-2, incr++, short flip = 0;
vertexValsDA, normalValsDA, colorValsDA, pick for (cnt = 2; ok && cnt < sp->nverts; cnt++){
ColorValsDA, SetVertexValuesForVBO(G, cgo, pl, plc, cnt - (flip ? 0 : 2), incr
vertexVals, normalValsC, normalVals, colorVal ++,
sUC, colorVals, vertexValsDA, normalValsDA, colorValsDA, pi
pickColorValsTMP, accessibilityVals, accessib ckColorValsDA,
ilityValsDA); vertexVals, normalValsC, normalVals, colorV
idxpl++; pl += 3; plc += 4; alsUC, colorVals,
SetVertexValuesForVBO(G, cgo, arrays, pl, plc, cnt-1, incr++, pickColorValsTMP, accessibilityVals, access
vertexValsDA, normalValsDA, colorValsDA, pick ibilityValsDA);
ColorValsDA, idxpl++; pl += 3; plc += 4;
vertexVals, normalValsC, normalVals, colorVal SetVertexValuesForVBO(G, cgo, pl, plc, cnt-1, incr++,
sUC, colorVals, vertexValsDA, normalValsDA, colorValsDA, pi
pickColorValsTMP, accessibilityVals, accessib ckColorValsDA,
ilityValsDA); vertexVals, normalValsC, normalVals, colorV
idxpl++; pl += 3; plc += 4; alsUC, colorVals,
SetVertexValuesForVBO(G, cgo, arrays, pl, plc, cnt, incr++, pickColorValsTMP, accessibilityVals, access
vertexValsDA, normalValsDA, colorValsDA, pick ibilityValsDA);
ColorValsDA, idxpl++; pl += 3; plc += 4;
vertexVals, normalValsC, normalVals, colorVal SetVertexValuesForVBO(G, cgo, pl, plc, cnt - (flip ? 2 : 0) , inc
sUC, colorVals, r++,
pickColorValsTMP, accessibilityVals, accessib vertexValsDA, normalValsDA, colorValsDA, pi
ilityValsDA); ckColorValsDA,
idxpl++; pl += 3; plc += 4; vertexVals, normalValsC, normalVals, colorV
ok &= !G->Interrupt; alsUC, colorVals,
pickColorValsTMP, accessibilityVals, access
ibilityValsDA);
FixPickColorsForTriangle(pickColorValsTMP + (incr-3) * 2,
pickColorValsTMP + (incr-2) * 2,
pickColorValsTMP + (incr-1) * 2);
idxpl++; pl += 3; plc += 4;
ok &= !G->Interrupt;
flip = !flip;
}
} }
break; break;
case GL_TRIANGLE_FAN: case GL_TRIANGLE_FAN:
for (cnt = 2; ok && cnt < nverts; cnt++){ for (cnt = 2; ok && cnt < sp->nverts; cnt++){
SetVertexValuesForVBO(G, cgo, arrays, pl, plc, 0, incr++, SetVertexValuesForVBO(G, cgo, pl, plc, 0, incr++,
vertexValsDA, normalValsDA, colorValsDA, pick ColorValsDA, vertexValsDA, normalValsDA, colorValsDA, pick ColorValsDA,
vertexVals, normalValsC, normalVals, colorVal sUC, colorVals, vertexVals, normalValsC, normalVals, colorVal sUC, colorVals,
pickColorValsTMP, accessibilityVals, accessib ilityValsDA); pickColorValsTMP, accessibilityVals, accessib ilityValsDA);
idxpl++; pl += 3; plc += 4; idxpl++; pl += 3; plc += 4;
SetVertexValuesForVBO(G, cgo, arrays, pl, plc, cnt - 1, incr++, SetVertexValuesForVBO(G, cgo, pl, plc, cnt - 1, incr++,
vertexValsDA, normalValsDA, colorValsDA, pick ColorValsDA, vertexValsDA, normalValsDA, colorValsDA, pick ColorValsDA,
vertexVals, normalValsC, normalVals, colorVal sUC, colorVals, vertexVals, normalValsC, normalVals, colorVal sUC, colorVals,
pickColorValsTMP, accessibilityVals, accessib ilityValsDA); pickColorValsTMP, accessibilityVals, accessib ilityValsDA);
idxpl++; pl += 3; plc += 4; idxpl++; pl += 3; plc += 4;
SetVertexValuesForVBO(G, cgo, arrays, pl, plc, cnt, incr++, SetVertexValuesForVBO(G, cgo, pl, plc, cnt, incr++,
vertexValsDA, normalValsDA, colorValsDA, pick ColorValsDA, vertexValsDA, normalValsDA, colorValsDA, pick ColorValsDA,
vertexVals, normalValsC, normalVals, colorVal sUC, colorVals, vertexVals, normalValsC, normalVals, colorVal sUC, colorVals,
pickColorValsTMP, accessibilityVals, accessib ilityValsDA); pickColorValsTMP, accessibilityVals, accessib ilityValsDA);
FixPickColorsForTriangle(pickColorValsTMP + (incr-3) * 2,
pickColorValsTMP + (incr-2) * 2,
pickColorValsTMP + (incr-1) * 2);
idxpl++; pl += 3; plc += 4; idxpl++; pl += 3; plc += 4;
ok &= !G->Interrupt; ok &= !G->Interrupt;
} }
break; break;
} }
vpl += nverts; vpl += sp->nverts;
pc += nvals + 4;
save_pc += nvals + 4 ;
} else {
{
int nvals = narrays*nverts ;
pc += nvals + 4;
save_pc += nvals + 4 ;
}
} }
} }
break; break;
default: default:
break; break;
} }
if (ok){ if (ok){
pc = save_pc; pc = save_pc;
pc += CGO_sz[op]; pc += CGO_sz[op];
} }
ok &= !G->Interrupt; ok &= !G->Interrupt;
} }
ok &= !G->Interrupt; ok &= !G->Interrupt;
return ok; return ok;
} }
static
int CGOProcessScreenCGOtoArrays(PyMOLGlobals * G, float *pcarg, CGO *cgo, float *vertexVals, float *texcoordVals, float *colorVals, uchar *colorValsUC){ int CGOProcessScreenCGOtoArrays(PyMOLGlobals * G, float *pcarg, CGO *cgo, float *vertexVals, float *texcoordVals, float *colorVals, uchar *colorValsUC){
float *pc = pcarg; float *pc = pcarg;
int op = 0; int op = 0;
short err = 0;
int sz = 0; int sz = 0;
int ok = true; int ok = true;
int pl = 0, skip = false; int pl = 0, skip = false;
cgo->alpha = 1.f; cgo->alpha = 1.f;
while(ok && (op = (CGO_MASK & CGO_read_int(pc)))) { while(ok && (op = (CGO_MASK & CGO_read_int(pc)))) {
err = 0;
skip = false; skip = false;
switch (op) { switch (op) {
case CGO_BOUNDING_BOX: case CGO_BOUNDING_BOX:
case CGO_DRAW_SPHERE_BUFFERS: case CGO_DRAW_SPHERE_BUFFERS:
case CGO_DRAW_LABELS: case CGO_DRAW_LABELS:
case CGO_DRAW_TEXTURES: case CGO_DRAW_TEXTURES:
case CGO_DRAW_SCREEN_TEXTURES_AND_POLYGONS: case CGO_DRAW_SCREEN_TEXTURES_AND_POLYGONS:
case CGO_DRAW_CYLINDER_BUFFERS: case CGO_DRAW_CYLINDER_BUFFERS:
case CGO_DRAW_BUFFERS:
case CGO_DRAW_BUFFERS_NOT_INDEXED: case CGO_DRAW_BUFFERS_NOT_INDEXED:
case CGO_DRAW_BUFFERS_INDEXED: case CGO_DRAW_BUFFERS_INDEXED:
case CGO_DRAW_ARRAYS: case CGO_DRAW_ARRAYS:
case CGO_ACCESSIBILITY: case CGO_ACCESSIBILITY:
PRINTFB(G, FB_CGO, FB_Warnings) "WARNING: CGOProcessScreenCGOtoArrays() ca lled with bad op=%d in cgo\n", op ENDFB(G); PRINTFB(G, FB_CGO, FB_Warnings) "WARNING: CGOProcessScreenCGOtoArrays() ca lled with bad op=%d in cgo\n", op ENDFB(G);
ok = false; ok = false;
break; break;
case CGO_NORMAL: case CGO_NORMAL:
cgo->normal[0] = *pc; cgo->normal[1] = *(pc + 1); cgo->normal[2] = *(pc + 2); cgo->normal[0] = *pc; cgo->normal[1] = *(pc + 1); cgo->normal[2] = *(pc + 2);
break; break;
case CGO_TEX_COORD: case CGO_TEX_COORD:
cgo->texture[0] = *pc; cgo->texture[1] = *(pc + 1); cgo->texture[0] = *pc; cgo->texture[1] = *(pc + 1);
break; break;
case CGO_COLOR: case CGO_COLOR:
cgo->color[0] = *pc; cgo->color[1] = *(pc + 1); cgo->color[2] = *(pc + 2); cgo->color[0] = *pc; cgo->color[1] = *(pc + 1); cgo->color[2] = *(pc + 2);
break; break;
case CGO_ALPHA: case CGO_ALPHA:
cgo->alpha = *pc; cgo->alpha = *pc;
break; break;
case CGO_PICK_COLOR: case CGO_PICK_COLOR:
cgo->current_pick_color_index = CGO_get_int(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);
break; break;
case CGO_BEGIN: case CGO_BEGIN:
{ {
int err = 0, end = 0; int err = 0, end = 0;
short has_texcoord = false;
int mode = CGO_read_int(pc); int mode = CGO_read_int(pc);
int nverts = 0, ipl = 0; int nverts = 0, ipl = 0;
(void)mode; (void)mode;
cgo->texture[0] = cgo->texture[1] = 0.f; cgo->texture[0] = cgo->texture[1] = 0.f;
while(!err && !end && (op = (CGO_MASK & CGO_read_int(pc)))) { while(!err && !end && (op = (CGO_MASK & CGO_read_int(pc)))) {
end = (op == CGO_END); end = (op == CGO_END);
switch (op) { switch (op) {
case CGO_TEX_COORD: case CGO_TEX_COORD:
cgo->texture[0] = *pc; cgo->texture[1] = *(pc + 1); cgo->texture[0] = *pc; cgo->texture[1] = *(pc + 1);
has_texcoord = true;
break; break;
case CGO_COLOR: case CGO_COLOR:
cgo->color[0] = *pc; cgo->color[1] = *(pc + 1); cgo->color[2] = *(pc + 2); cgo->color[0] = *pc; cgo->color[1] = *(pc + 1); cgo->color[2] = *(pc + 2);
break; break;
case CGO_ALPHA: case CGO_ALPHA:
cgo->alpha = *pc; cgo->alpha = *pc;
break; break;
case CGO_VERTEX: case CGO_VERTEX:
{ {
switch (mode){ switch (mode){
skipping to change at line 3039 skipping to change at line 2758
} }
if (!skip){ if (!skip){
sz = CGO_sz[op]; sz = CGO_sz[op];
pc += sz; pc += sz;
} }
} }
ok &= !G->Interrupt; ok &= !G->Interrupt;
return ok; return ok;
} }
CGO *CGOOptimizeToVBONotIndexed(CGO * I, int est){ bool CGOOptimizeToVBONotIndexed(CGO ** I) {
return CGOOptimizeToVBONotIndexedWithReturnedData(I, est, true, NULL); CGO *cgo = CGOOptimizeToVBONotIndexed(*I, 0, true, NULL);
CGOFree(*I);
*I = cgo;
return (cgo != NULL);
} }
CGO *CGOOptimizeToVBONotIndexedWithReturnedData(CGO * I, int est, short addshade rs, float **returnedData) CGO *CGOOptimizeToVBONotIndexed(const CGO * I, int est, bool addshaders, float * *returnedData)
{ {
CGO *cgo; CGO *cgo;
float *pc = I->op; float *pc = I->op;
int op; int op;
float *save_pc; float *save_pc;
int num_total_vertices = 0, num_total_indexes = 0, num_total_vertices_lines = 0, num_total_indexes_lines = 0, int num_total_vertices = 0, num_total_indexes = 0, num_total_vertices_lines = 0, num_total_indexes_lines = 0,
num_total_vertices_points = 0; num_total_vertices_points = 0;
short err = 0;
short has_draw_buffer = false; short has_draw_buffer = false;
float min[3] = { MAXFLOAT, MAXFLOAT, MAXFLOAT }, max[3] = { -MAXFLOAT, -MAXFLO AT, -MAXFLOAT }; float min[3] = { MAXFLOAT, MAXFLOAT, MAXFLOAT }, max[3] = { -MAXFLOAT, -MAXFLO AT, -MAXFLOAT };
int ambient_occlusion = 0; int ambient_occlusion = 0;
int ok = true; int ok = true;
cgo = CGONewSized(I->G, 0); cgo = CGONewSized(I->G, 0);
CGOCountNumVertices(I, &num_total_vertices, &num_total_indexes, CGOCountNumVertices(I, &num_total_vertices, &num_total_indexes,
&num_total_vertices_lines, &num_total_indexes_lines, &num_total_vertices_lines, &num_total_indexes_lines,
&num_total_vertices_points); &num_total_vertices_points);
if (num_total_vertices_points>0){ if (num_total_vertices_points>0){
if (!OptimizePointsToVBO(I, cgo, num_total_vertices_points, min, max, &has_d raw_buffer)){ if (!OptimizePointsToVBO(I, cgo, num_total_vertices_points, min, max, &has_d raw_buffer, addshaders)){
CGOFree(cgo); CGOFree(cgo);
return NULL; return NULL;
} }
} }
if (num_total_indexes>0){ if (num_total_indexes>0){
float *vertexVals = 0, *colorVals = 0, *normalVals; float *vertexVals = 0, *colorVals = 0, *normalVals;
float *pickColorVals, *accessibilityVals = 0; float *pickColorVals, *accessibilityVals = 0;
int tot, nxtn; int tot, nxtn;
uchar *colorValsUC = 0; uchar *colorValsUC = 0;
uchar *normalValsC = 0; uchar *normalValsC = 0;
pc = I->op; pc = I->op;
cgo->alpha = 1.f; cgo->alpha = 1.f;
cgo->color[0] = 1.f; cgo->color[1] = 1.f; cgo->color[2] = 1.f; cgo->color[0] = 1.f; cgo->color[1] = 1.f; cgo->color[2] = 1.f;
tot = num_total_indexes * (3 * 6) ; tot = num_total_indexes * (3 * 6) ;
// tot = num_total_indexes * (3 * 3 + 2) ; // tot = num_total_indexes * (3 * 3 + 2) ;
/* NOTE/TODO: Not sure why 3*5 needs to be used, but 3*3+2, which is the /* NOTE/TODO: Not sure why 3*5 needs to be used, but 3*3+2, which is the
correct length, crashes in glBufferData */ correct length, crashes in glBufferData */
/* before allocating anything, we should check to make sure that we have eno
ugh memory on IOS,
otherwise we should just fail */
vertexVals = Alloc(float, tot); vertexVals = Alloc(float, tot);
if (!vertexVals){ if (!vertexVals){
PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeToVBONotIndexed() vert exVals could not be allocated\n" ENDFB(I->G); PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeToVBONotIndexed() vert exVals could not be allocated\n" ENDFB(I->G);
CGOFree(cgo); CGOFree(cgo);
return (NULL); return (NULL);
} }
normalVals = vertexVals + 3 * num_total_indexes; normalVals = vertexVals + 3 * num_total_indexes;
nxtn = 3; nxtn = 3;
if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_normal)){ if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_normal)){
normalValsC = (uchar*) normalVals; normalValsC = (uchar*) normalVals;
skipping to change at line 3106 skipping to change at line 2828
if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_color)){ if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_color)){
colorValsUC = (uchar*) colorVals; colorValsUC = (uchar*) colorVals;
nxtn = 1; nxtn = 1;
} else { } else {
nxtn = 4; nxtn = 4;
} }
pickColorVals = (colorVals + nxtn * num_total_indexes); pickColorVals = (colorVals + nxtn * num_total_indexes);
nxtn = 3; nxtn = 3;
accessibilityVals = pickColorVals + nxtn * num_total_indexes; accessibilityVals = pickColorVals + nxtn * num_total_indexes;
ok = CGOProcessCGOtoArrays(I->G, pc, cgo, cgo, min, max, &ambient_occlusion bool has_normals = false, has_colors = false, has_accessibility = false;
, vertexVals, normalVals, normalValsC, colorVals, colorValsUC, pickColorVals, ac ok = CGOProcessCGOtoArrays(I->G, pc, cgo, cgo, min, max, &ambient_occlusion
cessibilityVals); , vertexVals, normalVals, normalValsC, colorVals, colorValsUC, pickColorVals, ac
cessibilityVals, has_normals, has_colors, has_accessibility);
if (!ok){ if (!ok){
if (!I->G->Interrupt) if (!I->G->Interrupt)
PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOProcessCGOtoArrays() could no t allocate enough memory\n" ENDFB(I->G); PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOProcessCGOtoArrays() could no t allocate enough memory\n" ENDFB(I->G);
FreeP(vertexVals); FreeP(vertexVals);
CGOFree(cgo); CGOFree(cgo);
return (NULL); return (NULL);
} }
if (ok){ if (ok){
uint bufs[4] = {0, 0, 0, 0 }, allbufs[4] = { 0, 0, 0, 0 }; short nsz = VERTEX_NORMAL_SIZE * 4;
short bufpl = 0, numbufs = 3; GLenum ntp = GL_FLOAT;
GLenum err ; bool nnorm = GL_FALSE;
// printf("CGOOptimizeToVBOIndexed: End: num_total_vertices=%d num_to if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_normal)){
tal_indexes=%d verts_skipped=%d\n", num_total_vertices, num_total_indexes, verts nsz = VERTEX_NORMAL_SIZE;
_skipped); ntp = GL_BYTE;
// CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBONotIndexed() BEFORE glGenBuffe nnorm = GL_TRUE;
rs returns err=%d\n");
if (ambient_occlusion){
numbufs++;
}
if (ok){
glGenBuffers(numbufs, bufs);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBONotIndexed() glGenBuffers retur
ns err=%d\n");
}
if (ok){
glBindBuffer(GL_ARRAY_BUFFER, bufs[bufpl]);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBONotIndexed() glBindBuffer retur
ns err=%d\n");
}
if (ok && !glIsBuffer(bufs[bufpl])){
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeToVBONotIndexed()
glGenBuffers created bad buffer bufpl=%d bufs[bufpl]=%d\n", bufpl, bufs[bufpl]
ENDFB(I->G);
ok = false;
} else if (ok) {
allbufs[0] = bufs[bufpl++];
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*num_total_indexes*3, vertexVa
ls, GL_STATIC_DRAW);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBONotIndexed() glBufferData retur
ns err=%d\n");
}
if (ok){
glBindBuffer(GL_ARRAY_BUFFER, bufs[bufpl]);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBONotIndexed() glBindBuffer retur
ns err=%d\n");
}
if (ok && !glIsBuffer(bufs[bufpl])){
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeToVBONotIndexed()
glGenBuffers created bad buffer bufpl=%d bufs[bufpl]=%d\n", bufpl, bufs[bufpl]
ENDFB(I->G);
ok = false;
} else if (ok){
short sz = 3;
allbufs[1] = bufs[bufpl++];
if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_normal)){
sz = 1;
}
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*num_total_indexes*sz, normalV
als, GL_STATIC_DRAW);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBONotIndexed() glBufferData retur
ns err=%d\n");
}
if (ok){
glBindBuffer(GL_ARRAY_BUFFER, bufs[bufpl]);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBONotIndexed() glBindBuffer retur
ns err=%d\n");
}
if (ok && !glIsBuffer(bufs[bufpl])){
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeToVBONotIndexed()
glGenBuffers created bad buffer bufpl=%d bufs[bufpl]=%d\n", bufpl, bufs[bufpl]
ENDFB(I->G);
ok = false;
} else if (ok){
short sz = 4;
allbufs[2] = bufs[bufpl++];
if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_color)){
sz = 1;
}
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*num_total_indexes*sz, colorVa
ls, GL_STATIC_DRAW);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBONotIndexed() glBufferData retur
ns err=%d\n");
}
if (ok && ambient_occlusion){
glBindBuffer(GL_ARRAY_BUFFER, bufs[bufpl]);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBONotIndexed() glBindBuffer retur
ns err=%d\n");
if (ok && !glIsBuffer(bufs[bufpl])){
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeToVBONotIndexed
() glGenBuffers created bad buffer bufpl=%d bufs[bufpl]=%d\n", bufpl, bufs[bufpl
] ENDFB(I->G);
ok = false;
} else if (ok){
allbufs[3] = bufs[bufpl++];
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*num_total_indexes, accessib
ilityVals, GL_STATIC_DRAW);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBONotIndexed() glBufferData ret
urns err=%d\n");
}
} }
short csz = 4;
GLenum ctp = GL_FLOAT;
bool cnorm = GL_FALSE;
if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_color)){
csz = 1;
ctp = GL_UNSIGNED_BYTE;
cnorm = GL_TRUE;
}
VertexBuffer * vbo = I->G->ShaderMgr->newGPUBuffer<VertexBuffer>(VertexBuf
fer::SEQUENTIAL);
BufferDataDesc bufData =
{ { "a_Vertex", GL_FLOAT, 3, sizeof(float) * num_total_indexes * 3, vert
exVals, GL_FALSE } };
if (has_normals){
bufData.push_back( { "a_Normal", ntp, VERTEX_NORMAL_SIZE, (size_t)(
num_total_indexes * nsz), normalVals, nnorm } );
}
if (has_colors){
bufData.push_back( { "a_Color", ctp, 4, sizeof(float) * num_total_
indexes * csz, colorVals, cnorm } );
}
if (has_accessibility){
bufData.push_back( { "a_Accessibility", GL_FLOAT, 1, sizeof(float) * num
_total_indexes, accessibilityVals, GL_FALSE } );
}
ok = vbo->bufferData((BufferDataDesc)bufData);
size_t vboid = vbo->get_hash_id();
// 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);
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 )
});
size_t pickvboid = pickvbo->get_hash_id();
if (ok){ if (ok){
GLfloat *newPickColorVals ; float *newPickColorVals ;
int arrays = CGO_VERTEX_ARRAY | CGO_NORMAL_ARRAY | CGO_COLOR_ARRAY | CGO_ PICK_COLOR_ARRAY; int arrays = CGO_VERTEX_ARRAY | CGO_NORMAL_ARRAY | CGO_COLOR_ARRAY | CGO_ PICK_COLOR_ARRAY;
if (ambient_occlusion){ if (ambient_occlusion){
arrays |= CGO_ACCESSIBILITY_ARRAY; arrays |= CGO_ACCESSIBILITY_ARRAY;
} }
if (addshaders) if (addshaders)
CGOEnable(cgo, GL_DEFAULT_SHADER); CGOEnable(cgo, GL_DEFAULT_SHADER_WITH_SETTINGS);
newPickColorVals = CGODrawBuffersNotIndexed(cgo, GL_TRIANGLES, arrays, nu newPickColorVals = cgo->add<cgo::draw::buffers_not_indexed>(GL_TRIANGLES,
m_total_indexes, allbufs); arrays, num_total_indexes, vboid, pickvboid);
if (ok && addshaders) if (ok && addshaders)
ok &= CGODisable(cgo, GL_DEFAULT_SHADER); ok &= CGODisable(cgo, GL_DEFAULT_SHADER);
CHECKOK(ok, newPickColorVals); CHECKOK(ok, newPickColorVals);
if (!newPickColorVals){ if (!newPickColorVals){
CShaderMgr_AddVBOsToFree(I->G->ShaderMgr, bufs, numbufs); I->G->ShaderMgr->freeGPUBuffer(pickvboid);
I->G->ShaderMgr->freeGPUBuffer(vboid);
} }
if (!ok){ if (!ok){
PRINTFB(I->G, FB_CGO, FB_Errors) "CGOOptimizeToVBONotIndexedWithReturne dData: ERROR: CGODrawBuffersNotIndexed() could not allocate enough memory\n" END FB(I->G); PRINTFB(I->G, FB_CGO, FB_Errors) "CGOOptimizeToVBONotIndexedWithReturne dData: ERROR: CGODrawBuffersNotIndexed() could not allocate enough memory\n" END FB(I->G);
FreeP(vertexVals); FreeP(vertexVals);
CGOFree(cgo); CGOFree(cgo);
return (NULL); return (NULL);
} }
memcpy(newPickColorVals + num_total_indexes, pickColorVals, num_total_ind exes * 2 * sizeof(float)); memcpy(newPickColorVals + num_total_indexes, pickColorVals, num_total_ind exes * 2 * sizeof(float));
has_draw_buffer = true; has_draw_buffer = true;
} else { } else {
CShaderMgr_AddVBOsToFree(I->G->ShaderMgr, bufs, numbufs); I->G->ShaderMgr->freeGPUBuffer(vboid);
I->G->ShaderMgr->freeGPUBuffer(pickvboid);
} }
} }
if (ok && returnedData){ if (ok && returnedData){
returnedData[0] = vertexVals; returnedData[0] = vertexVals;
} else { } else {
FreeP(vertexVals); FreeP(vertexVals);
} }
} }
if (ok && num_total_indexes_lines>0){ if (ok && num_total_indexes_lines>0){
bool has_color = false, has_normals = false;
float *vertexVals = 0, *colorVals = 0, *normalVals; float *vertexVals = 0, *colorVals = 0, *normalVals;
float *pickColorVals; float *pickColorVals;
int pl = 0, plc = 0, idxpl = 0, vpl = 0, tot, nxtn; int pl = 0, plc = 0, idxpl = 0, vpl = 0, tot, nxtn;
uchar *colorValsUC = 0; uchar *colorValsUC = 0;
uchar *normalValsC = 0; uchar *normalValsC = 0;
pc = I->op; pc = I->op;
cgo->alpha = 1.f; cgo->alpha = 1.f;
cgo->color[0] = 1.f; cgo->color[1] = 1.f; cgo->color[2] = 1.f; cgo->color[0] = 1.f; cgo->color[1] = 1.f; cgo->color[2] = 1.f;
skipping to change at line 3255 skipping to change at line 2953
colorVals = normalVals + nxtn * num_total_indexes_lines; colorVals = normalVals + nxtn * num_total_indexes_lines;
if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_color)){ if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_color)){
colorValsUC = (uchar*) colorVals; colorValsUC = (uchar*) colorVals;
nxtn = 1; nxtn = 1;
} else { } else {
nxtn = 4; nxtn = 4;
} }
pickColorVals = (colorVals + nxtn * num_total_indexes_lines); pickColorVals = (colorVals + nxtn * num_total_indexes_lines);
while((op = (CGO_MASK & CGO_read_int(pc)))) { while((op = (CGO_MASK & CGO_read_int(pc)))) {
save_pc = pc; save_pc = pc;
err = 0;
switch (op) { switch (op) {
case CGO_LINEWIDTH_SPECIAL: case CGO_SPECIAL:
case CGO_RESET_NORMAL: case CGO_RESET_NORMAL:
{ {
float *newpc = pc, *nc; float *newpc = pc;
int sz; cgo->add_to_cgo(op, newpc);
sz = CGO_sz[op];
nc = CGO_add(cgo, sz + 1);
*(nc++) = *(pc - 1);
while(sz--)
*(nc++) = *(newpc++);
} }
break; break;
case CGO_NORMAL: case CGO_NORMAL:
has_normals = true;
cgo->normal[0] = *pc; cgo->normal[1] = *(pc + 1); cgo->normal[2] = *(pc + 2); cgo->normal[0] = *pc; cgo->normal[1] = *(pc + 1); cgo->normal[2] = *(pc + 2);
break; break;
case CGO_COLOR: case CGO_COLOR:
has_color = true;
cgo->color[0] = *pc; cgo->color[1] = *(pc + 1); cgo->color[2] = *(pc + 2) ; cgo->color[0] = *pc; cgo->color[1] = *(pc + 1); cgo->color[2] = *(pc + 2) ;
break; break;
case CGO_ACCESSIBILITY: case CGO_ACCESSIBILITY:
cgo->current_accessibility = pc[0]; cgo->current_accessibility = pc[0];
break; break;
case CGO_ALPHA: case CGO_ALPHA:
cgo->alpha = *pc; cgo->alpha = *pc;
break; break;
case CGO_PICK_COLOR: case CGO_PICK_COLOR:
cgo->current_pick_color_index = CGO_get_int(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);
break; break;
case CGO_DRAW_ARRAYS: case CGO_DRAW_ARRAYS:
{ {
int mode = CGO_get_int(pc), arrays = CGO_get_int(pc + 1), narrays = CGO_g cgo::draw::arrays * sp = reinterpret_cast<decltype(sp)>(pc);
et_int(pc + 2), nverts = CGO_get_int(pc + 3);
short shouldCompress = false; short shouldCompress = false;
switch(mode){ switch(sp->mode){
case GL_LINE_LOOP: case GL_LINE_LOOP:
case GL_LINE_STRIP: case GL_LINE_STRIP:
case GL_LINES: case GL_LINES:
shouldCompress = true; shouldCompress = true;
default: default:
break; break;
} }
if (shouldCompress){ if (shouldCompress){
int nvals = narrays*nverts, cnt, nxtn = 3, incr = 0; int cnt, nxtn = 3, incr = 0;
float *vertexValsDA = 0, *nxtVals = 0, *colorValsDA = 0, *normalValsDA; float *vertexValsDA = NULL, *nxtVals = NULL, *colorValsDA = NULL, *norm
float *pickColorValsDA, *pickColorValsTMP; alValsDA = NULL;
float *pickColorValsDA = NULL, *pickColorValsTMP;
nxtVals = vertexValsDA = pc + 4; nxtVals = vertexValsDA = sp->floatdata;
for (cnt=0; cnt<nverts*3; cnt+=3){ for (cnt=0; cnt<sp->nverts*3; cnt+=3){
set_min_max(min, max, &vertexValsDA[cnt]); set_min_max(min, max, &vertexValsDA[cnt]);
} }
if (arrays & CGO_NORMAL_ARRAY){ if (sp->arraybits & CGO_NORMAL_ARRAY){
nxtVals = normalValsDA = vertexValsDA + (nxtn*nverts); has_normals = true;
nxtVals = normalValsDA = vertexValsDA + (nxtn*sp->nverts);
} }
if (arrays & CGO_COLOR_ARRAY){ if (sp->arraybits & CGO_COLOR_ARRAY){
nxtVals = colorValsDA = nxtVals + (nxtn*nverts); has_color = true;
nxtVals = colorValsDA = nxtVals + (nxtn*sp->nverts);
nxtn = 4; nxtn = 4;
} }
if (arrays & CGO_PICK_COLOR_ARRAY){ if (sp->arraybits & CGO_PICK_COLOR_ARRAY){
nxtVals = nxtVals + (nxtn*nverts); nxtVals = nxtVals + (nxtn*sp->nverts);
pickColorValsDA = nxtVals + nverts; pickColorValsDA = nxtVals + sp->nverts;
nxtn = 3; nxtn = 3;
} }
pickColorValsTMP = pickColorVals + (idxpl * 2); pickColorValsTMP = pickColorVals + (idxpl * 2);
/* if (idxpl + nverts > num_total_indexes){ switch (sp->mode){
printf("num_total_indexes=%d mode=%d nverts=%d idxpl=%d\n", num_total
_indexes, mode, nverts, idxpl);
}*/
switch (mode){
case GL_LINES: case GL_LINES:
for (cnt = 0; cnt < nverts; cnt++){ for (cnt = 0; cnt < sp->nverts; cnt++){
SetVertexValuesForVBO(I->G, cgo, arrays, pl, plc, cnt, incr++, SetVertexValuesForVBO(I->G, cgo, pl, plc, cnt, incr++,
vertexValsDA, normalValsDA, colorValsDA, pick ColorValsDA, vertexValsDA, normalValsDA, colorValsDA, pick ColorValsDA,
vertexVals, normalValsC, normalVals, colorVal sUC, colorVals, vertexVals, normalValsC, normalVals, colorVal sUC, colorVals,
pickColorValsTMP, NULL, NULL); pickColorValsTMP);
if (incr && (incr % 2) == 0){
FixPickColorsForLine(pickColorValsTMP + (incr-2) * 2,
pickColorValsTMP + (incr-1) * 2);
}
idxpl++; pl += 3; plc += 4; idxpl++; pl += 3; plc += 4;
} }
break; break;
case GL_LINE_STRIP: case GL_LINE_STRIP:
for (cnt = 1; cnt < nverts; cnt++){ for (cnt = 1; cnt < sp->nverts; cnt++){
SetVertexValuesForVBO(I->G, cgo, arrays, pl, plc, cnt-1, incr++, SetVertexValuesForVBO(I->G, cgo, pl, plc, cnt-1, incr++,
vertexValsDA, normalValsDA, colorValsDA, pick ColorValsDA, vertexValsDA, normalValsDA, colorValsDA, pick ColorValsDA,
vertexVals, normalValsC, normalVals, colorVal sUC, colorVals, vertexVals, normalValsC, normalVals, colorVal sUC, colorVals,
pickColorValsTMP, NULL, NULL); pickColorValsTMP);
idxpl++; pl += 3; plc += 4; idxpl++; pl += 3; plc += 4;
SetVertexValuesForVBO(I->G, cgo, arrays, pl, plc, cnt, incr++, SetVertexValuesForVBO(I->G, cgo, pl, plc, cnt, incr++,
vertexValsDA, normalValsDA, colorValsDA, pick ColorValsDA, vertexValsDA, normalValsDA, colorValsDA, pick ColorValsDA,
vertexVals, normalValsC, normalVals, colorVal sUC, colorVals, vertexVals, normalValsC, normalVals, colorVal sUC, colorVals,
pickColorValsTMP, NULL, NULL); pickColorValsTMP);
FixPickColorsForLine(pickColorValsTMP + (incr-2) * 2,
pickColorValsTMP + (incr-1) * 2);
idxpl++; pl += 3; plc += 4; idxpl++; pl += 3; plc += 4;
} }
break; break;
case GL_LINE_LOOP: case GL_LINE_LOOP:
for (cnt = 1; cnt < nverts; cnt++){ for (cnt = 1; cnt < sp->nverts; cnt++){
SetVertexValuesForVBO(I->G, cgo, arrays, pl, plc, cnt-1, incr++, SetVertexValuesForVBO(I->G, cgo, pl, plc, cnt-1, incr++,
vertexValsDA, normalValsDA, colorValsDA, pick ColorValsDA, vertexValsDA, normalValsDA, colorValsDA, pick ColorValsDA,
vertexVals, normalValsC, normalVals, colorVal sUC, colorVals, vertexVals, normalValsC, normalVals, colorVal sUC, colorVals,
pickColorValsTMP, NULL, NULL); pickColorValsTMP);
idxpl++; pl += 3; plc += 4; idxpl++; pl += 3; plc += 4;
SetVertexValuesForVBO(I->G, cgo, arrays, pl, plc, cnt, incr++, SetVertexValuesForVBO(I->G, cgo, pl, plc, cnt, incr++,
vertexValsDA, normalValsDA, colorValsDA, pick ColorValsDA, vertexValsDA, normalValsDA, colorValsDA, pick ColorValsDA,
vertexVals, normalValsC, normalVals, colorVal sUC, colorVals, vertexVals, normalValsC, normalVals, colorVal sUC, colorVals,
pickColorValsTMP, NULL, NULL); pickColorValsTMP);
FixPickColorsForLine(pickColorValsTMP + (incr-2) * 2,
pickColorValsTMP + (incr-1) * 2);
idxpl++; pl += 3; plc += 4; idxpl++; pl += 3; plc += 4;
} }
SetVertexValuesForVBO(I->G, cgo, arrays, pl, plc, 0, incr++, SetVertexValuesForVBO(I->G, cgo, pl, plc, 0, incr++,
vertexValsDA, normalValsDA, colorValsDA, pickCo lorValsDA, vertexValsDA, normalValsDA, colorValsDA, pickCo lorValsDA,
vertexVals, normalValsC, normalVals, colorValsU C, colorVals, vertexVals, normalValsC, normalVals, colorValsU C, colorVals,
pickColorValsTMP, NULL, NULL); pickColorValsTMP);
idxpl++; pl += 3; plc += 4; idxpl++; pl += 3; plc += 4;
SetVertexValuesForVBO(I->G, cgo, arrays, pl, plc, nverts-1, incr++, SetVertexValuesForVBO(I->G, cgo, pl, plc, sp->nverts-1, incr++,
vertexValsDA, normalValsDA, colorValsDA, pickCo lorValsDA, vertexValsDA, normalValsDA, colorValsDA, pickCo lorValsDA,
vertexVals, normalValsC, normalVals, colorValsU C, colorVals, vertexVals, normalValsC, normalVals, colorValsU C, colorVals,
pickColorValsTMP, NULL, NULL); pickColorValsTMP);
FixPickColorsForLine(pickColorValsTMP + (incr-2) * 2,
pickColorValsTMP + (incr-1) * 2);
idxpl++; pl += 3; plc += 4; idxpl++; pl += 3; plc += 4;
break; break;
} }
// pl += 3 * nverts; // pl += 3 * nverts;
// plc += 4 * nverts; // plc += 4 * nverts;
vpl += nverts; vpl += sp->nverts;
pc += nvals + 4;
save_pc += nvals + 4 ;
} else {
{
int nvals = narrays*nverts ;
pc += nvals + 4;
save_pc += nvals + 4 ;
}
}
} }
}
break; break;
default: default:
break; break;
} }
pc = save_pc; pc = save_pc;
pc += CGO_sz[op]; pc += CGO_sz[op];
} }
{ {
uint bufs[3] = {0, 0, 0 }, allbufs[4] = { 0, 0, 0, 0 }; short nsz = VERTEX_NORMAL_SIZE * 4;
short bufpl = 0; GLenum ntp = GL_FLOAT;
GLenum err ; bool nnorm = GL_FALSE;
// printf("CGOOptimizeToVBOIndexed: End: num_total_vertices=%d num_to if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_normal)){
tal_indexes=%d verts_skipped=%d\n", num_total_vertices, num_total_indexes, verts nsz = VERTEX_NORMAL_SIZE;
_skipped); ntp = GL_BYTE;
// CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBONotIndexed() BEFORE glGenBuffe nnorm = GL_TRUE;
rs returns err=%d\n");
if (ok){
glGenBuffers(3, bufs);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBONotIndexed() glGenBuffers returns
err=%d\n");
}
if (ok){
glBindBuffer(GL_ARRAY_BUFFER, bufs[bufpl]);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBONotIndexed() glBindBuffer retur
ns err=%d\n");
}
if (ok && !glIsBuffer(bufs[bufpl])){
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeToVBONotIndexed()
glGenBuffers created bad buffer bufpl=%d bufs[bufpl]=%d\n", bufpl, bufs[bufpl]
ENDFB(I->G);
ok = false;
} else if (ok){
allbufs[0] = bufs[bufpl++];
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*num_total_indexes_lines*3, ve
rtexVals, GL_STATIC_DRAW);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBONotIndexed() glBufferData retur
ns err=%d\n");
}
if (ok){
glBindBuffer(GL_ARRAY_BUFFER, bufs[bufpl]);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBONotIndexed() glBindBuffer retur
ns err=%d\n");
}
if (ok && !glIsBuffer(bufs[bufpl])){
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeToVBONotIndexed()
glGenBuffers created bad buffer bufpl=%d bufs[bufpl]=%d\n", bufpl, bufs[bufpl]
ENDFB(I->G);
ok = false;
} else if (ok){
short sz = 3;
allbufs[1] = bufs[bufpl++];
if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_normal)){
sz = 1;
}
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*num_total_indexes_lines*sz, n
ormalVals, GL_STATIC_DRAW);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBONotIndexed() glBufferData retur
ns err=%d\n");
}
if (ok){
glBindBuffer(GL_ARRAY_BUFFER, bufs[bufpl]);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBONotIndexed() glBindBuffer retur
ns err=%d\n");
}
if (ok && !glIsBuffer(bufs[bufpl])){
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeToVBONotIndexed()
glGenBuffers created bad buffer bufpl=%d bufs[bufpl]=%d\n", bufpl, bufs[bufpl]
ENDFB(I->G);
ok = false;
} else if (ok){
short sz = 4;
allbufs[2] = bufs[bufpl++];
if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_color)){
sz = 1;
}
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*num_total_indexes_lines*sz, c
olorVals, GL_STATIC_DRAW);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBONotIndexed() glBufferData retur
ns err=%d\n");
} }
short csz = 4;
GLenum ctp = GL_FLOAT;
bool cnorm = GL_FALSE;
if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_color)){
csz = 1;
ctp = GL_UNSIGNED_BYTE;
cnorm = GL_TRUE;
}
VertexBuffer * vbo = I->G->ShaderMgr->newGPUBuffer<VertexBuffer>(VertexBuf
fer::SEQUENTIAL);
BufferDataDesc bufData =
{ { "a_Vertex", GL_FLOAT, 3, sizeof(float) * num_total_indexes_lines * 3
, vertexVals, GL_FALSE } };
if (has_normals){
bufData.push_back( { "a_Normal", ntp, VERTEX_NORMAL_SIZE, (size_t)(
num_total_indexes_lines * nsz), normalVals, nnorm } );
}
if (has_color){
bufData.push_back( { "a_Color", ctp, 4, sizeof(float) * num_total_
indexes_lines * csz, colorVals, cnorm } );
}
ok = vbo->bufferData((BufferDataDesc)bufData);
size_t vboid = vbo->get_hash_id();
// 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);
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 )
});
size_t pickvboid = pickvbo->get_hash_id();
if (ok){ if (ok){
GLfloat *newPickColorVals ; float *newPickColorVals ;
if (addshaders) if (addshaders)
CGOEnable(cgo, GL_DEFAULT_SHADER); CGOEnable(cgo, GL_DEFAULT_SHADER_WITH_SETTINGS);
CGODisable(cgo, GL_SHADER_LIGHTING); CGODisable(cgo, GL_SHADER_LIGHTING);
newPickColorVals = CGODrawBuffersNotIndexed(cgo, GL_LINES, CGO_VERTEX_ARR AY | CGO_NORMAL_ARRAY | CGO_COLOR_ARRAY | CGO_PICK_COLOR_ARRAY, num_total_indexe s_lines, allbufs); newPickColorVals = cgo->add<cgo::draw::buffers_not_indexed>(GL_LINES, CGO _VERTEX_ARRAY | CGO_NORMAL_ARRAY | CGO_COLOR_ARRAY | CGO_PICK_COLOR_ARRAY, num_t otal_indexes_lines, vboid, pickvboid);
if (ok && addshaders) if (ok && addshaders)
ok &= CGODisable(cgo, GL_DEFAULT_SHADER); ok &= CGODisable(cgo, GL_DEFAULT_SHADER);
CHECKOK(ok, newPickColorVals); CHECKOK(ok, newPickColorVals);
if (!ok){ if (!ok){
PRINTFB(I->G, FB_CGO, FB_Errors) "CGOOptimizeToVBONotIndexedWithReturne dData: ERROR: CGODrawBuffersNotIndexed() could not allocate enough memory\n" END FB(I->G); PRINTFB(I->G, FB_CGO, FB_Errors) "CGOOptimizeToVBONotIndexedWithReturne dData: ERROR: CGODrawBuffersNotIndexed() could not allocate enough memory\n" END FB(I->G);
FreeP(vertexVals); FreeP(vertexVals);
CGOFree(cgo); CGOFree(cgo);
if (!newPickColorVals) if (!newPickColorVals) {
CShaderMgr_AddVBOsToFree(I->G->ShaderMgr, bufs, 3); I->G->ShaderMgr->freeGPUBuffer(pickvboid);
I->G->ShaderMgr->freeGPUBuffer(vboid);
}
return (NULL); return (NULL);
} }
memcpy(newPickColorVals + num_total_indexes_lines, pickColorVals, num_tot al_indexes_lines * 2 * sizeof(float)); memcpy(newPickColorVals + num_total_indexes_lines, pickColorVals, num_tot al_indexes_lines * 2 * sizeof(float));
has_draw_buffer = true; has_draw_buffer = true;
} else { } else {
CShaderMgr_AddVBOsToFree(I->G->ShaderMgr, bufs, 3); I->G->ShaderMgr->freeGPUBuffer(pickvboid);
I->G->ShaderMgr->freeGPUBuffer(vboid);
} }
} }
if (ok && returnedData){ if (ok && returnedData){
returnedData[1] = vertexVals; returnedData[1] = vertexVals;
} else { } else {
FreeP(vertexVals); FreeP(vertexVals);
} }
} }
if (ok && (num_total_vertices>0 || num_total_vertices_lines>0 || num_total_ver tices_points>0)){ if (ok && (num_total_vertices>0 || num_total_vertices_lines>0 || num_total_ver tices_points>0)){
skipping to change at line 3496 skipping to change at line 3179
if (has_draw_buffer){ if (has_draw_buffer){
cgo->has_draw_buffers = true; cgo->has_draw_buffers = true;
} }
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 (!ok){ if (!ok){
CGOFree(cgo); CGOFree(cgo);
cgo = NULL;
} }
return (cgo); return (cgo);
} }
CGO *CGOOptimizeToVBOIndexedWithColorImpl(CGO * I, int est, float *color, short CGO *CGOOptimizeToVBOIndexed(CGO * I, int est,
addshaders); const float *color, bool addshaders, bool embedTransparencyInfo)
CGO *CGOOptimizeToVBOIndexed(CGO * I, int est){
return CGOOptimizeToVBOIndexedWithColorImpl(I, est, NULL, true);
}
CGO *CGOOptimizeToVBOIndexedNoShader(CGO * I, int est){
return CGOOptimizeToVBOIndexedWithColorImpl(I, est, NULL, false);
}
CGO *CGOOptimizeToVBOIndexedWithColor(CGO * I, int est, float *color)
{
return CGOOptimizeToVBOIndexedWithColorImpl(I, est, color, true);
}
CGO *CGOOptimizeToVBOIndexedWithColorImpl(CGO * I, int est, float *color, short
addshaders)
{ {
CGO *cgo; CGO *cgo;
float *pc = I->op; float *pc = I->op;
int op; int op;
float *save_pc; float *save_pc;
int num_total_vertices = 0, num_total_indexes = 0, num_total_vertices_lines = 0, num_total_indexes_lines = 0, int num_total_vertices = 0, num_total_indexes = 0, num_total_vertices_lines = 0, num_total_indexes_lines = 0,
num_total_vertices_points = 0; num_total_vertices_points = 0;
short err = 0;
short has_draw_buffer = false; short has_draw_buffer = false;
float min[3] = { MAXFLOAT, MAXFLOAT, MAXFLOAT }, max[3] = { -MAXFLOAT, -MAXFLO AT, -MAXFLOAT }; float min[3] = { MAXFLOAT, MAXFLOAT, MAXFLOAT }, max[3] = { -MAXFLOAT, -MAXFLO AT, -MAXFLOAT };
int ok = true; int ok = true;
CGOCountNumVertices(I, &num_total_vertices, &num_total_indexes,
&num_total_vertices_lines, &num_total_indexes_lines,
&num_total_vertices_points);
cgo = CGONewSized(I->G, I->c + est); cgo = CGONewSized(I->G, I->c + est);
CHECKOK(ok, cgo); CHECKOK(ok, cgo);
if (ok){ if (ok){
cgo->alpha = 1.f;
if (color){ if (color){
cgo->color[0] = color[0]; cgo->color[1] = color[1]; cgo->color[2] = color[ 2]; cgo->color[0] = color[0]; cgo->color[1] = color[1]; cgo->color[2] = color[ 2];
cgo->alpha = color[3]; cgo->alpha = color[3];
} else { } else {
cgo->color[0] = 1.f; cgo->color[1] = 1.f; cgo->color[2] = 1.f; cgo->color[0] = 1.f; cgo->color[1] = 1.f; cgo->color[2] = 1.f;
cgo->alpha = 1.f;
} }
CGOCountNumVertices(I, &num_total_vertices, &num_total_indexes,
&num_total_vertices_lines, &num_total_indexes_lines,
&num_total_vertices_points);
} }
#if defined(_PYMOL_IOS) && !defined(_WEBGL)
if (num_total_indexes > MAX_INDICES_FOR_IOS || num_total_indexes_lines > MAX_I
NDICES_FOR_IOS){
PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeToVBOIndexed() VBO Memor
y Limitation: The requested \n operation requires a larger buffer than PyM
OL currently allows. \n The operation has not entirely completed successfu
lly.\n" ENDFB(I->G);
firePyMOLLimitationWarning();
CGOFree(cgo);
return NULL;
}
#endif
if (num_total_vertices_points>0){ if (num_total_vertices_points>0){
/* This does not need to be indexed (for now) */ /* This does not need to be indexed (for now) */
if (!OptimizePointsToVBO(I, cgo, num_total_vertices_points, min, max, &has_d raw_buffer)){ if (!OptimizePointsToVBO(I, cgo, num_total_vertices_points, min, max, &has_d raw_buffer, addshaders)){
CGOFree(cgo); CGOFree(cgo);
return NULL; return NULL;
} }
} }
if (num_total_vertices>0){ if (num_total_vertices>0){
float *vertexVals = 0, *colorVals = 0, *normalVals, *accessibilityVals = 0; float *vertexVals = 0, *colorVals = 0, *normalVals, *accessibilityVals = 0;
float *pickColorVals; float *pickColorVals;
GL_C_INT_TYPE *vertexIndexes; GL_C_INT_TYPE *vertexIndices;
short vertexIndicesAllocated = 0;
int pl = 0, plc = 0, idxpl = 0, vpl = 0, tot, nxtn; int pl = 0, plc = 0, idxpl = 0, vpl = 0, tot, nxtn;
uchar *colorValsUC = 0; uchar *colorValsUC = 0;
uchar *normalValsC = 0; uchar *normalValsC = 0;
short ambient_occlusion = 0; short ambient_occlusion = 0;
float *sumarray = NULL;
int n_data = 0;
pc = I->op; pc = I->op;
vertexIndexes = Alloc(GL_C_INT_TYPE, num_total_indexes);
if (!vertexIndexes){ if (embedTransparencyInfo){
PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeToVBOIndexed() vertexI int n_tri = num_total_indexes / 3;
ndexes could not be allocated\n" ENDFB(I->G); int bytes_to_allocate = 2 * num_total_indexes * sizeof(GL_C_INT_TYPE) + //
vertexIndicesOriginal, vertexIndices
3 * num_total_indexes * sizeof(float) + // 3 * for sum
n_tri * sizeof(float) + 2 * n_tri * sizeof(int) + 256 * sizeof(int); /
/ z_value (float * n_tri), ix (n_tri * int), sort_mem ((n_tri + 256) * int)
// round to 4 byte words for the length of the CGO
n_data = bytes_to_allocate / 4 + (((bytes_to_allocate % 4) == 0) ? 0 : 1)
;
}
vertexIndices = Calloc(GL_C_INT_TYPE, num_total_indexes);
vertexIndicesAllocated = 1;
if (!vertexIndices){
PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeToVBOIndexed() vertexI
ndices could not be allocated\n" ENDFB(I->G);
CGOFree(cgo); CGOFree(cgo);
return (NULL); return (NULL);
} }
tot = num_total_vertices * (3 * 6) ; tot = num_total_vertices * (3 * 6) ;
// tot = num_total_vertices * (3 * 3 + 2) ; // tot = num_total_vertices * (3 * 3 + 2) ;
/* NOTE/TODO: Not sure why 3*5 needs to be used, but 3*3+2, which is the /* NOTE/TODO: Not sure why 3*5 needs to be used, but 3*3+2, which is the
correct length, crashes in glBufferData */ correct length, crashes in glBufferData */
vertexVals = Alloc(float, tot); vertexVals = Alloc(float, tot);
if (!vertexVals){ if (!vertexVals){
PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeToVBOIndexed() vertexV als could not be allocated\n" ENDFB(I->G); PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeToVBOIndexed() vertexV als could not be allocated\n" ENDFB(I->G);
skipping to change at line 3595 skipping to change at line 3288
colorValsUC = (uchar*) colorVals; colorValsUC = (uchar*) colorVals;
nxtn = 1; nxtn = 1;
} else { } else {
nxtn = 4; nxtn = 4;
} }
pickColorVals = (colorVals + nxtn * num_total_vertices); pickColorVals = (colorVals + nxtn * num_total_vertices);
accessibilityVals = pickColorVals + 3 * num_total_vertices; accessibilityVals = pickColorVals + 3 * num_total_vertices;
while(ok && (op = (CGO_MASK & CGO_read_int(pc)))) { while(ok && (op = (CGO_MASK & CGO_read_int(pc)))) {
save_pc = pc; save_pc = pc;
err = 0;
switch (op) { switch (op) {
case CGO_NORMAL: case CGO_NORMAL:
cgo->normal[0] = *pc; cgo->normal[1] = *(pc + 1); cgo->normal[2] = *(pc + 2); cgo->normal[0] = *pc; cgo->normal[1] = *(pc + 1); cgo->normal[2] = *(pc + 2);
break; break;
case CGO_COLOR: case CGO_COLOR:
cgo->color[0] = *pc; cgo->color[1] = *(pc + 1); cgo->color[2] = *(pc + 2) ; cgo->color[0] = *pc; cgo->color[1] = *(pc + 1); cgo->color[2] = *(pc + 2) ;
break; break;
case CGO_ALPHA: case CGO_ALPHA:
cgo->alpha = *pc; cgo->alpha = *pc;
break; break;
case CGO_ACCESSIBILITY: case CGO_ACCESSIBILITY:
cgo->current_accessibility = *pc; cgo->current_accessibility = *pc;
break; break;
case CGO_PICK_COLOR: case CGO_PICK_COLOR:
cgo->current_pick_color_index = CGO_get_int(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);
break; break;
case CGO_DRAW_ARRAYS: case CGO_DRAW_ARRAYS:
{ {
int mode = CGO_get_int(pc), arrays = CGO_get_int(pc + 1), narrays = CGO_g et_int(pc + 2), nverts = CGO_get_int(pc + 3); cgo::draw::arrays * sp = reinterpret_cast<decltype(sp)>(pc);
short shouldCompress = false; short shouldCompress = false;
switch(mode){ switch(sp->mode){
case GL_TRIANGLE_FAN: case GL_TRIANGLE_FAN:
case GL_TRIANGLE_STRIP: case GL_TRIANGLE_STRIP:
case GL_TRIANGLES: case GL_TRIANGLES:
shouldCompress = true; shouldCompress = true;
default: default:
break; break;
} }
if (shouldCompress){ if (shouldCompress){
int nvals = narrays*nverts, cnt, nxtn = 3; int cnt, nxtn = 3;
float *vertexValsDA = 0, *nxtVals = 0, *colorValsDA = 0, *normalValsDA, *accessibilityValsDA; float *vertexValsDA = 0, *nxtVals = 0, *colorValsDA = 0, *normalValsDA, *accessibilityValsDA;
float *pickColorValsDA, *pickColorValsTMP, *accessibilityValsTMP; float *pickColorValsDA, *pickColorValsTMP, *accessibilityValsTMP;
nxtVals = vertexValsDA = pc + 4; nxtVals = vertexValsDA = sp->floatdata;
for (cnt=0; cnt<nverts*3; cnt+=3){ for (cnt=0; cnt<sp->nverts*3; cnt+=3){
set_min_max(min, max, &vertexValsDA[cnt]); set_min_max(min, max, &vertexValsDA[cnt]);
} }
for (cnt=0; cnt<nverts*3; cnt++){ for (cnt=0; cnt<sp->nverts*3; cnt++){
vertexVals[pl + cnt] = vertexValsDA[cnt]; vertexVals[pl + cnt] = vertexValsDA[cnt];
} }
if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_normal)){ if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_normal)){
if (arrays & CGO_NORMAL_ARRAY){ if (sp->arraybits & CGO_NORMAL_ARRAY){
nxtVals = normalValsDA = vertexValsDA + (nxtn*nverts); nxtVals = normalValsDA = vertexValsDA + (nxtn*sp->nverts);
for (cnt=0; cnt<nverts*3; cnt++){ for (cnt=0; cnt<sp->nverts*3; cnt++){
normalValsC[VAR_FOR_NORMAL + cnt VAR_FOR_NORMAL_CNT_PLUS] = CLIP_ NORMAL_VALUE(normalValsDA[cnt]); normalValsC[VAR_FOR_NORMAL + cnt VAR_FOR_NORMAL_CNT_PLUS] = CLIP_ NORMAL_VALUE(normalValsDA[cnt]);
} }
} else { } else {
uchar norm[3] = { CLIP_NORMAL_VALUE(cgo->normal[0]), CLIP_NORMAL_VA LUE(cgo->normal[1]), CLIP_NORMAL_VALUE(cgo->normal[2]) }; uchar norm[3] = { CLIP_NORMAL_VALUE(cgo->normal[0]), CLIP_NORMAL_VA LUE(cgo->normal[1]), CLIP_NORMAL_VALUE(cgo->normal[2]) };
for (cnt=0; cnt<nverts*3; cnt++){ for (cnt=0; cnt<sp->nverts*3; cnt++){
normalValsC[VAR_FOR_NORMAL + cnt VAR_FOR_NORMAL_CNT_PLUS] = norm[ cnt%3]; normalValsC[VAR_FOR_NORMAL + cnt VAR_FOR_NORMAL_CNT_PLUS] = norm[ cnt%3];
} }
} }
} else { } else {
if (arrays & CGO_NORMAL_ARRAY){ if (sp->arraybits & CGO_NORMAL_ARRAY){
nxtVals = normalValsDA = vertexValsDA + (nxtn*nverts); nxtVals = normalValsDA = vertexValsDA + (nxtn*sp->nverts);
for (cnt=0; cnt<nverts*3; cnt++){ for (cnt=0; cnt<sp->nverts*3; cnt++){
normalVals[pl + cnt] = normalValsDA[cnt]; normalVals[pl + cnt] = normalValsDA[cnt];
} }
} else { } else {
for (cnt=0; cnt<nverts*3; cnt++){ for (cnt=0; cnt<sp->nverts*3; cnt++){
normalVals[pl + cnt] = cgo->normal[cnt%3]; normalVals[pl + cnt] = cgo->normal[cnt%3];
} }
} }
} }
nxtn = 3; nxtn = 3;
if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_color)){ if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_color)){
if (arrays & CGO_COLOR_ARRAY){ if (sp->arraybits & CGO_COLOR_ARRAY){
nxtVals = colorValsDA = nxtVals + (nxtn*nverts); nxtVals = colorValsDA = nxtVals + (nxtn*sp->nverts);
for (cnt=0; cnt<nverts*4; cnt++){ for (cnt=0; cnt<sp->nverts*4; cnt+=4){
colorValsUC[plc + cnt] = CLIP_COLOR_VALUE(colorValsDA[cnt]); colorValsUC[plc + cnt] = CLIP_COLOR_VALUE(colorValsDA[cnt]);
colorValsUC[plc + cnt + 1] = CLIP_COLOR_VALUE(colorValsDA[cnt+1])
;
colorValsUC[plc + cnt + 2] = CLIP_COLOR_VALUE(colorValsDA[cnt+2])
;
colorValsUC[plc + cnt + 3] = CLIP_COLOR_VALUE(colorValsDA[cnt+3])
;
} }
nxtn = 1; nxtn = 4;
} else { } else {
uchar col[4] = { CLIP_COLOR_VALUE(cgo->color[0]), CLIP_COLOR_VALUE( cgo->color[1]), CLIP_COLOR_VALUE(cgo->color[2]), CLIP_COLOR_VALUE(cgo->alpha) }; uchar col[4] = { CLIP_COLOR_VALUE(cgo->color[0]), CLIP_COLOR_VALUE( cgo->color[1]), CLIP_COLOR_VALUE(cgo->color[2]), CLIP_COLOR_VALUE(cgo->alpha) };
for (cnt=0; cnt<nverts*4; cnt++){ for (cnt=0; cnt<sp->nverts*4; cnt++){
colorValsUC[plc + cnt] = col[cnt%4]; colorValsUC[plc + cnt] = col[cnt%4];
} }
} }
} else { } else {
if (arrays & CGO_COLOR_ARRAY){ if (sp->arraybits & CGO_COLOR_ARRAY){
nxtVals = colorValsDA = nxtVals + (nxtn*nverts); nxtVals = colorValsDA = nxtVals + (nxtn*sp->nverts);
for (cnt=0; cnt<nverts*4; cnt++){ for (cnt=0; cnt<sp->nverts*4; cnt+=4){
colorVals[plc + cnt] = colorValsDA[cnt]; colorVals[plc + cnt] = colorValsDA[cnt];
colorVals[plc + cnt + 1] = colorValsDA[cnt+1];
colorVals[plc + cnt + 2] = colorValsDA[cnt+2];
colorVals[plc + cnt + 3] = colorValsDA[cnt+3];
} }
nxtn = 4; nxtn = 4;
} else { } else {
float col[4] = { cgo->color[0], cgo->color[1], cgo->color[2], cgo-> alpha }; float col[4] = { cgo->color[0], cgo->color[1], cgo->color[2], cgo-> alpha };
for (cnt=0; cnt<nverts*4; cnt++){ for (cnt=0; cnt<sp->nverts*4; cnt++){
colorVals[plc + cnt] = col[cnt%4]; colorVals[plc + cnt] = col[cnt%4];
} }
} }
} }
if (arrays & CGO_PICK_COLOR_ARRAY){ if (sp->arraybits & CGO_PICK_COLOR_ARRAY){
nxtVals = nxtVals + (nxtn*nverts); nxtVals = nxtVals + (nxtn*sp->nverts);
pickColorValsDA = nxtVals + nverts; pickColorValsDA = nxtVals + sp->nverts;
pickColorValsTMP = pickColorVals + (vpl * 2); pickColorValsTMP = pickColorVals + (vpl * 2);
for (cnt=0; cnt<nverts; cnt++){ for (cnt=0; cnt<sp->nverts; cnt++){
CGO_put_int(pickColorValsTMP++, CGO_get_int(pickColorValsDA++)); CGO_put_int(pickColorValsTMP++, CGO_get_int(pickColorValsDA++));
CGO_put_int(pickColorValsTMP++, CGO_get_int(pickColorValsDA++)); CGO_put_int(pickColorValsTMP++, CGO_get_int(pickColorValsDA++));
} }
nxtn = 3; nxtn = 3;
} else { } else {
pickColorValsTMP = pickColorVals + (vpl * 2); pickColorValsTMP = pickColorVals + (vpl * 2);
for (cnt=0; cnt<nverts; cnt++){ for (cnt=0; cnt<sp->nverts; cnt++){
CGO_put_int(pickColorValsTMP++, cgo->current_pick_color_index); CGO_put_uint(pickColorValsTMP++, cgo->current_pick_color_index);
CGO_put_int(pickColorValsTMP++, cgo->current_pick_color_bond); CGO_put_int(pickColorValsTMP++, cgo->current_pick_color_bond);
} }
} }
if (arrays & CGO_ACCESSIBILITY_ARRAY){ if (sp->arraybits & CGO_ACCESSIBILITY_ARRAY){
if (!ambient_occlusion){ if (!ambient_occlusion){
for (cnt=0; cnt<vpl; cnt++){ for (cnt=0; cnt<vpl; cnt++){
accessibilityVals[cnt] = 1.f; accessibilityVals[cnt] = 1.f;
} }
} }
ambient_occlusion = 1; ambient_occlusion = 1;
nxtVals = nxtVals + (nxtn*nverts); nxtVals = nxtVals + (nxtn*sp->nverts);
accessibilityValsDA = nxtVals; accessibilityValsDA = nxtVals;
accessibilityValsTMP = accessibilityVals + vpl; accessibilityValsTMP = accessibilityVals + vpl;
for (cnt=0; cnt<nverts; cnt++){ for (cnt=0; cnt<sp->nverts; cnt++){
accessibilityValsTMP[cnt] = accessibilityValsDA[cnt]; accessibilityValsTMP[cnt] = accessibilityValsDA[cnt];
} }
} else { } else {
if (ambient_occlusion){ if (ambient_occlusion){
accessibilityValsTMP = accessibilityVals + vpl; accessibilityValsTMP = accessibilityVals + vpl;
for (cnt=0; cnt<nverts; cnt++){ for (cnt=0; cnt<sp->nverts; cnt++){
accessibilityValsTMP[cnt] = 1.f; accessibilityValsTMP[cnt] = 1.f;
} }
} }
} }
switch (sp->mode){
/* if (idxpl + nverts > num_total_indexes){
printf("num_total_indexes=%d mode=%d nverts=%d idxpl=%d\n", num_total
_indexes, mode, nverts, idxpl);
}*/
switch (mode){
case GL_TRIANGLES: case GL_TRIANGLES:
for (cnt = 0; cnt < nverts; cnt++){ for (cnt = 0; cnt < sp->nverts; cnt++){
vertexIndexes[idxpl++] = vpl + cnt; vertexIndices[idxpl++] = vpl + cnt;
} }
break; break;
case GL_TRIANGLE_STRIP: case GL_TRIANGLE_STRIP:
for (cnt = 2; cnt < nverts; cnt++){ {
vertexIndexes[idxpl++] = vpl + cnt - 2; short flip = 0;
vertexIndexes[idxpl++] = vpl + cnt - 1; for (cnt = 2; cnt < sp->nverts; cnt++){
vertexIndexes[idxpl++] = vpl + cnt; vertexIndices[idxpl++] = vpl + cnt - (flip ? 0 : 2);
vertexIndices[idxpl++] = vpl + cnt - 1;
vertexIndices[idxpl++] = vpl + cnt - (flip ? 2 : 0);
flip = !flip;
}
} }
break; break;
case GL_TRIANGLE_FAN: case GL_TRIANGLE_FAN:
for (cnt = 2; cnt < nverts; cnt++){ for (cnt = 2; cnt < sp->nverts; cnt++){
vertexIndexes[idxpl++] = vpl; vertexIndices[idxpl++] = vpl;
vertexIndexes[idxpl++] = vpl + cnt - 1; vertexIndices[idxpl++] = vpl + cnt - 1;
vertexIndexes[idxpl++] = vpl + cnt; vertexIndices[idxpl++] = vpl + cnt;
} }
break; break;
} }
pl += 3 * sp->nverts;
pl += 3 * nverts; plc += 4 * sp->nverts;
plc += 4 * nverts; vpl += sp->nverts;
vpl += nverts;
pc += nvals + 4;
save_pc += nvals + 4 ;
} else {
{
int nvals = narrays*nverts ;
pc += nvals + 4;
save_pc += nvals + 4 ;
}
} }
} }
break; break;
default: default:
break; break;
} }
pc = save_pc; pc = save_pc;
pc += CGO_sz[op]; pc += CGO_sz[op];
ok &= !I->G->Interrupt; ok &= !I->G->Interrupt;
} }
if (ok) { if (sumarray){
uint bufs[5] = {0, 0, 0, 0, 0 }, allbufs[5] = { 0, 0, 0, 0, 0 }; for (idxpl = 0; idxpl < num_total_indexes; idxpl+=3){
short bufpl = 0; add3f(&vertexVals[3 * vertexIndices[idxpl]], &vertexVals[3 * vertexIndice
GLenum err ; s[idxpl+1]], sumarray);
// printf("CGOOptimizeToVBOIndexed: End: num_total_vertices=%d num_to add3f(&vertexVals[3 * vertexIndices[idxpl+2]], sumarray, sumarray);
tal_indexes=%d verts_skipped=%d\n", num_total_vertices, num_total_indexes, verts sumarray += 3;
_skipped);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBOIndexed() BEFORE glGenBuffers re
turns err=%d\n");
if (ok){
glGenBuffers(5, bufs);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBOIndexed() glGenBuffers returns
err=%d\n");
}
if (ok){
glBindBuffer(GL_ARRAY_BUFFER, bufs[bufpl]);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBOIndexed() glBindBuffer returns
err=%d\n");
}
if (ok && !glIsBuffer(bufs[bufpl])){
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeToVBOIndexed() gl
GenBuffers created bad buffer bufpl=%d bufs[bufpl]=%d\n", bufpl, bufs[bufpl] END
FB(I->G);
ok = false;
} else if (ok) {
allbufs[0] = bufs[bufpl++];
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*num_total_vertices*3, vertexV
als, GL_STATIC_DRAW);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBOIndexed() glBufferData returns
err=%d\n");
}
if (ok){
glBindBuffer(GL_ARRAY_BUFFER, bufs[bufpl]);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBOIndexed() glBindBuffer returns
err=%d\n");
}
if (ok && !glIsBuffer(bufs[bufpl])){
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeToVBOIndexed() gl
GenBuffers created bad buffer bufpl=%d bufs[bufpl]=%d\n", bufpl, bufs[bufpl] END
FB(I->G);
ok = false;
} else if (ok){
short sz = 3;
allbufs[1] = bufs[bufpl++];
if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_normal)){
sz = 1;
}
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*num_total_vertices*sz, normal
Vals, GL_STATIC_DRAW);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBOIndexed() glBufferData returns
err=%d\n");
}
if (ok){
glBindBuffer(GL_ARRAY_BUFFER, bufs[bufpl]);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBOIndexed() glBindBuffer returns
err=%d\n");
}
if (ok && !glIsBuffer(bufs[bufpl])){
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeToVBOIndexed() gl
GenBuffers created bad buffer bufpl=%d bufs[bufpl]=%d\n", bufpl, bufs[bufpl] END
FB(I->G);
ok = false;
} else if (ok) {
short sz = 4;
allbufs[2] = bufs[bufpl++];
if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_color)){
sz = 1;
}
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*num_total_vertices*sz, colorV
als, GL_STATIC_DRAW);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBOIndexed() glBufferData returns
err=%d\n");
} }
if (ok){ }
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufs[bufpl]); if (ok) {
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBOIndexed() glBindBuffer returns short nsz = VERTEX_NORMAL_SIZE * 4;
err=%d\n"); GLenum ntp = GL_FLOAT;
if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_normal)){
nsz = VERTEX_NORMAL_SIZE;
ntp = GL_BYTE;
} }
if (ok && !glIsBuffer(bufs[bufpl])){
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeToVBOIndexed() gl short csz = 4;
GenBuffers created bad buffer bufpl=%d bufs[bufpl]=%d\n", bufpl, bufs[bufpl] END GLenum ctp = GL_FLOAT;
FB(I->G); if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_color)){
ok = false; csz = 1;
} else if (ok){ ctp = GL_UNSIGNED_BYTE;
allbufs[3] = bufs[bufpl++];
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GL_C_INT_TYPE)*num_total_ind
exes, vertexIndexes, GL_STATIC_DRAW);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBOIndexed() glBufferData returns
err=%d\n");
}
if (ok && ambient_occlusion){
glBindBuffer(GL_ARRAY_BUFFER, bufs[bufpl]);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBOIndexed() glBindBuffer returns
err=%d\n");
if (ok && !glIsBuffer(bufs[bufpl])){
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeToVBOIndexed()
glGenBuffers created bad buffer bufpl=%d bufs[bufpl]=%d\n", bufpl, bufs[bufpl] E
NDFB(I->G);
ok = false;
} else if (ok){
allbufs[4] = bufs[bufpl++];
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*num_total_indexes, accessib
ilityVals, GL_STATIC_DRAW);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBOIndexed() glBufferData return
s err=%d\n");
}
} }
VertexBuffer * vbo = I->G->ShaderMgr->newGPUBuffer<VertexBuffer>();
ok &= vbo->bufferData({
BufferDesc( "a_Vertex", GL_FLOAT, 3, sizeof(float) * num_total_
vertices * 3, vertexVals, GL_FALSE ),
BufferDesc( "a_Normal", ntp, VERTEX_NORMAL_SIZE, num_total
_vertices * nsz, normalVals, GL_FALSE ),
BufferDesc( "a_Color", ctp, 4, sizeof(float) * num_total_
vertices * csz, colorVals, GL_TRUE ),
BufferDesc( "a_Accessibility", GL_FLOAT, 1, sizeof(float) * num_total_
vertices, accessibilityVals, GL_FALSE )
});
IndexBuffer * ibo = I->G->ShaderMgr->newGPUBuffer<IndexBuffer>();
ok &= ibo->bufferData({
BufferDesc( GL_UNSIGNED_INT, sizeof(GL_C_INT_TYPE) * num_total_indexes
, vertexIndices )
});
size_t vboid = vbo->get_hash_id();
size_t iboid = ibo->get_hash_id();
VertexBuffer * pickvbo = I->G->ShaderMgr->newGPUBuffer<VertexBuffer>(Verte
xBuffer::SEQUENTIAL, GL_DYNAMIC_DRAW);
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 )
});
size_t pickvboid = pickvbo->get_hash_id();
if (ok) { if (ok) {
GLfloat *newPickColorVals ; float *newPickColorVals ;
int arrays = CGO_VERTEX_ARRAY | CGO_NORMAL_ARRAY | CGO_COLOR_ARRAY | CGO_ PICK_COLOR_ARRAY; int arrays = CGO_VERTEX_ARRAY | CGO_NORMAL_ARRAY | CGO_COLOR_ARRAY | CGO_ PICK_COLOR_ARRAY;
if (ambient_occlusion){ if (ambient_occlusion){
arrays |= CGO_ACCESSIBILITY_ARRAY; arrays |= CGO_ACCESSIBILITY_ARRAY;
} }
if (addshaders) if (addshaders)
CGOEnable(cgo, GL_DEFAULT_SHADER); CGOEnable(cgo, GL_DEFAULT_SHADER);
newPickColorVals = CGODrawBuffersIndexed(cgo, GL_TRIANGLES, arrays, num_t newPickColorVals = cgo->add<cgo::draw::buffers_indexed>(GL_TRIANGLES, arr
otal_indexes, num_total_vertices, allbufs); ays, num_total_indexes, num_total_vertices, vboid, iboid, n_data, pickvboid);
if (embedTransparencyInfo){
int n_tri = num_total_indexes/3;
float *sumarray;
float *sum = sumarray = newPickColorVals + num_total_vertices*3;
float *z_value = sum + (num_total_indexes*3);
int *ix = (int *)z_value + n_tri;
int *sort_mem = ix + n_tri;
GL_C_INT_TYPE *vertexIndicesOriginalTI = (GL_C_INT_TYPE *)(sort_mem + n
_tri + 256);
for (idxpl = 0; idxpl < num_total_indexes; idxpl+=3){
add3f(&vertexVals[3 * vertexIndices[idxpl]], &vertexVals[3 * vertexIn
dices[idxpl+1]], sumarray);
add3f(&vertexVals[3 * vertexIndices[idxpl+2]], sumarray, sumarray);
sumarray += 3;
}
memcpy(vertexIndicesOriginalTI, vertexIndices, sizeof(GL_C_INT_TYPE) *
num_total_indexes);
}
if (addshaders && ok) if (addshaders && ok)
ok &= CGODisable(cgo, GL_DEFAULT_SHADER); ok &= CGODisable(cgo, GL_DEFAULT_SHADER);
CHECKOK(ok, newPickColorVals); CHECKOK(ok, newPickColorVals);
if (!newPickColorVals){ if (!newPickColorVals){
CShaderMgr_AddVBOsToFree(I->G->ShaderMgr, bufs, 5); I->G->ShaderMgr->freeGPUBuffer(pickvboid);
I->G->ShaderMgr->freeGPUBuffer(vboid);
I->G->ShaderMgr->freeGPUBuffer(iboid);
} }
if (ok) if (ok)
memcpy(newPickColorVals + num_total_vertices, pickColorVals, num_total_ vertices * 2 * sizeof(float)); memcpy(newPickColorVals + num_total_vertices, pickColorVals, num_total_ vertices * 2 * sizeof(float));
has_draw_buffer = true; has_draw_buffer = true;
} else { } else {
CShaderMgr_AddVBOsToFree(I->G->ShaderMgr, bufs, 5); I->G->ShaderMgr->freeGPUBuffer(pickvboid);
I->G->ShaderMgr->freeGPUBuffer(vboid);
I->G->ShaderMgr->freeGPUBuffer(iboid);
} }
} }
FreeP(vertexIndexes); if (vertexIndicesAllocated)
FreeP(vertexIndices);
FreeP(vertexVals); FreeP(vertexVals);
} }
if (ok && num_total_vertices_lines>0){ if (ok && num_total_vertices_lines>0){
float *vertexVals = 0, *colorVals = 0, *normalVals; float *vertexVals = 0, *colorVals = 0, *normalVals = NULL, *nxtVals;
float *pickColorVals; float *pickColorVals;
GL_C_INT_TYPE *vertexIndexes; GL_C_INT_TYPE *vertexIndexes;
uchar *colorValsUC = 0; uchar *colorValsUC = 0;
uchar *normalValsC = 0; uchar *normalValsC = 0;
int pl = 0, plc = 0, idxpl = 0, vpl = 0, tot, sz; int pl = 0, plc = 0, idxpl = 0, vpl = 0, tot, sz;
bool hasNormals = 0;
pc = I->op; pc = I->op;
hasNormals = !CGOHasAnyLineVerticesWithoutNormals(I);
vertexIndexes = Alloc(GL_C_INT_TYPE, num_total_indexes_lines); vertexIndexes = Alloc(GL_C_INT_TYPE, num_total_indexes_lines);
if (!vertexIndexes){ if (!vertexIndexes){
PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeToVBOIndexed() vertexI ndexes could not be allocated\n" ENDFB(I->G); PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeToVBOIndexed() vertexI ndexes could not be allocated\n" ENDFB(I->G);
CGOFree(cgo); CGOFree(cgo);
return (NULL); return (NULL);
} }
tot = num_total_vertices_lines * (3 * 5) ; tot = num_total_vertices_lines * (3 * 5) ;
// tot = num_total_vertices * (3 * 3 + 2) ; // tot = num_total_vertices * (3 * 3 + 2) ;
/* NOTE/TODO: Not sure why 3*5 needs to be used, but 3*3+2, which is the /* NOTE/TODO: Not sure why 3*5 needs to be used, but 3*3+2, which is the
correct length, crashes in glBufferData */ correct length, crashes in glBufferData */
vertexVals = Alloc(float, tot); vertexVals = Alloc(float, tot);
if (!vertexVals){ if (!vertexVals){
PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeToVBOIndexed() vertexV als could not be allocated\n" ENDFB(I->G); PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeToVBOIndexed() vertexV als could not be allocated\n" ENDFB(I->G);
CGOFree(cgo); CGOFree(cgo);
return (NULL); return (NULL);
} }
normalVals = vertexVals + 3 * num_total_vertices_lines; nxtVals = vertexVals + 3 * num_total_vertices_lines;
sz = 3; sz = 3;
if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_normal)){ if (hasNormals){
normalValsC = (uchar*) normalVals; normalVals = nxtVals;
sz = 1; if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_normal)){
normalValsC = (uchar*) normalVals;
sz = 1;
}
} }
colorVals = normalVals + sz * num_total_vertices_lines; colorVals = nxtVals + sz * num_total_vertices_lines;
if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_color)){ if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_color)){
colorValsUC = (uchar*) colorVals; colorValsUC = (uchar*) colorVals;
sz = 1; sz = 1;
} else { } else {
sz = 4; sz = 4;
} }
pickColorVals = (colorVals + sz * num_total_vertices_lines); pickColorVals = (colorVals + sz * num_total_vertices_lines);
while(ok && (op = (CGO_MASK & CGO_read_int(pc)))) { while(ok && (op = (CGO_MASK & CGO_read_int(pc)))) {
save_pc = pc; save_pc = pc;
err = 0;
switch (op) { switch (op) {
case CGO_NORMAL: case CGO_NORMAL:
cgo->normal[0] = *pc; cgo->normal[1] = *(pc + 1); cgo->normal[2] = *(pc + 2); cgo->normal[0] = *pc; cgo->normal[1] = *(pc + 1); cgo->normal[2] = *(pc + 2);
break; break;
case CGO_COLOR: case CGO_COLOR:
cgo->color[0] = *pc; cgo->color[1] = *(pc + 1); cgo->color[2] = *(pc + 2) ; cgo->color[0] = *pc; cgo->color[1] = *(pc + 1); cgo->color[2] = *(pc + 2) ;
break; break;
case CGO_ACCESSIBILITY: case CGO_ACCESSIBILITY:
cgo->current_accessibility = *pc; cgo->current_accessibility = *pc;
break; break;
case CGO_ALPHA: case CGO_ALPHA:
cgo->alpha = *pc; cgo->alpha = *pc;
break; break;
case CGO_PICK_COLOR: case CGO_PICK_COLOR:
cgo->current_pick_color_index = CGO_get_int(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);
break; break;
case CGO_DRAW_ARRAYS: case CGO_DRAW_ARRAYS:
{ {
int mode = CGO_get_int(pc), arrays = CGO_get_int(pc + 1), narrays = CGO_g et_int(pc + 2), nverts = CGO_get_int(pc + 3); cgo::draw::arrays * sp = reinterpret_cast<decltype(sp)>(pc);
short shouldCompress = false; short shouldCompress = false;
switch(mode){ switch(sp->mode){
case GL_LINE_LOOP: case GL_LINE_LOOP:
case GL_LINE_STRIP: case GL_LINE_STRIP:
case GL_LINES: case GL_LINES:
shouldCompress = true; shouldCompress = true;
default: default:
break; break;
} }
if (shouldCompress){ if (shouldCompress){
int nvals = narrays*nverts, cnt, nxtn = 3; int cnt, nxtn = 3;
float *vertexValsDA = 0, *nxtVals = 0, *colorValsDA = 0, *normalValsDA; float *vertexValsDA = 0, *nxtVals2 = 0, *colorValsDA = 0, *normalValsDA
float *pickColorValsDA, *pickColorValsTMP; = 0;
float *pickColorValsDA = 0, *pickColorValsTMP;
nxtVals = vertexValsDA = pc + 4; nxtVals2 = vertexValsDA = sp->floatdata;
for (cnt=0; cnt<nverts*3; cnt+=3){ for (cnt=0; cnt<sp->nverts*3; cnt+=3){
set_min_max(min, max, &vertexValsDA[cnt]); set_min_max(min, max, &vertexValsDA[cnt]);
} }
for (cnt=0; cnt<nverts*3; cnt++){ for (cnt=0; cnt<sp->nverts*3; cnt++){
vertexVals[pl + cnt] = vertexValsDA[cnt]; vertexVals[pl + cnt] = vertexValsDA[cnt];
} }
if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_normal)){ if (normalVals){
if (arrays & CGO_NORMAL_ARRAY){ if (sp->arraybits & CGO_NORMAL_ARRAY){
nxtVals = normalValsDA = vertexValsDA + (nxtn*nverts); if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_normal)){
for (cnt=0; cnt<nverts*3; cnt++){ nxtVals2 = normalValsDA = nxtVals2 + (nxtn*sp->nverts);
normalValsC[VAR_FOR_NORMAL + cnt VAR_FOR_NORMAL_CNT_PLUS] = CLIP_ for (cnt=0; cnt<sp->nverts*3; cnt++){
NORMAL_VALUE(normalValsDA[cnt]); normalValsC[VAR_FOR_NORMAL + cnt VAR_FOR_NORMAL_CNT_PLUS] = CLI
} P_NORMAL_VALUE(normalValsDA[cnt]);
} else { }
uchar norm[3] = { CLIP_NORMAL_VALUE(cgo->normal[0]), CLIP_NORMAL_VA } else {
LUE(cgo->normal[1]), CLIP_NORMAL_VALUE(cgo->normal[2]) }; nxtVals2 = normalValsDA = nxtVals2 + (nxtn*sp->nverts);
for (cnt=0; cnt<nverts*3; cnt++){ for (cnt=0; cnt<sp->nverts*3; cnt++){
normalValsC[VAR_FOR_NORMAL + cnt VAR_FOR_NORMAL_CNT_PLUS] = norm[ normalVals[VAR_FOR_NORMAL + cnt] = normalValsDA[cnt];
cnt%3]; }
}
}
} else {
if (arrays & CGO_NORMAL_ARRAY){
nxtVals = normalValsDA = vertexValsDA + (nxtn*nverts);
for (cnt=0; cnt<nverts*3; cnt++){
normalVals[VAR_FOR_NORMAL + cnt] = normalValsDA[cnt];
}
} else {
for (cnt=0; cnt<nverts*3; cnt++){
normalVals[VAR_FOR_NORMAL + cnt] = I->normal[cnt%3];
} }
} }
} }
if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_color)){ if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_color)){
if (arrays & CGO_COLOR_ARRAY){ if (sp->arraybits & CGO_COLOR_ARRAY){
nxtVals = colorValsDA = nxtVals + (nxtn*nverts); nxtVals2 = colorValsDA = nxtVals2 + (nxtn*sp->nverts);
for (cnt=0; cnt<nverts*4; cnt++){ for (cnt=0; cnt<sp->nverts*4; cnt++){
colorValsUC[plc + cnt] = CLIP_COLOR_VALUE(colorValsDA[cnt]); colorValsUC[plc + cnt] = CLIP_COLOR_VALUE(colorValsDA[cnt]);
} }
nxtn = 4; nxtn = 4;
} else { } else {
uchar col[4] = { CLIP_COLOR_VALUE(cgo->color[0]), CLIP_COLOR_VALUE( cgo->color[1]), CLIP_COLOR_VALUE(cgo->color[2]), CLIP_COLOR_VALUE(cgo->alpha) }; uchar col[4] = { CLIP_COLOR_VALUE(cgo->color[0]), CLIP_COLOR_VALUE( cgo->color[1]), CLIP_COLOR_VALUE(cgo->color[2]), CLIP_COLOR_VALUE(cgo->alpha) };
for (cnt=0; cnt<nverts*4; cnt++){ for (cnt=0; cnt<sp->nverts*4; cnt++){
colorValsUC[plc + cnt] = col[cnt%4]; colorValsUC[plc + cnt] = col[cnt%4];
} }
} }
} else { } else {
if (arrays & CGO_COLOR_ARRAY){ if (sp->arraybits & CGO_COLOR_ARRAY){
nxtVals = colorValsDA = nxtVals + (nxtn*nverts); nxtVals2 = colorValsDA = nxtVals2 + (nxtn*sp->nverts);
for (cnt=0; cnt<nverts*4; cnt++){ for (cnt=0; cnt<sp->nverts*4; cnt++){
colorVals[plc + cnt] = colorValsDA[cnt]; colorVals[plc + cnt] = colorValsDA[cnt];
} }
nxtn = 4; nxtn = 4;
} else { } else {
float col[4] = { cgo->color[0], cgo->color[1], cgo->color[2], cgo-> alpha }; float col[4] = { cgo->color[0], cgo->color[1], cgo->color[2], cgo-> alpha };
for (cnt=0; cnt<nverts*4; cnt++){ for (cnt=0; cnt<sp->nverts*4; cnt++){
colorVals[plc + cnt] = col[cnt%4]; colorVals[plc + cnt] = col[cnt%4];
} }
} }
} }
if (arrays & CGO_PICK_COLOR_ARRAY){ if (sp->arraybits & CGO_PICK_COLOR_ARRAY){
nxtVals = nxtVals + (nxtn*nverts); nxtVals2 = nxtVals2 + (nxtn*sp->nverts);
pickColorValsDA = nxtVals + nverts; pickColorValsDA = nxtVals2 + sp->nverts;
pickColorValsTMP = pickColorVals + (vpl * 2); pickColorValsTMP = pickColorVals + (vpl * 2);
for (cnt=0; cnt<nverts; cnt++){ for (cnt=0; cnt<sp->nverts; cnt++){
CGO_put_int(pickColorValsTMP++, CGO_get_int(pickColorValsDA++)); CGO_put_int(pickColorValsTMP++, CGO_get_int(pickColorValsDA++));
CGO_put_int(pickColorValsTMP++, CGO_get_int(pickColorValsDA++)); CGO_put_int(pickColorValsTMP++, CGO_get_int(pickColorValsDA++));
} }
nxtn = 3; nxtn = 3;
} else { } else {
pickColorValsTMP = pickColorVals + (vpl * 2); pickColorValsTMP = pickColorVals + (vpl * 2);
for (cnt=0; cnt<nverts; cnt++){ for (cnt=0; cnt<sp->nverts; cnt++){
CGO_put_int(pickColorValsTMP++, cgo->current_pick_color_index); CGO_put_uint(pickColorValsTMP++, cgo->current_pick_color_index);
CGO_put_int(pickColorValsTMP++, cgo->current_pick_color_bond); CGO_put_int(pickColorValsTMP++, cgo->current_pick_color_bond);
} }
} }
if (idxpl + nverts > num_total_indexes_lines){ if (idxpl + sp->nverts > num_total_indexes_lines){
PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeToVBOIndexed() nu PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeToVBOIndexed() nu
m_total_indexes_lines=%d mode=%d nverts=%d idxpl=%d\n", num_total_indexes_lines, m_total_indexes_lines=%d mode=%d nverts=%d idxpl=%d\n", num_total_indexes_lines,
mode, nverts, idxpl ENDFB(I->G); sp->mode, sp->nverts, idxpl ENDFB(I->G);
} }
switch (mode){ switch (sp->mode){
case GL_LINES: case GL_LINES:
for (cnt = 0; cnt < nverts; cnt++){ for (cnt = 0; cnt < sp->nverts; cnt++){
vertexIndexes[idxpl++] = vpl + cnt; vertexIndexes[idxpl++] = vpl + cnt;
} }
break; break;
case GL_LINE_STRIP: case GL_LINE_STRIP:
for (cnt = 1; cnt < nverts; cnt++){ for (cnt = 1; cnt < sp->nverts; cnt++){
vertexIndexes[idxpl++] = vpl + cnt - 1; vertexIndexes[idxpl++] = vpl + cnt - 1;
vertexIndexes[idxpl++] = vpl + cnt; vertexIndexes[idxpl++] = vpl + cnt;
} }
break; break;
case GL_LINE_LOOP: case GL_LINE_LOOP:
for (cnt = 1; cnt < nverts; cnt++){ for (cnt = 1; cnt < sp->nverts; cnt++){
vertexIndexes[idxpl++] = vpl + cnt - 1; vertexIndexes[idxpl++] = vpl + cnt - 1;
vertexIndexes[idxpl++] = vpl + cnt; vertexIndexes[idxpl++] = vpl + cnt;
} }
vertexIndexes[idxpl++] = vpl; vertexIndexes[idxpl++] = vpl;
vertexIndexes[idxpl++] = vpl + nverts - 1; vertexIndexes[idxpl++] = vpl + sp->nverts - 1;
break; break;
} }
pl += 3 * nverts; pl += 3 * sp->nverts;
plc += 4 * nverts; plc += 4 * sp->nverts;
vpl += nverts; vpl += sp->nverts;
pc += nvals + 4;
save_pc += nvals + 4 ;
} else {
{
int nvals = narrays*nverts ;
pc += nvals + 4;
save_pc += nvals + 4 ;
}
} }
} }
break; break;
case CGO_LINEWIDTH_SPECIAL: case CGO_SPECIAL:
CGOLinewidthSpecial(cgo, CGO_get_int(pc)); CGOSpecial(cgo, CGO_get_int(pc));
default: default:
break; break;
} }
pc = save_pc; pc = save_pc;
pc += CGO_sz[op]; pc += CGO_sz[op];
ok &= !I->G->Interrupt; ok &= !I->G->Interrupt;
} }
if (ok) { if (ok) {
uint bufs[4] = {0, 0, 0, 0 }, allbufs[5] = { 0, 0, 0, 0, 0 }; short nsz = VERTEX_NORMAL_SIZE * 4;
short bufpl = 0; GLenum ntp = GL_FLOAT;
GLenum err ; if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_normal)){
// printf("CGOOptimizeToVBOIndexed: End: num_total_vertices=%d num_to nsz = VERTEX_NORMAL_SIZE;
tal_indexes=%d verts_skipped=%d\n", num_total_vertices, num_total_indexes, verts ntp = GL_BYTE;
_skipped);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBOIndexed() BEFORE glGenBuffers re
turns err=%d\n");
if (ok){
glGenBuffers(4, bufs);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBOIndexed() glGenBuffers returns
err=%d\n");
}
if (ok){
glBindBuffer(GL_ARRAY_BUFFER, bufs[bufpl]);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBOIndexed() glBindBuffer returns
err=%d\n");
}
if (ok && !glIsBuffer(bufs[bufpl])){
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeToVBOIndexed() gl
GenBuffers created bad buffer bufpl=%d bufs[bufpl]=%d\n", bufpl, bufs[bufpl] END
FB(I->G);
ok = false;
} else if (ok){
allbufs[0] = bufs[bufpl++];
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*num_total_vertices_lines*3, v
ertexVals, GL_STATIC_DRAW);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBOIndexed() glBufferData returns
err=%d\n");
}
if (ok){
glBindBuffer(GL_ARRAY_BUFFER, bufs[bufpl]);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBOIndexed() glBindBuffer returns
err=%d\n");
}
if (ok && !glIsBuffer(bufs[bufpl])){
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeToVBOIndexed() gl
GenBuffers created bad buffer bufpl=%d bufs[bufpl]=%d\n", bufpl, bufs[bufpl] END
FB(I->G);
ok = false;
} else if (ok){
short sz = 3;
allbufs[1] = bufs[bufpl++];
if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_normal)){
sz = 1;
}
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*num_total_vertices_lines*sz,
normalVals, GL_STATIC_DRAW);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBOIndexed() glBufferData returns
err=%d\n");
}
if (ok){
glBindBuffer(GL_ARRAY_BUFFER, bufs[bufpl]);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBOIndexed() glBindBuffer returns
err=%d\n");
}
if (ok && !glIsBuffer(bufs[bufpl])){
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeToVBOIndexed() gl
GenBuffers created bad buffer bufpl=%d bufs[bufpl]=%d\n", bufpl, bufs[bufpl] END
FB(I->G);
ok = false;
} else if (ok){
short sz = 4;
allbufs[2] = bufs[bufpl++];
if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_color)){
sz = 1;
}
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*num_total_vertices_lines*sz,
colorVals, GL_STATIC_DRAW);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBOIndexed() glBufferData returns
err=%d\n");
}
if (ok){
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufs[bufpl]);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBOIndexed() glBindBuffer returns
err=%d\n");
} }
if (ok && !glIsBuffer(bufs[bufpl])){
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeToVBOIndexed() gl short csz = 4;
GenBuffers created bad buffer bufpl=%d bufs[bufpl]=%d\n", bufpl, bufs[bufpl] END GLenum ctp = GL_FLOAT;
FB(I->G); if (SettingGetGlobal_i(I->G, cSetting_cgo_shader_ub_color)){
ok = false; csz = 1;
} else { ctp = GL_UNSIGNED_BYTE;
allbufs[3] = bufs[bufpl++];
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GL_C_INT_TYPE)*num_total_ind
exes_lines, vertexIndexes, GL_STATIC_DRAW);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeToVBOIndexed() glBufferData returns
err=%d\n");
} }
VertexBuffer * vbo = I->G->ShaderMgr->newGPUBuffer<VertexBuffer>();
ok &= vbo->bufferData({
BufferDesc( "a_Vertex", GL_FLOAT, 3, sizeof(float) * num_total_
vertices_lines * 3, vertexVals, GL_FALSE ),
BufferDesc( "a_Normal", ntp, VERTEX_NORMAL_SIZE, num_total
_vertices_lines * nsz, normalVals, GL_FALSE ),
BufferDesc( "a_Color", ctp, 4, sizeof(float) * num_total_
vertices_lines * csz, colorVals, GL_TRUE )
});
IndexBuffer * ibo = I->G->ShaderMgr->newGPUBuffer<IndexBuffer>();
ok &= ibo->bufferData({
BufferDesc( GL_UNSIGNED_INT, sizeof(GL_C_INT_TYPE) * num_total_indexes
_lines, vertexIndexes )
});
size_t vboid = vbo->get_hash_id();
size_t iboid = ibo->get_hash_id();
VertexBuffer * pickvbo = I->G->ShaderMgr->newGPUBuffer<VertexBuffer>(Verte
xBuffer::SEQUENTIAL, GL_DYNAMIC_DRAW);
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 )
});
size_t pickvboid = pickvbo->get_hash_id();
if (ok){ if (ok){
GLfloat *newPickColorVals ; float *newPickColorVals ;
if (addshaders){ if (addshaders){
CGOEnable(cgo, GL_DEFAULT_SHADER); CGOEnable(cgo, GL_DEFAULT_SHADER);
CGODisable(cgo, GL_SHADER_LIGHTING); CGODisable(cgo, GL_SHADER_LIGHTING);
} }
newPickColorVals = CGODrawBuffersIndexed(cgo, GL_LINES, CGO_VERTEX_ARRAY newPickColorVals = cgo->add<cgo::draw::buffers_indexed>(GL_LINES,
| CGO_NORMAL_ARRAY | CGO_COLOR_ARRAY | CGO_PICK_COLOR_ARRAY, num_total_indexes_l CGO_VERTEX_ARRAY
ines, num_total_vertices_lines, allbufs); | CGO_NORMAL_ARRAY |
CGO_COLOR_ARRAY
| CGO_PICK_COLOR_ARRAY,
num_total_indexe
s_lines,
num_total_vertic
es_lines, vboid, iboid, 0, pickvboid);
CHECKOK(ok, newPickColorVals); CHECKOK(ok, newPickColorVals);
if (addshaders && ok) if (addshaders && ok)
ok &= CGODisable(cgo, GL_DEFAULT_SHADER); ok &= CGODisable(cgo, GL_DEFAULT_SHADER);
if (!newPickColorVals) if (!newPickColorVals) {
CShaderMgr_AddVBOsToFree(I->G->ShaderMgr, bufs, 4); I->G->ShaderMgr->freeGPUBuffer(pickvboid);
I->G->ShaderMgr->freeGPUBuffer(vboid);
I->G->ShaderMgr->freeGPUBuffer(iboid);
}
if (ok) if (ok)
memcpy(newPickColorVals + num_total_vertices_lines, pickColorVals, num_ memcpy(newPickColorVals + num_total_vertices_lines,
total_vertices_lines * 2 * sizeof(float)); pickColorVals, num_total_vertices_lines * 2 * sizeof(float));
has_draw_buffer = true; has_draw_buffer = true;
} else { } else {
CShaderMgr_AddVBOsToFree(I->G->ShaderMgr, bufs, 4); I->G->ShaderMgr->freeGPUBuffer(pickvboid);
I->G->ShaderMgr->freeGPUBuffer(vboid);
I->G->ShaderMgr->freeGPUBuffer(iboid);
} }
} }
FreeP(vertexIndexes); FreeP(vertexIndexes);
FreeP(vertexVals); FreeP(vertexVals);
} }
if (ok && (num_total_vertices>0 || num_total_vertices_lines>0)){ if (ok && (num_total_vertices>0 || num_total_vertices_lines>0)){
ok &= CGOBoundingBox(cgo, min, max); ok &= CGOBoundingBox(cgo, min, max);
} }
if (ok) if (ok)
skipping to change at line 4182 skipping to change at line 3826
cgo->has_draw_buffers = true; cgo->has_draw_buffers = true;
} }
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 _ub_normal); cgo->cgo_shader_ub_normal = SettingGetGlobal_i(cgo->G, cSetting_cgo_shader _ub_normal);
} }
} }
if (!ok){ if (!ok){
CGOFree(cgo); CGOFree(cgo);
cgo = NULL;
} }
return (cgo); return (cgo);
} }
CGO *CGOOptimizeGLSLCylindersToVBOIndexedImpl(CGO * I, int est, short no_color, CGO *CGOOptimizeSpheresToVBONonIndexed(const CGO * I, int est, bool addshaders,
CGO *leftOverCGO); CGO *leftOverCGO)
CGO *CGOOptimizeGLSLCylindersToVBOIndexedNoColor(CGO * I, int est){
return (CGOOptimizeGLSLCylindersToVBOIndexedImpl(I, est, true, NULL));
}
CGO *CGOOptimizeGLSLCylindersToVBOIndexedWithLeftOver(CGO * I, int est, CGO *lef
tOverCGO){
return (CGOOptimizeGLSLCylindersToVBOIndexedImpl(I, est, false, leftOverCGO));
}
CGO *CGOOptimizeGLSLCylindersToVBOIndexed(CGO * I, int est){
return (CGOOptimizeGLSLCylindersToVBOIndexedImpl(I, est, false, NULL));
}
int CGOCountNumberCustomCylinders(CGO *I, int *has_2nd_color);
#define NUM_VERTICES_PER_CYLINDER 8
#define NUM_TOTAL_VERTICES_PER_CYLINDER 36
CGO *CGOOptimizeGLSLCylindersToVBOIndexedImpl(CGO * I, int est, short no_color,
CGO *leftOverCGO)
{ {
CGO *cgo = NULL; CGO *cgo = NULL;
float *pc = I->op; float *pc = I->op;
int op; int op;
int sz; int sz;
int box_indices[NUM_TOTAL_VERTICES_PER_CYLINDER] = { // box indices
0, 2, 1, 2, 0, 3, 1, 6, 5, 6, 1, 2, 0, 1, 5, 5, 4, 0,
0, 7, 3, 7, 0, 4, 3, 6, 2, 6, 3, 7, 4, 5, 6, 6, 7, 4 };
int right_idx[8] = { 0, 1, 1, 0, 0, 1, 1, 0 };
int up_idx[8] = { 0, 0, 1, 1, 0, 0, 1, 1 };
int out_idx[8] = { 0, 0, 0, 0, 1, 1, 1, 1 };
short color2nd = 0, customCyl = 0;
int rightup_flags[4] = { 0, 1, 3, 2 };
float *save_pc; float *save_pc;
int num_total_cylinders = 0, num_cylinders_with_2nd_color = 0, num_custom_cyli int num_total_spheres = 0;
nders = 0, num_custom_cylinders_with_2nd_color = 0;
short err = 0;
short has_draw_buffer = false; short has_draw_buffer = false;
float min[3] = { MAXFLOAT, MAXFLOAT, MAXFLOAT }, max[3] = { -MAXFLOAT, -MAXFLO AT, -MAXFLOAT }; float min[3] = { MAXFLOAT, MAXFLOAT, MAXFLOAT }, max[3] = { -MAXFLOAT, -MAXFLO AT, -MAXFLOAT };
int vv, total_vert = 0, total_cyl = 0; int vv, total_vert = 0, total_spheres = 0;
int ok = true; int ok = true;
num_custom_cylinders = CGOCountNumberCustomCylinders(I, &num_custom_cylinders_
with_2nd_color);
num_cylinders_with_2nd_color = CGOCountNumberOfOperationsOfType(I, CGO_SHADER_
CYLINDER_WITH_2ND_COLOR);
num_total_cylinders = CGOCountNumberOfOperationsOfType(I, CGO_SHADER_CYLINDER)
+ num_cylinders_with_2nd_color + num_custom_cylinders;
num_cylinders_with_2nd_color += num_custom_cylinders_with_2nd_color;
/*
The structure for cylinders is following:
first vertex is a cylinder origin num_total_spheres = CGOCountNumberOfOperationsOfType(I, CGO_SPHERE);
second vertex is cylinder axis vector if (num_total_spheres>0) {
third vertex is a corner flag (radius, right, up) float *vertVals = 0;
*/ GLubyte *rightUpFlagValsUB = 0;
if (num_total_cylinders>0) { float *rightUpFlagVals = 0;
float *originVals = 0, *axisVals = 0; GLubyte *colorValsUB = 0;
float *colorVals = 0, *color2Vals = 0; int tot = VERTICES_PER_SPHERE * 4 * num_total_spheres;
float axis[3], rad, col2[3]; float *org_vertVals = NULL;
int capvals; GLubyte *org_colorValsUB = NULL;
GL_C_INT_TYPE *indexVals = 0; int *org_pickcolorVals = NULL, *pickcolorVals = NULL;
int tot = 4 * 4 * 3 * num_total_cylinders; GLubyte *org_rightUpFlagValsUB = NULL;
short copyToLeftOver, copyColorToLeftOver, copyPickColorToLeftOver, copyAlph float *org_rightUpFlagVals = NULL;
aToLeftOver, copyToReturnCGO ;
float *org_originVals = NULL;
float *org_axisVals;
float *org_colorVals;
float *org_color2Vals = NULL;
GL_C_INT_TYPE *org_indexVals;
float min_alpha; float min_alpha;
short cgo_shader_ub_flags;
bool copyToLeftOver, copyNormalToLeftOver, copyColorToLeftOver, copyPickColo
rToLeftOver, copyAlphaToLeftOver ;
bool has_picking = CGOHasOperationsOfType(I, CGO_PICK_COLOR);
cgo = CGONewSized(I->G, I->c + est); cgo = CGONewSized(I->G, I->c + est);
CHECKOK(ok, cgo);
if (ok) cgo_shader_ub_flags = SettingGetGlobal_i(cgo->G, cSetting_cgo_shader_ub_flag
org_originVals = originVals = Alloc(float, tot); s);
CHECKOK(ok, org_originVals);
if (!ok){ org_vertVals = vertVals = Alloc(float, tot);
PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeGLSLCylindersToVBOInde if (!org_vertVals){
xedImpl() org_originVals could not be allocated\n" ENDFB(I->G); PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeSpheresToVBONonIndexed
() org_vertVals could not be allocated\n" ENDFB(I->G);
CGOFree(cgo); CGOFree(cgo);
return (NULL); return (NULL);
} }
org_axisVals = axisVals = Alloc(float, tot);
CHECKOK(ok, org_axisVals); org_colorValsUB = colorValsUB = Alloc(GLubyte, tot);
if (!ok){ if (!org_colorValsUB){
PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeGLSLCylindersToVBOInde PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeSpheresToVBONonIndexed
xedImpl() org_axisVals could not be allocated\n" ENDFB(I->G); () org_colorValsUB could not be allocated\n" ENDFB(I->G);
FreeP(org_originVals); FreeP(org_vertVals);
CGOFree(cgo); CGOFree(cgo);
return (NULL); return (NULL);
} }
if (!no_color){
org_colorVals = colorVals = Alloc(float, tot); if (cgo_shader_ub_flags){
CHECKOK(ok, org_colorVals); org_rightUpFlagValsUB = rightUpFlagValsUB = Alloc(GLubyte, VALUES_PER_IMPO
if (!ok){ STER_SPACE_COORD * VERTICES_PER_SPHERE * num_total_spheres);
PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeGLSLCylindersToVBOInd if (!org_rightUpFlagValsUB){
exedImpl() org_colorVals could not be allocated\n" ENDFB(I->G); PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeSpheresToVBONonIndexe
FreeP(org_originVals); d() org_rightUpFlagValsUB could not be allocated\n" ENDFB(I->G);
FreeP(org_axisVals); FreeP(org_colorValsUB); FreeP(org_vertVals);
CGOFree(cgo); CGOFree(cgo);
return (NULL); return (NULL);
} }
if (num_cylinders_with_2nd_color){ } else {
org_color2Vals = color2Vals = Alloc(float, tot); org_rightUpFlagVals = rightUpFlagVals = Alloc(float, VALUES_PER_IMPOSTER_S
CHECKOK(ok, org_color2Vals); PACE_COORD * VERTICES_PER_SPHERE * num_total_spheres);
if (!ok){ if (!org_rightUpFlagVals){
PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeGLSLCylindersToVBOI PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeSpheresToVBONonIndexe
ndexedImpl() org_color2Vals could not be allocated\n" ENDFB(I->G); d() org_rightUpFlagVals could not be allocated\n" ENDFB(I->G);
FreeP(org_colorVals); FreeP(org_colorValsUB); FreeP(org_vertVals);
FreeP(org_originVals); CGOFree(cgo);
FreeP(org_axisVals); return (NULL);
CGOFree(cgo);
return (NULL);
}
} }
} }
org_indexVals = indexVals = Alloc(GL_C_INT_TYPE, tot); if (has_picking){
CHECKOK(ok, org_indexVals); // atom/bond info for picking, 2 ints for each sphere
if (!ok){ org_pickcolorVals = pickcolorVals = Alloc(int, num_total_spheres * 2 * 4);
PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeGLSLCylindersToVBOInde
xedImpl() org_indexVals could not be allocated\n" ENDFB(I->G);
FreeP(org_color2Vals);
FreeP(org_colorVals);
FreeP(org_originVals);
FreeP(org_axisVals);
CGOFree(cgo);
return (NULL);
} }
pc = I->op; pc = I->op;
cgo->alpha = 1.f; cgo->alpha = 1.f;
min_alpha = 1.f; min_alpha = 1.f;
copyToReturnCGO = copyToLeftOver = copyColorToLeftOver = copyPickColorToLeft Over = copyAlphaToLeftOver = 0; copyToLeftOver = copyNormalToLeftOver = copyColorToLeftOver = copyPickColorT oLeftOver = copyAlphaToLeftOver = 0;
while(ok && (op = (CGO_MASK & CGO_read_int(pc)))) { while(ok && (op = (CGO_MASK & CGO_read_int(pc)))) {
copyToLeftOver = false; copyToLeftOver = false;
copyToReturnCGO = false;
save_pc = pc; save_pc = pc;
err = 0;
color2nd = false;
customCyl = false;
sz = -1; sz = -1;
switch (op) { switch (op) {
case CGO_NORMAL: case CGO_NORMAL:
cgo->normal[0] = *pc; cgo->normal[1] = *(pc + 1); cgo->normal[2] = *(pc + 2); cgo->normal[0] = *pc; cgo->normal[1] = *(pc + 1); cgo->normal[2] = *(pc + 2);
break; copyNormalToLeftOver = true;
break;
case CGO_COLOR: case CGO_COLOR:
cgo->color[0] = *pc; cgo->color[1] = *(pc + 1); cgo->color[2] = *(pc + 2 ); cgo->color[0] = *pc; cgo->color[1] = *(pc + 1); cgo->color[2] = *(pc + 2 );
copyColorToLeftOver = true; copyColorToLeftOver = true;
break; break;
case CGO_ALPHA: case CGO_ALPHA:
cgo->alpha = *pc; cgo->alpha = *pc;
if (cgo->alpha < min_alpha) min_alpha = cgo->alpha; if (cgo->alpha < min_alpha) min_alpha = cgo->alpha;
copyAlphaToLeftOver = true; copyAlphaToLeftOver = true;
break; break;
case CGO_PICK_COLOR: case CGO_PICK_COLOR:
cgo->current_pick_color_index = CGO_get_int(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);
copyPickColorToLeftOver = true; copyPickColorToLeftOver = true;
break; break;
case CGO_SAUSAGE: case CGO_SPHERE:
case CGO_CYLINDER: for (vv=0; vv<VERTICES_PER_SPHERE; vv++) { // generate eight vertices of
case CGO_CUSTOM_CYLINDER: a bounding box for each cylinder
customCyl = true; vertVals[0] = *(pc);
axis[0] = *(pc+3) - *(pc); vertVals[1] = *(pc+1);
axis[1] = *(pc+4) - *(pc+1); vertVals[2] = *(pc+2);
axis[2] = *(pc+5) - *(pc+2); vertVals[3] = *(pc+3);
if (op==CGO_CUSTOM_CYLINDER){ set_min_max(min, max, vertVals);
capvals = ((*(pc+13) > 1.5f) ? 5 : (*(pc+13) > 0.5f) ? 1 : 0) | if (cgo_shader_ub_flags){
((*(pc+14) > 1.5f) ? 10 : (*(pc+14) > 0.5f) ? 2 : 0); rightUpFlagValsUB[0] = rightup_flags[vv];
} else if (op==CGO_CYLINDER) { rightUpFlagValsUB++;
capvals = 3; } else {
} else { rightUpFlagVals[0] = rightup_flags[vv];
capvals = 15; rightUpFlagVals++;
}
cgo->color[0] = *(pc+7);
cgo->color[1] = *(pc+8);
cgo->color[2] = *(pc+9);
if (*(pc+7) != *(pc+10) || *(pc+8) != *(pc+11) || *(pc+9) != *(pc+12)){
color2nd = true;
col2[0] = *(pc+10);
col2[1] = *(pc+11);
col2[2] = *(pc+12);
}
case CGO_SHADER_CYLINDER_WITH_2ND_COLOR:
if (!customCyl){
color2nd = true;
col2[0] = *(pc+8);
col2[1] = *(pc+9);
col2[2] = *(pc+10);
}
case CGO_SHADER_CYLINDER:
if (!customCyl){
axis[0] = *(pc+3);
axis[1] = *(pc+4);
axis[2] = *(pc+5);
capvals = CGO_get_int(pc+7);
}
rad = *(pc+6);
for (vv=0; vv<NUM_VERTICES_PER_CYLINDER; vv++) { // generate eight vertic
es of a bounding box for each cylinder
originVals[0] = *(pc);
originVals[1] = *(pc+1);
originVals[2] = *(pc+2);
set_min_max(min, max, originVals);
axisVals[0] = axis[0];
axisVals[1] = axis[1];
axisVals[2] = axis[2];
originVals[3] = rad;
// pack the corner + cap flags into a single float
// start cap = 1, end cap = 2
axisVals[3] = ((capvals << 18) |
(right_idx[vv] << 12) |
(up_idx[vv] << 6) |
(out_idx[vv]));
if (!no_color){
colorVals[0] = cgo->color[0];
colorVals[1] = cgo->color[1];
colorVals[2] = cgo->color[2];
colorVals[3] = cgo->alpha;
if (color2Vals) {
if (color2nd){
color2Vals[0] = col2[0];
color2Vals[1] = col2[1];
color2Vals[2] = col2[2];
color2Vals[3] = cgo->alpha;
} else {
color2Vals[0] = cgo->color[0];
color2Vals[1] = cgo->color[1];
color2Vals[2] = cgo->color[2];
color2Vals[3] = cgo->alpha;
}
color2Vals += 4;
}
colorVals += 4;
} }
originVals += 4; colorValsUB[0] = CLIP_COLOR_VALUE(cgo->color[0]);
axisVals += 4; colorValsUB[1] = CLIP_COLOR_VALUE(cgo->color[1]);
colorValsUB[2] = CLIP_COLOR_VALUE(cgo->color[2]);
colorValsUB[3] = CLIP_COLOR_VALUE(cgo->alpha);
colorValsUB += 4;
vertVals += 4;
total_vert++; total_vert++;
} }
for (vv=0; vv<NUM_TOTAL_VERTICES_PER_CYLINDER; vv++) { if (has_picking){
*(indexVals++) = box_indices[vv] + NUM_VERTICES_PER_CYLINDER * total_cy *(pickcolorVals++) = cgo->current_pick_color_index;
l; *(pickcolorVals++) = cgo->current_pick_color_bond;
} }
total_cyl++; total_spheres++;
break;
case CGO_DRAW_ARRAYS:
{
int narrays = CGO_get_int(pc + 2), nverts = CGO_get_int(pc + 3);
int nvals = narrays*nverts, onvals;
onvals = nvals;
pc += 4;
save_pc += onvals + 4 ;
sz = onvals + 4 ;
copyToLeftOver = true;
}
break; break;
case CGO_DRAW_BUFFERS_INDEXED: case CGO_DRAW_BUFFERS_INDEXED:
case CGO_DRAW_BUFFERS_NOT_INDEXED: case CGO_DRAW_BUFFERS_NOT_INDEXED:
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeGLSLCylindersToVB O() CGO_DRAW_BUFFERS_INDEXED or CGO_DRAW_BUFFERS_INDEXED encountered op=0x%X\n", op ENDFB(I->G); PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeSpheresToVBONonIn dexed() CGO_DRAW_BUFFERS_INDEXED or CGO_DRAW_BUFFERS_INDEXED encountered op=%d\n ", op ENDFB(I->G);
break; break;
case CGO_DRAW_SCREEN_TEXTURES_AND_POLYGONS: case CGO_DRAW_SCREEN_TEXTURES_AND_POLYGONS:
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeGLSLCylindersToVB O() CGO_DRAW_SCREEN_TEXTURES_AND_POLYGONS encountered op=0x%X\n", op ENDFB(I->G) ; PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeCylindersToVBO() CGO_DRAW_SCREEN_TEXTURES_AND_POLYGONS encountered op=0x%X\n", op ENDFB(I->G);
break; break;
case CGO_DRAW_LABELS: case CGO_DRAW_LABELS:
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeGLSLCylindersToVB O() CGO_DRAW_LABELS encountered op=0x%X\n", op ENDFB(I->G); PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeCylindersToVBO() CGO_DRAW_LABELS encountered op=0x%X\n", op ENDFB(I->G);
break; break;
case CGO_DRAW_TEXTURES: case CGO_DRAW_TEXTURES:
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeGLSLCylindersToVB PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeCylindersToVBO()
O() CGO_DRAW_TEXTURES encountered op=0x%X\n", op ENDFB(I->G); CGO_DRAW_TEXTURES encountered op=0x%X\n", op ENDFB(I->G);
break;
case CGO_LINEWIDTH_SPECIAL:
copyToReturnCGO = true;
break; break;
case CGO_DRAW_ARRAYS:
default: default:
copyToLeftOver = true; copyToLeftOver = true;
} sz = CGO_sz[op];
if (copyToReturnCGO){ pc += sz;
float *npc = save_pc, *nc;
int origsz = sz;
if (sz < 0){
sz = CGO_sz[op];
} else {
npc -= sz;
}
nc = CGO_add(cgo, sz + 1);
*(nc++) = *(npc - 1);
while(sz--)
*(nc++) = *(npc++);
sz = origsz;
} }
if (leftOverCGO && copyToLeftOver){ if (leftOverCGO && copyToLeftOver){
float *npc = save_pc, *nc; float *npc = pc;
if (copyAlphaToLeftOver){ if (copyAlphaToLeftOver){
CGOAlpha(leftOverCGO, cgo->alpha); CGOAlpha(leftOverCGO, cgo->alpha);
} }
if (copyColorToLeftOver){ if (copyColorToLeftOver){
CGOColor(leftOverCGO, cgo->color[0], cgo->color[1], cgo->color[2] ); CGOColor(leftOverCGO, cgo->color[0], cgo->color[1], cgo->color[2] );
} }
if (copyNormalToLeftOver){
CGONormalv(leftOverCGO, cgo->normal );
}
if (copyPickColorToLeftOver){ if (copyPickColorToLeftOver){
CGOPickColor(leftOverCGO, cgo->current_pick_color_index, cgo->current_p ick_color_bond); CGOPickColor(leftOverCGO, cgo->current_pick_color_index, cgo->current_p ick_color_bond);
} }
if (sz < 0){ if (sz < 0){
sz = CGO_sz[op]; sz = CGO_sz[op];
} else { } else {
npc -= sz; npc -= sz;
} }
nc = CGO_add(leftOverCGO, sz + 1); leftOverCGO->add_to_cgo(op, npc);
*(nc++) = *(npc - 1);
while(sz--)
*(nc++) = *(npc++);
copyToLeftOver = copyColorToLeftOver = copyPickColorToLeftOver = copyAlph aToLeftOver = 0; copyToLeftOver = copyColorToLeftOver = copyPickColorToLeftOver = copyAlph aToLeftOver = 0;
} }
pc = save_pc; pc = save_pc;
pc += CGO_sz[op]; pc += CGO_sz[op];
#ifndef _WEBGL
ok &= !I->G->Interrupt; ok &= !I->G->Interrupt;
#endif
} }
// printf("total_cyl=%d total_vert=%d\n", total_cyl, total_vert); if (ok && total_spheres > 0) {
if (ok && total_cyl > 0) { GLenum rtp = GL_FLOAT;
uint bufpl, bufs[5] = { 0, 0, 0, 0, 0}; short rsz = sizeof(float);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeGLSLCylindersToVBO() BEFORE glGenBuff void * radiusptr = (void *)org_rightUpFlagVals;
ers returns err=%d\n"); if (cgo_shader_ub_flags) {
if (ok){ rtp = GL_UNSIGNED_BYTE;
glGenBuffers(5, bufs); rsz = sizeof(GLubyte);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeGLSLCylindersToVBO() glGenBuffers re radiusptr = (void *)org_rightUpFlagValsUB;
turns err=%d\n"); }
}
for (bufpl=0; ok && bufpl<5; bufpl++) { VertexBuffer * vbo = I->G->ShaderMgr->newGPUBuffer<VertexBuffer>();
glBindBuffer(GL_ARRAY_BUFFER, bufs[bufpl]); ok &= vbo->bufferData({
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeGLSLCylindersToVBO() glBindBuffer re BufferDesc( "a_vertex_radius", GL_FLOAT, 4, sizeof(float) * total_vert
turns err=%d\n"); * 4, org_vertVals, GL_FALSE ),
if (ok && !glIsBuffer(bufs[bufpl])){ BufferDesc( "a_Color", GL_UNSIGNED_BYTE, 4, sizeof(float) * total_vert
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeGLSLCylindersT , org_colorValsUB, GL_TRUE ),
oVBO() glGenBuffers created bad buffer bufpl=%d bufs[bufpl]=%d\n", bufpl, bufs[b BufferDesc( "a_rightUpFlags", rtp, VALUES_PER_IMPOSTER_SPACE_COORD, rs
ufpl] ENDFB(I->G); z * total_vert * VALUES_PER_IMPOSTER_SPACE_COORD, radiusptr, GL_FALSE )
ok = false; });
} else if (ok){ size_t vboid = vbo->get_hash_id();
switch(bufpl) {
case 0: // midpoint VertexBuffer * pickvbo = I->G->ShaderMgr->newGPUBuffer<VertexBuffer>(Verte
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*total_vert*4, org_orig xBuffer::SEQUENTIAL, GL_DYNAMIC_DRAW);
inVals, GL_STATIC_DRAW); ok &= pickvbo->bufferData({
break; BufferDesc( "a_Color", GL_UNSIGNED_BYTE, 4, 0, GL_TRUE ),
case 1: // axis BufferDesc( "a_Color", GL_UNSIGNED_BYTE, 4, sizeof(float) * total_vert
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*total_vert*4, org_axis , GL_TRUE )
Vals, GL_STATIC_DRAW); }, 0, sizeof(float) * total_vert * 2, 0);
break; size_t pickvboid = pickvbo->get_hash_id();
case 2: // color
if (!no_color){
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*total_vert*4, org_col
orVals, GL_STATIC_DRAW);
} else {
if (bufs[2]){
CShaderMgr_AddVBOToFree(I->G->ShaderMgr, bufs[2]);
bufs[2] = 0;
}
}
break;
case 3: // color2
if (!no_color && num_cylinders_with_2nd_color){
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*total_vert*4, org_col
or2Vals, GL_STATIC_DRAW);
} else {
if (bufs[3]){
CShaderMgr_AddVBOToFree(I->G->ShaderMgr, bufs[3]);
bufs[3] = 0;
}
}
break;
}
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeGLSLCylindersToVBO() glBufferData
returns err=%d\n");
}
}
has_draw_buffer = true;
auto freebuffers = [vboid, pickvboid, I]() {
I->G->ShaderMgr->freeGPUBuffer(vboid);
I->G->ShaderMgr->freeGPUBuffer(pickvboid);
};
if (ok){ if (ok){
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufs[4]); int *pickcolor_data;
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeGLSLCylindersToVBO() glBindBuffer re if (addshaders)
turns err=%d\n"); CGOEnable(cgo, GL_SPHERE_SHADER);
} pickcolor_data = (int*)cgo->add<cgo::draw::sphere_buffers>(total_spheres,
if (ok){ (cgo_shader_ub_flags ? 3 : 1), vboid, pickvboid); // always cgo_shader_ub_color
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GL_C_INT_TYPE)*total_cyl*NUM CHECKOK(ok, pickcolor_data);
_TOTAL_VERTICES_PER_CYLINDER, org_indexVals, GL_STATIC_DRAW); if (ok && has_picking){
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeGLSLCylindersToVBO() glBufferData re memcpy(pickcolor_data, org_pickcolorVals, num_total_spheres * 2 * 4);
turns err=%d\n"); }
} if (ok && addshaders)
if (ok){ ok &= CGODisable(cgo, GL_SPHERE_SHADER);
has_draw_buffer = true;
ok &= CGODrawCylinderBuffers(cgo, total_cyl, (int)(255 * min_alpha), bufs
);
if (!ok){ if (!ok){
CShaderMgr_AddVBOsToFree(I->G->ShaderMgr, bufs, 5); freebuffers();
} }
} else { } else {
CShaderMgr_AddVBOsToFree(I->G->ShaderMgr, bufs, 5); freebuffers();
} }
} }
FreeP(org_axisVals); FreeP(org_pickcolorVals);
FreeP(org_originVals); FreeP(org_vertVals);
if (!no_color){ FreeP(org_colorValsUB);
FreeP(org_colorVals); if (cgo_shader_ub_flags){
if (org_color2Vals){ FreeP(org_rightUpFlagValsUB);
FreeP(org_color2Vals); } else {
} FreeP(org_rightUpFlagVals);
} }
FreeP(org_indexVals);
if (ok) if (ok && num_total_spheres>0){
ok &= CGOBoundingBox(cgo, min, max); ok &= CGOBoundingBox(cgo, min, max);
}
if (ok) if (ok)
ok &= CGOStop(cgo); ok &= CGOStop(cgo);
if (ok && has_draw_buffer){
cgo->has_draw_buffers = true;
cgo->has_draw_cylinder_buffers = true;
}
if (ok){ if (ok){
if (has_draw_buffer){
cgo->has_draw_buffers = true;
cgo->has_draw_sphere_buffers = true;
}
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 = true;
cgo->cgo_shader_ub_normal = SettingGetGlobal_i(cgo->G, cSetting_cgo_shade r_ub_normal); cgo->cgo_shader_ub_normal = SettingGetGlobal_i(cgo->G, cSetting_cgo_shade r_ub_normal);
} }
} }
} }
if (!ok){ if (!ok){
CGOFree(cgo); CGOFree(cgo);
cgo = NULL;
} }
return (cgo); return (cgo);
} }
#define VALUES_PER_IMPOSTER_SPACE_COORD 1 /*
* converts a CGO that has primitives into pure geometry,
CGO *CGOOptimizeSpheresToVBONonIndexed(CGO * I, int est, bool addshaders, CGO *l * and converts CGO_BEGIN/CGO_END blocks into CGO_DRAW_ARRAYS
eftOverCGO) * operations, similar to what CGOCombineBeginEnd() does.
{ *
return (CGOOptimizeSpheresToVBONonIndexedImpl(I, est, leftOverCGO)); * I: input CGO
} * est: initial size of the newly allocated CGO array
* that is returned by this function
#define VERTICES_PER_SPHERE 4 * sphere_quality: the quality of the spheres generated by this function
* (if -1, defaults to cgo_sphere_quality)
CGO *CGOOptimizeSpheresToVBONonIndexedImpl(CGO * I, int est, CGO *leftOverCGO) * stick_round_nub: if true, a round cap is generated, otherwise, it generates
* the old "pointed" caps
*/
CGO *CGOSimplify(const CGO * I, int est, short sphere_quality, bool stick_round_
nub)
{ {
CGO *cgo = NULL; CGO *cgo;
float *pc = I->op; float *pc = I->op;
int op;
int sz;
int rightup_flags[4] = { 0, 1, 3, 2 };
float *save_pc;
int num_total_spheres = 0;
short err = 0;
short has_draw_buffer = false;
float min[3] = { MAXFLOAT, MAXFLOAT, MAXFLOAT }, max[3] = { -MAXFLOAT, -MAXFLO
AT, -MAXFLOAT };
int vv, total_vert = 0, total_spheres = 0;
int ok = true;
num_total_spheres = CGOCountNumberOfOperationsOfType(I, CGO_SPHERE);
if (num_total_spheres>0) {
float *vertVals = 0;
GLubyte *rightUpFlagValsUB = 0;
float *rightUpFlagVals = 0;
GLubyte *colorValsUB = 0;
float *colorVals = 0;
int tot = VERTICES_PER_SPHERE * 4 * num_total_spheres;
float *org_vertVals = NULL;
float *org_colorVals = NULL;
GLubyte *org_colorValsUB = NULL;
GLubyte *org_rightUpFlagValsUB = NULL;
float *org_rightUpFlagVals = NULL;
float min_alpha;
short cgo_shader_ub_color, cgo_shader_ub_flags;
short copyToLeftOver, copyColorToLeftOver, copyPickColorToLeftOver, copyAlph
aToLeftOver ;
cgo = CGONewSized(I->G, I->c + est);
cgo_shader_ub_color = SettingGetGlobal_i(cgo->G, cSetting_cgo_shader_ub_colo
r);
cgo_shader_ub_flags = SettingGetGlobal_i(cgo->G, cSetting_cgo_shader_ub_flag
s);
org_vertVals = vertVals = Alloc(float, tot);
if (!org_vertVals){
PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeSpheresToVBONonIndexed
Impl() org_vertVals could not be allocated\n" ENDFB(I->G);
CGOFree(cgo);
return (NULL);
}
if(cgo_shader_ub_color){
org_colorValsUB = colorValsUB = Alloc(GLubyte, tot);
if (!org_colorValsUB){
PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeSpheresToVBONonIndexe
dImpl() org_colorValsUB could not be allocated\n" ENDFB(I->G);
FreeP(org_vertVals);
CGOFree(cgo);
return (NULL);
}
} else {
org_colorVals = colorVals = Alloc(float, tot);
if (!org_colorVals){
PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeSpheresToVBONonIndexe
dImpl() org_colorValsUB could not be allocated\n" ENDFB(I->G);
FreeP(org_vertVals);
CGOFree(cgo);
return (NULL);
}
}
if (cgo_shader_ub_flags){
org_rightUpFlagValsUB = rightUpFlagValsUB = Alloc(GLubyte, VALUES_PER_IMPO
STER_SPACE_COORD * VERTICES_PER_SPHERE * num_total_spheres);
if (!org_rightUpFlagValsUB){
PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeSpheresToVBONonIndexe
dImpl() org_rightUpFlagValsUB could not be allocated\n" ENDFB(I->G);
FreeP(org_colorVals); FreeP(org_colorValsUB); FreeP(org_vertVals);
CGOFree(cgo);
return (NULL);
}
} else {
org_rightUpFlagVals = rightUpFlagVals = Alloc(float, VALUES_PER_IMPOSTER_S
PACE_COORD * VERTICES_PER_SPHERE * num_total_spheres);
if (!org_rightUpFlagVals){
PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeSpheresToVBONonIndexe
dImpl() org_rightUpFlagVals could not be allocated\n" ENDFB(I->G);
FreeP(org_colorVals); FreeP(org_colorValsUB); FreeP(org_vertVals);
CGOFree(cgo);
return (NULL);
}
}
pc = I->op;
cgo->alpha = 1.f;
min_alpha = 1.f;
copyToLeftOver = copyColorToLeftOver = copyPickColorToLeftOver = copyAlphaTo
LeftOver = 0;
while(ok && (op = (CGO_MASK & CGO_read_int(pc)))) {
copyToLeftOver = false;
save_pc = pc;
err = 0;
sz = -1;
switch (op) {
case CGO_NORMAL:
cgo->normal[0] = *pc; cgo->normal[1] = *(pc + 1); cgo->normal[2] = *(pc
+ 2);
break;
case CGO_COLOR:
cgo->color[0] = *pc; cgo->color[1] = *(pc + 1); cgo->color[2] = *(pc + 2
);
copyColorToLeftOver = true;
break;
case CGO_ALPHA:
cgo->alpha = *pc;
if (cgo->alpha < min_alpha) min_alpha = cgo->alpha;
copyAlphaToLeftOver = true;
break;
case CGO_PICK_COLOR:
cgo->current_pick_color_index = CGO_get_int(pc);
cgo->current_pick_color_bond = CGO_get_int(pc + 1);
copyPickColorToLeftOver = true;
break;
case CGO_SPHERE:
for (vv=0; vv<VERTICES_PER_SPHERE; vv++) { // generate eight vertices of
a bounding box for each cylinder
vertVals[0] = *(pc);
vertVals[1] = *(pc+1);
vertVals[2] = *(pc+2);
vertVals[3] = *(pc+3);
set_min_max(min, max, vertVals);
if (cgo_shader_ub_flags){
rightUpFlagValsUB[0] = rightup_flags[vv];
rightUpFlagValsUB++;
} else {
rightUpFlagVals[0] = rightup_flags[vv];
rightUpFlagVals++;
}
if (cgo_shader_ub_color){
colorValsUB[0] = CLIP_COLOR_VALUE(cgo->color[0]);
colorValsUB[1] = CLIP_COLOR_VALUE(cgo->color[1]);
colorValsUB[2] = CLIP_COLOR_VALUE(cgo->color[2]);
colorValsUB[3] = CLIP_COLOR_VALUE(cgo->alpha);
colorValsUB += 4;
} else {
colorVals[0] = cgo->color[0];
colorVals[1] = cgo->color[1];
colorVals[2] = cgo->color[2];
colorVals[3] = cgo->alpha;
colorVals += 4;
}
vertVals += 4;
total_vert++;
}
total_spheres++;
break;
case CGO_DRAW_ARRAYS:
{
int mode = CGO_get_int(pc), arrays = CGO_get_int(pc + 1), narrays = CGO
_get_int(pc + 2), nverts = CGO_get_int(pc + 3);
GLfloat *vals = CGODrawArrays(cgo, mode, arrays, nverts);
int nvals = narrays*nverts, onvals;
onvals = nvals;
pc += 4;
while(nvals--)
*(vals++) = *(pc++);
save_pc += onvals + 4 ;
sz = onvals + 4 ;
copyToLeftOver = true;
}
break;
case CGO_DRAW_BUFFERS_INDEXED:
case CGO_DRAW_BUFFERS_NOT_INDEXED:
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeSpheresToVBONonIn
dexed() CGO_DRAW_BUFFERS_INDEXED or CGO_DRAW_BUFFERS_INDEXED encountered op=%d\n
", op ENDFB(I->G);
break;
case CGO_DRAW_SCREEN_TEXTURES_AND_POLYGONS:
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeGLSLCylindersToVB
O() CGO_DRAW_SCREEN_TEXTURES_AND_POLYGONS encountered op=0x%X\n", op ENDFB(I->G)
;
break;
case CGO_DRAW_LABELS:
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeGLSLCylindersToVB
O() CGO_DRAW_LABELS encountered op=0x%X\n", op ENDFB(I->G);
break;
case CGO_DRAW_TEXTURES:
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeGLSLCylindersToVB
O() CGO_DRAW_TEXTURES encountered op=0x%X\n", op ENDFB(I->G);
break;
default:
copyToLeftOver = true;
sz = CGO_sz[op];
pc += sz;
/* nc = CGO_add(cgo, sz + 1);
*(nc++) = *(pc - 1);
while(sz--)
*(nc++) = *(pc++);*/
}
if (leftOverCGO && copyToLeftOver){
float *npc = pc, *nc;
if (copyAlphaToLeftOver){
CGOAlpha(leftOverCGO, cgo->alpha);
}
if (copyColorToLeftOver){
CGOColor(leftOverCGO, cgo->color[0], cgo->color[1], cgo->color[2] );
}
if (copyPickColorToLeftOver){
CGOPickColor(leftOverCGO, cgo->current_pick_color_index, cgo->current_p
ick_color_bond);
}
if (sz < 0){
sz = CGO_sz[op];
} else {
npc -= sz;
}
nc = CGO_add(leftOverCGO, sz + 1);
*(nc++) = *(npc - 1);
while(sz--)
*(nc++) = *(npc++);
copyToLeftOver = copyColorToLeftOver = copyPickColorToLeftOver = copyAlph
aToLeftOver = 0;
}
pc = save_pc;
pc += CGO_sz[op];
ok &= !I->G->Interrupt;
}
if (ok && total_spheres > 0) {
uint bufpl, bufs[3] = { 0, 0, 0 };
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeSpheresToVBONonIndexed() BEFORE glGen
Buffers returns err=%d\n");
if (ok){
glGenBuffers(3, bufs);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeSpheresToVBONonIndexed() glGenBuffer
s returns err=%d\n");
}
for (bufpl=0; ok && bufpl<3; bufpl++) {
glBindBuffer(GL_ARRAY_BUFFER, bufs[bufpl]);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeSpheresToVBONonIndexed() glBindBuffe
r returns err=%d\n");
if (ok && !glIsBuffer(bufs[bufpl])){
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeSpheresToVBONo
nIndexed() glGenBuffers created bad buffer bufpl=%d bufs[bufpl]=%d\n", bufpl, bu
fs[bufpl] ENDFB(I->G);
ok = false;
} else {
switch(bufpl) {
case 0: // vertex xyz + right/up flag in w
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*total_vert*4, org_vert
Vals, GL_STATIC_DRAW);
break;
case 1: // color in UNSIGNED_BYTE
if (cgo_shader_ub_color){
glBufferData(GL_ARRAY_BUFFER, sizeof(GLubyte)*total_vert*4, org_c
olorValsUB, GL_STATIC_DRAW);
} else {
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*total_vert*4, org_col
orVals, GL_STATIC_DRAW);
}
break;
case 2: // radius
if (cgo_shader_ub_flags){
glBufferData(GL_ARRAY_BUFFER, sizeof(GLubyte)*total_vert*VALUES_P
ER_IMPOSTER_SPACE_COORD, org_rightUpFlagValsUB, GL_STATIC_DRAW);
} else {
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*total_vert*VALUES_PER
_IMPOSTER_SPACE_COORD, org_rightUpFlagVals, GL_STATIC_DRAW);
}
break;
}
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeSpheresToVBONonIndexed() glBufferD
ata returns err=%d\n");
}
}
has_draw_buffer = true;
if (ok){
ok &= CGODrawSphereBuffers(cgo, total_spheres, (cgo_shader_ub_color ? 1 :
0) | (cgo_shader_ub_flags ? 2 : 0), bufs);
if (!ok){
CShaderMgr_AddVBOsToFree(I->G->ShaderMgr, bufs, 3);
}
} else {
CShaderMgr_AddVBOsToFree(I->G->ShaderMgr, bufs, 3);
}
}
FreeP(org_vertVals);
if (cgo_shader_ub_color){
FreeP(org_colorValsUB);
} else {
FreeP(org_colorVals);
}
if (cgo_shader_ub_flags){
FreeP(org_rightUpFlagValsUB);
} else {
FreeP(org_rightUpFlagVals);
}
if (ok && num_total_spheres>0){
ok &= CGOBoundingBox(cgo, min, max);
}
if (ok)
ok &= CGOStop(cgo);
if (ok){
if (has_draw_buffer){
cgo->has_draw_buffers = true;
cgo->has_draw_sphere_buffers = true;
}
cgo->use_shader = I->use_shader;
if (cgo->use_shader){
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_shade
r_ub_normal);
}
}
}
if (!ok){
CGOFree(cgo);
cgo = NULL;
}
return (cgo);
}
CGO *CGOSimplify(CGO * I, int est)
{
CGO *cgo;
float *pc = I->op;
float *nc = NULL;
int op = 0; int op = 0;
float *save_pc = NULL; float *save_pc = NULL;
int sz = 0; int sz = 0;
int ok = true; int ok = true;
if (sphere_quality < 0){
sphere_quality = SettingGet_i(I->G, NULL, NULL, cSetting_cgo_sphere_quality)
;
}
cgo = CGONewSized(I->G, I->c + est); cgo = CGONewSized(I->G, I->c + est);
CHECKOK(ok, cgo); CHECKOK(ok, cgo);
while(ok && (op = (CGO_MASK & CGO_read_int(pc)))) { while(ok && (op = (CGO_MASK & CGO_read_int(pc)))) {
save_pc = pc; save_pc = pc;
switch (op) { switch (op) {
case CGO_COLOR:
copy3f(pc, cgo->color);
CGOColorv(cgo, pc);
break;
case CGO_PICK_COLOR: case CGO_PICK_COLOR:
cgo->current_pick_color_index = CGO_get_int(pc); CGOPickColor(cgo, CGO_get_uint(pc), 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);
break; break;
case CGO_SHADER_CYLINDER: case CGO_SHADER_CYLINDER:
{ {
float v2[3]; float v2[3];
int cap = CGO_get_int(pc + 7);
int fcap = (cap & 1) ? ((cap & cCylShaderCap1RoundBit) ? 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, 1, 1); ok &= CGOSimpleCylinder(cgo, pc, v2, *(pc + 6), 0, 0, (cap & cCylShaderI
nterpColor),
fcap, bcap, NULL, stick_round_nub);
} }
break; break;
case CGO_SHADER_CYLINDER_WITH_2ND_COLOR: case CGO_SHADER_CYLINDER_WITH_2ND_COLOR:
{ {
float haxis[3], v1[3], v2[3]; float v1[3];
mult3f(pc + 3, .5f, haxis); int cap = CGO_get_int(pc + 7);
add3f(pc, haxis, v1); int fcap = (cap & 1) ? ((cap & cCylShaderCap1RoundBit) ? 2 : 1) : 0;
ok &= CGOSimpleCylinder(cgo, pc, v1, *(pc + 6), 0, 0, 1, 0); int bcap = (cap & 2) ? ((cap & cCylShaderCap2RoundBit) ? 2 : 1) : 0;
if (ok){ Pickable pickcolor2 = { CGO_get_uint(pc + 11), CGO_get_int(pc + 12) };
add3f(v1, haxis, v2); float color1[3] = { cgo->color[0], cgo->color[1], cgo->color[2] };
ok &= CGOSimpleCylinder(cgo, v1, v2, *(pc + 6), pc+8, pc+8, 0, 1); add3f(pc, pc + 3, v1);
} float mid[3];
mult3f(pc + 3, .5f, mid);
add3f(pc, mid, mid);
if (cap & cCylShaderInterpColor){
ok &= CGOSimpleCylinder(cgo, pc, v1, *(pc + 6), color1, pc+8, true, bc
ap, fcap, &pickcolor2, stick_round_nub);
} else {
ok &= CGOColorv(cgo, color1);
ok &= CGOSimpleCylinder(cgo, pc, mid, *(pc + 6), color1, NULL, false,
fcap, 0, NULL, stick_round_nub);
ok &= CGOColorv(cgo, pc+8);
ok &= CGOPickColor(cgo, pickcolor2.index, pickcolor2.bond);
ok &= CGOSimpleCylinder(cgo, mid, v1, *(pc + 6), pc+8, NULL, 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, 1, 1) ; ok &= CGOSimpleCylinder(cgo, pc, pc + 3, *(pc + 6), pc + 7, pc + 10, true, 1, 1, NULL, 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, 2, 2) ; ok &= CGOSimpleCylinder(cgo, pc, pc + 3, *(pc + 6), pc + 7, pc + 10, true, 2, 2, NULL, 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, (int) ok &= CGOSimpleCylinder(cgo, pc, pc + 3, *(pc + 6), pc + 7, pc + 10, true,
*(pc + 13), (int) *(pc + 13),
(int) *(pc + 14)); (int) *(pc + 14), NULL, stick_round_nub);
break; break;
case CGO_SPHERE: case CGO_SPHERE:
ok &= CGOSimpleSphere(cgo, pc, *(pc + 3)); 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;
case CGO_DRAW_BUFFERS_INDEXED: case CGO_DRAW_BUFFERS_INDEXED:
{ PRINTFB(I->G, FB_CGO, FB_Errors) "CGOSimplify-Error: CGO_DRAW_BUFFERS_IND
int nverts = CGO_get_int(pc + 4); EXED encountered\n" ENDFB(I->G);
pc += nverts*3 + 10 ;
PRINTFB(I->G, FB_CGO, FB_Errors) "WARNING: CGOSimplify: CGO_DRAW_BUFFERS_
INDEXED encountered nverts=%d\n", nverts ENDFB(I->G);
}
break; break;
case CGO_DRAW_BUFFERS_NOT_INDEXED: case CGO_DRAW_BUFFERS_NOT_INDEXED:
{ PRINTFB(I->G, FB_CGO, FB_Errors) "CGOSimplify-Error: CGO_DRAW_BUFFERS_NOT
int nverts = CGO_get_int(pc + 3); _INDEXED encountered\n" ENDFB(I->G);
pc += nverts*3 + 8 ; break;
PRINTFB(I->G, FB_CGO, FB_Errors) "WARNING: CGOSimplify: CGO_DRAW_BUFFERS_ case CGO_DRAW_SPHERE_BUFFERS:
NOT_INDEXED encountered nverts=%d\n", nverts ENDFB(I->G); PRINTFB(I->G, FB_CGO, FB_Errors) "CGOSimplify-Error: CGO_DRAW_SPHERE_BUF
} FERS encountered\n" ENDFB(I->G);
break;
case CGO_DRAW_CYLINDER_BUFFERS:
PRINTFB(I->G, FB_CGO, FB_Errors) "CGOSimplify-Error: CGO_DRAW_CYLINDER_B
UFFERS encountered\n" ENDFB(I->G);
break; break;
case CGO_DRAW_LABELS: case CGO_DRAW_LABELS:
{ PRINTFB(I->G, FB_CGO, FB_Errors) "CGOSimplify-Error: CGO_DRAW_LABELS enco
int nlabels = CGO_get_int(pc); untered\n" ENDFB(I->G);
pc += nlabels * 18 + 5;
PRINTFB(I->G, FB_CGO, FB_Errors) "WARNING: CGOSimplify: CGO_DRAW_LABELS e
ncountered nlabels=%d\n", nlabels ENDFB(I->G);
}
break; break;
case CGO_DRAW_TEXTURES: case CGO_DRAW_TEXTURES:
{ PRINTFB(I->G, FB_CGO, FB_Errors) "CGOSimplify-Error: CGO_DRAW_TEXTURES en
int ntextures = CGO_get_int(pc); countered \n" ENDFB(I->G);
pc += ntextures * 18 + 4;
PRINTFB(I->G, FB_CGO, FB_Errors) "WARNING: CGOSimplify: CGO_DRAW_TEXTURES
encountered ntextures=%d\n", ntextures ENDFB(I->G);
}
break;
case CGO_DRAW_ARRAYS:
{
int mode = CGO_get_int(pc), arrays = CGO_get_int(pc + 1), narrays = CGO_g
et_int(pc + 2), nverts = CGO_get_int(pc + 3);
int nvals = narrays*nverts, onvals;
GLfloat *vals = CGODrawArrays(cgo, mode, arrays, nverts);
CHECKOK(ok, vals);
if (ok){
onvals = nvals;
pc += 4;
while(nvals--)
*(vals++) = *(pc++);
save_pc += onvals + 4 ;
}
}
break; break;
case CGO_END: case CGO_END:
PRINTFB(I->G, FB_CGO, FB_Warnings) " CGOSimplify: CGO_END encountered with out CGO_BEGIN but skipped for OpenGLES\n" ENDFB(I->G); PRINTFB(I->G, FB_CGO, FB_Warnings) "CGOSimplify-Warning: CGO_END encounter ed without CGO_BEGIN but skipped for OpenGLES\n" ENDFB(I->G);
break; break;
case CGO_VERTEX: case CGO_VERTEX:
PRINTFB(I->G, FB_CGO, FB_Warnings) " CGOSimplify: CGO_VERTEX encountered w ithout CGO_BEGIN but skipped for OpenGLES\n" ENDFB(I->G); PRINTFB(I->G, FB_CGO, FB_Warnings) "CGOSimplify-Warning: CGO_VERTEX encoun tered without CGO_BEGIN but skipped for OpenGLES\n" ENDFB(I->G);
break; break;
case CGO_BEGIN: case CGO_BEGIN:
{ {
float *origpc = pc; float *origpc = pc, firstColor[3], firstAlpha;
char hasFirstColor = 0, hasFirstAlpha = 0;
int nverts = 0, damode = CGO_VERTEX_ARRAY, err = 0, end = 0; int nverts = 0, damode = CGO_VERTEX_ARRAY, err = 0, end = 0;
int mode = CGO_read_int(pc); int mode = CGO_read_int(pc);
while(ok && !err && !end && (op = (CGO_MASK & CGO_read_int(pc)))) { while(ok && !err && !end && (op = (CGO_MASK & CGO_read_int(pc)))) {
switch (op) { switch (op) {
case CGO_DRAW_ARRAYS: case CGO_DRAW_ARRAYS:
PRINTFB(I->G, FB_CGO, FB_Warnings) " CGOSimplify: CGO_DRAW_ARRAYS enc ountered inside CGO_BEGIN/CGO_END\n" ENDFB(I->G); PRINTFB(I->G, FB_CGO, FB_Warnings) " CGOSimplify-Warning: CGO_DRAW_AR RAYS encountered inside CGO_BEGIN/CGO_END\n" ENDFB(I->G);
err = true; err = true;
continue; continue;
case CGO_NORMAL: case CGO_NORMAL:
damode |= CGO_NORMAL_ARRAY; damode |= CGO_NORMAL_ARRAY;
break; break;
case CGO_COLOR: case CGO_COLOR:
damode |= CGO_COLOR_ARRAY; if (!nverts){
hasFirstColor = 1;
firstColor[0] = pc[0]; firstColor[1] = pc[1]; firstColor[2] = pc[2]
;
} else {
hasFirstColor = 0;
damode |= CGO_COLOR_ARRAY;
}
break; break;
case CGO_PICK_COLOR: case CGO_PICK_COLOR:
damode |= CGO_PICK_COLOR_ARRAY; damode |= CGO_PICK_COLOR_ARRAY;
break; break;
case CGO_ACCESSIBILITY:
damode |= CGO_ACCESSIBILITY_ARRAY;
break;
case CGO_VERTEX: case CGO_VERTEX:
nverts++; nverts++;
break; break;
case CGO_END: case CGO_END:
end = 1; end = 1;
break; break;
case CGO_ALPHA: case CGO_ALPHA:
I->alpha = *pc; cgo->alpha = *pc;
if (!nverts){
hasFirstAlpha = 1;
firstAlpha = cgo->alpha;
} else {
hasFirstAlpha = 0;
damode |= CGO_COLOR_ARRAY;
}
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; float *normalVals, *colorVals = 0, *nxtVals = 0, *pickColorVals = 0, *a
uchar *pickColorValsUC; ccessibilityVals = 0;
short notHaveValue = 0, nxtn = 3; short notHaveValue = 0, nxtn = 3;
nxtVals = vertexVals = CGODrawArrays(cgo, mode, damode, nverts); if (hasFirstAlpha || hasFirstColor){
CHECKOK(ok, vertexVals); if (hasFirstAlpha){
if (!ok){ CGOAlpha(cgo, firstAlpha);
break; }
} if (hasFirstColor){
if (damode & CGO_NORMAL_ARRAY){ CGOColorv(cgo, firstColor);
nxtVals = normalVals = vertexVals + (nxtn*nverts); }
} }
nxtVals = vertexVals = cgo->add<cgo::draw::arrays>(mode, damode, nverts
);
CHECKOK(ok, vertexVals);
if (!ok){
break;
}
if (damode & CGO_NORMAL_ARRAY){
nxtVals = normalVals = vertexVals + (nxtn*nverts);
}
if (damode & CGO_COLOR_ARRAY){ if (damode & CGO_COLOR_ARRAY){
nxtVals = colorVals = nxtVals + (nxtn*nverts); nxtVals = colorVals = nxtVals + (nxtn*nverts);
nxtn = 4; nxtn = 4;
} }
if (damode & CGO_PICK_COLOR_ARRAY){ if (damode & CGO_PICK_COLOR_ARRAY){
nxtVals = nxtVals + (nxtn*nverts); nxtVals = nxtVals + (nxtn*nverts);
pickColorVals = nxtVals + nverts; pickColorVals = nxtVals + nverts;
pickColorValsUC = (uchar*)nxtVals;
nxtn = 3; nxtn = 3;
} }
if (damode & CGO_ACCESSIBILITY_ARRAY){
nxtVals = nxtVals + (nxtn*nverts);
accessibilityVals = nxtVals;
nxtn = 1;
}
pc = origpc + 1; pc = origpc + 1;
notHaveValue = damode; notHaveValue = damode;
end = 0; end = 0;
bool skiptoend = false; bool skiptoend = false;
while(!err && !end && (op = (CGO_MASK & CGO_read_int(pc)))) { while(!err && !end && (op = (CGO_MASK & CGO_read_int(pc)))) {
if (skiptoend && op!=CGO_END){ if (skiptoend && op!=CGO_END){
sz = CGO_sz[op]; sz = CGO_sz[op];
pc += sz; pc += sz;
continue; continue;
} }
switch (op) { switch (op) {
case CGO_NORMAL: case CGO_NORMAL:
normalVals[pl] = pc[0]; normalVals[pl+1] = pc[1]; normalVals[pl+2] = pc[2]; normalVals[pl] = pc[0]; normalVals[pl+1] = pc[1]; normalVals[pl+2] = pc[2];
notHaveValue &= ~CGO_NORMAL_ARRAY; notHaveValue &= ~CGO_NORMAL_ARRAY;
break; break;
case CGO_COLOR: case CGO_COLOR:
colorVals[plc] = pc[0]; colorVals[plc+1] = pc[1]; if (colorVals){
colorVals[plc+2] = pc[2]; colorVals[plc+3] = I->alpha; colorVals[plc] = pc[0]; colorVals[plc+1] = pc[1];
notHaveValue &= ~CGO_COLOR_ARRAY; colorVals[plc+2] = pc[2]; colorVals[plc+3] = cgo->alpha;
notHaveValue &= ~CGO_COLOR_ARRAY;
}
break; break;
case CGO_PICK_COLOR: case CGO_PICK_COLOR:
cgo->current_pick_color_index = CGO_get_int(pc); CGOPickColor(cgo, CGO_get_uint(pc), CGO_get_int(pc + 1));
cgo->current_pick_color_bond = CGO_get_int(pc + 1);
notHaveValue &= ~CGO_PICK_COLOR_ARRAY; notHaveValue &= ~CGO_PICK_COLOR_ARRAY;
break; break;
case CGO_ACCESSIBILITY:
cgo->current_accessibility = pc[0];
break;
case CGO_VERTEX: case CGO_VERTEX:
if (notHaveValue & CGO_NORMAL_ARRAY){ if (notHaveValue & CGO_NORMAL_ARRAY){
tmp_ptr = &normalVals[pl-3]; if (pl){
normalVals[pl] = tmp_ptr[0]; normalVals[pl+1] = tmp_ptr[1]; norma tmp_ptr = &normalVals[pl-3];
lVals[pl+2] = tmp_ptr[2]; normalVals[pl] = tmp_ptr[0]; normalVals[pl+1] = tmp_ptr[1]; nor
malVals[pl+2] = tmp_ptr[2];
} else {
copy3f(cgo->normal, &normalVals[pl]);
}
} }
if (notHaveValue & CGO_COLOR_ARRAY){ if (notHaveValue & CGO_COLOR_ARRAY){
tmp_ptr = &colorVals[plc-4]; if (plc){
colorVals[plc] = tmp_ptr[0]; colorVals[plc+1] = tmp_ptr[1]; tmp_ptr = &colorVals[plc-4];
colorVals[plc+2] = tmp_ptr[2]; colorVals[plc+3] = tmp_ptr[3]; colorVals[plc] = tmp_ptr[0]; colorVals[plc+1] = tmp_ptr[1];
colorVals[plc+2] = tmp_ptr[2]; colorVals[plc+3] = tmp_pt
r[3];
} else {
copy3f(cgo->color, &colorVals[plc]);
colorVals[plc+3] = cgo->alpha;
}
} }
if (pickColorVals){ if (pickColorVals){
CGO_put_int(pickColorVals + pla * 2, cgo->current_pick_color_inde x); CGO_put_uint(pickColorVals + pla * 2, cgo->current_pick_color_ind ex);
CGO_put_int(pickColorVals + pla * 2 + 1, cgo->current_pick_color_ bond); CGO_put_int(pickColorVals + pla * 2 + 1, cgo->current_pick_color_ bond);
} }
if (accessibilityVals){
accessibilityVals[pla] = cgo->current_accessibility;
}
vertexVals[pl++] = pc[0]; vertexVals[pl++] = pc[1]; vertexVals[pl++ ] = pc[2]; vertexVals[pl++] = pc[0]; vertexVals[pl++] = pc[1]; vertexVals[pl++ ] = pc[2];
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:
I->alpha = *pc; cgo->alpha = *pc;
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;
} }
op = CGO_NULL; op = CGO_NULL;
} }
break; break;
case CGO_ALPHA: case CGO_ALPHA:
I->alpha = *pc; cgo->alpha = *pc;
default: default:
sz = CGO_sz[op]; cgo->add_to_cgo(op, pc);
nc = CGO_add(cgo, sz + 1); }
ok &= nc ? true : false; pc = save_pc;
if (!ok){ pc += CGO_sz[op];
break; ok &= !I->G->Interrupt;
}
if (ok){
ok &= CGOStop(cgo);
}
if (!ok){
CGOFree(cgo);
}
return (cgo);
}
/*
* converts a CGO that has primitives into pure geomtry, just like CGOSimplify
* but without converting the CGO_BEGIN/CGO_END blocks.
*
*/
CGO *CGOSimplifyNoCompress(const CGO * I, int est, short sphere_quality, bool st
ick_round_nub)
{
CGO *cgo;
float *pc = I->op;
int op = 0;
float *save_pc = NULL;
int ok = true;
if (sphere_quality < 0){
sphere_quality = SettingGet_i(I->G, NULL, NULL, cSetting_cgo_sphere_quality)
;
}
cgo = CGONewSized(I->G, I->c + est);
CHECKOK(ok, cgo);
while(ok && (op = (CGO_MASK & CGO_read_int(pc)))) {
save_pc = pc;
switch (op) {
case CGO_PICK_COLOR:
CGOPickColor(cgo, CGO_get_uint(pc), CGO_get_int(pc + 1));
break;
case CGO_SHADER_CYLINDER:
{
float v2[3];
int cap = CGO_get_int(pc + 7);
int fcap = (cap & 1) ? ((cap & cCylShaderCap1RoundBit) ? 2 : 1) : 0;
int bcap = (cap & 2) ? ((cap & cCylShaderCap2RoundBit) ? 2 : 1) : 0;
add3f(pc, pc + 3, v2);
ok &= CGOSimpleCylinder(cgo, pc, v2, *(pc + 6), 0, 0, (cap & cCylShaderI
nterpColor),
fcap, bcap, NULL, stick_round_nub);
}
break;
case CGO_SHADER_CYLINDER_WITH_2ND_COLOR:
{
float v1[3];
int cap = CGO_get_int(pc + 7);
int fcap = (cap & 1) ? ((cap & cCylShaderCap1RoundBit) ? 2 : 1) : 0;
int bcap = (cap & 2) ? ((cap & cCylShaderCap2RoundBit) ? 2 : 1) : 0;
Pickable pickcolor2 = { CGO_get_uint(pc + 11), CGO_get_int(pc + 12) };
float color1[3] = { cgo->color[0], cgo->color[1], cgo->color[2] };
add3f(pc, pc + 3, v1);
float mid[3];
mult3f(pc + 3, .5f, mid);
add3f(pc, mid, mid);
if (cap & cCylShaderInterpColor){
ok &= CGOSimpleCylinder(cgo, pc, v1, *(pc + 6), color1, pc+8, true, bc
ap, fcap, &pickcolor2, stick_round_nub);
} else {
ok &= CGOColorv(cgo, color1);
ok &= CGOSimpleCylinder(cgo, pc, mid, *(pc + 6), color1, NULL, false,
fcap, 0, NULL, stick_round_nub);
ok &= CGOColorv(cgo, pc+8);
ok &= CGOPickColor(cgo, pickcolor2.index, pickcolor2.bond);
ok &= CGOSimpleCylinder(cgo, mid, v1, *(pc + 6), pc+8, NULL, false, 0,
bcap, NULL, stick_round_nub);
}
} }
*(nc++) = *(pc - 1); break;
while(sz--) case CGO_CYLINDER:
*(nc++) = *(pc++); ok &= CGOSimpleCylinder(cgo, pc, pc + 3, *(pc + 6), pc + 7, pc + 10, true,
1, 1, NULL, stick_round_nub);
break;
case CGO_CONE:
ok &= CGOSimpleCone(cgo, pc, pc + 3, *(pc + 6), *(pc + 7), pc + 8, pc + 11
,
(int) *(pc + 14), (int) *(pc + 15));
break;
case CGO_SAUSAGE:
ok &= CGOSimpleCylinder(cgo, pc, pc + 3, *(pc + 6), pc + 7, pc + 10, true,
2, 2, NULL, stick_round_nub);
break;
case CGO_CUSTOM_CYLINDER:
ok &= CGOSimpleCylinder(cgo, pc, pc + 3, *(pc + 6), pc + 7, pc + 10, true,
(int) *(pc + 13),
(int) *(pc + 14), NULL, stick_round_nub);
break;
case CGO_SPHERE:
ok &= CGOSimpleSphere(cgo, pc, *(pc + 3), sphere_quality);
break;
case CGO_ELLIPSOID:
ok &= CGOSimpleEllipsoid(cgo, pc, *(pc + 3), pc + 4, pc + 7, pc + 10);
break;
case CGO_QUADRIC:
ok &= CGOSimpleQuadric(cgo, pc, *(pc + 3), pc + 4);
break;
case CGO_DRAW_BUFFERS_INDEXED:
PRINTFB(I->G, FB_CGO, FB_Errors) "CGOSimplifyNoCompress-Error: CGO_DRAW_B
UFFERS_INDEXED encountered\n" ENDFB(I->G);
break;
case CGO_DRAW_BUFFERS_NOT_INDEXED:
PRINTFB(I->G, FB_CGO, FB_Errors) "CGOSimplifyNoCompress-Error: CGO_DRAW_B
UFFERS_NOT_INDEXED encountered\n" ENDFB(I->G);
break;
case CGO_DRAW_SPHERE_BUFFERS:
PRINTFB(I->G, FB_CGO, FB_Errors) "CGOSimplifyNoCompress-Error: CGO_DRAW_
SPHERE_BUFFERS encountered\n" ENDFB(I->G);
break;
case CGO_DRAW_CYLINDER_BUFFERS:
PRINTFB(I->G, FB_CGO, FB_Errors) "CGOSimplifyNoCompress-Error: CGO_DRAW_
CYLINDER_BUFFERS encountered\n" ENDFB(I->G);
break;
case CGO_DRAW_LABELS:
PRINTFB(I->G, FB_CGO, FB_Errors) "CGOSimplifyNoCompress-Error: CGO_DRAW_L
ABELS encountered\n" ENDFB(I->G);
break;
case CGO_DRAW_TEXTURES:
PRINTFB(I->G, FB_CGO, FB_Errors) "CGOSimplifyNoCompress-Error: CGO_DRAW_T
EXTURES encountered\n" ENDFB(I->G);
break;
case CGO_BEGIN:
cgo->has_begin_end = true;
default:
cgo->add_to_cgo(op, pc);
} }
pc = save_pc; pc = save_pc;
pc += CGO_sz[op]; pc += CGO_sz[op];
ok &= !I->G->Interrupt; ok &= !I->G->Interrupt;
} }
if (ok){ if (ok){
ok &= CGOStop(cgo); ok &= CGOStop(cgo);
} }
if (!ok){ if (!ok){
CGOFree(cgo); CGOFree(cgo);
cgo = NULL;
} }
return (cgo); return (cgo);
} }
CGO *CGOOptimizeTextures(CGO * I, int est) CGO *CGOOptimizeTextures(CGO * I, int est)
{ {
CGO *cgo = NULL; CGO *cgo = NULL;
float *pc = I->op; float *pc = I->op;
int op; int op;
int num_total_textures; int num_total_textures;
skipping to change at line 5189 skipping to change at line 4553
FreeP(textExtents); FreeP(textExtents);
FreeP(screenValues); FreeP(screenValues);
FreeP(worldPos); FreeP(worldPos);
return NULL; return NULL;
} }
cgo = CGONewSized(I->G, 0); cgo = CGONewSized(I->G, 0);
while(ok && (op = (CGO_MASK & CGO_read_int(pc)))) { while(ok && (op = (CGO_MASK & CGO_read_int(pc)))) {
switch (op) { switch (op) {
case CGO_PICK_COLOR: case CGO_PICK_COLOR:
cgo->current_pick_color_index = CGO_get_int(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);
break; break;
case CGO_DRAW_ARRAYS:
{
int narrays = CGO_get_int(pc + 2), nverts = CGO_get_int(pc + 3), floatl
ength = narrays*nverts;
pc += floatlength + 4 ;
}
break;
case CGO_DRAW_BUFFERS_INDEXED: case CGO_DRAW_BUFFERS_INDEXED:
case CGO_DRAW_BUFFERS_NOT_INDEXED: case CGO_DRAW_BUFFERS_NOT_INDEXED:
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeTextures() CGO_DR AW_BUFFERS_INDEXED or CGO_DRAW_BUFFERS_INDEXED encountered op=%d\n", op ENDFB(I- >G); PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeTextures() CGO_DR AW_BUFFERS_INDEXED or CGO_DRAW_BUFFERS_INDEXED encountered op=%d\n", op ENDFB(I- >G);
break; break;
case CGO_DRAW_TEXTURE: case CGO_DRAW_TEXTURE:
{ {
float screenMin[3], screenMax[3], textExtent[4]; float screenMin[3], screenMax[3], textExtent[4];
copy3f(pc, &worldPos[place3]); copy3f(pc, &worldPos[place3]);
copy3f(pc, &worldPos[place3+3]); copy3f(pc, &worldPos[place3+3]);
copy3f(pc, &worldPos[place3+6]); copy3f(pc, &worldPos[place3+6]);
skipping to change at line 5226 skipping to change at line 4584
copy3f(screenMin, &screenValues[place3+6]); copy3f(screenMin, &screenValues[place3+6]);
copy3f(screenMin, &screenValues[place3+9]); copy3f(screenMin, &screenValues[place3+9]);
copy3f(screenMin, &screenValues[place3+12]); copy3f(screenMin, &screenValues[place3+12]);
copy3f(screenMax, &screenValues[place3+15]); copy3f(screenMax, &screenValues[place3+15]);
screenValues[place3+4] = screenMax[1]; screenValues[place3+4] = screenMax[1];
screenValues[place3+6] = screenMax[0]; screenValues[place3+6] = screenMax[0];
screenValues[place3+10] = screenMax[1]; screenValues[place3+10] = screenMax[1];
screenValues[place3+12] = screenMax[0]; screenValues[place3+12] = screenMax[0];
screenValues[place3+17] = screenMin[2]; screenValues[place3+17] = screenMin[2];
place3 += 18; place3 += 18;
CGO_put_int(pickColorVals + place2, cgo->current_pick_color_index); CGO_put_uint(pickColorVals + place2, cgo->current_pick_color_index);
CGO_put_int(pickColorVals + place2 + 1, cgo->current_pick_color_bond); CGO_put_int(pickColorVals + place2 + 1, cgo->current_pick_color_bond);
textExtents[place2++] = textExtent[0]; textExtents[place2++] = textExte nt[1]; textExtents[place2++] = textExtent[0]; textExtents[place2++] = textExte nt[1];
CGO_put_int(pickColorVals + place2, cgo->current_pick_color_index); CGO_put_uint(pickColorVals + place2, cgo->current_pick_color_index);
CGO_put_int(pickColorVals + place2 + 1, cgo->current_pick_color_bond); CGO_put_int(pickColorVals + place2 + 1, cgo->current_pick_color_bond);
textExtents[place2++] = textExtent[0]; textExtents[place2++] = textExte nt[3]; textExtents[place2++] = textExtent[0]; textExtents[place2++] = textExte nt[3];
CGO_put_int(pickColorVals + place2, cgo->current_pick_color_index); CGO_put_uint(pickColorVals + place2, cgo->current_pick_color_index);
CGO_put_int(pickColorVals + place2 + 1, cgo->current_pick_color_bond); CGO_put_int(pickColorVals + place2 + 1, cgo->current_pick_color_bond);
textExtents[place2++] = textExtent[2]; textExtents[place2++] = textExte nt[1]; textExtents[place2++] = textExtent[2]; textExtents[place2++] = textExte nt[1];
CGO_put_int(pickColorVals + place2, cgo->current_pick_color_index); CGO_put_int(pickColorVals + place2, cgo->current_pick_color_index);
CGO_put_int(pickColorVals + place2 + 1, cgo->current_pick_color_bond); CGO_put_uint(pickColorVals + place2 + 1, cgo->current_pick_color_bond);
textExtents[place2++] = textExtent[0]; textExtents[place2++] = textExte nt[3]; textExtents[place2++] = textExtent[0]; textExtents[place2++] = textExte nt[3];
CGO_put_int(pickColorVals + place2, cgo->current_pick_color_index); CGO_put_uint(pickColorVals + place2, cgo->current_pick_color_index);
CGO_put_int(pickColorVals + place2 + 1, cgo->current_pick_color_bond); CGO_put_int(pickColorVals + place2 + 1, cgo->current_pick_color_bond);
textExtents[place2++] = textExtent[2]; textExtents[place2++] = textExte nt[1]; textExtents[place2++] = textExtent[2]; textExtents[place2++] = textExte nt[1];
CGO_put_int(pickColorVals + place2, cgo->current_pick_color_index); CGO_put_uint(pickColorVals + place2, cgo->current_pick_color_index);
CGO_put_int(pickColorVals + place2 + 1, cgo->current_pick_color_bond); CGO_put_int(pickColorVals + place2 + 1, cgo->current_pick_color_bond);
textExtents[place2++] = textExtent[2]; textExtents[place2++] = textExte nt[3]; textExtents[place2++] = textExtent[2]; textExtents[place2++] = textExte nt[3];
} }
break; break;
} }
pc += CGO_sz[op]; pc += CGO_sz[op];
ok &= !I->G->Interrupt; ok &= !I->G->Interrupt;
} }
if (ok) { if (ok) {
uint bufs[3] = {0, 0, 0 }; VertexBuffer * vbo = I->G->ShaderMgr->newGPUBuffer<VertexBuffer>(VertexBuf
short bufpl = 0; fer::SEQUENTIAL);
GLenum err ; ok &= vbo->bufferData({
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeTextures() BEFORE glGenBuffers return BufferDesc( "attr_worldpos", GL_FLOAT, 3, sizeof(float) * num_total_te
s err=%d\n"); xtures * 18, worldPos, GL_FALSE ),
if (ok){ BufferDesc( "attr_screenoffset", GL_FLOAT, 3, sizeof(float) * num_tota
glGenBuffers(3, bufs); l_textures * 18, screenValues, GL_FALSE ),
} BufferDesc( "attr_texcoords", GL_FLOAT, 3, sizeof(float) * num_total_t
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeTextures() glGenBuffers returns err=% extures * 18, textExtents, GL_FALSE )
d\n"); });
if (ok) size_t vboid = vbo->get_hash_id();
glBindBuffer(GL_ARRAY_BUFFER, bufs[bufpl]);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeTextures() glBindBuffer returns err=%
d\n");
if (ok && !glIsBuffer(bufs[bufpl])){
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeTextures() glGenB
uffers created bad buffer bufpl=%d bufs[bufpl]=%d\n", bufpl, bufs[bufpl] ENDFB(I
->G);
ok = false;
} else if (ok) {
bufpl++;
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*num_total_textures*18, worldP
os, GL_STATIC_DRAW);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeTextures() glBufferData returns err=
%d\n");
}
if (ok)
glBindBuffer(GL_ARRAY_BUFFER, bufs[bufpl]);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeTextures() glBindBuffer returns err=%
d\n");
if (ok && !glIsBuffer(bufs[bufpl])){
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeTextures() glGenB
uffers created bad buffer bufpl=%d bufs[bufpl]=%d\n", bufpl, bufs[bufpl] ENDFB(I
->G);
ok = false;
} else if (ok){
bufpl++;
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*num_total_textures*18, screen
Values, GL_STATIC_DRAW);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeTextures() glBufferData returns err=
%d\n");
}
if (ok)
glBindBuffer(GL_ARRAY_BUFFER, bufs[bufpl]);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeTextures() glBindBuffer returns err=%
d\n");
if (ok && !glIsBuffer(bufs[bufpl])){
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeTextures() glGenB
uffers created bad buffer bufpl=%d bufs[bufpl]=%d\n", bufpl, bufs[bufpl] ENDFB(I
->G);
ok = false;
} else if (ok){
bufpl++;
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*num_total_textures*12, textEx
tents, GL_STATIC_DRAW);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeTextures() glBufferData returns err=
%d\n")
}
if (ok) { if (ok) {
float *pickArray = CGODrawTextures(cgo, num_total_textures, bufs); float *pickArray = cgo->add<cgo::draw::textures>(num_total_textures, vboi d);
CHECKOK(ok, pickArray); CHECKOK(ok, pickArray);
if (!pickArray) if (!pickArray)
CShaderMgr_AddVBOsToFree(I->G->ShaderMgr, bufs, 3); I->G->ShaderMgr->freeGPUBuffer(vboid);
if (ok) if (ok)
memcpy(pickArray + num_total_textures * 6, pickColorVals, num_total_tex tures * 12 * sizeof(float)); memcpy(pickArray + num_total_textures * 6, pickColorVals, num_total_tex tures * 12 * sizeof(float));
if (ok) if (ok)
ok &= CGOStop(cgo); ok &= CGOStop(cgo);
} else { } else {
CShaderMgr_AddVBOsToFree(I->G->ShaderMgr, bufs, 3); I->G->ShaderMgr->freeGPUBuffer(vboid);
} }
if (!ok){ if (!ok){
CGOFree(cgo); CGOFree(cgo);
cgo = NULL;
} }
} }
FreeP(worldPos); FreeP(worldPos);
FreeP(screenValues); FreeP(screenValues);
FreeP(textExtents); FreeP(textExtents);
FreeP(pickColorVals); FreeP(pickColorVals);
} }
return cgo; return cgo;
} }
CGO *CGOOptimizeLabels(CGO * I, int est) CGO *CGOConvertToLabelShader(const CGO *I, CGO * addTo){
/* Lines that pass in two vertices per line */
PyMOLGlobals *G = I->G;
AttribDataOp world_pos_op =
{ { CGO_DRAW_LABEL, 1, FLOAT3_TO_FLOAT3, offsetof(cgo::draw::label, wo
rld_pos), 0 } };
AttribDataOp screen_offset_op =
{ { CGO_DRAW_LABEL, 2, FLOAT3_TO_FLOAT3, offsetof(cgo::draw::label, sc
reen_world_offset), 0 } };
AttribDataOp screen_min_op =
{ { CGO_DRAW_LABEL, 3, FLOAT3_TO_FLOAT3, offsetof(cgo::draw::label, sc
reen_min), 0 } };
AttribDataOp screen_max_op =
{ { CGO_DRAW_LABEL, 4, FLOAT3_TO_FLOAT3, offsetof(cgo::draw::label, sc
reen_max), 0 } };
AttribDataOp text_extent_op =
{ { CGO_DRAW_LABEL, 5, FLOAT2_TO_FLOAT2, offsetof(cgo::draw::label, te
xt_extent), 0 } };
AttribDataOp relative_mode_op =
{ { CGO_DRAW_LABEL, 6, FLOAT_TO_FLOAT, offsetof(cgo::draw::label, re
lative_mode), 0 } };
AttribDataOp target_pos_op =
{ { 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 },
{ "attr_targetpos", GL_FLOAT, 3, GL_FALSE,
target_pos_op },
{ "attr_screenoffset", GL_FLOAT, 3, GL_FALSE,
screen_offset_op },
{ "attr_texcoords", GL_FLOAT, 2, GL_FALSE,
text_extent_op },
{ "attr_screenworldoffset", GL_FLOAT, 3, GL_FALSE,
screen_offset_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 sp = reinterpret_cast<const cgo::draw::label *>(pc);
const vec3 & smin = sp->screen_min;
const vec3 & smax = sp->screen_max;
float * v = reinterpret_cast<float *>(varData);
switch (idx) {
case 0:
v[0] = smin[0]; v[1] = smin[1]; v[2] = smin[2];
break;
case 1:
v[0] = smin[0]; v[1] = smax[1]; v[2] = smin[2];
break;
case 2:
v[0] = smax[0]; v[1] = smin[1]; v[2] = smin[2];
break;
case 3:
v[0] = smin[0]; v[1] = smax[1]; v[2] = smin[2];
break;
case 4:
v[0] = smax[0]; v[1] = smin[1]; v[2] = smin[2];
break;
case 5:
v[0] = smax[0]; v[1] = smax[1]; v[2] = smin[2];
break;
};
};
auto ComputeTexCoords = [](void * varData, const float * pc, void * discard, i
nt idx) {
auto sp = reinterpret_cast<const cgo::draw::label *>(pc);
float * v = reinterpret_cast<float *>(varData);
const vec4 & te = sp->text_extent;
static ivec2 idxs[6] = {
{ 0, 1 },
{ 0, 3 },
{ 2, 1 },
{ 0, 3 },
{ 2, 1 },
{ 2, 3 }
};
v[0] = te[idxs[idx].x];
v[1] = te[idxs[idx].y];
};
attrDesc[1].attrOps[0].funcDataConversions.push_back({ ComputeScreenValues, nu
llptr, "attr_screenoffset" });
attrDesc[1].attrOps[0].funcDataConversions.push_back({ ComputeTexCoords, nullp
tr, "attr_texcoords" });
uchar pickdata[4] = { 0, 0, 0, 0 };
addTo->add<cgo::draw::vertex_attribute_4ub>(G->ShaderMgr->GetAttributeUID("att
r_pickcolor"), pickdata);
AttribDataOp pickOp = { { CGO_PICK_COLOR, 1, UINT_INT_TO_PICK_DATA, 0, 0 } };
AttribDataDesc pickDesc = { { "attr_pickcolor", GL_UNSIGNED_BYTE, 4, GL_TRUE,
pickOp } };
return CGOConvertToShader(I, attrDesc, pickDesc, GL_TRIANGLES, VertexBuffer::I
NTERLEAVED, true);
}
CGO *CGOOptimizeLabels(CGO * I, int est, bool addshaders)
{ {
CGO *cgo = NULL; CGO *cgo = NULL;
float *pc = I->op; float *pc = I->op;
int op; int op;
int num_total_labels; int num_total_labels;
int ok = true; int ok = true;
num_total_labels = CGOCountNumberOfOperationsOfType(I, CGO_DRAW_LABEL); num_total_labels = CGOCountNumberOfOperationsOfType(I, CGO_DRAW_LABEL);
if (num_total_labels){ if (num_total_labels){
float *worldPos, *screenValues, *screenWorldValues, *textExtents, *pickColor float *targetPos, *worldPos, *screenValues, *screenWorldValues, *textExtents
Vals; , *pickColorVals;
int place3 = 0, place2 = 0; float *relativeMode;
worldPos = Alloc(float, num_total_labels * 18); int place3 = 0, place2 = 0, place = 0;
worldPos = Alloc(float, num_total_labels * 6 * 17);
if (!worldPos){ if (!worldPos){
PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeLabels() worldPos coul d not be allocated\n" ENDFB(I->G); PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeLabels() worldPos coul d not be allocated\n" ENDFB(I->G);
return NULL; return NULL;
} }
screenValues = Alloc(float, num_total_labels * 18); screenValues = worldPos + (num_total_labels * 18);
if (!screenValues){ targetPos = screenValues + (num_total_labels * 18);
PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeLabels() screenValues screenWorldValues = targetPos + (num_total_labels * 18);
could not be allocated\n" ENDFB(I->G); textExtents = screenWorldValues + (num_total_labels * 18);
FreeP(worldPos); pickColorVals = textExtents + (num_total_labels * 12); /* pick index and bon
return NULL; d */
} relativeMode = (float *)(pickColorVals + (num_total_labels * 12));
screenWorldValues = Alloc(float, num_total_labels * 18);
if (!screenWorldValues){
PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeLabels() screenWorldVa
lues could not be allocated\n" ENDFB(I->G);
FreeP(screenValues);
FreeP(worldPos);
return NULL;
}
textExtents = Alloc(float, num_total_labels * 12);
if (!textExtents){
PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeLabels() textExtents c
ould not be allocated\n" ENDFB(I->G);
FreeP(screenWorldValues);
FreeP(screenValues);
FreeP(worldPos);
return NULL;
}
pickColorVals = Alloc(float, num_total_labels * 12); /* pick index and bond
*/
if (!pickColorVals){
PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeLabels() pickColorVals
could not be allocated\n" ENDFB(I->G);
FreeP(screenWorldValues);
FreeP(textExtents);
FreeP(screenValues);
FreeP(worldPos);
return NULL;
}
cgo = CGONewSized(I->G, 0); cgo = CGONewSized(I->G, 0);
while(ok && (op = (CGO_MASK & CGO_read_int(pc)))) { while(ok && (op = (CGO_MASK & CGO_read_int(pc)))) {
switch (op) { switch (op) {
case CGO_PICK_COLOR: case CGO_PICK_COLOR:
cgo->current_pick_color_index = CGO_get_int(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);
break; break;
case CGO_DRAW_ARRAYS:
{
int narrays = CGO_get_int(pc + 2), nverts = CGO_get_int(pc + 3), floatl
ength = narrays*nverts;
pc += floatlength + 4 ;
}
break;
case CGO_DRAW_BUFFERS_INDEXED: case CGO_DRAW_BUFFERS_INDEXED:
case CGO_DRAW_BUFFERS_NOT_INDEXED: case CGO_DRAW_BUFFERS_NOT_INDEXED:
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeLabels() CGO_DRAW _BUFFERS_INDEXED or CGO_DRAW_BUFFERS_INDEXED encountered op=%d\n", op ENDFB(I->G ); PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeLabels() CGO_DRAW _BUFFERS_INDEXED or CGO_DRAW_BUFFERS_INDEXED encountered op=%d\n", op ENDFB(I->G );
break; break;
case CGO_DRAW_LABEL: case CGO_DRAW_LABEL:
{ {
float screenWorldOffset[3], screenMin[3], screenMax[3], textExtent[4]; float screenWorldOffset[3], screenMin[3], screenMax[3], textExtent[4];
copy3f(pc, &worldPos[place3]); copy3f(pc, &worldPos[place3]);
copy3f(pc, &worldPos[place3+3]); copy3f(pc, &worldPos[place3+3]);
copy3f(pc, &worldPos[place3+6]); copy3f(pc, &worldPos[place3+6]);
copy3f(pc, &worldPos[place3+9]); copy3f(pc, &worldPos[place3+9]);
copy3f(pc, &worldPos[place3+12]); copy3f(pc, &worldPos[place3+12]);
copy3f(pc, &worldPos[place3+15]); copy3f(pc, &worldPos[place3+15]);
copy3f(pc + 3, screenWorldOffset); copy3f(pc + 3, screenWorldOffset);
copy3f(pc + 6, screenMin); copy3f(pc + 6, screenMin);
copy3f(pc + 9, screenMax); copy3f(pc + 9, screenMax);
copy4f(pc + 12, textExtent); copy4f(pc + 12, textExtent);
copy3f(screenWorldOffset, &screenWorldValues[place3]); copy3f(screenWorldOffset, &screenWorldValues[place3]);
copy3f(screenWorldValues, &screenWorldValues[place3+3]); copy3f(&screenWorldValues[place3], &screenWorldValues[place3+3]);
copy3f(screenWorldValues, &screenWorldValues[place3+6]); copy3f(&screenWorldValues[place3], &screenWorldValues[place3+6]);
copy3f(screenWorldValues, &screenWorldValues[place3+9]); copy3f(&screenWorldValues[place3], &screenWorldValues[place3+9]);
copy3f(screenWorldValues, &screenWorldValues[place3+12]); copy3f(&screenWorldValues[place3], &screenWorldValues[place3+12]);
copy3f(screenWorldValues, &screenWorldValues[place3+15]); copy3f(&screenWorldValues[place3], &screenWorldValues[place3+15]);
copy3f(screenMin, &screenValues[place3]); copy3f(screenMin, &screenValues[place3]);
copy3f(screenMin, &screenValues[place3+3]); copy3f(screenMin, &screenValues[place3+3]);
copy3f(screenMin, &screenValues[place3+6]); copy3f(screenMin, &screenValues[place3+6]);
copy3f(screenMin, &screenValues[place3+9]); copy3f(screenMin, &screenValues[place3+9]);
copy3f(screenMin, &screenValues[place3+12]); copy3f(screenMin, &screenValues[place3+12]);
copy3f(screenMax, &screenValues[place3+15]); copy3f(screenMax, &screenValues[place3+15]);
screenValues[place3+4] = screenMax[1]; screenValues[place3+4] = screenMax[1];
screenValues[place3+6] = screenMax[0]; screenValues[place3+6] = screenMax[0];
screenValues[place3+10] = screenMax[1]; screenValues[place3+10] = screenMax[1];
screenValues[place3+12] = screenMax[0]; screenValues[place3+12] = screenMax[0];
screenValues[place3+17] = screenMin[2]; screenValues[place3+17] = screenMin[2];
copy3f(pc + 17, &targetPos[place3]);
copy3f(pc + 17, &targetPos[place3+3]);
copy3f(pc + 17, &targetPos[place3+6]);
copy3f(pc + 17, &targetPos[place3+9]);
copy3f(pc + 17, &targetPos[place3+12]);
copy3f(pc + 17, &targetPos[place3+15]);
place3 += 18; place3 += 18;
CGO_put_int(pickColorVals + place2, cgo->current_pick_color_index); CGO_put_uint(pickColorVals + place2, cgo->current_pick_color_index);
CGO_put_int(pickColorVals + place2 + 1, cgo->current_pick_color_bond); CGO_put_int(pickColorVals + place2 + 1, cgo->current_pick_color_bond);
// screenWorldValues[place2] = screenWorldOffset[0]; screenWorldVa lues[place2+1] = screenWorldOffset[1];
textExtents[place2++] = textExtent[0]; textExtents[place2++] = textExte nt[1]; textExtents[place2++] = textExtent[0]; textExtents[place2++] = textExte nt[1];
CGO_put_int(pickColorVals + place2, cgo->current_pick_color_index); CGO_put_uint(pickColorVals + place2, cgo->current_pick_color_index);
CGO_put_int(pickColorVals + place2 + 1, cgo->current_pick_color_bond); CGO_put_int(pickColorVals + place2 + 1, cgo->current_pick_color_bond);
// screenWorldValues[place2] = screenWorldOffset[0]; screenWorldVa lues[place2+1] = screenWorldOffset[1];
textExtents[place2++] = textExtent[0]; textExtents[place2++] = textExte nt[3]; textExtents[place2++] = textExtent[0]; textExtents[place2++] = textExte nt[3];
CGO_put_int(pickColorVals + place2, cgo->current_pick_color_index); CGO_put_uint(pickColorVals + place2, cgo->current_pick_color_index);
CGO_put_int(pickColorVals + place2 + 1, cgo->current_pick_color_bond); CGO_put_int(pickColorVals + place2 + 1, cgo->current_pick_color_bond);
// screenWorldValues[place2] = screenWorldOffset[0]; screenWorldVa lues[place2+1] = screenWorldOffset[1];
textExtents[place2++] = textExtent[2]; textExtents[place2++] = textExte nt[1]; textExtents[place2++] = textExtent[2]; textExtents[place2++] = textExte nt[1];
CGO_put_int(pickColorVals + place2, cgo->current_pick_color_index); CGO_put_uint(pickColorVals + place2, cgo->current_pick_color_index);
CGO_put_int(pickColorVals + place2 + 1, cgo->current_pick_color_bond); CGO_put_int(pickColorVals + place2 + 1, cgo->current_pick_color_bond);
// screenWorldValues[place2] = screenWorldOffset[0]; screenWorldVa lues[place2+1] = screenWorldOffset[1];
textExtents[place2++] = textExtent[0]; textExtents[place2++] = textExte nt[3]; textExtents[place2++] = textExtent[0]; textExtents[place2++] = textExte nt[3];
CGO_put_int(pickColorVals + place2, cgo->current_pick_color_index); CGO_put_uint(pickColorVals + place2, cgo->current_pick_color_index);
CGO_put_int(pickColorVals + place2 + 1, cgo->current_pick_color_bond); CGO_put_int(pickColorVals + place2 + 1, cgo->current_pick_color_bond);
// screenWorldValues[place2] = screenWorldOffset[0]; screenWorldVa lues[place2+1] = screenWorldOffset[1];
textExtents[place2++] = textExtent[2]; textExtents[place2++] = textExte nt[1]; textExtents[place2++] = textExtent[2]; textExtents[place2++] = textExte nt[1];
CGO_put_int(pickColorVals + place2, cgo->current_pick_color_index); CGO_put_uint(pickColorVals + place2, cgo->current_pick_color_index);
CGO_put_int(pickColorVals + place2 + 1, cgo->current_pick_color_bond); CGO_put_int(pickColorVals + place2 + 1, cgo->current_pick_color_bond);
// screenWorldValues[place2] = screenWorldOffset[0]; screenWorldVa lues[place2+1] = screenWorldOffset[1];
textExtents[place2++] = textExtent[2]; textExtents[place2++] = textExte nt[3]; textExtents[place2++] = textExtent[2]; textExtents[place2++] = textExte nt[3];
{
uchar rM = (uchar)*(pc + 16);
relativeMode[place++] = rM;
relativeMode[place++] = rM;
relativeMode[place++] = rM;
relativeMode[place++] = rM;
relativeMode[place++] = rM;
relativeMode[place++] = rM;
}
} }
break; break;
} }
pc += CGO_sz[op]; pc += CGO_sz[op];
ok &= !I->G->Interrupt; ok &= !I->G->Interrupt;
} }
if (ok) { if (ok) {
uint bufs[4] = {0, 0, 0, 0 }; // Static Vertex Data
short bufpl = 0; VertexBuffer * vbo = I->G->ShaderMgr->newGPUBuffer<VertexBuffer>(VertexBuf
GLenum err ; fer::SEQUENTIAL);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeLabels() BEFORE glGenBuffers returns ok &= vbo->bufferData({
err=%d\n"); BufferDesc( "attr_worldpos", GL_FLOAT, 3, sizeof(float)*18*num_total_l
if (ok){ abels, worldPos, GL_FALSE ),
glGenBuffers(4, bufs); BufferDesc( "attr_targetpos", GL_FLOAT, 3, sizeof(float)*18*num_total_
} labels, targetPos, GL_FALSE ),
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeLabels() glGenBuffers returns err=%d\ BufferDesc( "attr_screenoffset", GL_FLOAT, 3, sizeof(float)*18*num_tot
n"); al_labels, screenValues, GL_FALSE ),
if (ok) BufferDesc( "attr_texcoords", GL_FLOAT, 2, sizeof(float)*12*num_total_
glBindBuffer(GL_ARRAY_BUFFER, bufs[bufpl]); labels, textExtents, GL_FALSE ),
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeLabels() glBindBuffer returns err=%d\ BufferDesc( "attr_screenworldoffset", GL_FLOAT, 3, sizeof(float)*18*nu
n"); m_total_labels, screenWorldValues, GL_FALSE ),
BufferDesc( "attr_relative_mode", GL_FLOAT, 1, sizeof(float)*6*num_tot
if (ok && !glIsBuffer(bufs[bufpl])){ al_labels, relativeMode, GL_FALSE )
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeLabels() glGenBuf });
fers created bad buffer bufpl=%d bufs[bufpl]=%d\n", bufpl, bufs[bufpl] ENDFB(I-> size_t vboid = vbo->get_hash_id();
G);
ok = false; VertexBuffer * pickvbo = I->G->ShaderMgr->newGPUBuffer<VertexBuffer>(Verte
} else if (ok) { xBuffer::SEQUENTIAL, GL_DYNAMIC_DRAW);
bufpl++; ok &= pickvbo->bufferData({
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*num_total_labels*18, worldPos BufferDesc( "attr_pickcolor", GL_UNSIGNED_BYTE, VERTEX_COLOR_SIZE, 0,
, GL_STATIC_DRAW); GL_TRUE ),
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeLabels() glBufferData returns err=%d BufferDesc( "attr_pickcolor", GL_UNSIGNED_BYTE, VERTEX_COLOR_SIZE, siz
\n"); eof(float) * num_total_labels * 6, GL_TRUE )
} }, 0, sizeof(float) * num_total_labels * 12, 0);
size_t pickvboid = pickvbo->get_hash_id();
if (ok)
glBindBuffer(GL_ARRAY_BUFFER, bufs[bufpl]); auto freebuffers = [vboid, pickvboid, I]() {
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeLabels() glBindBuffer returns err=%d\ I->G->ShaderMgr->freeGPUBuffer(vboid);
n"); I->G->ShaderMgr->freeGPUBuffer(pickvboid);
if (ok && !glIsBuffer(bufs[bufpl])){ };
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeTextures() glGenB
uffers created bad buffer bufpl=%d bufs[bufpl]=%d\n", bufpl, bufs[bufpl] ENDFB(I
->G);
ok = false;
} else if (ok){
bufpl++;
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*num_total_labels*18, screenVa
lues, GL_STATIC_DRAW);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeLabels() glBufferData returns err=%d
\n");
}
if (ok)
glBindBuffer(GL_ARRAY_BUFFER, bufs[bufpl]);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeLabels() glBindBuffer returns err=%d\
n");
if (ok && !glIsBuffer(bufs[bufpl])){
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeLabels() glGenBuf
fers created bad buffer bufpl=%d bufs[bufpl]=%d\n", bufpl, bufs[bufpl] ENDFB(I->
G);
ok = false;
} else if (ok){
bufpl++;
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*num_total_labels*12, textExte
nts, GL_STATIC_DRAW);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeLabels() glBufferData returns err=%d
\n")
}
if (ok)
glBindBuffer(GL_ARRAY_BUFFER, bufs[bufpl]);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeLabels() glBindBuffer returns err=%d\
n");
if (ok && !glIsBuffer(bufs[bufpl])){
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeTextures() glGenB
uffers created bad buffer bufpl=%d bufs[bufpl]=%d\n", bufpl, bufs[bufpl] ENDFB(I
->G);
ok = false;
} else if (ok){
bufpl++;
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*num_total_labels*18, screenWo
rldValues, GL_STATIC_DRAW);
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeLabels() glBufferData returns err=%d
\n")
}
if (ok) { if (ok) {
float *pickArray = CGODrawLabels(cgo, num_total_labels, bufs); float *pickArray = NULL;
if (addshaders){
CGOEnable(cgo, GL_LABEL_SHADER);
}
pickArray = cgo->add<cgo::draw::labels>(num_total_labels, vboid, pickvboi
d);
if (addshaders){
CGODisable(cgo, GL_LABEL_SHADER);
}
CHECKOK(ok, pickArray); CHECKOK(ok, pickArray);
if (!pickArray) if (!pickArray) {
CShaderMgr_AddVBOsToFree(I->G->ShaderMgr, bufs, 4); freebuffers();
}
if (ok) if (ok)
memcpy(pickArray + num_total_labels * 6, pickColorVals, num_total_label s * 12 * sizeof(float)); memcpy(pickArray + num_total_labels * 6, pickColorVals, num_total_label s * 12 * sizeof(float));
if (ok) if (ok)
ok &= CGOStop(cgo); ok &= CGOStop(cgo);
} else { } else {
CShaderMgr_AddVBOsToFree(I->G->ShaderMgr, bufs, 4); freebuffers();
} }
if (!ok){ if (!ok){
CGOFree(cgo); CGOFree(cgo);
cgo = NULL;
} }
} }
FreeP(worldPos); FreeP(worldPos);
FreeP(screenWorldValues);
FreeP(screenValues);
FreeP(textExtents);
FreeP(pickColorVals);
} }
return cgo; return cgo;
} }
CGO *CGOExpandDrawTextures(CGO * I, int est) CGO *CGOOptimizeConnectors(CGO * I, int est)
{ {
CGO *cgo = NULL; CGO *cgo = NULL;
float *pc = I->op, *nc = NULL; float *pc = I->op;
int op = 0; int op;
int num_total_connectors;
int ok = true; int ok = true;
int sz = 0; int use_geometry_shaders = SettingGetGlobal_b(I->G, cSetting_use_geometry_shad
ers);
int factor = (use_geometry_shaders ? 1 : 4);
num_total_connectors = CGOCountNumberOfOperationsOfType(I, CGO_DRAW_CONNECTOR)
;
if (num_total_connectors){
float *targetPt3d, *labelCenterPt3d, *indentFactor, *screenWorldOffset, *con
nectorColor, *textSize;
float *bkgrdColor, *relExtLength, *connectorWidth;
uchar *relativeMode, *drawBkgrd;
uchar *isCenterPt = NULL;
int place3 = 0, place2 = 0, place = 0;
targetPt3d = Calloc(float, num_total_connectors * 20 * factor); /* too much,
relativeMode only needs 1 byte per vertex, instead of 1 float */
if (!targetPt3d){
PRINTFB(I->G, FB_CGO, FB_Errors) "ERROR: CGOOptimizeConnectors() could not
be allocated\n" ENDFB(I->G);
return NULL;
}
labelCenterPt3d = targetPt3d + (num_total_connectors*3 * factor);
indentFactor = labelCenterPt3d + (num_total_connectors*3 * factor);
screenWorldOffset = indentFactor + (num_total_connectors*2 * factor);
connectorColor = screenWorldOffset + (num_total_connectors*3 * factor);
textSize = connectorColor + (num_total_connectors*factor);
relativeMode = (uchar *)(textSize + (num_total_connectors*2*factor));
drawBkgrd = (uchar *)(relativeMode + (num_total_connectors*factor));
bkgrdColor = (float*)(drawBkgrd + (num_total_connectors*factor));
relExtLength = (float*)(bkgrdColor + (num_total_connectors*factor));
connectorWidth = (float*)(relExtLength + (num_total_connectors*factor));
if (!use_geometry_shaders)
isCenterPt = (uchar *)(connectorWidth + (num_total_connectors*factor));
else
isCenterPt = nullptr;
cgo = CGONewSized(I->G, 0);
cgo = CGONew(I->G); while(ok && (op = (CGO_MASK & CGO_read_int(pc)))) {
while(ok && (op = (CGO_MASK & CGO_read_int(pc)))) { switch (op) {
switch (op) { case CGO_PICK_COLOR:
case CGO_PICK_COLOR: cgo->current_pick_color_index = CGO_get_uint(pc);
cgo->current_pick_color_index = CGO_get_int(pc); cgo->current_pick_color_bond = CGO_get_int(pc + 1);
cgo->current_pick_color_bond = CGO_get_int(pc + 1); break;
break; case CGO_DRAW_BUFFERS_INDEXED:
case CGO_DRAW_ARRAYS: case CGO_DRAW_BUFFERS_NOT_INDEXED:
{ PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeConnectors() CGO_
int mode = CGO_get_int(pc), arrays = CGO_get_int(pc + 1), narrays = CGO_g DRAW_BUFFERS_INDEXED or CGO_DRAW_BUFFERS_INDEXED encountered op=%d\n", op ENDFB(
et_int(pc + 2), nverts = CGO_get_int(pc + 3); I->G);
int nvals = narrays*nverts, onvals; break;
GLfloat *vals = CGODrawArrays(cgo, mode, arrays, nverts); case CGO_DRAW_CONNECTOR:
CHECKOK(ok, vals); {
if (ok){ uchar *uc;
onvals = nvals; int f;
pc += 4; if (!use_geometry_shaders){
while(nvals--) isCenterPt[place] = 0; isCenterPt[place+1] = 2; isCenterPt[place+2]
*(vals++) = *(pc++); = 2; isCenterPt[place+3] = 1;
}
copy3f(pc, &targetPt3d[place3]);
copy3f(pc + 3, &labelCenterPt3d[place3]);
copy2f(pc + 6, &indentFactor[place2]);
copy3f(pc + 9, &screenWorldOffset[place3]);
copy2f(pc + 12, &textSize[place2]);
relativeMode[place] = (uchar)(int)pc[17];
drawBkgrd[place] = (uchar)(int)pc[18];
uc = (uchar *)&bkgrdColor[place];
uc[0] = CLIP_COLOR_VALUE(*(pc+19));
uc[1] = CLIP_COLOR_VALUE(*(pc+20));
uc[2] = CLIP_COLOR_VALUE(*(pc+21));
uc[3] = CLIP_COLOR_VALUE(*(pc+22));
uc = (uchar *)&connectorColor[place];
uc[0] = CLIP_COLOR_VALUE(*(pc+14));
uc[1] = CLIP_COLOR_VALUE(*(pc+15));
uc[2] = CLIP_COLOR_VALUE(*(pc+16));
uc[3] = 255;
relExtLength[place] = *(pc + 8);
connectorWidth[place] = *(pc + 23);
place3 += 3; place2 += 2; place += 1;
for (f=1;f<factor; f++){
copy3f(pc, &targetPt3d[place3]);
copy3f(pc + 3, &labelCenterPt3d[place3]);
copy2f(pc + 6, &indentFactor[place2]);
copy3f(pc + 9, &screenWorldOffset[place3]);
copy2f(pc + 12, &textSize[place2]);
relativeMode[place] = (uchar)(int)pc[17];
drawBkgrd[place] = (uchar)(int)pc[18];
relExtLength[place] = *(pc + 8);
connectorWidth[place] = *(pc + 23);
uc = (uchar *)&bkgrdColor[place];
uc[0] = uc[-4];
uc[1] = uc[-3];
uc[2] = uc[-2];
uc[3] = uc[-1];
uc = (uchar *)&connectorColor[place];
uc[0] = uc[-4];
uc[1] = uc[-3];
uc[2] = uc[-2];
uc[3] = uc[-1];
place3 += 3; place2 += 2; place += 1;
}
} }
break;
} }
break; pc += CGO_sz[op];
case CGO_DRAW_BUFFERS_INDEXED: ok &= !I->G->Interrupt;
case CGO_DRAW_BUFFERS_NOT_INDEXED: }
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeTextures() CGO_DRA if (ok) {
W_BUFFERS_INDEXED or CGO_DRAW_BUFFERS_INDEXED encountered op=%d\n", op ENDFB(I-> const size_t quant = factor * num_total_connectors;
G); VertexBuffer * vbo = I->G->ShaderMgr->newGPUBuffer<VertexBuffer>();
break; ok = vbo->bufferData({
case CGO_DRAW_TEXTURE: BufferDesc( "a_target_pt3d", GL_FLOAT, 3, sizeof(float) * 3 * qu
{ ant, targetPt3d, GL_FALSE ),
float screenMin[3], screenMax[3], textExtent[4]; BufferDesc( "a_center_pt3d", GL_FLOAT, 3, sizeof(float) * 3 * qu
float alpha = cgo->alpha; ant, labelCenterPt3d, GL_FALSE ),
CGOAlpha(cgo, 0.f); BufferDesc( "a_indentFactor", GL_FLOAT, 2, sizeof(float) * 2 * qu
CGOColor(cgo, 0.f,0.f,0.f); ant, indentFactor, GL_FALSE ),
copy3f(pc + 3, screenMin); BufferDesc( "a_screenWorldOffset", GL_FLOAT, 3, sizeof(float) * 3 * qu
copy3f(pc + 6, screenMax); ant, screenWorldOffset, GL_FALSE ),
copy4f(pc + 9, textExtent); BufferDesc( "a_textSize", GL_FLOAT, 2, sizeof(float) * 2 * qu
CGOBegin(cgo, GL_TRIANGLES); ant, textSize, GL_FALSE ),
CGOTexCoord2f(cgo, textExtent[0], textExtent[1]); BufferDesc( "a_Color", GL_UNSIGNED_BYTE, 4, sizeof(float)
CGOVertexv(cgo, screenMin); * quant, connectorColor, GL_TRUE ),
CGOTexCoord2f(cgo, textExtent[0], textExtent[3]); BufferDesc( "a_relative_mode", GL_UNSIGNED_BYTE, 1, sizeof(uchar)
* quant, relativeMode, GL_FALSE ),
BufferDesc( "a_draw_flags", GL_UNSIGNED_BYTE, 1, sizeof(uchar)
* quant, drawBkgrd, GL_FALSE ),
BufferDesc( "a_bkgrd_color", GL_UNSIGNED_BYTE, 4, sizeof(float)
* quant, bkgrdColor, GL_TRUE ),
BufferDesc( "a_rel_ext_length", GL_FLOAT, 1, sizeof(float) * quant,
relExtLength, GL_FALSE ),
BufferDesc( "a_con_width", GL_FLOAT, 1, sizeof(float) * quant,
connectorWidth, GL_FALSE ),
BufferDesc( "a_isCenterPt", GL_UNSIGNED_BYTE, 1, sizeof(uchar)
* quant, isCenterPt, GL_FALSE )
});
size_t vboid = vbo->get_hash_id();
if (ok) {
cgo->add<cgo::draw::connectors>(num_total_connectors, vboid);
if (ok)
ok &= CGOStop(cgo);
}
if (!ok){
I->G->ShaderMgr->freeGPUBuffer(vboid);
CGOFree(cgo);
}
}
FreeP(targetPt3d);
}
{
GLenum err ;
CHECK_GL_ERROR_OK("ERROR: CGOOptimizeConnectors() end returns err=%d\n");
}
return cgo;
}
CGO *CGOExpandDrawTextures(const CGO * I, int est)
{
CGO *cgo = CGONew(I->G);
int ok = true;
for (auto it = I->begin(); ok && !it.is_stop(); ++it) {
auto pc = it.data();
int op = it.op_code();
switch (op) {
case CGO_PICK_COLOR:
cgo->current_pick_color_index = CGO_get_uint(pc);
cgo->current_pick_color_bond = CGO_get_int(pc + 1);
break;
case CGO_DRAW_BUFFERS_INDEXED:
case CGO_DRAW_BUFFERS_NOT_INDEXED:
PRINTFB(I->G, FB_CGO, FB_Warnings) "WARNING: CGOOptimizeTextures() CGO_DRA
W_BUFFERS_INDEXED or CGO_DRAW_BUFFERS_INDEXED encountered op=%d\n", op ENDFB(I->
G);
break;
case CGO_DRAW_TEXTURE:
{
float screenMin[3], screenMax[3], textExtent[4];
float alpha = cgo->alpha;
CGOAlpha(cgo, 0.f);
CGOColor(cgo, 0.f,0.f,0.f);
copy3f(pc + 3, screenMin);
copy3f(pc + 6, screenMax);
copy4f(pc + 9, textExtent);
CGOBegin(cgo, GL_TRIANGLES);
CGOTexCoord2f(cgo, textExtent[0], textExtent[1]);
CGOVertexv(cgo, screenMin);
CGOTexCoord2f(cgo, textExtent[0], textExtent[3]);
CGOVertex(cgo, screenMin[0], screenMax[1], screenMin[2]); CGOVertex(cgo, screenMin[0], screenMax[1], screenMin[2]);
CGOTexCoord2f(cgo, textExtent[2], textExtent[1]); CGOTexCoord2f(cgo, textExtent[2], textExtent[1]);
CGOVertex(cgo, screenMax[0], screenMin[1], screenMin[2]); CGOVertex(cgo, screenMax[0], screenMin[1], screenMin[2]);
CGOTexCoord2f(cgo, textExtent[0], textExtent[3]); CGOTexCoord2f(cgo, textExtent[0], textExtent[3]);
CGOVertex(cgo, screenMin[0], screenMax[1], screenMin[2]); CGOVertex(cgo, screenMin[0], screenMax[1], screenMin[2]);
CGOTexCoord2f(cgo, textExtent[2], textExtent[1]); CGOTexCoord2f(cgo, textExtent[2], textExtent[1]);
CGOVertex(cgo, screenMax[0], screenMin[1], screenMin[2]); CGOVertex(cgo, screenMax[0], screenMin[1], screenMin[2]);
CGOTexCoord2f(cgo, textExtent[2], textExtent[3]); CGOTexCoord2f(cgo, textExtent[2], textExtent[3]);
CGOVertex(cgo, screenMax[0], screenMax[1], screenMin[2]); CGOVertex(cgo, screenMax[0], screenMax[1], screenMin[2]);
CGOEnd(cgo); CGOEnd(cgo);
CGOAlpha(cgo, alpha); CGOAlpha(cgo, alpha);
pc += CGO_DRAW_TEXTURE_SZ;
} }
break; break;
case CGO_ALPHA:
I->alpha = *pc;
default: default:
sz = CGO_sz[op]; cgo->add_to_cgo(op, pc);
nc = CGO_add(cgo, sz + 1);
CHECKOK(ok, nc);
if (!ok){
break;
}
*(nc++) = *(pc - 1);
while(sz--)
*(nc++) = *(pc++);
} }
ok &= !I->G->Interrupt; ok &= !I->G->Interrupt;
} }
CGOStop(cgo); CGOStop(cgo);
return cgo; return cgo;
} }
/* ======== Raytrace Renderer ======== */ /* ======== Raytrace Renderer ======== */
int CGOGetExtent(CGO * I, float *mn, float *mx) int CGOGetExtent(CGO * I, float *mn, float *mx)
skipping to change at line 5675 skipping to change at line 5141
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:
{ {
int arrays = CGO_get_int(pc + 1), narrays = CGO_get_int(pc + 2), nverts = cgo::draw::arrays * sp = reinterpret_cast<decltype(sp)>(pc);
CGO_get_int(pc + 3), pl; float *pct = sp->floatdata;
float *pct = pc + 4; int pl;
int nvals = narrays*nverts;
if (arrays & CGO_VERTEX_ARRAY){ if (sp->arraybits & CGO_VERTEX_ARRAY){
for (pl = 0; pl < nverts; pl++){ for (pl = 0; pl < sp->nverts; pl++){
check_extent(pct, 0); check_extent(pct, 0);
pct += 3; pct += 3;
} }
} }
if (arrays & CGO_NORMAL_ARRAY){ if (sp->arraybits & CGO_NORMAL_ARRAY){
for (pl = 0; pl < nverts; pl++){ for (pl = 0; pl < sp->nverts; pl++){
pct += 3; pct += 3;
} }
} }
if (arrays & CGO_COLOR_ARRAY){ if (sp->arraybits & CGO_COLOR_ARRAY){
for (pl = 0; pl < nverts; pl++){ for (pl = 0; pl < sp->nverts; pl++){
pct += 4; pct += 4;
} }
} }
if (arrays & CGO_PICK_COLOR_ARRAY){ if (sp->arraybits & CGO_PICK_COLOR_ARRAY){
for (pl = 0; pl < nverts; pl++){ for (pl = 0; pl < sp->nverts; pl++){
pct += 3; pct += 3;
} }
} }
pc += nvals + 4;
}
break;
case CGO_DRAW_BUFFERS_INDEXED:
{
int nverts = CGO_get_int(pc + 4);
pc += nverts*3 + 10 ;
}
break;
case CGO_DRAW_BUFFERS_NOT_INDEXED:
{
int nverts = CGO_get_int(pc + 3);
pc += nverts*3 + 8 ;
}
break;
case CGO_DRAW_TEXTURES:
{
int ntextures = CGO_get_int(pc);
pc += ntextures * 18 + 4;
}
break;
case CGO_DRAW_LABELS:
{
int nlabels = CGO_get_int(pc);
pc += nlabels * 18 + 5;
} }
break; break;
case CGO_BOUNDING_BOX: case CGO_BOUNDING_BOX:
{ {
if (!result){ if (!result){
mn[0]=(*pc); mn[0]=(*pc);
mn[1]=*(pc+1); mn[1]=*(pc+1);
mn[2]=*(pc+2); mn[2]=*(pc+2);
mx[0]=*(pc+3); mx[0]=*(pc+3);
mx[1]=*(pc+4); mx[1]=*(pc+4);
skipping to change at line 5771 skipping to change at line 5212
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:
result |= 1; result |= 1;
break; break;
case CGO_DRAW_ARRAYS: case CGO_DRAW_ARRAYS:
{ {
int arrays = CGO_get_int(pc + 1), narrays = CGO_get_int(pc + 2), nverts = cgo::draw::arrays * sp = reinterpret_cast<decltype(sp)>(pc);
CGO_get_int(pc + 3); if (sp->arraybits & CGO_NORMAL_ARRAY){
int nvals = narrays*nverts;
if (arrays & CGO_NORMAL_ARRAY){
result |= 1; result |= 1;
} }
pc += nvals + 4;
}
break;
case CGO_DRAW_BUFFERS_INDEXED:
{
int nverts = CGO_get_int(pc + 4);
pc += nverts*3 + 10 ;
}
break;
case CGO_DRAW_BUFFERS_NOT_INDEXED:
{
int nverts = CGO_get_int(pc + 3);
pc += nverts*3 + 8 ;
}
break;
case CGO_DRAW_TEXTURES:
{
int ntextures = CGO_get_int(pc);
pc += ntextures * 18 + 4;
}
break;
case CGO_DRAW_LABELS:
{
int nlabels = CGO_get_int(pc);
pc += nlabels * 18 + 5;
} }
break; break;
} }
pc += CGO_sz[op]; pc += CGO_sz[op];
} }
return (result); return (result);
} }
static int CGOQuadricToEllipsoid(float *v, float r, float *q, static int CGOQuadricToEllipsoid(float *v, float r, float *q,
float *r_el, float *n0, float *n1, float *n2) float *r_el, float *n0, float *n1, float *n2)
skipping to change at line 5894 skipping to change at line 5309
{ {
float r_el, n0[3], n1[3], n2[3]; float r_el, n0[3], n1[3], n2[3];
int ok = true; int ok = true;
if(CGOQuadricToEllipsoid(v, r, q, &r_el, n0, n1, n2)) if(CGOQuadricToEllipsoid(v, r, q, &r_el, n0, n1, n2))
ok &= ray->ellipsoid3fv(v, r_el, n0, n1, n2); ok &= ray->ellipsoid3fv(v, r_el, n0, n1, n2);
return ok; return ok;
} }
/* ======== Raytrace Renderer ======== */ /* ======== Raytrace Renderer ======== */
int CGORenderRay(CGO * I, CRay * ray, const float *color, CSetting * set1, CSett ing * set2) int CGORenderRay(CGO * I, CRay * ray, RenderInfo * info, const float *color, Obj ectGadgetRamp *ramp, CSetting * set1, CSetting * set2)
{ {
#ifdef _PYMOL_NO_RAY
return 0;
#else
float *pc; float *pc;
int op; int op;
int vc = 0; int vc = 0;
float linewidth = 1.0F; float linewidth = 1.0F;
float widthscale = 0.15F; float widthscale = 0.15F;
float lineradius, dotradius, dotwidth; float lineradius, dotradius, dotwidth;
float white[] = { 1.0, 1.0, 1.0 }; float white[] = { 1.0, 1.0, 1.0 };
float zee[] = { 0.0, 0.0, 1.0 }; float zee[] = { 0.0, 0.0, 1.0 };
int ok = true; int ok = true;
const float *n0 = NULL, *n1 = NULL, *n2 = NULL, *v0 = NULL, *v1 = NULL, *v2 = NULL, *c0 = const float *n0 = NULL, *n1 = NULL, *n2 = NULL, *v0 = NULL, *v1 = NULL, *v2 = NULL, *c0 =
NULL, *c1 = NULL, *c2 = NULL; NULL, *c1 = NULL, *c2 = NULL;
float rampc0[3], rampc1[3], rampc2[3];
int mode = -1; int mode = -1;
/* workaround; multi-state ray-trace bug */ /* workaround; multi-state ray-trace bug */
if (I) if (I)
pc = I->op; pc = I->op;
else return 0; /* not sure if it should return 0 or 1, 0 - fails, but is it a memory issue? might not be since the arg is NULL */ else return 0; /* not sure if it should return 0 or 1, 0 - fails, but is it a memory issue? might not be since the arg is NULL */
I->G->CGORenderer->alpha = I->G->CGORenderer->alpha =
1.0F - SettingGet_f(I->G, set1, set2, cSetting_cgo_transparency); 1.0F - SettingGet_f(I->G, set1, set2, cSetting_cgo_transparency);
widthscale = SettingGet_f(I->G, set1, set2, cSetting_cgo_ray_width_scale); widthscale = SettingGet_f(I->G, set1, set2, cSetting_cgo_ray_width_scale);
skipping to change at line 5969 skipping to change at line 5388
dotwidth = *pc; dotwidth = *pc;
dotradius = widthscale * dotwidth; dotradius = widthscale * dotwidth;
break; break;
case CGO_LINEWIDTH: case CGO_LINEWIDTH:
linewidth = *pc; linewidth = *pc;
lineradius = widthscale * linewidth; lineradius = widthscale * linewidth;
break; break;
case CGO_NORMAL: case CGO_NORMAL:
n0 = pc; n0 = pc;
break; break;
case CGO_SPECIAL_WITH_ARG:
{
float argval = *(pc + 1);
switch (*(int*)pc){
case LINEWIDTH_FOR_LINES:
linewidth = argval;
lineradius = widthscale * linewidth;
}
}
break;
case CGO_SPECIAL:
{
switch ((*(int*)pc)){
case LINEWIDTH_DYNAMIC_WITH_SCALE_RIBBON:
{
float radius = SettingGet_f(I->G, set1, set2, cSetting_ribbon_radius
);
if(radius == 0.0F) {
float ribbon_width = SettingGet_f(I->G, set1, set2, cSetting_ribbo
n_width);
float line_width = SceneGetDynamicLineWidth(info, ribbon_width);
SceneGetDynamicLineWidth(info, line_width);
radius = ray->PixelRadius * line_width / 2.0F;
}
lineradius = radius;
}
break;
case LINEWIDTH_FOR_LINES:
{
float radius = SettingGet_f(I->G, set1, set2, cSetting_line_radius);
<