Complete hello triangle program but with GLAD instead of GLEW
This commit is contained in:
commit
23bc471bc2
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
thirdparty/SDL2/
|
||||||
|
thirdparty/GLEW/
|
||||||
|
|
||||||
|
build/
|
||||||
|
.cache/
|
||||||
|
.vscode/
|
||||||
75
CMakeLists.txt
Normal file
75
CMakeLists.txt
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
project(openglsdl2proj VERSION 0.1.0 LANGUAGES C CXX)
|
||||||
|
|
||||||
|
set(EXE_NAME project)
|
||||||
|
|
||||||
|
set(SDL2_LOCAL OFF)
|
||||||
|
set(GLEW_LOCAL OFF)
|
||||||
|
set(GLEW_NOT_GLAD OFF)
|
||||||
|
|
||||||
|
function(copy_shaders_to_target_dir target)
|
||||||
|
add_custom_command(
|
||||||
|
TARGET ${target} POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||||
|
"$<TARGET_PROPERTY:${target},SOURCE_DIR>/shaders"
|
||||||
|
"$<TARGET_PROPERTY:${target},BINARY_DIR>/"
|
||||||
|
)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# Option to switch between a system sdl library and a sdl library from in project
|
||||||
|
# source code
|
||||||
|
option(SDL2_LOCAL "Use non-system SDL2 library" OFF)
|
||||||
|
# Same thing but for GLEW
|
||||||
|
option(GLEW_LOCAL "Use non-system GLEW library" OFF)
|
||||||
|
|
||||||
|
# Copied almost verbatim from here https://wiki.libsdl.org/SDL2/README/cmake#including-sdl-in-your-project
|
||||||
|
# This either gets SDL2 from it's CMakeLists.txt in source or links it from the system dll
|
||||||
|
if(SDL2_LOCAL)
|
||||||
|
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/thirdparty//SDL2 EXCLUDE_FROM_ALL ${CMAKE_CURRENT_BINARY_DIR}/SDL2)
|
||||||
|
else()
|
||||||
|
# 1. Look for a SDL2 package, 2. look for the SDL2 component and 3. fail if none can be found
|
||||||
|
find_package(SDL2 REQUIRED CONFIG REQUIRED COMPONENTS SDL2)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Get OpenGL since we need it
|
||||||
|
#find_package(OpenGL REQUIRED COMPONENTS EGL)
|
||||||
|
|
||||||
|
# find glew either by local source code for just link to system dll
|
||||||
|
if(GLEW_LOCAL AND GLEW_NOT_GLAD)
|
||||||
|
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/GLEW/build/cmake EXCLUDE_FROM_ALL ${CMAKE_CURRENT_BINARY_DIR}/GLEW)
|
||||||
|
else()
|
||||||
|
find_package(GLEW REQUIRED)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Main executable
|
||||||
|
add_executable(${EXE_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc)
|
||||||
|
# Show all warnings, works for clang and GCC
|
||||||
|
target_compile_options(${EXE_NAME} PRIVATE -Wall -Wextra -Wpedantic) #-Werror)
|
||||||
|
# Set c++ standard for executable
|
||||||
|
set_target_properties(${EXE_NAME}
|
||||||
|
PROPERTIES
|
||||||
|
CXX_STANDARD 17
|
||||||
|
CXX_STANDARD_REQUIRED ON
|
||||||
|
CXX_EXTENSIONS ON
|
||||||
|
)
|
||||||
|
target_include_directories(${EXE_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/include)
|
||||||
|
copy_shaders_to_target_dir(${EXE_NAME})
|
||||||
|
|
||||||
|
# Link to the actual SDL2 library.
|
||||||
|
# SDL2::SDL2 is the shared SDL library, SDL2::SDL2-static is the static SDL library.
|
||||||
|
if(NOT SDL2_LOCAL)
|
||||||
|
target_link_libraries(${EXE_NAME} PRIVATE SDL2::SDL2)
|
||||||
|
else()
|
||||||
|
target_link_libraries(${EXE_NAME} PRIVATE SDL2::SDL2-static)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Link to OpenGL
|
||||||
|
#target_link_libraries(${EXE_NAME} PRIVATE OpenGL::EGL)
|
||||||
|
|
||||||
|
# Link to GLEW
|
||||||
|
if(NOT GLEW_LOCAL AND GLEW_NOT_GLAD)
|
||||||
|
target_link_libraries(${EXE_NAME} PRIVATE ${GLEW_LIBRARIES})
|
||||||
|
elseif(GLEW_NOT_GLAD)
|
||||||
|
# Static version of GLEW
|
||||||
|
target_link_libraries(${EXE_NAME} PRIVATE glew_s)
|
||||||
|
endif()
|
||||||
1437
include/glad/egl.h
Normal file
1437
include/glad/egl.h
Normal file
File diff suppressed because it is too large
Load Diff
3787
include/glad/gles2.h
Normal file
3787
include/glad/gles2.h
Normal file
File diff suppressed because it is too large
Load Diff
4
shaders/hello_triangle.frag
Normal file
4
shaders/hello_triangle.frag
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#version 320 es
|
||||||
|
out mediump vec4 FragColor;
|
||||||
|
|
||||||
|
void main(){ FragColor = vec4(0.0f, 0.5f, 0.25f, 1.0f);}
|
||||||
7
shaders/hello_triangle.vert
Normal file
7
shaders/hello_triangle.vert
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#version 320 es
|
||||||
|
layout (location = 0) in vec3 aPos;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
|
||||||
|
}
|
||||||
277
src/main.cc
Normal file
277
src/main.cc
Normal file
@ -0,0 +1,277 @@
|
|||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
#define GLAD_EGL_IMPLEMENTATION
|
||||||
|
#define GLAD_GLES2_IMPLEMENTATION
|
||||||
|
#include "glad/gles2.h"
|
||||||
|
|
||||||
|
#include "SDL.h"
|
||||||
|
|
||||||
|
const char *mouseButtonName(int);
|
||||||
|
bool handleEvents(const SDL_Event&);
|
||||||
|
|
||||||
|
const char *readFile(const char *);
|
||||||
|
|
||||||
|
int main(const int argc, char **argv) {
|
||||||
|
for(int i=0;i<argc;i++) {
|
||||||
|
printf("Arg %d: %s\n", i, argv[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Init(SDL_INIT_VIDEO|SDL_INIT_EVENTS);
|
||||||
|
SDL_Window *window = SDL_CreateWindow("SDL2 Window",
|
||||||
|
SDL_WINDOWPOS_CENTERED,
|
||||||
|
SDL_WINDOWPOS_CENTERED,
|
||||||
|
512,
|
||||||
|
512,
|
||||||
|
SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);
|
||||||
|
|
||||||
|
SDL_Event event;
|
||||||
|
|
||||||
|
// Initialize GL context stuff (OpenGL ES 3.2)
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); // change to 3 later
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); // change to 2 later
|
||||||
|
SDL_GL_SetAttribute(
|
||||||
|
SDL_GL_CONTEXT_PROFILE_MASK,
|
||||||
|
SDL_GL_CONTEXT_PROFILE_ES); // SDL_GL_CONTEXT_PROFILE_CORE
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||||
|
|
||||||
|
|
||||||
|
// Create GL context for SDL2
|
||||||
|
SDL_GLContext GLContext = SDL_GL_CreateContext(window);
|
||||||
|
if (GLContext == nullptr) {
|
||||||
|
fprintf(stderr, "Failed to create OpenGL context!\n");
|
||||||
|
|
||||||
|
SDL_DestroyWindow(window);
|
||||||
|
SDL_Quit();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_GL_SetSwapInterval(1); // sets VSYNC
|
||||||
|
|
||||||
|
// Setup GLAD (OpenGL ES 3.2)
|
||||||
|
int gladVersion = gladLoadGLES2(reinterpret_cast<GLADloadfunc>(SDL_GL_GetProcAddress));
|
||||||
|
printf("GL Version %d.%d\n", GLAD_VERSION_MAJOR(gladVersion), GLAD_VERSION_MINOR(gladVersion));
|
||||||
|
if (gladVersion == 0) {
|
||||||
|
fputs("Failed to init GLAD\n", stderr);
|
||||||
|
|
||||||
|
SDL_GL_DeleteContext(GLContext);
|
||||||
|
SDL_DestroyWindow(window);
|
||||||
|
SDL_Quit();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Variables needed for next steps
|
||||||
|
const char* vertexShaderSource = readFile("hello_triangle.vert");
|
||||||
|
const char* fragmentShaderSource = readFile("hello_triangle.frag");
|
||||||
|
|
||||||
|
if(vertexShaderSource == nullptr || fragmentShaderSource == nullptr) {
|
||||||
|
fputs("Could not get shaders from files!\n", stderr);
|
||||||
|
|
||||||
|
SDL_GL_DeleteContext(GLContext);
|
||||||
|
SDL_DestroyWindow(window);
|
||||||
|
SDL_Quit();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int success;
|
||||||
|
char infoLog[512];
|
||||||
|
|
||||||
|
// Vertex shader
|
||||||
|
GLuint vertexShader;
|
||||||
|
vertexShader = glCreateShader(GL_VERTEX_SHADER);
|
||||||
|
glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
|
||||||
|
glCompileShader(vertexShader);
|
||||||
|
|
||||||
|
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
|
||||||
|
if(!success)
|
||||||
|
{
|
||||||
|
glGetShaderInfoLog(vertexShader, 512, nullptr, infoLog);
|
||||||
|
printf("Vertex shader compile failure!\n%s\n", infoLog);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fragment shader
|
||||||
|
GLuint fragmentShader;
|
||||||
|
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
|
||||||
|
glCompileShader(fragmentShader);
|
||||||
|
|
||||||
|
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
|
||||||
|
if(!success)
|
||||||
|
{
|
||||||
|
glGetShaderInfoLog(fragmentShader, 512, nullptr, infoLog);
|
||||||
|
fprintf(stderr, "Fragment shader compile failure!\n%s\n", infoLog);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shader program
|
||||||
|
GLuint shaderProgram;
|
||||||
|
shaderProgram = glCreateProgram();
|
||||||
|
|
||||||
|
glAttachShader(shaderProgram, vertexShader);
|
||||||
|
glAttachShader(shaderProgram, fragmentShader);
|
||||||
|
glLinkProgram(shaderProgram);
|
||||||
|
|
||||||
|
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
|
||||||
|
if(!success) {
|
||||||
|
glGetProgramInfoLog(shaderProgram, 512, nullptr, infoLog);
|
||||||
|
fprintf(stderr, "Shader program linking failure!\n%s\n", infoLog);
|
||||||
|
}
|
||||||
|
|
||||||
|
glDeleteShader(vertexShader);
|
||||||
|
glDeleteShader(fragmentShader);
|
||||||
|
|
||||||
|
// Setup for our hello triangle
|
||||||
|
float vertices[] = {
|
||||||
|
-0.5f, -0.5f, 0.0f,
|
||||||
|
0.5f, -0.5f, 0.0f,
|
||||||
|
0.0f, 0.5f, 0.0f
|
||||||
|
};
|
||||||
|
|
||||||
|
// Vertex insanity
|
||||||
|
GLuint VBO, VAO;
|
||||||
|
glGenVertexArrays(1, &VAO);
|
||||||
|
glGenBuffers(1, &VBO);
|
||||||
|
glBindVertexArray(VAO);
|
||||||
|
|
||||||
|
// Bind buffers?
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
// Something with the vertex array
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
|
||||||
|
// Not sure what this is for
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
|
||||||
|
// Main loop
|
||||||
|
bool running = true;
|
||||||
|
while (running)
|
||||||
|
{
|
||||||
|
while (SDL_PollEvent(&event) > 0)
|
||||||
|
{
|
||||||
|
running = handleEvents(event);
|
||||||
|
|
||||||
|
// set color for window then
|
||||||
|
// clear color buffer
|
||||||
|
glClearColor(0.13f, 0.31f, 0.5f, 1.0f);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
// Draw our triangle
|
||||||
|
glUseProgram(shaderProgram);
|
||||||
|
glBindVertexArray(VAO);
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||||
|
|
||||||
|
// Draw everything to the window
|
||||||
|
SDL_GL_SwapWindow(window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
glDeleteVertexArrays(1, &VAO);
|
||||||
|
glDeleteBuffers(1, &VBO);
|
||||||
|
glDeleteProgram(shaderProgram);
|
||||||
|
|
||||||
|
SDL_GL_DeleteContext(GLContext);
|
||||||
|
SDL_DestroyWindow(window);
|
||||||
|
SDL_Quit();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* readFile(const char* path) {
|
||||||
|
FILE *fd = nullptr;
|
||||||
|
#if _MSC_VER
|
||||||
|
fopen_s(&fd, path, "rb");
|
||||||
|
#else
|
||||||
|
fd = fopen(path, "rb");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
long fileSize = 0;
|
||||||
|
char* buf = nullptr;
|
||||||
|
|
||||||
|
if(fd == nullptr) {
|
||||||
|
fprintf(stderr, "Could not open %s\n", path);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(fd, 0L, SEEK_END);
|
||||||
|
fileSize = ftell(fd);
|
||||||
|
fseek(fd, 0L, SEEK_SET);
|
||||||
|
|
||||||
|
buf = reinterpret_cast<char*>(malloc(sizeof(char) * (fileSize + 1)));
|
||||||
|
|
||||||
|
fread((void*)buf, sizeof(uint8_t), fileSize, fd);
|
||||||
|
fclose(fd);
|
||||||
|
|
||||||
|
buf[fileSize] = '\0';
|
||||||
|
printf("0x%02x\n", buf[fileSize]);
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
char const *mouseButtonName(const int button)
|
||||||
|
{
|
||||||
|
const char *result = "NO_BUTTON";
|
||||||
|
switch (button)
|
||||||
|
{
|
||||||
|
case SDL_BUTTON_LEFT:
|
||||||
|
result = "left";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SDL_BUTTON_MIDDLE:
|
||||||
|
result = "middle";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SDL_BUTTON_RIGHT:
|
||||||
|
result = "right";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
result = "unknown";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool handleEvents(const SDL_Event& event)
|
||||||
|
{
|
||||||
|
switch (event.type)
|
||||||
|
{
|
||||||
|
case SDL_QUIT:
|
||||||
|
puts("Quitting application");
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Shows xy of mouse in window
|
||||||
|
case SDL_MOUSEMOTION:
|
||||||
|
printf("Mouse Position = { %d %d }\n",
|
||||||
|
event.motion.x,
|
||||||
|
event.motion.y);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// For debugging, shows name of mouse button pressed
|
||||||
|
case SDL_MOUSEBUTTONDOWN:
|
||||||
|
case SDL_MOUSEBUTTONUP:
|
||||||
|
printf("%s mouse button %s\n",
|
||||||
|
mouseButtonName(event.button.button)
|
||||||
|
,((event.button.state == SDL_PRESSED) ? "pressed" : "released"));
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// For debugging, shows name of key that is pressed
|
||||||
|
case SDL_KEYDOWN:
|
||||||
|
case SDL_KEYUP:
|
||||||
|
printf("Key %s %s\n",
|
||||||
|
SDL_GetKeyName(event.key.keysym.sym),
|
||||||
|
((event.key.state == SDL_PRESSED) ? "pressed" : "released"));
|
||||||
|
return true;
|
||||||
|
// Handle resizing window
|
||||||
|
case SDL_WINDOWEVENT:
|
||||||
|
if(event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
|
||||||
|
glViewport(0,0, event.window.data1,event.window.data2);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user