Added some comments

This commit is contained in:
Pablo Rodriguez
2025-07-31 02:09:45 -04:00
parent 40b7639c66
commit ffe7731f10
7 changed files with 73 additions and 4 deletions

View File

@@ -16,10 +16,12 @@
namespace ugly { namespace ugly {
int App::main(std::vector<std::string> &args) { int App::main(std::vector<std::string> &args) {
// Initialize global log.
auto cerrLog = TimestampLog{"ugly::log", std::cerr}; auto cerrLog = TimestampLog{"ugly::log", std::cerr};
log = LogAlias{&cerrLog}; log = LogAlias{&cerrLog};
log("hello, world! app started."); log("hello, world! app started.");
// Initialize GLFW.
glfwSetErrorCallback(error_callback_s); glfwSetErrorCallback(error_callback_s);
glfwInit(); glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
@@ -27,6 +29,7 @@ int App::main(std::vector<std::string> &args) {
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
// Create GLFW window and OpenGL context for GLEW.
auto window = glfwCreateWindow(640, 480, "uGLy", NULL, NULL); auto window = glfwCreateWindow(640, 480, "uGLy", NULL, NULL);
glfwMakeContextCurrent(window); glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE; glewExperimental = GL_TRUE;
@@ -34,9 +37,11 @@ int App::main(std::vector<std::string> &args) {
log("glewInit() failed!"); log("glewInit() failed!");
} }
// Run app.
auto app = App{window}; auto app = App{window};
app.game_loop(); app.game_loop();
// Clean up.
glfwTerminate(); glfwTerminate();
glfwSetErrorCallback(NULL); glfwSetErrorCallback(NULL);
log("app quitting."); log("app quitting.");
@@ -57,7 +62,8 @@ void App::key_callback_s(GLFWwindow *window, int key, int scancode, int action,
App::App(GLFWwindow *window): App::App(GLFWwindow *window):
mpWindow{window} { mpWindow{window},
mShaderProgram{} {
glfwSetWindowUserPointer(mpWindow, this); glfwSetWindowUserPointer(mpWindow, this);
glfwSetKeyCallback(mpWindow, key_callback_s); glfwSetKeyCallback(mpWindow, key_callback_s);

View File

@@ -5,9 +5,17 @@
namespace ugly { namespace ugly {
/**
* \brief Interface for a generic log-like object.
*/
class ILogFacility { class ILogFacility {
public: public:
~ILogFacility() = default; ~ILogFacility() = default;
/**
* \brief Put a message into the log, \c std::vformat -style.
* \param fmt Format string.
* \param args Format arguments.
*/
virtual void vlog(std::string_view fmt, std::format_args args) = 0; virtual void vlog(std::string_view fmt, std::format_args args) = 0;
}; };

View File

@@ -6,6 +6,9 @@
namespace ugly { namespace ugly {
/**
* \brief Provides \c std::format -style variadic template functions for \ref ILogFacility.
*/
class LogAlias { class LogAlias {
public: public:
ILogFacility *mpLog; ILogFacility *mpLog;
@@ -19,6 +22,11 @@ public:
} }
}; };
/**
* \brief Globally-shared log.
*
* Should be assigned to by the user, defaults to a null log.
*/
extern LogAlias log; extern LogAlias log;
} }

View File

@@ -10,6 +10,9 @@
namespace ugly { namespace ugly {
/**
* \brief Log that automatically annotates messages with time and name.
*/
class TimestampLog: virtual public ILogFacility { class TimestampLog: virtual public ILogFacility {
private: private:
std::chrono::high_resolution_clock::time_point mStartTime; std::chrono::high_resolution_clock::time_point mStartTime;
@@ -17,6 +20,10 @@ private:
std::string mDescription; std::string mDescription;
public: public:
/**
* \param description Name of the log to appear in the messages.
* \param os Output stream.
*/
TimestampLog(std::string_view description, std::ostream &os); TimestampLog(std::string_view description, std::ostream &os);
void vlog(std::string_view fmt, std::format_args args) override; void vlog(std::string_view fmt, std::format_args args) override;
}; };

View File

@@ -12,6 +12,7 @@ TimestampLog::TimestampLog(std::string_view description, std::ostream &os):
void TimestampLog::vlog(std::string_view fmt, std::format_args args) { void TimestampLog::vlog(std::string_view fmt, std::format_args args) {
// Format message as "[123.4567] Name: User Message\n"
using namespace std::chrono; using namespace std::chrono;
auto now = high_resolution_clock::now(); auto now = high_resolution_clock::now();
auto timestamp = duration_cast<duration<float>>(now - mStartTime).count(); auto timestamp = duration_cast<duration<float>>(now - mStartTime).count();

View File

@@ -6,6 +6,13 @@
namespace ugly{ namespace ugly{
/**
* \brief Builder class for OpenGL shader and programs.
*
* On initialization, creates a new OpenGL program. Attach and compile shader
* sources using `attachFrom*`. Link and get the program with `link()`. User is
* responsible of managing returned program's lifetime, including destroying it.
*/
class ShaderProgramBuilder { class ShaderProgramBuilder {
private: private:
GLuint mProgram; GLuint mProgram;
@@ -13,10 +20,36 @@ private:
public: public:
ShaderProgramBuilder(); ShaderProgramBuilder();
~ShaderProgramBuilder(); ~ShaderProgramBuilder();
/**
* \brief Deletes program and starts from scratch.
*/
void reset(); void reset();
/**
* \brief Creates, compiles, and attaches a shader.
* \param type Specifies the type of shader to be created. Must be one of
* \c GL_VERTEX_SHADER, \c GL_GEOMETRY_SHADER or
* \c GL_FRAGMENT_SHADER .
* \param string Shader source code.
* \param length Bytes to read from \p string, \c 0 reads until NUL byte.
* \returns *this
*/
ShaderProgramBuilder &attachFromMemory(GLenum type, const GLchar *string, GLint length = 0); ShaderProgramBuilder &attachFromMemory(GLenum type, const GLchar *string, GLint length = 0);
/**
* \brief Creates, compiles, and attaches a shader. Reads source from file.
* \param type Specifies the type of shader to be created. Must be one of
* \c GL_VERTEX_SHADER, \c GL_GEOMETRY_SHADER or
* \c GL_FRAGMENT_SHADER .
* \param filename Shader source code file.
* \returns \c *this
*/
ShaderProgramBuilder &attachFromFile(GLenum type, const char *filename); ShaderProgramBuilder &attachFromFile(GLenum type, const char *filename);
GLuint link(); /**
* \brief Links OpenGL program after attaching sources.
*
* After this function is called the builder object is reset.
* \return OpenGL object name. User is reponsible for managing it.
*/
[[nodiscard]] GLuint link();
}; };
} }

View File

@@ -13,6 +13,7 @@ ShaderProgramBuilder::ShaderProgramBuilder():
ShaderProgramBuilder::~ShaderProgramBuilder() { ShaderProgramBuilder::~ShaderProgramBuilder() {
// link() sets mProgram=0 to prevent it from being deleted after being given to the user.
if(mProgram != 0) { if(mProgram != 0) {
glDeleteProgram(mProgram); glDeleteProgram(mProgram);
} }
@@ -21,8 +22,8 @@ ShaderProgramBuilder::~ShaderProgramBuilder() {
void ShaderProgramBuilder::reset() { void ShaderProgramBuilder::reset() {
using namespace std; using namespace std;
ShaderProgramBuilder b; ShaderProgramBuilder newBuilder;
swap(*this, b); swap(*this, newBuilder);
} }
@@ -31,6 +32,7 @@ ShaderProgramBuilder &ShaderProgramBuilder::attachFromMemory(GLenum type, const
glShaderSource(shader, 1, &string, length != 0 ? &length : NULL); glShaderSource(shader, 1, &string, length != 0 ? &length : NULL);
glCompileShader(shader); glCompileShader(shader);
// Check for shader compilation errors
GLint status; GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status); glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if(status != GL_TRUE) { if(status != GL_TRUE) {
@@ -40,6 +42,7 @@ ShaderProgramBuilder &ShaderProgramBuilder::attachFromMemory(GLenum type, const
log("failed to compile shader:\n\t{}", buf); log("failed to compile shader:\n\t{}", buf);
} }
// After the shader is attached, it can safely be marked for deletion and OpenGL will handle it.
glAttachShader(mProgram, shader); glAttachShader(mProgram, shader);
glDeleteShader(shader); glDeleteShader(shader);
return *this; return *this;
@@ -47,6 +50,7 @@ ShaderProgramBuilder &ShaderProgramBuilder::attachFromMemory(GLenum type, const
ShaderProgramBuilder &ShaderProgramBuilder::attachFromFile(GLenum type, const char *filename) { ShaderProgramBuilder &ShaderProgramBuilder::attachFromFile(GLenum type, const char *filename) {
// Load entire file to memory then let attachFromMemory handle it.
auto file = std::filebuf{}; auto file = std::filebuf{};
auto ss = std::ostringstream{}; auto ss = std::ostringstream{};
@@ -64,6 +68,7 @@ ShaderProgramBuilder &ShaderProgramBuilder::attachFromFile(GLenum type, const ch
GLuint ShaderProgramBuilder::link() { GLuint ShaderProgramBuilder::link() {
glLinkProgram(mProgram); glLinkProgram(mProgram);
// Check for program linking errors
GLint status; GLint status;
glGetProgramiv(mProgram, GL_LINK_STATUS, &status); glGetProgramiv(mProgram, GL_LINK_STATUS, &status);
if(status != GL_TRUE) { if(status != GL_TRUE) {
@@ -72,6 +77,7 @@ GLuint ShaderProgramBuilder::link() {
log("failed to link program:\n\t{}", buf); log("failed to link program:\n\t{}", buf);
} }
// reset() this object but take care of not deleting the program returned to the caller.
auto result = mProgram; auto result = mProgram;
mProgram = 0; mProgram = 0;
reset(); reset();