#define FPL_IMPLEMENTATION
#define FPL_NO_VIDEO_SOFTWARE
#define FPL_NO_AUDIO
#include <GL/gl.h>
#ifndef APIENTRY
#define APIENTRY
#endif
#define APIENTRYP APIENTRY *
#include <stddef.h>
typedef ptrdiff_t GLsizeiptr;
typedef ptrdiff_t GLintptr;
typedef char GLchar;
#ifndef GL_CONTEXT_PROFILE_MASK
#define GL_CONTEXT_PROFILE_MASK 0x9126
#define GL_CONTEXT_FLAGS 0x821E
#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001
#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT 0x00000004
#define GL_CONTEXT_FLAG_NO_ERROR_BIT 0x00000008
#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001
#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
#endif
#define GL_COMPILE_STATUS 0x8B81
#define GL_INFO_LOG_LENGTH 0x8B84
#define GL_FRAGMENT_SHADER 0x8B30
#define GL_VERTEX_SHADER 0x8B31
#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
#define GL_LINK_STATUS 0x8B82
#define GL_STATIC_DRAW 0x88E4
typedef GLuint(APIENTRYP PFNGLCREATESHADERPROC) (GLenum type);
typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
typedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader);
typedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params);
typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
typedef GLuint(APIENTRYP PFNGLCREATEPROGRAMPROC) (void);
typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program);
typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program);
typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params);
typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
typedef void (APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader);
typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program);
static PFNGLCREATESHADERPROC glCreateShader = NULL;
static PFNGLSHADERSOURCEPROC glShaderSource = NULL;
static PFNGLCOMPILESHADERPROC glCompileShader = NULL;
static PFNGLGETSHADERIVPROC glGetShaderiv = NULL;
static PFNGLATTACHSHADERPROC glAttachShader = NULL;
static PFNGLCREATEPROGRAMPROC glCreateProgram = NULL;
static PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog = NULL;
static PFNGLLINKPROGRAMPROC glLinkProgram = NULL;
static PFNGLVALIDATEPROGRAMPROC glValidateProgram = NULL;
static PFNGLGETPROGRAMIVPROC glGetProgramiv = NULL;
static PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog = NULL;
static PFNGLDELETESHADERPROC glDeleteShader = NULL;
static PFNGLUSEPROGRAMPROC glUseProgram = NULL;
#define GL_ARRAY_BUFFER 0x8892
typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays);
typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array);
typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);
typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index);
typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index);
typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays);
static PFNGLGENVERTEXARRAYSPROC glGenVertexArrays = NULL;
static PFNGLBINDVERTEXARRAYPROC glBindVertexArray = NULL;
static PFNGLGENBUFFERSPROC glGenBuffers = NULL;
static PFNGLBINDBUFFERPROC glBindBuffer = NULL;
static PFNGLBUFFERDATAPROC glBufferData = NULL;
static PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray = NULL;
static PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray = NULL;
static PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer = NULL;
static PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays = NULL;
#if defined(FPL_PLATFORM_WINDOWS)
static void *GLProcAddress(const char *name) {
fpl__VideoState *videoState = (fpl__VideoState *)fpl__global__AppState->video.mem;
fplAssert(videoState->win32.opengl.api.wglGetProcAddress != NULL);
void *result = videoState->win32.opengl.api.wglGetProcAddress(name);
return(result);
}
#else
static void *GLProcAddress(const char *name) {
fpl__VideoState *videoState = (fpl__VideoState *)fpl__global__AppState->video.mem;
fplAssert(videoState->x11.opengl.api.glXGetProcAddress != NULL);
void *result = videoState->x11.opengl.api.glXGetProcAddress((const GLubyte *)name);
return(result);
}
#endif
static void LoadGLExtensions() {
glCreateShader = (PFNGLCREATESHADERPROC)GLProcAddress("glCreateShader");
glShaderSource = (PFNGLSHADERSOURCEPROC)GLProcAddress("glShaderSource");
glCompileShader = (PFNGLCOMPILESHADERPROC)GLProcAddress("glCompileShader");
glGetShaderiv = (PFNGLGETSHADERIVPROC)GLProcAddress("glGetShaderiv");
glAttachShader = (PFNGLATTACHSHADERPROC)GLProcAddress("glAttachShader");
glCreateProgram = (PFNGLCREATEPROGRAMPROC)GLProcAddress("glCreateProgram");
glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)GLProcAddress("glGetShaderInfoLog");
glLinkProgram = (PFNGLLINKPROGRAMPROC)GLProcAddress("glLinkProgram");
glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)GLProcAddress("glValidateProgram");
glGetProgramiv = (PFNGLGETPROGRAMIVPROC)GLProcAddress("glGetProgramiv");
glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)GLProcAddress("glGetProgramInfoLog");
glDeleteShader = (PFNGLDELETESHADERPROC)GLProcAddress("glDeleteShader");
glUseProgram = (PFNGLUSEPROGRAMPROC)GLProcAddress("glUseProgram");
glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)GLProcAddress("glGenVertexArrays");
glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)GLProcAddress("glBindVertexArray");
glGenBuffers = (PFNGLGENBUFFERSPROC)GLProcAddress("glGenBuffers");
glBindBuffer = (PFNGLBINDBUFFERPROC)GLProcAddress("glBindBuffer");
glBufferData = (PFNGLBUFFERDATAPROC)GLProcAddress("glBufferData");
glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)GLProcAddress("glEnableVertexAttribArray");
glDisableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)GLProcAddress("glDisableVertexAttribArray");
glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)GLProcAddress("glVertexAttribPointer");
glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)GLProcAddress("glDeleteVertexArrays");
}
#define MODERN_OPENGL 1
static GLuint CreateShaderType(GLenum type, const char *source) {
GLuint shaderId = glCreateShader(type);
glShaderSource(shaderId, 1, &source, NULL);
glCompileShader(shaderId);
GLint compileResult;
glGetShaderiv(shaderId, GL_COMPILE_STATUS, &compileResult);
if(!compileResult) {
GLint infoLen;
glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &infoLen);
glGetShaderInfoLog(shaderId, infoLen, &infoLen, info);
fplConsoleFormatError(
"Failed compiling %s shader!\n", (type == GL_VERTEX_SHADER ?
"vertex" :
"fragment"));
}
return(shaderId);
}
static GLuint CreateShaderProgram(const char *name, const char *vertexSource, const char *fragmentSource) {
GLuint programId = glCreateProgram();
GLuint vertexShader = CreateShaderType(GL_VERTEX_SHADER, vertexSource);
GLuint fragmentShader = CreateShaderType(GL_FRAGMENT_SHADER, fragmentSource);
glAttachShader(programId, vertexShader);
glAttachShader(programId, fragmentShader);
glLinkProgram(programId);
glValidateProgram(programId);
GLint linkResult;
glGetProgramiv(programId, GL_LINK_STATUS, &linkResult);
if(!linkResult) {
GLint infoLen;
glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &infoLen);
glGetProgramInfoLog(programId, infoLen, &infoLen, info);
}
glDeleteShader(fragmentShader);
glDeleteShader(vertexShader);
return(programId);
}
static bool RunModern() {
LoadGLExtensions();
GLuint vertexArrayID;
glGenVertexArrays(1, &vertexArrayID);
glBindVertexArray(vertexArrayID);
const char *glslVersion = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION);
int profileMask;
int contextFlags;
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &profileMask);
glGetIntegerv(GL_CONTEXT_FLAGS, &contextFlags);
fplConsoleFormatOut(
"\tCore: %s\n", ((profileMask & GL_CONTEXT_CORE_PROFILE_BIT) ?
"yes" :
"no"));
fplConsoleFormatOut(
"\tForward: %s\n", ((contextFlags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT) ?
"yes" :
"no"));
const char vertexSource[] = {
"#version 330 core\n"
"\n"
"layout(location = 0) in vec4 inPosition;\n"
"\n"
"void main() {\n"
"\tgl_Position = inPosition;\n"
"}\n"
};
const char fragmentSource[] = {
"#version 330 core\n"
"\n"
"layout(location = 0) out vec4 outColor;\n"
"\n"
"void main() {\n"
"\toutColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}\n"
};
GLuint shaderProgram = CreateShaderProgram("Test", vertexSource, fragmentSource);
float vertices[] = {
0.0f, 0.5f,
-0.5f, -0.5f,
0.5f, -0.5f
};
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glUseProgram(shaderProgram);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, NULL);
glClearColor(0.39f, 0.58f, 0.93f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
glDisableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glDeleteVertexArrays(1, &vertexArrayID);
return true;
}
int main(int argc, char **args) {
int result = 0;
const char *version = (const char *)glGetString(GL_VERSION);
const char *vendor = (const char *)glGetString(GL_VENDOR);
const char *renderer = (const char *)glGetString(GL_RENDERER);
RunModern();
result = 0;
} else {
result = -1;
}
return(result);
}
fpl_platform_api void fplConsoleOut(const char *text)
Writes the given text to the standard output console buffer.
fpl_common_api void fplConsoleFormatOut(const char *format,...)
Writes the given formatted text to the standard output console buffer.
fpl_common_api void fplConsoleFormatError(const char *format,...)
Writes the given formatted text to the standard error console buffer.
#define fplAssert(exp)
Breaks with a runtime assertion when the specified expression evaluates to false.
#define fplZeroInit
Initializes a struct to zero.
#define fplArrayCount(arr)
Returns the element count from a static array.
fpl_common_api fplSettings fplMakeDefaultSettings(void)
Creates a full settings structure containing default values.
@ fplInitFlags_Video
Use a video backbuffer (This flag ensures that fplInitFlags_Window is included always).
@ fplOpenGLCompabilityFlags_Core
Use core profile.
@ fplVideoBackendType_OpenGL
OpenGL video backend.
fpl_common_api char * fplCopyString(const char *source, char *dest, const size_t maxDestLen)
Copies the given source string into a destination string.
fpl_common_api void fplVideoFlip(void)
Forces the window to be redrawn or to swap the back/front buffer.
fpl_platform_api bool fplWindowUpdate(void)
Clears the internal event queue and updates input devices if needed.
fpl_platform_api bool fplGetWindowSize(fplWindowSize *outSize)
Retrieves the inner window size.
fpl_platform_api bool fplPollEvent(fplEvent *ev)
Polls the next event from the internal event queue or from the OS, handles them, and removes it from ...
A structure containing event data for all event types (Window, Keyboard, Mouse, etc....
fplOpenGLSettings opengl
OpenGL settings.
uint32_t minorVersion
Desired minor version.
fplOpenGLCompabilityFlags compabilityFlags
Compatibility flags.
uint8_t multiSamplingCount
Multisampling count.
uint32_t majorVersion
Desired major version.
Stores settings, such as window, video, etc.
fplWindowSettings window
Window settings.
fplVideoSettings video
Video settings.
fplVideoBackendType backend
Video backend type.
fplGraphicsApiSettings graphics
Graphics API settings.
char title[FPL_MAX_NAME_LENGTH]
Window title.
Stores the size of a window.
uint32_t width
Width in screen coordinates.
uint32_t height
Height in screen coordinates.