ptf.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /*
  2. James William Fletcher (james@voxdsp.com)
  3. December 2021
  4. Converts .ply ASCII file to OpenGL buffers
  5. Designed for small model files with no more than 65,535 vertices
  6. as GLushort is used for the index buffer and there is a hard coded
  7. limit on the buffers used to generate the file output (MAX_BUFF).
  8. This is basically perfect for converting low poly ASCII PLY
  9. files to C OpenGL buffers for use in OpenGL ES applications.
  10. I'm not a high poly modeller and I like to target low end hardware.
  11. Compile: gcc ptf.c -lm -Ofast -o ptf
  12. Usage: ./ptf filename_noextension
  13. **********************************************************************
  14. An older version of this that uses GLuint for the index buffer
  15. and no fixed output buffers can be found here:
  16. https://github.com/mrbid/esAux-Menger/blob/main/PTO/pto.c
  17. but this solution needs to be updated to use the %g format specifier
  18. and in some instances has the potential to garble file output.
  19. (Basically it needs some work.)
  20. **********************************************************************
  21. */
  22. #include <stdio.h>
  23. #include <string.h>
  24. #include <unistd.h>
  25. #define MAX_BUFF 1048576
  26. int main(int argc, char** argv)
  27. {
  28. // ensure an input file is specified
  29. if(argc < 2)
  30. {
  31. printf("Please specify an input file.\n");
  32. return 0;
  33. }
  34. // take the input file name and strip any supplied extension
  35. char name[32] = {0};
  36. strcat(name, argv[1]);
  37. char* p = strstr(name, ".");
  38. if(p != NULL)
  39. *p = 0x00;
  40. // generate the read file path (reads .ply files from a local `ply/` directory)
  41. char readfile[32] = {0};
  42. strcat(readfile, "ply/");
  43. strcat(readfile, name);
  44. strcat(readfile, ".ply");
  45. // pre-init our buffers
  46. char vertex_array[MAX_BUFF] = {0};
  47. char index_array[MAX_BUFF] = {0};
  48. char normal_array[MAX_BUFF] = {0};
  49. char color_array[MAX_BUFF] = {0};
  50. unsigned int numvert=0, numind=0;
  51. // open our ASCII PLY file for reading
  52. int mode = 0;
  53. printf("Open: %s\n", readfile);
  54. FILE* f = fopen(readfile, "r");
  55. while(f == NULL)
  56. {
  57. f = fopen(readfile, "r");
  58. sleep(1);
  59. }
  60. // do the conversion
  61. char line[256];
  62. while(fgets(line, 256, f) != NULL)
  63. {
  64. //printf("%s\n",line);
  65. if(strcmp(line, "end_header\n") == 0)
  66. {
  67. mode = 1;
  68. continue;
  69. }
  70. // load index
  71. if(mode == 2)
  72. {
  73. unsigned short n,x,y,z;
  74. if(sscanf(line, "%hu %hu %hu %hu", &n, &x, &y, &z) == 4)
  75. {
  76. char add[256];
  77. sprintf(add, "%hu,%hu,%hu,", x, y, z);
  78. strcat(index_array, add);
  79. numind += 3;
  80. }
  81. }
  82. // load vertex, normal, color
  83. if(mode == 1)
  84. {
  85. float vx,vy,vz,nx,ny,nz,r,g,b;
  86. if(sscanf(line, "%f %f %f %f %f %f %f %f %f", &vx, &vy, &vz, &nx, &ny, &nz, &r, &g, &b) == 9)
  87. {
  88. char add[256];
  89. sprintf(add, "%g,%g,%g,", vx, vy, vz);
  90. strcat(vertex_array, add);
  91. numvert++;
  92. sprintf(add, "%g,%g,%g,", nx, ny, nz);
  93. strcat(normal_array, add);
  94. sprintf(add, "%.3g,%.3g,%.3g,", 0.003921568859f*r, 0.003921568859f*g, 0.003921568859f*b);
  95. strcat(color_array, add);
  96. }
  97. else if(sscanf(line, "%f %f %f %f %f %f", &vx, &vy, &vz, &nx, &ny, &nz) == 6)
  98. {
  99. char add[256];
  100. sprintf(add, "%g,%g,%g,", vx, vy, vz);
  101. strcat(vertex_array, add);
  102. numvert++;
  103. sprintf(add, "%g,%g,%g,", nx, ny, nz);
  104. strcat(normal_array, add);
  105. }
  106. else if(sscanf(line, "%f %f %f", &vx, &vy, &vz) == 3)
  107. {
  108. if(vx == 3.0 && vy == 0.0 && vz == 1.0)
  109. {
  110. strcat(index_array, "0,1,2,");
  111. numind += 3;
  112. mode = 2;
  113. continue;
  114. }
  115. char add[256];
  116. sprintf(add, "%g,%g,%g,", vx, vy, vz);
  117. strcat(vertex_array, add);
  118. numvert++;
  119. }
  120. else
  121. {
  122. strcat(index_array, "0,1,2,");
  123. numind += 3;
  124. mode = 2;
  125. continue;
  126. }
  127. }
  128. }
  129. // close PLY file
  130. fclose(f);
  131. // remove trailng comma's
  132. if(vertex_array[0] != 0x00)
  133. vertex_array[strlen(vertex_array)-1] = 0x00;
  134. if(normal_array[0] != 0x00)
  135. normal_array[strlen(normal_array)-1] = 0x00;
  136. if(index_array[0] != 0x00)
  137. index_array[strlen(index_array)-1] = 0x00;
  138. if(color_array[0] != 0x00)
  139. color_array[strlen(color_array)-1] = 0x00;
  140. // output the resultant file
  141. char outfile[256];
  142. sprintf(outfile, "%s.h", name);
  143. f = fopen(outfile, "w");
  144. while(f == NULL)
  145. {
  146. f = fopen(outfile, "w");
  147. sleep(1);
  148. }
  149. fprintf(f, "\n#ifndef %s_H\n#define %s_H\n\nconst GLfloat %s_vertices[] = {%s};\n", name, name, name, vertex_array);
  150. if(normal_array[0] != 0x00)
  151. fprintf(f, "const GLfloat %s_normals[] = {%s};\n", name, normal_array);
  152. if(color_array[0] != 0x00)
  153. fprintf(f, "const GLfloat %s_colors[] = {%s};\n", name, color_array);
  154. fprintf(f, "const GLushort %s_indices[] = {%s};\nconst GLsizeiptr %s_numind = %u;\nconst GLsizeiptr %s_numvert = %u;\n\n#endif\n", name, index_array, name, numind, name, numvert);
  155. fclose(f);
  156. printf("Output: %s.h\n", name);
  157. return 0;
  158. }