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