Tutorial: How to add shaders and shader problem files to the CMake project of sdl3-sample
- Install the
sdl3-sample
template - Convert SDL rendering to OpenGL rendering
- Create two shader files:
color.vert
andcolor.frag
in thesdl3-sample/assets/shaders
folder - Open the
sdl3-sample/CMakeLists.txt
file and add this code:
if(CMAKE_SYSTEM_NAME MATCHES Emscripten)
set(CMAKE_EXECUTABLE_SUFFIX ".html" CACHE INTERNAL "")
target_link_options("${EXECUTABLE_NAME}" PRIVATE "SHELL:--embed-file ${CMAKE_CURRENT_SOURCE_DIR}/assets/shaders/color.vert@/assets/shaders/color.vert")
set_property(TARGET "${EXECUTABLE_NAME}" APPEND PROPERTY LINK_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/assets/shaders/color.vert")
target_link_options("${EXECUTABLE_NAME}" PRIVATE "SHELL:--embed-file ${CMAKE_CURRENT_SOURCE_DIR}/assets/shaders/color.frag@/assets/shaders/color.frag")
set_property(TARGET "${EXECUTABLE_NAME}" APPEND PROPERTY LINK_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/assets/shaders/color.frag")
endif()
- Create the
sdl3-sample/src/shader_program.cpp
andshader_probram.cpp
files inside of thesdl3-sample/src
folder - Add the
sdl3-sample/src/shader_program.cpp
line to thesdl3-sample/CMakeLists.txt
file:
target_sources(${EXECUTABLE_NAME}
PRIVATE
src/main.cpp
src/iosLaunchScreen.storyboard
src/Sample.appxManifest
src/shader_program.cpp
)
- Copy the next content to the files:
assets/shaders/color.vert
attribute vec3 aPosition;
uniform mat4 uMvpMatrix;
void main()
{
gl_Position = uMvpMatrix * vec4(aPosition, 1.0);
}
assets/shaders/color.frag
#ifdef GL_ES
precision mediump float;
#endif
uniform vec3 uColor;
void main()
{
gl_FragColor = vec4(uColor, 1.0);
}
src/shader_program.h
#ifndef SHADER_PROGRAM_H
#define SHADER_PROGRAM_H
#include <SDL3/SDL_opengles2.h>
#include <string>
// Helper function for creating shaders
GLuint createShader(const char *shaderSource, int shaderType);
// Helper function for creating a shader program
GLuint createShaderProgram(const std::string vShaderPath, const std::string fShaderPath);
#endif // SHADER_PROGRAM_H
src/shader_program.cpp
#include "shader_program.h"
#include <iostream>
#include <fstream>
#include <iostream>
#include <sstream>
// Helper function for creating shaders
GLuint createShader(const char *shaderSource, int shaderType)
{
GLuint shader = glCreateShader(shaderType);
glShaderSource(shader, 1, &shaderSource, NULL);
glCompileShader(shader);
GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE)
{
GLint maxLength = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength);
std::vector<GLchar> errorLog(maxLength);
glGetShaderInfoLog(shader, maxLength, &maxLength, &errorLog[0]);
glDeleteShader(shader); // Don't leak the shader
std::cout << &(errorLog[0]) << std::endl;
std::cout << shaderSource << std::endl;
}
return shader;
}
// Helper function for creating a shader program
GLuint createShaderProgram(const std::string vShaderPath,
const std::string fShaderPath)
{
std::ifstream vf(vShaderPath);
if (!vf.is_open())
{
std::cout << "Failed to open the file: " << vShaderPath << std::endl;
return 0;
}
std::stringstream vsstr;
vf >> vsstr.rdbuf();
std::string vContent = vsstr.str();
vf.close();
std::ifstream ff(fShaderPath);
if (!ff.is_open())
{
std::cout << "Failed to open the file: " << fShaderPath << std::endl;
return 0;
}
std::stringstream fsstr;
ff >> fsstr.rdbuf();
std::string fContent = fsstr.str();
ff.close();
GLuint program = glCreateProgram();
GLuint vShader = createShader(vContent.c_str(), GL_VERTEX_SHADER);
GLuint fShader = createShader(fContent.c_str(), GL_FRAGMENT_SHADER);
glAttachShader(program, vShader);
glAttachShader(program, fShader);
glLinkProgram(program);
glUseProgram(program);
return program;
}