201VuoMesh VuoMesh_makeFromGPUBuffers(
unsigned int vertexCount,
unsigned int combinedBuffer,
unsigned int combinedBufferSize,
void *normalOffset,
void *textureCoordinateOffset,
void *colorOffset,
unsigned int elementCount,
unsigned int elementBuffer,
unsigned int elementBufferSize,
VuoMesh_ElementAssemblyMethod elementAssemblyMethod)
203 VuoMesh_internal *m = VuoMesh_makeInternal();
205 m->vertexCount = vertexCount;
206 m->elementCount = elementCount;
207 m->elementAssemblyMethod = elementAssemblyMethod;
208 m->glUpload.combinedBuffer = combinedBuffer;
209 m->glUpload.combinedBufferSize = combinedBufferSize;
210 m->glUpload.normalOffset = normalOffset;
211 m->glUpload.textureCoordinateOffset = textureCoordinateOffset;
212 m->glUpload.colorOffset = colorOffset;
213 m->glUpload.elementBuffer = elementBuffer;
214 m->glUpload.elementBufferSize = elementBufferSize;
258 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
261 return m->elementCount ? m->elementCount/3 : m->vertexCount/3;
263 return m->elementCount ? m->elementCount-2 : m->vertexCount-2;
265 return m->elementCount ? m->elementCount-2 : m->vertexCount-2;
267 return m->elementCount ? m->elementCount/2 : m->vertexCount/2;
269 return m->elementCount ? m->elementCount-1 : m->vertexCount-1;
271 return m->elementCount ? m->elementCount : m->vertexCount;
289 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
291 if (m->elementCount == 0 && m->vertexCount == 0)
295 return m->elementCount ? m->elementCount : m->vertexCount;
297 return m->elementCount ? (m->elementCount-2)*3 : (m->vertexCount-2)*3;
299 return m->elementCount ? (m->elementCount-2)*3 : (m->vertexCount-2)*3;
301 return m->elementCount ? m->elementCount : m->vertexCount;
303 return m->elementCount ? (m->elementCount-1)*2 : (m->vertexCount-1)*2;
305 return m->elementCount ? m->elementCount : m->vertexCount;
337 if (!m || m->glUpload.combinedBuffer)
349 m->glUpload.combinedBufferSize =
sizeof(float) * 3 * m->vertexCount;
351 uint64_t normalOffsetBytes = 0;
354 normalOffsetBytes = m->glUpload.combinedBufferSize;
355 m->glUpload.combinedBufferSize +=
sizeof(float) * 3 * m->vertexCount;
357 m->glUpload.normalOffset = (
void *)normalOffsetBytes;
359 uint64_t textureCoordinateOffsetBytes = 0;
360 if (m->textureCoordinates)
362 textureCoordinateOffsetBytes = m->glUpload.combinedBufferSize;
363 m->glUpload.combinedBufferSize +=
sizeof(float) * 2 * m->vertexCount;
365 m->glUpload.textureCoordinateOffset = (
void *)textureCoordinateOffsetBytes;
367 uint64_t colorOffsetBytes = 0;
370 colorOffsetBytes = m->glUpload.combinedBufferSize;
371 m->glUpload.combinedBufferSize +=
sizeof(float) * 4 * m->vertexCount;
373 m->glUpload.colorOffset = (
void *)colorOffsetBytes;
375 float *combinedData = (
float *)malloc(m->glUpload.combinedBufferSize);
376 for (
int i =0; i < m->glUpload.combinedBufferSize/
sizeof(float); ++i)
381 for (
unsigned long i = 0; i < m->vertexCount; ++i)
383 combinedData[i * 3 ] = m->positions[i * 3 ];
384 combinedData[i * 3 + 1] = m->positions[i * 3 + 1];
385 combinedData[i * 3 + 2] = m->positions[i * 3 + 2];
388 combinedData[i * 3 + normalOffsetBytes /
sizeof(float) ] = m->normals[i * 3 ];
389 combinedData[i * 3 + normalOffsetBytes /
sizeof(float) + 1] = m->normals[i * 3 + 1];
390 combinedData[i * 3 + normalOffsetBytes /
sizeof(float) + 2] = m->normals[i * 3 + 2];
392 if (m->textureCoordinates)
394 combinedData[i * 2 + textureCoordinateOffsetBytes /
sizeof(float) ] = m->textureCoordinates[i * 2 ];
395 combinedData[i * 2 + textureCoordinateOffsetBytes /
sizeof(float) + 1] = m->textureCoordinates[i * 2 + 1];
399 combinedData[i * 4 + colorOffsetBytes /
sizeof(float) ] = m->colors[i * 4 ];
400 combinedData[i * 4 + colorOffsetBytes /
sizeof(float) + 1] = m->colors[i * 4 + 1];
401 combinedData[i * 4 + colorOffsetBytes /
sizeof(float) + 2] = m->colors[i * 4 + 2];
402 combinedData[i * 4 + colorOffsetBytes /
sizeof(float) + 3] = m->colors[i * 4 + 3];
412 m->glUpload.combinedBuffer =
VuoGlPool_use(cgl_ctx, VuoGlPool_ArrayBuffer, m->glUpload.combinedBufferSize);
414 glBindBuffer(GL_ARRAY_BUFFER, m->glUpload.combinedBuffer);
415 glBufferSubData(GL_ARRAY_BUFFER, 0, m->glUpload.combinedBufferSize, combinedData);
420 m->glUpload.elementBufferSize =
sizeof(
unsigned int)*m->elementCount;
421 m->glUpload.elementBuffer =
VuoGlPool_use(cgl_ctx, VuoGlPool_ElementArrayBuffer, m->glUpload.elementBufferSize);
423 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->glUpload.elementBuffer);
424 glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0,
sizeof(
unsigned int) * m->elementCount, m->elements);
426 glBindBuffer(GL_ARRAY_BUFFER, 0);
433 glFlushRenderAPPLE();
443 VuoMesh_internal *m = VuoMesh_makeSingletonInternal();
446 VuoMesh_allocateCPUBuffers(m->vertexCount, &m->positions, &m->normals, &m->textureCoordinates, NULL, m->elementCount, &m->elements);
455 for (
int i = 0; i < m->vertexCount; ++i)
486 VuoMesh_internal *m = VuoMesh_makeSingletonInternal();
492 m->positions[0] = -.5;
493 m->positions[1] = -.5;
496 m->positions[3] = .5;
497 m->positions[4] = -.5;
500 m->positions[6] = -.5;
501 m->positions[7] = .5;
504 m->positions[9] = .5;
505 m->positions[10] = .5;
506 m->positions[11] = 0;
509 m->textureCoordinates[0] = 0;
510 m->textureCoordinates[1] = 0;
512 m->textureCoordinates[2] = 1;
513 m->textureCoordinates[3] = 0;
515 m->textureCoordinates[4] = 0;
516 m->textureCoordinates[5] = 1;
518 m->textureCoordinates[6] = 1;
519 m->textureCoordinates[7] = 1;
541 VuoMesh_internal *m = VuoMesh_makeSingletonInternal();
544 VuoMesh_allocateCPUBuffers(m->vertexCount, &m->positions, &m->normals, &m->textureCoordinates, NULL, m->elementCount, &m->elements);
547 for (
int i = 0; i < m->vertexCount; ++i)
549 float angle = M_PI/2. + i * 2*M_PI/3.;
550 VuoPoint3d_setArray(&m->positions[i * 3], (VuoPoint3d){ cos(angle) / sqrt(3), sin(angle) / sqrt(3), 0 });
554 for (
int i = 0; i < m->vertexCount; ++i)
629 VuoPoint3d positions[] = (VuoPoint3d[]){
662 VuoPoint3d normals[] = (VuoPoint3d[]){
695 VuoPoint2d textureCoordinates[] = (VuoPoint2d[]){
728 unsigned int elements[] = (
unsigned int[]){
749 VuoMesh_internal *m = VuoMesh_makeSingletonInternal();
750 m->vertexCount = 6 * 4;
751 m->elementCount = 6 * 6;
752 VuoMesh_allocateCPUBuffers(m->vertexCount, &m->positions, &m->normals, &m->textureCoordinates, NULL, m->elementCount, &m->elements);
754 for (
int i = 0; i < m->vertexCount; ++i)
760 memcpy(m->elements, elements,
sizeof(elements));
789 unsigned int vertexCount = rows * columns;
790 unsigned int triangleCount = (rows-1) * (columns-1) * 6;
792 float *positions, *normals, *textureCoordinates;
793 unsigned int *elements;
796 unsigned int index = 0, t_index = 0;
798 for(
unsigned int i = 0; i < rows; i++)
800 float y = (i/(float)(rows-1)) - .5;
802 for(
unsigned int n = 0; n < columns; n++)
804 float x = (n/(float)(columns-1)) - .5;
810 if(n < columns-1 && i < rows-1)
812 elements[t_index++] = index + columns;
813 elements[t_index++] = index;
814 elements[t_index++] = index + 1;
816 elements[t_index++] = index + 1;
817 elements[t_index++] = index + columns + 1;
818 elements[t_index++] = index + columns;
826 positions, normals, textureCoordinates, NULL,
879 float *positionsFloat, *normals, *colorsFloat = NULL;
881 for (
unsigned long i = 0; i < positionCount; ++i)
883 VuoPoint2d xy = positionValues[i];
884 positionsFloat[i * 3 ] = xy.x;
885 positionsFloat[i * 3 + 1] = xy.y;
886 positionsFloat[i * 3 + 2] = 0;
889 normals[i * 3 + 1] = 0;
890 normals[i * 3 + 2] = 1;
894 float progress = (float)i /
MAX(1, positionCount - 1);
895 unsigned long colorIndex = round(progress * (colorCount - 1));
896 VuoColor c = colorValues[colorIndex];
897 colorsFloat[i * 4 ] = c.r * c.a;
898 colorsFloat[i * 4 + 1] = c.g * c.a;
899 colorsFloat[i * 4 + 2] = c.b * c.a;
900 colorsFloat[i * 4 + 3] = c.a;
905 positionsFloat, normals, NULL, colorsFloat,
906 0, NULL, elementAssemblyMethod);
927 float *positionsFloat, *normals, *colorsFloat = NULL;
929 for (
unsigned long i = 0; i < positionCount; ++i)
934 normals[i * 3 + 1] = 0;
935 normals[i * 3 + 2] = 1;
939 float progress = (float)i /
MAX(1, positionCount - 1);
940 unsigned long colorIndex = round(progress * (colorCount - 1));
941 VuoColor c = colorValues[colorIndex];
942 colorsFloat[i * 4 ] = c.r * c.a;
943 colorsFloat[i * 4 + 1] = c.g * c.a;
944 colorsFloat[i * 4 + 2] = c.b * c.a;
945 colorsFloat[i * 4 + 3] = c.a;
950 positionsFloat, normals, NULL, colorsFloat,
951 0, NULL, elementAssemblyMethod);
964 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
965 VuoMesh_internal *copiedMesh = VuoMesh_makeInternal();
966 copiedMesh->vertexCount = m->vertexCount;
967 copiedMesh->elementCount = m->elementCount;
971 unsigned long size =
sizeof(float) * 3 * copiedMesh->vertexCount;
972 copiedMesh->positions = (
float *)malloc(size);
973 memcpy(copiedMesh->positions, m->positions, size);
976 copiedMesh->positions = NULL;
980 unsigned long size =
sizeof(float) * 3 * copiedMesh->vertexCount;
981 copiedMesh->normals = (
float *)malloc(size);
982 memcpy(copiedMesh->normals, m->normals, size);
985 copiedMesh->normals = NULL;
987 if (m->textureCoordinates)
989 unsigned long size =
sizeof(float) * 3 * copiedMesh->vertexCount;
990 copiedMesh->textureCoordinates = (
float *)malloc(size);
991 memcpy(copiedMesh->textureCoordinates, m->textureCoordinates, size);
994 copiedMesh->textureCoordinates = NULL;
998 unsigned long size =
sizeof(float) * 3 * copiedMesh->vertexCount;
999 copiedMesh->colors = (
float *)malloc(size);
1000 memcpy(copiedMesh->colors, m->colors, size);
1003 copiedMesh->colors = NULL;
1005 copiedMesh->elementCount = m->elementCount;
1008 unsigned long elementByteCount =
sizeof(
unsigned int)*m->elementCount;
1009 copiedMesh->elements = (
unsigned int *)malloc(elementByteCount);
1010 memcpy(copiedMesh->elements, m->elements, elementByteCount);
1013 copiedMesh->elements = NULL;
1015 copiedMesh->elementAssemblyMethod = m->elementAssemblyMethod;
1016 copiedMesh->primitiveSize = m->primitiveSize;
1017 copiedMesh->faceCulling = m->faceCulling;
1019 memcpy(&copiedMesh->glUpload, &m->glUpload,
sizeof(copiedMesh->glUpload));
1041 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1042 VuoMesh_internal *copiedMesh = VuoMesh_makeInternal();
1044 copiedMesh->vertexCount = m->vertexCount;
1045 copiedMesh->elementCount = m->elementCount;
1047 copiedMesh->elementAssemblyMethod = m->elementAssemblyMethod;
1048 copiedMesh->primitiveSize = m->primitiveSize;
1049 copiedMesh->faceCulling = m->faceCulling;
1051 memcpy(&copiedMesh->glUpload, &m->glUpload,
sizeof(copiedMesh->glUpload));
1127 unsigned int *combinedBuffer,
1128 void **normalOffset,
void **textureCoordinateOffset,
void **colorOffset,
1129 unsigned int *elementCount,
unsigned int *elementBuffer)
1134 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1137 *vertexCount = m->vertexCount;
1139 *combinedBuffer = m->glUpload.combinedBuffer;
1141 *normalOffset = m->glUpload.normalOffset;
1142 if (textureCoordinateOffset)
1143 *textureCoordinateOffset = m->glUpload.textureCoordinateOffset;
1145 *colorOffset = m->glUpload.colorOffset;
1147 *elementCount = m->elementCount;
1149 *elementBuffer = m->glUpload.elementBuffer;
1236 float *positions,
float *normals,
float *textureCoordinates,
float *colors,
1237 unsigned int elementCount,
unsigned int *elements)
1242 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1244 m->vertexCount = vertexCount;
1246 if (m->positions != positions)
1249 m->positions = positions;
1252 if (m->normals != normals)
1255 m->normals = normals;
1258 if (m->textureCoordinates != textureCoordinates)
1260 free(m->textureCoordinates);
1261 m->textureCoordinates = textureCoordinates;
1264 if (m->colors != colors)
1270 m->elementCount = elementCount;
1272 if (m->elements != elements)
1275 m->elements = elements;
1278 VuoGlPool_release(VuoGlPool_ArrayBuffer, m->glUpload.combinedBufferSize, m->glUpload.combinedBuffer);
1279 VuoGlPool_release(VuoGlPool_ElementArrayBuffer, m->glUpload.elementBufferSize, m->glUpload.elementBuffer);
1280 m->glUpload.combinedBufferSize = 0;
1281 m->glUpload.combinedBuffer = 0;
1282 m->glUpload.elementBufferSize = 0;
1283 m->glUpload.elementBuffer = 0;
1367 if (!m->glUpload.combinedBuffer
1369 && (m->normals || !m->glUpload.normalOffset)
1370 && (m->textureCoordinates || !m->glUpload.textureCoordinateOffset)
1371 && (m->colors || !m->glUpload.colorOffset)
1372 && (m->elements || !m->glUpload.elementBuffer)))
1376 glBindBuffer(GL_ARRAY_BUFFER, m->glUpload.combinedBuffer);
1381 float *vertexData = (
float *)malloc(m->glUpload.combinedBufferSize);
1382 glGetBufferSubData(GL_ARRAY_BUFFER, 0, m->glUpload.combinedBufferSize, vertexData);
1383 glBindBuffer(GL_ARRAY_BUFFER, 0);
1387 m->positions = (
float *)malloc(
sizeof(
float) * 3 * m->vertexCount);
1388 memcpy(m->positions, vertexData,
sizeof(
float) * 3 * m->vertexCount);
1391 if (!m->normals && m->glUpload.normalOffset)
1393 m->normals = (
float *)malloc(
sizeof(
float) * 3 * m->vertexCount);
1394 memcpy(m->normals, (
char *)vertexData + (
int)m->glUpload.normalOffset,
sizeof(
float) * 3 * m->vertexCount);
1397 if (!m->textureCoordinates && m->glUpload.textureCoordinateOffset)
1399 m->textureCoordinates = (
float *)malloc(
sizeof(
float) * 2 * m->vertexCount);
1400 memcpy(m->textureCoordinates, (
char *)vertexData + (
int)m->glUpload.textureCoordinateOffset,
sizeof(
float) * 2 * m->vertexCount);
1403 if (!m->colors && m->glUpload.colorOffset)
1405 m->colors = (
float *)malloc(
sizeof(
float) * 4 * m->vertexCount);
1406 memcpy(m->colors, (
char *)vertexData + (
int)m->glUpload.colorOffset,
sizeof(
float) * 4 * m->vertexCount);
1411 if (!m->elements && m->glUpload.elementBuffer)
1413 m->elements = malloc(m->glUpload.elementBufferSize);
1414 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->glUpload.elementBuffer);
1415 glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, m->glUpload.elementBufferSize, m->elements);
1416 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1427 return VuoBox_make((VuoPoint3d){0,0,0}, (VuoPoint3d){0,0,0});
1429 VuoPoint3d min, max;
1432 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1433 unsigned int vertexCount = m->vertexCount;
1437 if(vertexCount > 0 && !init)
1443 for(
int n = 0; n < vertexCount; n++)
1447 min.x =
MIN(p.x, min.x);
1448 min.y =
MIN(p.y, min.y);
1449 min.z =
MIN(p.z, min.z);
1451 max.x =
MAX(p.x, max.x);
1452 max.y =
MAX(p.y, max.y);
1453 max.z =
MAX(p.z, max.z);
1460 return VuoBox_make((min + max) / (VuoPoint3d)(2.), max - min);
1462 return VuoBox_make( (VuoPoint3d){0,0,0}, (VuoPoint3d){0,0,0} );
1537 return strdup(
"Empty mesh");
1539 VuoMesh_internal *m = (VuoMesh_internal *)mesh;
1541 if (!m->vertexCount)
1542 return strdup(
"Mesh without any vertices");
1545 const char * objectString =
"";
1546 const char * assemblyMethod =
" (unknown element assembly method)";
1549 assemblyMethod =
", ";
1550 objectString =
"triangle";
1555 assemblyMethod =
" in a strip of ";
1556 objectString =
"triangle";
1560 assemblyMethod =
" in a fan of ";
1561 objectString =
"triangle";
1565 assemblyMethod =
", ";
1566 objectString =
"line";
1570 assemblyMethod =
" in a strip of ";
1571 objectString =
"line";
1575 assemblyMethod =
", ";
1576 objectString =
"point";
1579 const char * vertexCountString = m->vertexCount==1 ?
"vertex" :
"vertices";
1580 const char * objectStringPlural = objectCount==1 ?
"" :
"s";
1582 char *firstPosition = NULL;
1586 char *summary =
VuoText_format(
"<div>%u %s%s%lu %s%s</div>%s<div>%s positions</div><div>%s normals</div><div>%s texture coordinates</div><div>%s vertex colors</div>",
1587 m->vertexCount, vertexCountString, assemblyMethod, objectCount, objectString, objectStringPlural,
1588 firstPosition ? firstPosition :
"",
1589 (m->positions || m->glUpload.combinedBuffer ) ?
"✓" :
"◻",
1590 (m->normals || m->glUpload.normalOffset ) ?
"✓" :
"◻",
1591 (m->textureCoordinates || m->glUpload.textureCoordinateOffset) ?
"✓" :
"◻",
1592 (m->colors || m->glUpload.colorOffset ) ?
"✓" :
"◻");
1594 free(firstPosition);