Skip to content

Instantly share code, notes, and snippets.

@piusayowale
Created January 29, 2023 18:46
Show Gist options
  • Save piusayowale/9518b0a251a4a2e24855104f82ed39a3 to your computer and use it in GitHub Desktop.
Save piusayowale/9518b0a251a4a2e24855104f82ed39a3 to your computer and use it in GitHub Desktop.
1000 box with opengl
// 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