Created
January 28, 2023 19:08
-
-
Save piusayowale/52e9058760f37b5606225e4828a47c8f to your computer and use it in GitHub Desktop.
a step closer to batch rendering
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> | |
const char* vertex = R"( | |
#version 330 core | |
layout (location = 0) in vec3 aPos; | |
layout (location = 1) in vec3 aCol; | |
out vec3 color; | |
uniform mat4 model; | |
uniform mat4 projection; | |
void main() | |
{ | |
color = aCol; | |
gl_Position = projection * model * vec4(aPos.x, aPos.y, 0.0, 1.0); | |
} | |
)"; | |
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; | |
}; | |
static Batch gVertexBatch{}; | |
void addRectangle() { | |
for (auto i : indices) { | |
gVertexBatch.indices.push_back(i); | |
} | |
for (auto i : vertices) { | |
gVertexBatch.vertices.push_back(i); | |
} | |
} | |
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; | |
addRectangle(); | |
GLuint shaderProgram = getProgram(vertex, fragment); | |
unsigned int VBO, VAO, EBO; | |
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); | |
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, vertice)); | |
glEnableVertexAttribArray(0); | |
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, color)); | |
glEnableVertexAttribArray(1); | |
// 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 model = glm::mat4(1.0f); // make sure to initialize matrix to identity matrix first | |
model = glm::translate(model, glm::vec3((600 - 300) / 2, (600 - 100) / 2, 0.0f)); | |
model = glm::scale(model, glm::vec3(glm::vec2(70.0f, 50.0f), 1.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 transformLoc = glGetUniformLocation(shaderProgram, "model"); | |
glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(model)); | |
unsigned int projectLoc = glGetUniformLocation(shaderProgram, "projection"); | |
glUniformMatrix4fv(projectLoc, 1, GL_FALSE, glm::value_ptr(projection)); | |
glBindVertexArray(VAO); | |
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); | |
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