Я экспериментировал с использованием объектов Vertex Array и Element Buffer Objects. Мне удалось нарисовать букву «H» на моем экране, используя одну VAO с привязкой к EBO, поскольку все мои вершины и индексы были в одном массиве. Я хотел разделить каждый прямоугольник на отдельный объект и дать ему другой цвет, но только один из них рисует на экране.
Вот код:
#include <glew.h>
#include <glfw3.h>
#include <iostream>
const char* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
"gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\0";
const char* fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
"FragColor = vec4(0.2f, 0.6f, 0.7f, 1.0f);\n"
"}\0";
const char* fragmentShaderSource2 = "#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
"FragColor = vec4(0.7f, 0.4f, 0.3f, 1.0f);\n"
"}\0";
const char* fragmentShaderSource3 = "#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
"FragColor = vec4(0.1f, 0.2f, 0.6f, 1.0f);\n"
"}\0";
int main(void)
{
GLFWwindow* window;
glewInit();
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
/* Initialize the library */
if (!glfwInit())
return -1;
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
if (glewInit() != GLEW_OK)
std::cout << "Error!" << std::endl;
float vertices[] = {
0.2f, 0.7f, 0.0f,
0.3f, 0.7f, 0.0f,
0.3f, 0.2f, 0.0f,
0.2f, 0.2f, 0.0f
};
float vertices2[] = {
0.6f, 0.7f, 0.0f,
0.7f, 0.7f, 0.0f,
0.7f, 0.2f, 0.0f,
0.6f, 0.2f, 0.0f
};
float vertices3[] = {
0.3f, 0.4f, 0.0f,
0.3f, 0.5f, 0.0f,
0.6f, 0.5f, 0.0f,
0.6f, 0.4f, 0.0f
};
unsigned int indices[] = {
1, 0, 2,
2, 3, 0
};
unsigned int indices2[] = {
5, 4, 6,
6, 7, 4
};
unsigned int indices3[] = {
8, 9, 11,
11, 10, 9
};
unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
int success;
char infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
unsigned int fragmentShader2 = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader2, 1, &fragmentShaderSource2, NULL);
glCompileShader(fragmentShader2);
unsigned int fragmentShader3 = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader3, 1, &fragmentShaderSource3, NULL);
glCompileShader(fragmentShader3);
unsigned int shaderProgram;
shaderProgram = glCreateProgram();
unsigned int shaderProgram2;
shaderProgram2 = glCreateProgram();
unsigned int shaderProgram3;
shaderProgram3 = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glAttachShader(shaderProgram2, fragmentShader2);
glAttachShader(shaderProgram2, vertexShader);
glLinkProgram(shaderProgram2);
glAttachShader(shaderProgram3, fragmentShader3);
glAttachShader(shaderProgram3, vertexShader);
glLinkProgram(shaderProgram3);
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(shaderProgram, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
glDeleteShader(fragmentShader2);
glDeleteShader(fragmentShader3);
unsigned int VBOs[3], VAOs[3], EBOs[3];
glGenVertexArrays(3, VAOs);
glGenBuffers(3, VBOs);
glGenBuffers(3, EBOs);
glBindVertexArray(VAOs[0]);
glBindBuffer(GL_ARRAY_BUFFER, VBOs[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBOs[0]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindVertexArray(VAOs[1]);
glBindBuffer(GL_ARRAY_BUFFER, VBOs[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices2), vertices2, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBOs[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices2), indices2, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindVertexArray(VAOs[2]);
glBindBuffer(GL_ARRAY_BUFFER, VBOs[2]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices3), vertices3, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBOs[2]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices3), indices3, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
/* Render here */
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(VAOs[0]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glUseProgram(shaderProgram2);
glBindVertexArray(VAOs[1]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glUseProgram(shaderProgram3);
glBindVertexArray(VAOs[2]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glDeleteVertexArrays(3, VAOs);
glDeleteBuffers(3, VBOs);
glDeleteBuffers(3, EBOs);
glfwTerminate();
return 0;
}