Thank you for your response.
Blockquote And if the numbers you’ve listed above are correct and “mm = millimeter” instead of “sm” I think you mean “cm” (centimeter) (see [Unit_of_length#SI]
Yes, I meant cm (centimeter). Sorry for that.
Basically here I am creating vertices and indices and writing them to 2 txt files vertices.txt and indices.txt
for (int y = 0; y < yMax; y++)
{
for (int x = 0; x < xMax; x++)
{
if (phantom->voxel[x][y][z] == emptyVoxel) // checking if voxel is not empty. Empty voxels have value 255 in them
{
continue;
}
else
{
if ((x != 0 && x != (xMax - 1)) && (y != 0 && y != (yMax - 1)) && (z != 0 && z != (zMax - 1)) &&
(phantom->voxel[x + 1][y][z] != emptyVoxel) && (phantom->voxel[x - 1][y][z] != emptyVoxel) && (phantom->voxel[x][y + 1][z] != emptyVoxel) &&
(phantom->voxel[x][y - 1][z] != emptyVoxel) && (phantom->voxel[x][y][z + 1] != emptyVoxel) && (phantom->voxel[x][y][z - 1] != emptyVoxel))
// checking if a voxel is surrounded from all sides by non empty voxes. If its surrounded then we do not need to create vertices and indices for it.
{
continue;
}
// here I am creating vertices (that contain only coordinates) and multiplying each coordinate by voxelSize in order to scale phantom to more human like scale.
verticies_out_file << x * voxelSizeX << " " << y * voxelSizeY << " " << z * voxelSizeZ << std::endl;
verticies_out_file << x * voxelSizeX << " " << y * voxelSizeY << " " << (z + 1) * voxelSizeZ << std::endl;
verticies_out_file << x * voxelSizeX << " " << (y + 1) * voxelSizeY << " " << z * voxelSizeZ << std::endl;
verticies_out_file << x * voxelSizeX << " " << (y + 1) * voxelSizeY << " " << (z + 1) * voxelSizeZ << std::endl;
verticies_out_file << (x + 1) * voxelSizeX << " " << y * voxelSizeY << " " << z * voxelSizeZ << std::endl;
verticies_out_file << (x + 1) * voxelSizeX << " " << y * voxelSizeY << " " << (z + 1) * voxelSizeZ << std::endl;
verticies_out_file << (x + 1) * voxelSizeX << " " << (y + 1) * voxelSizeY << " " << z * voxelSizeZ << std::endl;
verticies_out_file << (x + 1) * voxelSizeX << " " << (y + 1) * voxelSizeY << " " << (z + 1) * voxelSizeZ << std::endl;
if (x != 0 && x != (xMax - 1))
{
if (phantom->voxel[x - 1][y][z] != emptyVoxel)
{
indicies_out_file << (elements * 8) << " " << (elements * 8 + 2) << " " << (elements * 8 + 3) << " "
<< (elements * 8) << " " << (elements * 8 + 1) << " "<< (elements * 8 + 3) << std::endl; // left face
}
if (phantom->voxel[x + 1][y][z] != emptyVoxel)
{
indicies_out_file << (elements * 8 + 4) << " " << (elements * 8 + 5) << " "<< (elements * 8 + 7) << " "
<< (elements * 8 + 4) << " "<< (elements * 8 + 6) << " " << (elements * 8 + 7) << std::endl; // right face
}
}
else
{
if (x == 0)
{
indicies_out_file << (elements * 8) << " " << (elements * 8 + 2) << " "<< (elements * 8 + 3) << " "
<< (elements * 8) << " "<< (elements * 8 + 1) << " "<< (elements * 8 + 3) << std::endl; // left face
}
if (x == (xMax - 1))
{
indicies_out_file << (elements * 8 + 4) << " "<< (elements * 8 + 5) << " "<< (elements * 8 + 7) << " "
<< (elements * 8 + 4) << " " << (elements * 8 + 6) << " " << (elements * 8 + 7) << std::endl; // right face
}
}
if (y != 0 && y != (yMax - 1))
{
if (phantom->voxel[x][y - 1][z] != emptyVoxel)
{
indicies_out_file << (elements * 8 + 1) << " " << (elements * 8 + 5) << " "<< (elements * 8 + 4) << " "
<< (elements * 8 + 1) << " " << (elements * 8) << " "<< (elements * 8 + 4) << std::endl; // bottom face
}
if (phantom->voxel[x][y + 1][z] != emptyVoxel)
{
indicies_out_file << (elements * 8 + 2) << " " << (elements * 8 + 3) << " " << (elements * 8 + 7) << " "
<< (elements * 8 + 2) << " " << (elements * 8 + 6) << " " << (elements * 8 + 7) << std::endl; // top face
}
}
else
{
if (y == 0)
{
indicies_out_file << (elements * 8 + 1) << " " << (elements * 8 + 5) << " " << (elements * 8 + 4) << " "
<< (elements * 8 + 1) << " " << (elements * 8) << " " << (elements * 8 + 4) << std::endl; // bottom face
}
if (y == (yMax - 1))
{
indicies_out_file << (elements * 8 + 2) << " " << (elements * 8 + 3) << " " << (elements * 8 + 7) << " "
<< (elements * 8 + 2) << " " << (elements * 8 + 6) << " " << (elements * 8 + 7) << std::endl; // top face
}
}
if (z != 0 && z != (zMax - 1))
{
if (phantom->voxel[x][y][z - 1] != emptyVoxel)
{
indicies_out_file << (elements * 8) << " " << (elements * 8 + 4) << " " << (elements * 8 + 6) << " "
<< (elements * 8) << " " << (elements * 8 + 2) << " " << (elements * 8 + 6) << std::endl; // front face
}
if (phantom->voxel[x][y][z + 1] != emptyVoxel)
{
indicies_out_file << (elements * 8 + 1) << " " << (elements * 8 + 5) << " " << (elements * 8 + 7) << " "
<< (elements * 8 + 1) << " " << (elements * 8 + 3) << " " << (elements * 8 + 7) << std::endl; // back face
}
}
else
{
if (z == 0)
{
indicies_out_file << (elements * 8) << " " << (elements * 8 + 4) << " " << (elements * 8 + 6) << " "
<< (elements * 8) << " " << (elements * 8 + 2) << " " << (elements * 8 + 6) << std::endl; // front face
}
if (z == (zMax - 1))
{
indicies_out_file << (elements * 8 + 1) << " " << (elements * 8 + 5) << " " << (elements * 8 + 7) << " "
<< (elements * 8 + 1) << " " << (elements * 8 + 3) << " " << (elements * 8 + 7) << std::endl; // back face
}
}
elements++;
}
}
}
}
In my Mesh class I am reading from 2 txt files vertices.txt and indices.txt first by allocating buffer and uploading whole files in order to speed up reading process as each file contains roughly 1 million lines. Then by reading character by character I am storing data in 2 vectors indices and vertices.
#include "Mesh.h"
#include <iostream>
#include <sstream>
#include <fstream>
#include <math.h>
Mesh::Mesh()
{
loaded = false;
}
Mesh::~Mesh()
{
glDeleteVertexArrays(1, &vao);
glDeleteBuffers(1, &vbo);
glDeleteBuffers(1, &ibo);
}
void Mesh::loadVertices(std::string fileName)
{
double item = 0;
int n = 0, x = 0, y = 0;
bool dotEncountered = false;
int numbersAfterDot = 0;
std::ifstream is(fileName, std::ifstream::binary);
if (is) {
is.seekg(0, is.end);
int length = is.tellg();
is.seekg(0, is.beg);
char* buffer = new char[length];
is.read(buffer, length);
is.close();
for (unsigned int i = 0; i < is.gcount(); i++)
{
switch (buffer[i])
{
case '\r':
break;
case '\n':
{
vertices.push_back(glm::vec3(y, item, x));
dotEncountered = false;
numbersAfterDot = 0;
n = 0;
item = 0;
break;
}
case ' ':
{
n++;
if (n == 1)
{
x = item;
dotEncountered = false;
numbersAfterDot = 0;
}
else
{
dotEncountered = false;
numbersAfterDot = 0;
y = item;
}
dotEncountered = false;
numbersAfterDot = 0;
item = 0;
break;
}
case '.':
dotEncountered = true;
break;
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
case '8': case '9':
if (!dotEncountered)
{
item = 10 * item + buffer[i] - '0';
break;
}
else
{
numbersAfterDot++;
item += (double) (buffer[i] - '0') / pow(10, numbersAfterDot);
break;
}
default:
std::cerr << "Bad format\n";
}
}
delete[] buffer;
}
}
void Mesh::loadIndices(std::string fileName)
{
int item = 0;
std::ifstream is(fileName, std::ifstream::binary);
if (is) {
is.seekg(0, is.end);
int length = is.tellg();
is.seekg(0, is.beg);
char* buffer = new char[length];
is.read(buffer, length);
is.close();
for (unsigned int i = 0; i < is.gcount(); i++)
{
switch (buffer[i])
{
case '\r':
break;
case '\n':
{
indicies.push_back(item);
item = 0;
break;
}
case ' ':
{
indicies.push_back(item);
item = 0;
break;
}
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
case '8': case '9':
item = 10 * item + buffer[i] - '0';
break;
default:
std::cerr << "Bad format\n";
}
}
delete[] buffer;
}
}
bool Mesh::loadOBJ()
{
loadVertices("Phantom Data/MA_vertices.txt");
loadIndices("Phantom Data/MA_indices.txt");
initBuffers();
return (loaded = true);
}
void Mesh::draw()
{
if (!loaded) return;
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, indicies.size(), GL_UNSIGNED_INT, nullptr);
glBindVertexArray(0);
}
void Mesh::initBuffers()
{
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3), NULL);
glEnableVertexAttribArray(0);
glGenBuffers(1, &ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicies.size() * sizeof(GLuint), &indicies[0], GL_STATIC_DRAW);
glBindVertexArray(0);
}
Draw method
void MyGLCanvas::draw(wxDC& dc)
{
glm::vec3 modelPos = glm::vec3(0.0f, -10.0f, -50.0f);
glm::mat4 model, view;
model = glm::translate(model, modelPos);
view = fpsCamera->getViewMatrix();
projection = glm::perspective(glm::radians(fpsCamera->getFOV()), (float)(windowWidth / windowHeight), 0.1f, 100.0f);
glm::mat4 trans;
trans = glm::rotate(trans, 30.0f, glm::vec3(0.0f, 1.0f, 0.0f)); // after rotation phantom will face the camera
trans = glm::scale(trans, glm::vec3(0.01, 0.01, 0.01));
ShaderProgram shaderProgram;
shaderProgram.loadShaders("basic.vert", "basic.frag");
glClearStencil(0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
shaderProgram.use();
shaderProgram.setUniform("transform", trans);
shaderProgram.setUniform("model", model);
shaderProgram.setUniform("view", view);
shaderProgram.setUniform("projection", projection);
shaderProgram.setUniform("color", glm::vec3(0.310f, 0.747f, 0.185f)); //ignore color for now
mesh->draw()
//degree += 0.05f;
SwapBuffers();
}