Created
January 29, 2023 18:46
-
-
Save piusayowale/9518b0a251a4a2e24855104f82ed39a3 to your computer and use it in GitHub Desktop.
1000 box with opengl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// graphOpengl.cpp : This file contains the 'main' function. Program execution begins and ends there. | |
// | |
#include <iostream> | |
#include <glad/glad.h> | |
#include <SDL2/SDL.h> | |
#include <SDL2/SDL_opengl.h> | |
#include <glm/glm.hpp> | |
#include <glm/gtc/matrix_transform.hpp> | |
#include <glm/gtc/type_ptr.hpp> | |
#include <vector> | |
#include <ctime> | |
#include <cstdlib> | |
const int MAXINSTANCE = 1000; | |
const char* vertex = R"( | |
#version 330 core | |
layout (location = 0) in vec3 aPos; | |
layout (std140) uniform MatricesBlock | |
{ | |
mat4 model[1000]; | |
}; | |
out vec3 color; | |
uniform mat4 projection; | |
uniform vec3 clor[1000]; | |
void main() | |
{ | |
color = clor[gl_InstanceID]; | |
gl_Position = projection * model[gl_InstanceID] * vec4(aPos.x, aPos.y, 0.0, 1.0f); | |
} | |
)"; | |
const char* fragment = R"( | |
#version 330 core | |
out vec4 FragColor; | |
in vec3 color; | |
void main() | |
{ | |
FragColor = vec4(color, 1.0f); | |
} | |
)"; | |
GLuint getProgram(const char* vertex, const char* fragment) { | |
// build and compile our shader program | |
// ------------------------------------ | |
// vertex shader | |
unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER); | |
glShaderSource(vertexShader, 1, &vertex, NULL); | |
glCompileShader(vertexShader); | |
// check for shader compile errors | |
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; | |
} | |
// fragment shader | |
unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); | |
glShaderSource(fragmentShader, 1, &fragment, NULL); | |
glCompileShader(fragmentShader); | |
// check for shader compile errors | |
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); | |
if (!success) | |
{ | |
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); | |
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; | |
} | |
// link shaders | |
unsigned int shaderProgram = glCreateProgram(); | |
glAttachShader(shaderProgram, vertexShader); | |
glAttachShader(shaderProgram, fragmentShader); | |
glLinkProgram(shaderProgram); | |
// check for linking errors | |
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); | |
if (!success) { | |
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); | |
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; | |
} | |
glDeleteShader(vertexShader); | |
glDeleteShader(fragmentShader); | |
return shaderProgram; | |
} | |
struct Vector3 { | |
float x; | |
float y; | |
float z; | |
}; | |
struct Vertex { | |
Vector3 vertice; | |
Vector3 color; | |
}; | |
Vertex vertices[] = { | |
Vector3{1.0f, 1.0f, 0.0f}, Vector3{1.0f, 0.5f, 1.0f}, | |
Vector3{1.0f, 0.0f, 0.0f}, Vector3{1.0f, 0.5f, 1.0f}, | |
Vector3{0.0f, 1.0f, 0.0f}, Vector3{1.0f, 0.5f, 1.0f}, | |
Vector3{0.0f, 0.0f, 0.0f}, Vector3{1.0f, 0.5f, 1.0f}, | |
}; | |
GLuint indices[] = { | |
0, 1, 2, | |
3, 2, 1 | |
}; | |
struct Batch { | |
std::vector<Vertex> vertices; | |
std::vector<GLuint> indices; | |
std::vector <glm::mat4> modelMatrix; | |
std::vector<glm::vec3> color; | |
}; | |
static Batch gVertexBatch{}; | |
static int counter = 0; | |
void addRectangle(const glm::vec3& pos, const glm::vec3& color) { | |
counter = counter + 1; | |
glm::mat4 tran = glm::mat4(1.0f); | |
tran = glm::translate(tran, pos); | |
tran = glm::scale(tran, glm::vec3(glm::vec2(float(rand() % 50), float(rand() % 50)), 1.0f)); | |
if (gVertexBatch.vertices.empty()) { | |
for (auto i : indices) { | |
gVertexBatch.indices.push_back(i); | |
} | |
for (const Vertex& i : vertices) { | |
gVertexBatch.vertices.push_back(i); | |
} | |
} | |
gVertexBatch.modelMatrix.push_back( tran); | |
gVertexBatch.color.push_back( color ); | |
std::cout << gVertexBatch.color.size() << "\n"; | |
} | |
int main(int argc, char ** argv) | |
{ | |
SDL_Init(SDL_INIT_EVERYTHING); | |
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); | |
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); | |
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 5); | |
// Also request a depth buffer | |
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); | |
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); | |
SDL_Window* window = SDL_CreateWindow("Test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 600, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL); | |
SDL_GLContext context = SDL_GL_CreateContext(window); | |
SDL_GL_SetSwapInterval(1); | |
gladLoadGLLoader(SDL_GL_GetProcAddress); | |
SDL_Event event; | |
srand(time(0)); | |
/*addRectangle(glm::vec3{0.0f, 40.0f, 0.0f}, glm::vec3{1.0f, 0.0f, 0.0f}); | |
addRectangle(glm::vec3{ 200.0f, 100.0f, 0.0f }, glm::vec3{ 0.0f, 1.0f, 0.0f }); | |
addRectangle(glm::vec3{ 500.0f, 0.0f, 0.0f }, glm::vec3{ 0.0f, 0.0f, 1.0f }); | |
addRectangle(glm::vec3{ rand() % 560, rand() % 560, 0.0f}, glm::vec3{0.5f, 0.1f, 1.0f}); | |
addRectangle(glm::vec3{ 90.0f, 50.0f, 0.0f }, glm::vec3{ 1.0f, 1.0f, 1.0f });*/ | |
for (int i = 0; i < 1000; i++) { | |
addRectangle(glm::vec3{ rand() % 560, rand() % 560, 0.0f }, glm::vec3{ (float)(rand() % 10) / 10.0f, (float)(rand() % 10) / 10.0f, (float)(rand() % 10) / 10.0f }); | |
} | |
/*addRectangle(glm::vec3{ rand() % 560, rand() % 560, 0.0f }, glm::vec3{ (float)(rand() % 10) / 10.0f, (float)(rand() % 10) / 10.0f, (float)(rand() % 10) / 10.0f }); | |
addRectangle(glm::vec3{ rand() % 560, rand() % 560, 0.0f }, glm::vec3{ (float)(rand() % 10) / 10.0f, (float)(rand() % 10) / 10.0f,(float)(rand() % 10) / 10.0f }); | |
addRectangle(glm::vec3{ rand() % 560, rand() % 560, 0.0f }, glm::vec3{ (float)(rand() % 10) / 10.0f, (float)(rand() % 10) / 10.0f, (float)(rand() % 10) / 10.0f }); | |
addRectangle(glm::vec3{ rand() % 560, rand() % 560, 0.0f }, glm::vec3{ (float)(rand() % 10) / 10.0f,(float)(rand() % 10) / 10.0f, (float)(rand() % 10) / 10.0f });*/ | |
GLuint shaderProgram = getProgram(vertex, fragment); | |
unsigned int VBO, VAO, EBO, UBO; | |
glGenVertexArrays(1, &VAO); | |
glGenBuffers(1, &VBO); | |
glGenBuffers(1, &EBO); | |
// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s). | |
glBindVertexArray(VAO); | |
glBindBuffer(GL_ARRAY_BUFFER, VBO); | |
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * gVertexBatch.vertices.size(), gVertexBatch.vertices.data(), GL_STATIC_DRAW); | |
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); | |
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * gVertexBatch.indices.size(), gVertexBatch.indices.data(), GL_STATIC_DRAW); | |
glBindBuffer(GL_ARRAY_BUFFER, VBO); | |
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, vertice)); | |
glEnableVertexAttribArray(0); | |
glGenBuffers(1, &UBO); | |
glBindBuffer(GL_UNIFORM_BUFFER, UBO); | |
glBufferData(GL_UNIFORM_BUFFER, (sizeof(glm::mat4) * MAXINSTANCE), NULL, GL_DYNAMIC_DRAW); | |
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4) * gVertexBatch.modelMatrix.size(), gVertexBatch.modelMatrix.data()); | |
// glBufferSubData(GL_UNIFORM_BUFFER, sizeof(glm::mat4) * MAXINSTANCE, sizeof(glm::vec3) * gVertexBatch.color.size(), (void *)gVertexBatch.color.data()); | |
GLuint bindingPoint = 1; | |
GLuint matricesBlockIndex = glGetUniformBlockIndex(shaderProgram, "MatricesBlock"); | |
glUniformBlockBinding(shaderProgram, matricesBlockIndex, bindingPoint); | |
glBindBufferBase(GL_UNIFORM_BUFFER, bindingPoint, UBO); | |
// note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind | |
glBindBuffer(GL_ARRAY_BUFFER, 0); | |
glBindVertexArray(0); | |
while (true) | |
{ | |
glViewport(0, 0, 600, 600); | |
glClearColor(1.f, 0.f, 1.f, 0.f); | |
glClear(GL_COLOR_BUFFER_BIT); | |
//glm::vec2 size = glm::vec2(50.0f, 50.0f); | |
glm::mat4 projection(1.0f); | |
projection = glm::ortho(0.0f, (float)600, (float)600, 0.0f, -1.0f, 0.0f); | |
// render | |
// ------ | |
glClearColor(0.2f, 0.3f, 0.3f, 1.0f); | |
glClear(GL_COLOR_BUFFER_BIT); | |
// draw our first triangle | |
glUseProgram(shaderProgram); | |
unsigned int projectLoc = glGetUniformLocation(shaderProgram, "projection"); | |
glUniformMatrix4fv(projectLoc, 1, GL_FALSE, glm::value_ptr(projection)); | |
unsigned int modelLoc = glGetUniformLocation(shaderProgram, "clor"); | |
glUniform3fv(modelLoc, counter, glm::value_ptr(gVertexBatch.color.data()[0])); | |
glBindVertexArray(VAO); | |
glDrawElementsInstanced(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0, counter); | |
if (SDL_PollEvent(&event)) { | |
switch (event.type) | |
{ | |
case SDL_QUIT: | |
goto QUIT; | |
default: | |
break; | |
} | |
} | |
SDL_GL_SwapWindow(window); | |
} | |
QUIT: | |
SDL_DestroyWindow(window); | |
SDL_Quit(); | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment