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