I am trying to get transparency blending to work properly on my cube and I have hit a bit of a roadblock. I have gotten blending to work on multiple cubes by simply drawing them in the correct order but getting it to work on the faces of a cube itself has been much harder.
They way I want to solve this is by reordering the indices in the EBO so that it draws the faces in the correct order. I have gotten it to reorder the indices, the problem is that they are not being ordered correctly.
The way I do this is with this method:
void GECCube::SortIndicies(glm::mat4 ModelMatrix)
{
glm::vec4 View = glm::vec4{0.0f, 0.0f, -3.0f, 0.f};
unsigned int NewIndices[36];
std::multimap<float, std::vector<unsigned int>> SortedMap;
for (int i = 0; i < 12; i += 2)
{
glm::vec4 Tri1 = glm::vec4{
(Vertices[Indices[i * 3] * 3] + Vertices[Indices[(i * 3) + 1] * 3] + Vertices[Indices[(i * 3) + 2] * 3]) / 3, //X
(Vertices[Indices[i * 3] * 4] + Vertices[Indices[(i * 3) + 1] * 4] + Vertices[Indices[(i * 3) + 2] * 4]) / 3, //Y
(Vertices[Indices[i * 3] * 5] + Vertices[Indices[(i * 3) + 1] * 5] + Vertices[Indices[(i * 3) + 2] * 5]) / 3, //Z
0.f
};
glm::vec4 Tri2 = glm::vec4{
(Vertices[Indices[(i + 1) * 3] * 3] + Vertices[Indices[((i + 1) * 3) + 1] * 3] + Vertices[Indices[((i + 1) * 3) + 2] * 3]) / 3, //X
(Vertices[Indices[(i + 1) * 3] * 4] + Vertices[Indices[((i + 1) * 3) + 1] * 4] + Vertices[Indices[((i + 1) * 3) + 2] * 4]) / 3, //Y
(Vertices[Indices[(i + 1) * 3] * 5] + Vertices[Indices[((i + 1) * 3) + 1] * 5] + Vertices[Indices[((i + 1) * 3) + 2] * 5]) / 3, //Z
0.f
};
glm::vec4 PlaneMed = glm::vec4{(Tri1.x + Tri2.x) / 2, (Tri1.y + Tri2.y) / 2 , (Tri1.z + Tri2.z) / 2, 0 };
float Distance = glm::length(View - (ModelMatrix * PlaneMed));
std::vector<unsigned int> TransportVector = std::vector<unsigned int>{ Indices[i * 3] , Indices[(i * 3) + 1] , Indices[(i * 3) + 2],
Indices[(i + 1) * 3] , Indices[((i + 1) * 3) + 1] , Indices[((i + 1) * 3) + 2] };
SortedMap.insert(std::pair<float, std::vector<unsigned int>>(Distance, TransportVector));
}
auto MapIterator = SortedMap.begin();
for (int i = 0; i < 12; i += 2)
{
NewIndices[i * 3] = MapIterator->second[0];
NewIndices[(i * 3) + 1] = MapIterator->second[1];
NewIndices[(i * 3) + 2] = MapIterator->second[2];
NewIndices[(i + 1) * 3] = MapIterator->second[3];
NewIndices[((i + 1) * 3) + 1] = MapIterator->second[4];
NewIndices[((i + 1) * 3) + 2] = MapIterator->second[5];
if (i != 10) { MapIterator++; }
}
std::copy(std::begin(NewIndices), std::end(NewIndices), std::begin(Indices));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);
}
I have yet to do something more complicated with the camera so for now it's just at position 0,0,-3.0
The place I think I have done this wrong is when it comes to calculating the distance between the camera and the plane. Namely this:
float Distance = glm::length(View - (ModelMatrix * Plane));
Originally I was just going to use View - Plane but I realized that that would give me the same value for every index so I thought on how to integrate the Model into the distance. I reason that since the shader uses the model matrix to draw at the correct position so should I be able to use it to find the correct position of the plane in model space. But I think I am wrong on this.
All of this comes together in the draw function (it draws multiple cubes):
...
glm::mat4 model = glm::mat4(1.0f);
model = glm::translate(model, it->second * 0.9f * std::clamp((float) sinf(( float )SDL_GetTicks() / 1000.f) + 1.5f, 0.f, 3.f));
float angle = 20.0f * ((i + 1)/20) * ( float )SDL_GetTicks() / 200 * glm::radians(50.0f);
model = glm::rotate(model, glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f));
OGLCMain->MainCube.SortIndicies(model);
int modelLoc = glGetUniformLocation(OGLCMain->ShaderProgram, "model");
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
...
So I made the system work by changing the distance code to be calculated using the dot product of the vector on the camera front vector
and by changing how the plane med is calculated into:
I also reversed the order it puts it back in:
and changed the distance calculation to:
BUT! This should not matter since both of these reverse the order, thus netting 0 change.
For clarity the vertex and index array I used for this project looks like this: