Okay now I have multiple cubes, but there is still an odd warping going on.
const GLchar *vertexShaderSource = R"(
#version 330 core
layout (location = 0) in vec3 pos;
layout (location = 1) in vec2 coord;
layout (location = 2) in vec2 offset;
out vec2 TexCoord;
uniform mat4 MVP;
void main()
{
gl_Position = MVP * vec4(pos.x + offset.x, pos.y + offset.y, pos.z, 1.0);
TexCoord = coord;
}
)";
const GLchar *fragmentShaderSource = R"(
#version 330 core
in vec2 TexCoord;
out vec4 Color;
uniform sampler2D ourTexture;
void main()
{
Color = texture(ourTexture, TexCoord);
}
)";
int render(GLFWwindow *window, GLuint window_width, GLuint window_height)
{
float vertices[] =
{
// positions // texture coords
//front
0.2f, 0.2f, 0.0f, 1.0f, 1.0f, // top right
0.2f, -0.2f, 0.0f, 1.0f, 0.0f, // bottom right
-0.2f, -0.2f, 0.0f, 0.0f, 0.0f, // bottom left
-0.2f, 0.2f, 0.0f, 0.0f, 1.0f, // top left
//back
0.2f, 0.2f, -0.4f, 1.0f, 1.0f, // top right
0.2f, -0.2f, -0.4f, 1.0f, 0.0f, // bottom right
-0.2f, -0.2f, -0.4f, 0.0f, 0.0f, // bottom left
-0.2f, 0.2f, -0.4f, 0.0f, 1.0f, // top left
//right
0.2f, 0.2f, 0.0f, 1.0f, 1.0f, // top right
0.2f, -0.2f, 0.0f, 1.0f, 0.0f, // bottom right
0.2f, -0.2f, -0.4f, 0.0f, 0.0f, // bottom left
0.2f, 0.2f, -0.4f, 0.0f, 1.0f, // top left
//left
-0.2f, 0.2f, 0.0f, 1.0f, 1.0f, // top right
-0.2f, -0.2f, 0.0f, 1.0f, 0.0f, // bottom right
-0.2f, -0.2f, -0.4f, 0.0f, 0.0f, // bottom left
-0.2f, 0.2f, -0.4f, 0.0f, 1.0f, // top left
//top
0.2f, 0.2f, 0.0f, 1.0f, 1.0f, // top right
0.2f, 0.2f, -0.4f, 1.0f, 0.0f, // bottom right
-0.2f, 0.2f, -0.4f, 0.0f, 0.0f, // bottom left
-0.2f, 0.2f, 0.0f, 0.0f, 1.0f, // top left
//bottom
0.2f, -0.2f, 0.0f, 1.0f, 1.0f, // top right
0.2f, -0.2f, -0.4f, 1.0f, 0.0f, // bottom right
-0.2f, -0.2f, -0.4f, 0.0f, 0.0f, // bottom left
-0.2f, -0.2f, 0.0f, 0.0f, 1.0f // top left
};
unsigned int indices[] =
{
0, 1, 2, 0, 2, 3, //front
4, 5, 6, 4, 6, 7, //right
8, 9, 10, 8, 10, 11, //back
12, 13, 14, 12, 14, 15, //left
16, 17, 18, 16, 18, 19, //upper
20, 21, 22, 20, 22, 23 //bottom
};
glm::vec2 translations[4];
for(int i = 0; i < 4; i++)
{
translations[i] = glm::vec2(0.4f * i, 0.4f * i);
}
// Vertex Array, Vertex Buffer and Element Buffer
GLuint VAO, VBO, EBO, iVBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glGenBuffers(1, &iVBO);
glBindVertexArray(VAO);
glEnable(GL_DEPTH_TEST);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
glBindBuffer(GL_ARRAY_BUFFER, iVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(translations), &translations[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
glVertexAttribDivisor(2, 1);
shader(window_width, window_height);
// Load Image
int width, height, channels;
unsigned char *image = SOIL_load_image("grass.png", &width, &height, &channels, SOIL_LOAD_RGB);
// Texture
unsigned int texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
// Settings
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
// Texture Image
if (image)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
out << "Failed to load texture" << end;
}
SOIL_free_image_data(image);
// Render Loop
while (!glfwWindowShouldClose(window))
{
processInput(window);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//glBindTexture(GL_TEXTURE_2D, texture);
//glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawElementsInstanced(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0, 4);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);
glDeleteBuffers(1, &iVBO);
glfwTerminate();
return 0;
}
void shader(GLuint window_width, GLuint window_height)
{
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);
glm::mat4 lookAt = glm::lookAt
(
glm::vec3(0, 0, 1), // Camera is at (x,y,z), in World Space,
glm::vec3(0, 0, 0), // and looks at the origin.
glm::vec3(0, 1, 0) // Head is up (set to 0,-1,0 to look upside-down).
);
glm::mat4 projection = glm::perspective(glm::radians(120.0f), window_width / (float)window_height, 0.1f, 100.0f);
glm::mat4 view_projection = glm::translate(projection, glm::vec3(0.0f, 0.0f, -1.0f));
glm::mat4 model_view_projection = glm::rotate(view_projection, glm::radians(0.0f), glm::vec3(1.0f, 0.0f, 0.0f));
// retrieve the matrix uniform locations
GLuint MVPLoc = glGetUniformLocation(shaderProgram, "MVP");
// pass them to the shaders (3 different ways)
glUniformMatrix4fv(MVPLoc, 1, GL_FALSE, glm::value_ptr(model_view_projection));
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
}
They need to all look like the one in the middle : square, since the rest of the cube should be directly behind.