Draw first triangle
This commit is contained in:
parent
1a60a9fc93
commit
579d8c3b1a
213
src/main.cc
Normal file
213
src/main.cc
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
// GLAD
|
||||||
|
#include "glad/glad.h"
|
||||||
|
|
||||||
|
// GLM
|
||||||
|
#define GLM_ENABLE_EXPERIMENTAL
|
||||||
|
#include "glm/ext/matrix_transform.hpp"
|
||||||
|
#include "glm/ext/vector_float3.hpp"
|
||||||
|
#include "glm/gtc/type_ptr.hpp"
|
||||||
|
#include "glm/trigonometric.hpp"
|
||||||
|
#include "glm/gtx/rotate_vector.hpp"
|
||||||
|
#include "glm/gtx/string_cast.hpp"
|
||||||
|
|
||||||
|
// SDL
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
#include <SDL2/SDL_stdinc.h>
|
||||||
|
#include <SDL2/SDL_error.h>
|
||||||
|
#include <SDL2/SDL_video.h>
|
||||||
|
#include <SDL2/SDL_events.h>
|
||||||
|
#include <SDL2/SDL_mouse.h>
|
||||||
|
#include <SDL2/SDL_keycode.h>
|
||||||
|
|
||||||
|
// STDLIB
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cmath>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#define WINDOW_WIDTH 1280
|
||||||
|
#define WINDOW_HEIGHT 720
|
||||||
|
#define WINDOW_HALF_WIDTH 640
|
||||||
|
#define WINDOW_HALF_HEIGHT 360
|
||||||
|
|
||||||
|
enum exit_codes : int {
|
||||||
|
EXIT_CODE_SUCCESS,
|
||||||
|
EXIT_CODE_SDL_INIT_FAILED,
|
||||||
|
EXIT_CODE_WINDOW_CREATION_FAILED,
|
||||||
|
EXIT_CODE_OPENGL_CONTEXT_FAILED,
|
||||||
|
EXIT_CODE_GLAD_LOADER_FAILED,
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string load_shader(const std::string &filepath);
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
|
||||||
|
return EXIT_CODE_SDL_INIT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 24);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||||
|
|
||||||
|
SDL_Window *window = SDL_CreateWindow("Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
||||||
|
WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
|
||||||
|
if (!window) {
|
||||||
|
return EXIT_CODE_WINDOW_CREATION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_GLContext context = SDL_GL_CreateContext(window);
|
||||||
|
if (!context) {
|
||||||
|
return EXIT_CODE_OPENGL_CONTEXT_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gladLoadGLLoader(SDL_GL_GetProcAddress) == 0) {
|
||||||
|
return EXIT_CODE_GLAD_LOADER_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||||
|
|
||||||
|
std::vector<GLfloat> vertices = {
|
||||||
|
-0.5f, -0.5f, 0.0f, // position
|
||||||
|
1.0f, 0.0f, 0.0f, // colour
|
||||||
|
0.5f, -0.5f, 0.0f, // position
|
||||||
|
0.0f, 0.0f, 1.0f, // colour
|
||||||
|
0.0f, 0.5f, 0.0f, // position
|
||||||
|
0.0f, 1.0f, 0.0f, // colour
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<GLuint> indices = {0, 1, 2};
|
||||||
|
|
||||||
|
GLuint vao = 0;
|
||||||
|
glGenVertexArrays(1, &vao);
|
||||||
|
glBindVertexArray(vao);
|
||||||
|
|
||||||
|
GLuint ebo = 0;
|
||||||
|
glGenBuffers(1, &ebo);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), indices.data(), GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
GLuint vbo = 0;
|
||||||
|
glGenBuffers(1, &vbo);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GLfloat), vertices.data(), GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void *)0);
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void *)(3 * sizeof(GLfloat)));
|
||||||
|
glEnableVertexAttribArray(1);
|
||||||
|
|
||||||
|
glBindVertexArray(0);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glDisableVertexAttribArray(0);
|
||||||
|
glDisableVertexAttribArray(1);
|
||||||
|
|
||||||
|
std::string vs_shader = load_shader("shaders/vert.glsl");
|
||||||
|
const char *vs_source = vs_shader.c_str();
|
||||||
|
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
|
||||||
|
glShaderSource(vs, 1, &vs_source, NULL);
|
||||||
|
glCompileShader(vs);
|
||||||
|
GLint vs_compiled;
|
||||||
|
glGetShaderiv(vs, GL_COMPILE_STATUS, &vs_compiled);
|
||||||
|
if (vs_compiled != GL_TRUE)
|
||||||
|
{
|
||||||
|
GLsizei log_length = 0;
|
||||||
|
GLchar message[1024];
|
||||||
|
glGetShaderInfoLog(vs, 1024, &log_length, message);
|
||||||
|
printf("Failed to compile vertex shader: %s\n", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string fs_shader = load_shader("shaders/frag.glsl");
|
||||||
|
const char *fs_source = fs_shader.c_str();
|
||||||
|
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
glShaderSource(fs, 1, &fs_source, NULL);
|
||||||
|
glCompileShader(fs);
|
||||||
|
GLint fs_compiled;
|
||||||
|
glGetShaderiv(fs, GL_COMPILE_STATUS, &fs_compiled);
|
||||||
|
if (fs_compiled != GL_TRUE)
|
||||||
|
{
|
||||||
|
GLsizei log_length = 0;
|
||||||
|
GLchar message[1024];
|
||||||
|
glGetShaderInfoLog(fs, 1024, &log_length, message);
|
||||||
|
printf("Failed to compile fragment shader: %s\n", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint program = glCreateProgram();
|
||||||
|
glAttachShader(program, vs);
|
||||||
|
glAttachShader(program, fs);
|
||||||
|
glLinkProgram(program);
|
||||||
|
GLint program_linked;
|
||||||
|
glGetProgramiv(program, GL_LINK_STATUS, &program_linked);
|
||||||
|
if (program_linked != GL_TRUE)
|
||||||
|
{
|
||||||
|
GLsizei log_length = 0;
|
||||||
|
GLchar message[1024];
|
||||||
|
glGetProgramInfoLog(program, 1024, &log_length, message);
|
||||||
|
printf("Failed to link program: %s\n", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
glDeleteShader(vs);
|
||||||
|
glDeleteShader(fs);
|
||||||
|
|
||||||
|
bool running = true;
|
||||||
|
SDL_Event event = {};
|
||||||
|
while (running) {
|
||||||
|
while (SDL_PollEvent(&event)) {
|
||||||
|
switch (event.type) {
|
||||||
|
case SDL_QUIT:
|
||||||
|
running = false;
|
||||||
|
break;
|
||||||
|
case SDL_KEYDOWN:
|
||||||
|
if (event.key.keysym.sym == SDLK_ESCAPE) {
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SDL_WINDOWEVENT:
|
||||||
|
if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
|
||||||
|
SDL_Window *wnd = SDL_GetWindowFromID(event.window.windowID);
|
||||||
|
if (!wnd) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int w, h;
|
||||||
|
SDL_GL_GetDrawableSize(wnd, &w, &h);
|
||||||
|
glViewport(0, 0, w, h);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
glUseProgram(program);
|
||||||
|
glBindVertexArray(vao);
|
||||||
|
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, NULL);
|
||||||
|
|
||||||
|
SDL_GL_SwapWindow(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_GL_DeleteContext(context);
|
||||||
|
SDL_DestroyWindow(window);
|
||||||
|
SDL_Quit();
|
||||||
|
|
||||||
|
return EXIT_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string load_shader(const std::string &filepath) {
|
||||||
|
FILE *fp = fopen(filepath.c_str(), "r");
|
||||||
|
if (!fp) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string output = {};
|
||||||
|
|
||||||
|
char buf[1024] = {0};
|
||||||
|
while (fgets(buf, sizeof(buf), fp)) {
|
||||||
|
output += buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user