I have a class where it crates a cube, load a shader, and render it, but i would like to know, how do I create two cubes, with two different vertices, two different matrices, and then merge these vertices together into one big mesh? So I can draw it once, but I dont want to configure the two cubes directly where I create the vertices, you know? I want to create both of vertices, and then merge them together based on their matrix positions.
Here is my class and the shader I use to render the cube:
PrimitiveCube.h
#pragma once
#include "Shader.h"
#include <glad/include/glad/glad.h>
#include <map>
#include <string>
#include <vector>
using std::map;
using std::vector;
using std::string;
class PrimitiveCube
{
vector<float> vertices;
GLuint vbo_vertices, vbo_colors;
GLuint ibo_cube_elements;
Shader* shader;
glm::mat4 transformation;
public:
PrimitiveCube(const glm::vec3& pos, const vector<float>& v);
~PrimitiveCube();
//here i pass the camera matrices to send to the cube's shader
void Render(map<string, glm::mat4> matrices);
};
PrimitiveCube.cpp
#include "PrimitiveCube.h"
PrimitiveCube::PrimitiveCube(const glm::vec3& pos, const vector<float>& v)
{
transformation = glm::translate(glm::mat4(1.0), pos);
vertices = v;
shader = new Shader("cube.vert", "cube.frag");
GLfloat cube_vertices[] =
{
// front
vertices[0], vertices[1], vertices[2],
vertices[3], vertices[4], vertices[5],
vertices[6], vertices[7], vertices[8],
vertices[9], vertices[10], vertices[11],
// back
vertices[12], vertices[13], vertices[14],
vertices[15], vertices[16], vertices[17],
vertices[18], vertices[19], vertices[20],
vertices[21], vertices[22], vertices[23],
};
//vertices
glGenBuffers(1, &vbo_vertices);
glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices);
glBufferData(GL_ARRAY_BUFFER, sizeof(cube_vertices), cube_vertices, GL_STATIC_DRAW);
GLfloat cube_colors[] = {
// front colors
0.6f, 1.0, 0.6f,
0.6f, 1.0, 0.6f,
0.6f, 1.0, 0.6f,
0.6f, 1.0, 0.6f,
// back colors
0.6f, 1.0, 0.6f,
0.6f, 1.0, 0.6f,
0.6f, 1.0, 0.6f,
0.6f, 1.0, 0.6f,
};
glGenBuffers(1, &vbo_colors);
glBindBuffer(GL_ARRAY_BUFFER, vbo_colors);
glBufferData(GL_ARRAY_BUFFER, sizeof(cube_colors), cube_colors, GL_STATIC_DRAW);
GLushort cube_elements[] = {
// front
0, 1, 2,
2, 3, 0,
// top
1, 5, 6,
6, 2, 1,
// back
7, 6, 5,
5, 4, 7,
// bottom
4, 0, 3,
3, 7, 4,
// left
4, 5, 1,
1, 0, 4,
// right
3, 2, 6,
6, 7, 3,
};
glGenBuffers(1, &ibo_cube_elements);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_cube_elements);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cube_elements), cube_elements, GL_STATIC_DRAW);
}
PrimitiveCube::~PrimitiveCube()
{
glDeleteBuffers(1, &vbo_vertices);
glDeleteBuffers(1, &vbo_colors);
glDeleteBuffers(1, &ibo_cube_elements);
delete shader;
}
void PrimitiveCube::Render(map<string, glm::mat4> matrices)
{
shader->Use();
//calculating the matrices i pass from where i call the render, with the names "projection" and "view"
map<string, glm::mat4>::const_iterator& it = matrices.begin();
while (it != matrices.end())
{
GLuint p = shader->GetUniformLocation(it->first);
glUniformMatrix4fv(p, 1, GL_FALSE, glm::value_ptr(it->second));
it++;
}
GLuint p = shader->GetUniformLocation("model");
glUniformMatrix4fv(p, 1, GL_FALSE, glm::value_ptr(transformation));
glEnableVertexAttribArray(glGetAttribLocation(shader->GetID(), "coord3d"));
// Describe our vertices array to OpenGL (it can't guess its format automatically)
glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices);
glVertexAttribPointer(
glGetAttribLocation(shader->GetID(), "coord3d"), // attribute
3, // number of elements per vertex, here (x,y,z)
GL_FLOAT, // the type of each element
GL_FALSE, // take our values as-is
0, // no extra data between each position
0 // offset of first element
);
glEnableVertexAttribArray(glGetAttribLocation(shader->GetID(), "v_color"));
glBindBuffer(GL_ARRAY_BUFFER, vbo_colors);
glVertexAttribPointer(
glGetAttribLocation(shader->GetID(), "v_color"), // attribute
3, // number of elements per vertex, here (R,G,B)
GL_FLOAT, // the type of each element
GL_FALSE, // take our values as-is
0, // no extra data between each position
0 // offset of first element
);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_cube_elements);
int size;
glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
glDrawElements(GL_TRIANGLES, size / sizeof(GLushort), GL_UNSIGNED_SHORT, 0);
glDisableVertexAttribArray(glGetAttribLocation(shader->GetID(), "coord3d"));
glDisableVertexAttribArray(glGetAttribLocation(shader->GetID(), "v_color"));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // Unbind the VBO
glBindBuffer(GL_ARRAY_BUFFER, 0);
shader->Unuse();
}
cube.vert
#version 330
attribute vec3 coord3d;
attribute vec3 v_color;
uniform mat4 model;
uniform mat4 projection;
uniform mat4 view;
varying vec3 f_color;
void main(void)
{
gl_Position = projection * view * model * vec4(coord3d, 1.0);
f_color = v_color;
}
cube.frag
#version 330
varying vec3 f_color;
void main(void)
{
gl_FragColor = vec4(f_color.x, f_color.y, f_color.z, 1.0);
}
Oh and btw, I use SDL+ OpenGL, GLAD and GLM.