now we are rendering something
This commit is contained in:
parent
30f9eca799
commit
56866d523d
|
@ -8,12 +8,11 @@
|
|||
"name": "(gdb) Launch",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/bin/evwm",
|
||||
"program": "${workspaceFolder}/debug/evwm",
|
||||
"args": [],
|
||||
"stopAtEntry": true,
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
"externalConsole": true,
|
||||
"preLaunchTask":"(Debug) Build",
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
{
|
||||
"label": "(Debug) Build",
|
||||
"type": "shell",
|
||||
"command": "make debug"
|
||||
"command": "make clean && make debug"
|
||||
},
|
||||
]
|
||||
}
|
2
Makefile
2
Makefile
|
@ -11,7 +11,7 @@ CCOBJFLAGS := $(CCFLAGS) -c
|
|||
# path macros
|
||||
BIN_PATH := bin
|
||||
OBJ_PATH := obj
|
||||
SRC_PATH := ./src
|
||||
SRC_PATH := src
|
||||
DBG_PATH := debug
|
||||
|
||||
# compile macros
|
||||
|
|
|
@ -1,14 +1,7 @@
|
|||
#version 330
|
||||
|
||||
in vec2 local_position;
|
||||
out vec4 fragment_colour;
|
||||
|
||||
uniform float opacity;
|
||||
uniform sampler2D texture_sampler;
|
||||
|
||||
void main(void) {
|
||||
vec4 colour = texture(texture_sampler, local_position * vec2(1.0, -1.0) + vec2(0.5));
|
||||
float alpha = opacity * (1.0 - colour.a);
|
||||
|
||||
fragment_colour = vec4(colour.rgb, alpha);
|
||||
fragment_colour = vec4(1.0f, 0.5f, 0.2f, 1.0f);
|
||||
}
|
|
@ -1,13 +1,11 @@
|
|||
#version 330
|
||||
|
||||
layout(location = 0) in vec2 vertex_position;
|
||||
out vec2 local_position;
|
||||
layout(location = 0) in vec3 vertex_position;
|
||||
|
||||
uniform float depth;
|
||||
uniform vec2 position;
|
||||
uniform vec2 size;
|
||||
uniform vec2 window_position;
|
||||
|
||||
void main(void) {
|
||||
local_position = vertex_position;
|
||||
gl_Position = vec4(vertex_position * size + position, depth, 1.0);
|
||||
vec3 final_position = vertex_position + vec3(window_position, 0.0);
|
||||
|
||||
gl_Position = vec4(final_position.x, final_position.y, final_position.z, 1.0);
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,198 @@
|
|||
|
||||
#include <glad/glad.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
|
||||
void processInput(GLFWwindow *window);
|
||||
|
||||
// settings
|
||||
const unsigned int SCR_WIDTH = 800;
|
||||
const unsigned int SCR_HEIGHT = 600;
|
||||
|
||||
const char *vertexShaderSource = "#version 330 core\n"
|
||||
"layout (location = 0) in vec3 aPos;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
|
||||
"}\0";
|
||||
const char *fragmentShaderSource = "#version 330 core\n"
|
||||
"out vec4 FragColor;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
|
||||
"}\n\0";
|
||||
|
||||
int main()
|
||||
{
|
||||
// glfw: initialize and configure
|
||||
// ------------------------------
|
||||
glfwInit();
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
|
||||
#ifdef __APPLE__
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||
#endif
|
||||
|
||||
// glfw window creation
|
||||
// --------------------
|
||||
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
|
||||
if (window == NULL)
|
||||
{
|
||||
std::cout << "Failed to create GLFW window" << std::endl;
|
||||
glfwTerminate();
|
||||
return -1;
|
||||
}
|
||||
glfwMakeContextCurrent(window);
|
||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||
|
||||
// glad: load all OpenGL function pointers
|
||||
// ---------------------------------------
|
||||
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
|
||||
{
|
||||
std::cout << "Failed to initialize GLAD" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// build and compile our shader program
|
||||
// ------------------------------------
|
||||
// vertex shader
|
||||
unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
|
||||
glCompileShader(vertexShader);
|
||||
// check for shader compile errors
|
||||
int success;
|
||||
char infoLog[512];
|
||||
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
|
||||
if (!success)
|
||||
{
|
||||
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
|
||||
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
|
||||
}
|
||||
// fragment shader
|
||||
unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
|
||||
glCompileShader(fragmentShader);
|
||||
// check for shader compile errors
|
||||
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
|
||||
if (!success)
|
||||
{
|
||||
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
|
||||
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
|
||||
}
|
||||
// link shaders
|
||||
unsigned int shaderProgram = glCreateProgram();
|
||||
glAttachShader(shaderProgram, vertexShader);
|
||||
glAttachShader(shaderProgram, fragmentShader);
|
||||
glLinkProgram(shaderProgram);
|
||||
// check for linking errors
|
||||
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
|
||||
if (!success) {
|
||||
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
|
||||
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
|
||||
}
|
||||
glDeleteShader(vertexShader);
|
||||
glDeleteShader(fragmentShader);
|
||||
|
||||
// set up vertex data (and buffer(s)) and configure vertex attributes
|
||||
// ------------------------------------------------------------------
|
||||
float vertices[] = {
|
||||
0.5f, 0.5f, 0.0f, // top right
|
||||
0.5f, -0.5f, 0.0f, // bottom right
|
||||
-0.5f, -0.5f, 0.0f, // bottom left
|
||||
-0.5f, 0.5f, 0.0f // top left
|
||||
};
|
||||
unsigned int indices[] = { // note that we start from 0!
|
||||
0, 1, 3, // first Triangle
|
||||
1, 2, 3 // second Triangle
|
||||
};
|
||||
unsigned int VBO, VAO, EBO;
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glGenBuffers(1, &VBO);
|
||||
glGenBuffers(1, &EBO);
|
||||
// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
|
||||
glBindVertexArray(VAO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
|
||||
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
// note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
// remember: do NOT unbind the EBO while a VAO is active as the bound element buffer object IS stored in the VAO; keep the EBO bound.
|
||||
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
|
||||
// You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
|
||||
// VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
|
||||
glBindVertexArray(0);
|
||||
|
||||
|
||||
// uncomment this call to draw in wireframe polygons.
|
||||
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
|
||||
// render loop
|
||||
// -----------
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
// input
|
||||
// -----
|
||||
processInput(window);
|
||||
|
||||
// render
|
||||
// ------
|
||||
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// draw our first triangle
|
||||
glUseProgram(shaderProgram);
|
||||
glBindVertexArray(VAO); // seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized
|
||||
//glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
||||
// glBindVertexArray(0); // no need to unbind it every time
|
||||
|
||||
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
|
||||
// -------------------------------------------------------------------------------
|
||||
glfwSwapBuffers(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
// optional: de-allocate all resources once they've outlived their purpose:
|
||||
// ------------------------------------------------------------------------
|
||||
glDeleteVertexArrays(1, &VAO);
|
||||
glDeleteBuffers(1, &VBO);
|
||||
glDeleteBuffers(1, &EBO);
|
||||
glDeleteProgram(shaderProgram);
|
||||
|
||||
// glfw: terminate, clearing all previously allocated GLFW resources.
|
||||
// ------------------------------------------------------------------
|
||||
glfwTerminate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
|
||||
// ---------------------------------------------------------------------------------------------------------
|
||||
void processInput(GLFWwindow *window)
|
||||
{
|
||||
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
|
||||
glfwSetWindowShouldClose(window, true);
|
||||
}
|
||||
|
||||
// glfw: whenever the window size changed (by OS or user resize) this callback function executes
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
||||
{
|
||||
// make sure the viewport matches the new window dimensions; note that width and
|
||||
// height will be significantly larger than specified on retina displays.
|
||||
glViewport(0, 0, width, height);
|
||||
}
|
||||
|
344
src/cm.c
344
src/cm.c
|
@ -18,23 +18,13 @@ typedef void (*glXBindTexImageEXT_t) (Display*, GLXDrawable, int,
|
|||
typedef void (*glXReleaseTexImageEXT_t) (Display*, GLXDrawable, int);
|
||||
typedef void (*glXSwapIntervalEXT_t) (Display*, GLXDrawable, int);
|
||||
|
||||
typedef struct vao_vbo_ibo_t
|
||||
{
|
||||
GLuint vao, vbo, ibo;
|
||||
} vao_vbo_ibo_t;
|
||||
|
||||
typedef struct window_vertices_t
|
||||
{
|
||||
float vertices[4 * 2];
|
||||
} window_vertices_t;
|
||||
|
||||
static const char * MAIN_SHADER_UNIFORM_NAMES[] = {
|
||||
"opacity",
|
||||
"texture_sampler",
|
||||
|
||||
"depth",
|
||||
"position",
|
||||
"size",
|
||||
"window_position"
|
||||
};
|
||||
|
||||
typedef struct main_shader_t
|
||||
|
@ -43,21 +33,16 @@ typedef struct main_shader_t
|
|||
|
||||
struct
|
||||
{
|
||||
int opacity;
|
||||
int texture_sampler;
|
||||
|
||||
int depth;
|
||||
int position;
|
||||
int size;
|
||||
int window_position;
|
||||
} uniforms;
|
||||
} main_shader_t;
|
||||
|
||||
typedef struct window_extra_t
|
||||
{
|
||||
bool drawable;
|
||||
|
||||
Pixmap xpixmap;
|
||||
GLXPixmap pixmap;
|
||||
|
||||
vao_vbo_ibo_t buffers;
|
||||
} window_extra_t;
|
||||
|
||||
typedef struct cm_t
|
||||
|
@ -67,7 +52,8 @@ typedef struct cm_t
|
|||
Display* display;
|
||||
Window root_window;
|
||||
|
||||
XWindowAttributes root_window_attributes;
|
||||
XWindowAttributes root_window_attributes,
|
||||
output_window_attributes;
|
||||
|
||||
Window check_window, overlay_window,
|
||||
output_window;
|
||||
|
@ -86,11 +72,15 @@ typedef struct cm_t
|
|||
glXSwapIntervalEXT_t glXSwapIntervalEXT;
|
||||
|
||||
main_shader_t main_shader;
|
||||
|
||||
bool allocated_buffer;
|
||||
unsigned int vbo, vao, ebo;
|
||||
} cm_t;
|
||||
|
||||
static cm_t cm = {0};
|
||||
|
||||
static const int DEFAULT_GLX_VISUAL_ATTRIBUTES[] = {
|
||||
static const int
|
||||
DEFAULT_GLX_VISUAL_ATTRIBUTES[] = {
|
||||
GLX_RGBA, GLX_DOUBLEBUFFER,
|
||||
GLX_SAMPLE_BUFFERS, 1,
|
||||
GLX_SAMPLES, 4,
|
||||
|
@ -103,7 +93,8 @@ static const int DEFAULT_GLX_VISUAL_ATTRIBUTES[] = {
|
|||
0
|
||||
};
|
||||
|
||||
static const int DEFAULT_GLX_FB_ATTRIBUTES[] = {
|
||||
static const int
|
||||
DEFAULT_GLX_FB_ATTRIBUTES[] = {
|
||||
GLX_BIND_TO_TEXTURE_RGBA_EXT, 1,
|
||||
GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT,
|
||||
GLX_RENDER_TYPE, GLX_RGBA_BIT,
|
||||
|
@ -125,7 +116,8 @@ static const int DEFAULT_GLX_FB_ATTRIBUTES[] = {
|
|||
0
|
||||
};
|
||||
|
||||
static const int DEFAULT_GLX_VERSION_ATTRIBUTES[] = {
|
||||
static const int
|
||||
DEFAULT_GLX_VERSION_ATTRIBUTES[] = {
|
||||
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
|
||||
GLX_CONTEXT_MINOR_VERSION_ARB, 3,
|
||||
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
|
||||
|
@ -133,6 +125,35 @@ static const int DEFAULT_GLX_VERSION_ATTRIBUTES[] = {
|
|||
0
|
||||
};
|
||||
|
||||
static const unsigned int
|
||||
WINDOW_INDICES[] = {
|
||||
0, 1, 3,
|
||||
1, 2, 3,
|
||||
};
|
||||
|
||||
static inline bool
|
||||
should_render_window( window_node_t * node )
|
||||
{
|
||||
return (
|
||||
node->window != cm.check_window &&
|
||||
node->window != cm.overlay_window &&
|
||||
node->window != cm.output_window &&
|
||||
node->window != cm.root_window
|
||||
);
|
||||
}
|
||||
|
||||
static void
|
||||
free_window_pixmap(window_extra_t *extra)
|
||||
{
|
||||
if (extra->xpixmap)
|
||||
XFreePixmap(cm.display, extra->xpixmap);
|
||||
|
||||
if (extra->pixmap)
|
||||
glXDestroyPixmap(cm.display, extra->pixmap);
|
||||
|
||||
extra->xpixmap = extra->pixmap = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
create_window_pixmap( window_node_t * window_node )
|
||||
{
|
||||
|
@ -147,7 +168,12 @@ create_window_pixmap( window_node_t * window_node )
|
|||
0
|
||||
};
|
||||
|
||||
extra = (window_extra_t *)window_node->extra;
|
||||
if(extra->pixmap)
|
||||
return;
|
||||
|
||||
XGetWindowAttributes(cm.display, window_node->window, &window_node->attributes);
|
||||
|
||||
for (int i = 0; i < cm.fb_config_count; i++) {
|
||||
config = cm.fb_config[i];
|
||||
|
||||
|
@ -163,88 +189,19 @@ create_window_pixmap( window_node_t * window_node )
|
|||
format = has_alpha ? GLX_TEXTURE_FORMAT_RGBA_EXT : GLX_TEXTURE_FORMAT_RGB_EXT;
|
||||
break;
|
||||
}
|
||||
|
||||
extra = (window_extra_t *)window_node->extra;
|
||||
|
||||
|
||||
pixmap_attributes[3] = format;
|
||||
extra->xpixmap = XCompositeNameWindowPixmap(cm.display, window_node->window);
|
||||
extra->pixmap = glXCreatePixmap(cm.display, config, extra->xpixmap, (const int *)pixmap_attributes);
|
||||
}
|
||||
|
||||
static vao_vbo_ibo_t
|
||||
create_vao_vbo_ibo( void )
|
||||
{
|
||||
vao_vbo_ibo_t buffers;
|
||||
|
||||
glGenVertexArrays(1, &buffers.vao);
|
||||
glGenBuffers(1, &buffers.vbo);
|
||||
glGenBuffers(1, &buffers.ibo);
|
||||
|
||||
return buffers;
|
||||
}
|
||||
|
||||
static void
|
||||
free_vao_vbo_ibo( vao_vbo_ibo_t buffers )
|
||||
{
|
||||
glDeleteBuffers(1, &buffers.ibo);
|
||||
glDeleteBuffers(1, &buffers.vbo);
|
||||
glDeleteVertexArrays(1, &buffers.vao);
|
||||
|
||||
clear(&buffers);
|
||||
}
|
||||
|
||||
static void
|
||||
get_window_vertices(window_node_t * node, window_vertices_t * vertices)
|
||||
{
|
||||
float half_width = 0.0f, half_height = 0.0f;
|
||||
|
||||
half_width = node->attributes.width / cm.root_window_attributes.width;
|
||||
half_height = node->attributes.height / cm.root_window_attributes.height;
|
||||
int v[] = {
|
||||
-half_width, half_height,
|
||||
half_width, half_height,
|
||||
|
||||
half_width, -half_height,
|
||||
-half_width, -half_height,
|
||||
};
|
||||
|
||||
memcpy(&vertices->vertices, v, sizeof(v));
|
||||
}
|
||||
|
||||
static int
|
||||
update_window_buffers( window_node_t * window_node )
|
||||
{
|
||||
window_extra_t * extra = NULL;
|
||||
window_vertices_t vertices = {0};
|
||||
|
||||
static const int indices[] = {
|
||||
3, 0, 1,
|
||||
1, 2, 3
|
||||
};
|
||||
|
||||
extra = (window_extra_t *)window_node->extra;
|
||||
get_window_vertices(window_node, &vertices);
|
||||
|
||||
glBindVertexArray(extra->buffers.vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, extra->buffers.vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices.vertices), vertices.vertices,
|
||||
GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, extra->buffers.ibo);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline window_extra_t *
|
||||
create_window_extra( window_node_t * node )
|
||||
{
|
||||
window_extra_t * extra = NULL;
|
||||
|
||||
extra = gcalloc(1, sizeof(window_extra_t));
|
||||
extra->buffers = create_vao_vbo_ibo();
|
||||
|
||||
create_window_pixmap(node);
|
||||
update_window_buffers(node);
|
||||
node->extra = extra;
|
||||
|
||||
return extra;
|
||||
}
|
||||
|
@ -323,25 +280,17 @@ compile_shaders( void )
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
free_window_pixmap(window_extra_t *extra)
|
||||
{
|
||||
if (extra->xpixmap)
|
||||
XFreePixmap(cm.display, extra->xpixmap);
|
||||
|
||||
if (extra->pixmap)
|
||||
glXDestroyPixmap(cm.display, extra->pixmap);
|
||||
}
|
||||
|
||||
static int
|
||||
bind_window_texture( window_node_t * window_node )
|
||||
{
|
||||
window_extra_t * extra = NULL;
|
||||
|
||||
extra = create_window_extra_if_none(window_node);
|
||||
extra = window_node->extra;
|
||||
if(!extra || !extra->drawable)
|
||||
return 0;
|
||||
|
||||
cm.glXBindTexImageEXT(cm.display, extra->pixmap, GLX_FRONT_LEFT_EXT,
|
||||
NULL);
|
||||
create_window_pixmap(window_node);
|
||||
cm.glXBindTexImageEXT(cm.display, extra->pixmap, GLX_FRONT_LEFT_EXT, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -351,46 +300,100 @@ unbind_window_texture( window_node_t * window_node )
|
|||
{
|
||||
window_extra_t * extra = NULL;
|
||||
|
||||
extra = create_window_extra_if_none(window_node);
|
||||
extra = window_node->extra;
|
||||
if(!extra || !extra->drawable)
|
||||
return 0;
|
||||
|
||||
if(extra->pixmap)
|
||||
cm.glXReleaseTexImageEXT(cm.display, extra->pixmap, GLX_FRONT_LEFT_EXT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
render_window( window_node_t * window_node )
|
||||
int
|
||||
cm_swap_buffers( void )
|
||||
{
|
||||
window_extra_t * extra = NULL;
|
||||
|
||||
extra = create_window_extra_if_none(window_node);
|
||||
|
||||
glUseProgram(cm.main_shader.program);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), 0);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
glUniform1i(cm.main_shader.uniforms.texture_sampler, 0);
|
||||
|
||||
bind_window_texture(window_node);
|
||||
|
||||
glBindVertexArray(extra->buffers.vao);
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
unbind_window_texture(window_node);
|
||||
|
||||
glXSwapBuffers(cm.display, cm.output_window);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
cm_render_windows( void )
|
||||
static int
|
||||
render_window( window_node_t * window_node )
|
||||
{
|
||||
int ret = 0;
|
||||
float h_height = 0.0f, h_width = 0.0f, x = 0, y = 0;
|
||||
window_extra_t * extra = NULL;
|
||||
|
||||
extra = create_window_extra_if_none(window_node);
|
||||
if(!extra->drawable)
|
||||
return 0;
|
||||
|
||||
XGetWindowAttributes(cm.display, cm.output_window, &cm.output_window_attributes);
|
||||
XGetWindowAttributes(cm.display, window_node->window, &window_node->attributes);
|
||||
|
||||
h_height = (float)window_node->attributes.height / (float)cm.output_window_attributes.height;
|
||||
h_width = (float)window_node->attributes.width / (float)cm.output_window_attributes.width;
|
||||
|
||||
x = (float)(window_node->attributes.x - window_node->attributes.width/2)/(float)cm.output_window_attributes.width;
|
||||
y = -(float)(window_node->attributes.y - window_node->attributes.height/2)/(float)cm.output_window_attributes.height;
|
||||
|
||||
float vertices[] = {
|
||||
h_width, h_height, 0.0f,
|
||||
h_width, -h_height, 0.0f,
|
||||
-h_width, -h_height, 0.0f,
|
||||
-h_width, h_height, 0.0f,
|
||||
};
|
||||
|
||||
bind_window_texture(window_node);
|
||||
|
||||
glBindVertexArray(cm.vao);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, cm.vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cm.ebo);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(WINDOW_INDICES), WINDOW_INDICES, GL_STATIC_DRAW);
|
||||
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
|
||||
glUseProgram(cm.main_shader.program);
|
||||
|
||||
glUniform2f(cm.main_shader.uniforms.window_position, x, y);
|
||||
|
||||
glBindVertexArray(cm.vao);
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
||||
|
||||
unbind_window_texture(window_node);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
cm_render_windows(void)
|
||||
{
|
||||
window_node_t * node = NULL;
|
||||
|
||||
glClearColor(0.16015625, 0.15625, 0.15625, 1.);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
XGrabServer(cm.display);
|
||||
|
||||
node = wm_get_first_window_node();
|
||||
while(node)
|
||||
{
|
||||
if(should_render_window(node))
|
||||
render_window(node);
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
cm_swap_buffers();
|
||||
|
||||
XUngrabServer(cm.display);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -406,8 +409,6 @@ free_window_extra(window_node_t * node)
|
|||
free_window_pixmap(extra);
|
||||
gfree(extra);
|
||||
extra = NULL;
|
||||
|
||||
free_vao_vbo_ibo(extra->buffers);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -418,7 +419,7 @@ on_create_window(window_node_t * node)
|
|||
free_window_extra(node->extra);
|
||||
|
||||
create_window_extra(node);
|
||||
render_window(node);
|
||||
((window_extra_t *)node->extra)->drawable = true;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -439,9 +440,7 @@ cm_init( unsigned int modkey )
|
|||
|
||||
clear(&cm);
|
||||
|
||||
callbacks.on_create_window = on_create_window;
|
||||
callbacks.on_destroy_window = on_destroy_window;
|
||||
err = wm_init(modkey, &callbacks);
|
||||
err = wm_init(modkey);
|
||||
if(err)
|
||||
ftl("cannot initialize window manager");
|
||||
|
||||
|
@ -453,42 +452,37 @@ cm_init( unsigned int modkey )
|
|||
|
||||
// Make it known to other apps that you are a compositing window
|
||||
// manager
|
||||
cm.check_window = XCreateSimpleWindow(cm.display, cm.root_window,
|
||||
0, 0, 1, 1, 0, 0, 0);
|
||||
Xutf8SetWMProperties(cm.display, cm.check_window, XCOMPMGR_PROPERTY,
|
||||
XCOMPMGR_PROPERTY, NULL, 0, NULL, NULL, NULL);
|
||||
cm.check_window = XCreateSimpleWindow(cm.display, cm.root_window, 0, 0, 1, 1, 0, 0, 0);
|
||||
Xutf8SetWMProperties(cm.display, cm.check_window, XCOMPMGR_PROPERTY, XCOMPMGR_PROPERTY,
|
||||
NULL, 0, NULL, NULL, NULL);
|
||||
|
||||
snprintf(net_wm_cm, sizeof(net_wm_cm), "_NET_WM_CM_S%d", cm.screen);
|
||||
cm.net_wm_cm_atom = XInternAtom(cm.display, net_wm_cm, 0);
|
||||
XSetSelectionOwner(cm.display, cm.net_wm_cm_atom, cm.check_window, 0);
|
||||
|
||||
XCompositeRedirectSubwindows(cm.display, cm.root_window, CompositeRedirectAutomatic);
|
||||
XCompositeRedirectSubwindows(cm.display, cm.root_window, CompositeRedirectManual);
|
||||
|
||||
// We use this so we can make windows transparents to events
|
||||
cm.overlay_window = XCompositeGetOverlayWindow(cm.display, cm.root_window);
|
||||
|
||||
region = XFixesCreateRegion(cm.display, NULL, 0);
|
||||
XFixesSetWindowShapeRegion(cm.display, cm.overlay_window, ShapeInput,
|
||||
0, 0, region);
|
||||
XFixesSetWindowShapeRegion(cm.display, cm.overlay_window, ShapeInput, 0, 0, region);
|
||||
XFixesDestroyRegion(cm.display, region);
|
||||
|
||||
// Create the window where we will be drawing on
|
||||
cm.default_visual = glXChooseVisual(cm.display, cm.screen,
|
||||
(int *)DEFAULT_GLX_VISUAL_ATTRIBUTES);
|
||||
cm.default_visual = glXChooseVisual(cm.display, cm.screen, (int *)DEFAULT_GLX_VISUAL_ATTRIBUTES);
|
||||
if(!cm.default_visual)
|
||||
ftl("cannot get default glx visual");
|
||||
|
||||
default_visual_attributes = (XSetWindowAttributes){
|
||||
.colormap = XCreateColormap(cm.display, cm.root_window, cm.default_visual->visual,
|
||||
AllocNone)
|
||||
};
|
||||
.colormap = XCreateColormap(cm.display, cm.root_window, cm.default_visual->visual, AllocNone),
|
||||
.border_pixel = 0};
|
||||
|
||||
// Get root window attributes for the output window
|
||||
wm_get_window_attributes(cm.root_window, &window_attrbiutes);
|
||||
cm.output_window = XCreateWindow(cm.display, cm.root_window, 0, 0,
|
||||
window_attrbiutes.width, window_attrbiutes.height, 0, cm.default_visual->depth,
|
||||
InputOutput, cm.default_visual->visual, CWBorderPixel | CWColormap,
|
||||
&default_visual_attributes);
|
||||
cm.output_window = XCreateWindow(cm.display, cm.root_window, 0, 0, window_attrbiutes.width,
|
||||
window_attrbiutes.height, 0, cm.default_visual->depth, InputOutput, cm.default_visual->visual,
|
||||
CWBorderPixel | CWColormap, &default_visual_attributes);
|
||||
|
||||
XReparentWindow(cm.display, cm.output_window, cm.overlay_window, 0, 0);
|
||||
XMapRaised(cm.display, cm.output_window);
|
||||
|
@ -500,15 +494,13 @@ cm_init( unsigned int modkey )
|
|||
ftl("cannot get glx framebuffer configs");
|
||||
|
||||
// Get OpenGL function callbacks
|
||||
cm.glXCreateContextAttribsARB = (glXCreateContextAttribsARB_t) glXGetProcAddressARB(
|
||||
(const GLubyte*) "glXCreateContextAttribsARB");
|
||||
cm.glXBindTexImageEXT = (glXBindTexImageEXT_t) glXGetProcAddress((const GLubyte*) "glXBindTexImageEXT");
|
||||
cm.glXReleaseTexImageEXT = (glXReleaseTexImageEXT_t) glXGetProcAddress((const GLubyte*) "glXReleaseTexImageEXT");
|
||||
cm.glXSwapIntervalEXT = (glXSwapIntervalEXT_t) glXGetProcAddress((const GLubyte*) "glXSwapIntervalEXT");
|
||||
cm.glXCreateContextAttribsARB = (glXCreateContextAttribsARB_t) glXGetProcAddressARB( (const GLubyte*) "glXCreateContextAttribsARB");
|
||||
cm.glXBindTexImageEXT = (glXBindTexImageEXT_t) glXGetProcAddress((const GLubyte*) "glXBindTexImageEXT");
|
||||
cm.glXReleaseTexImageEXT = (glXReleaseTexImageEXT_t) glXGetProcAddress((const GLubyte*) "glXReleaseTexImageEXT");
|
||||
cm.glXSwapIntervalEXT = (glXSwapIntervalEXT_t) glXGetProcAddress((const GLubyte*) "glXSwapIntervalEXT");
|
||||
|
||||
// Create OpenGL context
|
||||
cm.glx_context = cm.glXCreateContextAttribsARB(cm.display, cm.fb_config[0], NULL, 1,
|
||||
DEFAULT_GLX_VERSION_ATTRIBUTES);
|
||||
cm.glx_context = cm.glXCreateContextAttribsARB(cm.display, cm.fb_config[0], NULL, 1, DEFAULT_GLX_VERSION_ATTRIBUTES);
|
||||
if(!cm.glx_context)
|
||||
ftl("cannot create OpenGL context");
|
||||
|
||||
|
@ -516,6 +508,7 @@ cm_init( unsigned int modkey )
|
|||
glXMakeCurrent(cm.display, cm.output_window, cm.glx_context);
|
||||
|
||||
// Initialize GLEW
|
||||
glewExperimental = GL_TRUE;
|
||||
if(glewInit() != GLEW_OK)
|
||||
ftl("cannot initialize GLEW");
|
||||
|
||||
|
@ -525,6 +518,20 @@ cm_init( unsigned int modkey )
|
|||
ftl("cannot compile shaders")
|
||||
inf("done compiling shaders");
|
||||
|
||||
callbacks.on_create_window = on_create_window;
|
||||
callbacks.on_destroy_window = on_destroy_window;
|
||||
wm_set_callbacks(callbacks);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glGenVertexArrays(1, &cm.vao);
|
||||
glGenBuffers(1, &cm.vbo);
|
||||
glGenBuffers(1, &cm.ebo);
|
||||
|
||||
cm.allocated_buffer = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -545,6 +552,13 @@ cm_destroy( void )
|
|||
if(cm.main_shader.program)
|
||||
glDeleteProgram(cm.main_shader.program);
|
||||
|
||||
if(cm.allocated_buffer)
|
||||
{
|
||||
glDeleteVertexArrays(1, &cm.vao);
|
||||
glDeleteBuffers(1, &cm.vbo);
|
||||
glDeleteBuffers(1, &cm.ebo);
|
||||
}
|
||||
|
||||
wm_destroy();
|
||||
clear(&cm);
|
||||
|
||||
|
|
2
src/cm.h
2
src/cm.h
|
@ -13,6 +13,8 @@
|
|||
int cm_init( unsigned int modkey );
|
||||
int cm_destroy( void );
|
||||
|
||||
int cm_swap_buffers( void );
|
||||
|
||||
int cm_render_windows( void );
|
||||
|
||||
#endif
|
690
src/geometry.c
690
src/geometry.c
|
@ -1,690 +0,0 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "geometry.h"
|
||||
|
||||
#include "fmath.h"
|
||||
|
||||
// Debug functions I use to display the contents of
|
||||
// some structures. No need to pay much attention to
|
||||
// these tho
|
||||
const char*
|
||||
matrix_to_str(matrix_t m)
|
||||
{
|
||||
static char buff[1024] = {0};
|
||||
|
||||
snprintf(buff, 1024,
|
||||
"[%f]\t[%f]\t[%f]\t[%f]\n"
|
||||
"[%f]\t[%f]\t[%f]\t[%f]\n"
|
||||
"[%f]\t[%f]\t[%f]\t[%f]\n"
|
||||
"[%f]\t[%f]\t[%f]\t[%f]",
|
||||
m[0][0], m[0][1], m[0][2], m[0][3],
|
||||
m[1][0], m[1][1], m[1][2], m[1][3],
|
||||
m[2][0], m[2][1], m[2][2], m[2][3],
|
||||
m[3][0], m[3][1], m[3][2], m[3][3]
|
||||
);
|
||||
|
||||
return buff;
|
||||
}
|
||||
|
||||
const char*
|
||||
column_to_str(column_t c)
|
||||
{
|
||||
static char buff[1024] = {0};
|
||||
|
||||
snprintf(buff, 1024,
|
||||
"c[0][0] = %f, c[1][0] = %f, c[2][0] = %f, c[3][0] = %f",
|
||||
c[0][0],c[1][0],c[2][0],c[3][0]
|
||||
);
|
||||
|
||||
return buff;
|
||||
}
|
||||
|
||||
const char*
|
||||
pv_to_str(struct pv_t *p)
|
||||
{
|
||||
static char buff[1024] = {0};
|
||||
|
||||
snprintf(buff, 1024,
|
||||
"p->x = %f, p->y = %f, p->z = %f, p->w = %f",
|
||||
p->x, p->y, p->z, p->w
|
||||
);
|
||||
|
||||
return buff;
|
||||
}
|
||||
|
||||
// Copy the contents of matrix d to s
|
||||
void
|
||||
copy_matrix(matrix_t s, matrix_t d)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
for(r = 0; r < 4; r++)
|
||||
{
|
||||
d[r][0] = s[r][0];
|
||||
d[r][1] = s[r][1];
|
||||
d[r][2] = s[r][2];
|
||||
d[r][3] = s[r][3];
|
||||
}
|
||||
}
|
||||
|
||||
// Sets all the contents of a matrix to 0.0
|
||||
void
|
||||
clear_matrix(matrix_t m)
|
||||
{
|
||||
matrix_t b = {{0.0}};
|
||||
copy_matrix(b, m);
|
||||
}
|
||||
|
||||
// r = a - b
|
||||
void
|
||||
substract_pv(struct pv_t *a, struct pv_t *b, struct pv_t *r)
|
||||
{
|
||||
r->x = a->x - b->x;
|
||||
r->y = a->y - b->y;
|
||||
r->z = a->z - b->z;
|
||||
r->w = 0.0;
|
||||
}
|
||||
|
||||
// Returns a + b
|
||||
void
|
||||
add_pv(struct pv_t *a, struct pv_t *b, struct pv_t *r)
|
||||
{
|
||||
r->x = a->x + b->x;
|
||||
r->y = a->y + b->y;
|
||||
r->z = a->z + b->z;
|
||||
r->w = 0.0;
|
||||
}
|
||||
|
||||
// r = p * s
|
||||
void
|
||||
scale_pv(struct pv_t * p, float s, struct pv_t *r)
|
||||
{
|
||||
r->x = p->x * s;
|
||||
r->y = p->y * s;
|
||||
r->z = p->z * s;
|
||||
}
|
||||
|
||||
// r = p / s
|
||||
void
|
||||
divide_pv(struct pv_t *p, float s, struct pv_t *r)
|
||||
{
|
||||
scale_pv(p, 1.0/s, r);
|
||||
}
|
||||
|
||||
// r = a * b
|
||||
void
|
||||
multiply_pv(struct pv_t *a, struct pv_t *b, struct pv_t *r)
|
||||
{
|
||||
r->x = a->x * b->x;
|
||||
r->y = a->y * b->y;
|
||||
r->z = a->z * b->z;
|
||||
}
|
||||
|
||||
// Returns ||v||
|
||||
float
|
||||
magnitude_pv(struct pv_t *v)
|
||||
{
|
||||
return sqrtf(pow2((v)->x) + pow2((v)->y) + pow2((v)->z));
|
||||
}
|
||||
|
||||
// r = v/(||v||)
|
||||
void
|
||||
normalize_pv(struct pv_t *v, struct pv_t *r)
|
||||
{
|
||||
float m = 0.0;
|
||||
|
||||
m = magnitude_pv(v);
|
||||
|
||||
r->x = v->x/m;
|
||||
r->y = v->y/m;
|
||||
r->z = v->z/m;
|
||||
}
|
||||
|
||||
// r = 1/p
|
||||
// Returns the inverse of p.
|
||||
// I had to get a little experimental with this, so I hope
|
||||
// it works. Essentially this will check if any of the
|
||||
// components on the vector is equal to 0, and if they are,
|
||||
// the resulting value on r will be equal to INFINITY
|
||||
void inverse_pv(struct pv_t* p, struct pv_t *r)
|
||||
{
|
||||
#define csign(x) (((x) >= 0) - ((x) < 0))
|
||||
r->x = (p->x == 0 ? csign(p->x) * INFINITY : 1.0/p->x);
|
||||
r->y = (p->y == 0 ? csign(p->y) * INFINITY : 1.0/p->y);
|
||||
r->z = (p->z == 0 ? csign(p->z) * INFINITY : 1.0/p->z);
|
||||
#undef csgin
|
||||
}
|
||||
|
||||
float
|
||||
dot_product(struct pv_t *a, struct pv_t *b)
|
||||
{
|
||||
return a->x * b->x + a->y * b->y + a->z * b->z;
|
||||
}
|
||||
|
||||
void
|
||||
cross_pv(struct pv_t *a, struct pv_t *b, struct pv_t *r)
|
||||
{
|
||||
r->x = a->y * b->z - a->z * b->y;
|
||||
r->y = a->z * b->x - a->x * b->z;
|
||||
r->z = a->x * b->y - a->y * b->x;
|
||||
}
|
||||
|
||||
// Okay, so everyone seems to
|
||||
// Checks if pointvector is a point
|
||||
// Just in case I need to add other criteria to this
|
||||
// later
|
||||
static inline bool
|
||||
is_point(struct pv_t *p)
|
||||
{
|
||||
return p->w > 0;
|
||||
}
|
||||
|
||||
// Converts a pv_t to a column_t
|
||||
static inline void
|
||||
pv_to_column(struct pv_t *p, column_t c)
|
||||
{
|
||||
c[0][0] = p->x;
|
||||
c[1][0] = p->y;
|
||||
c[2][0] = p->z;
|
||||
c[3][0] = p->w;
|
||||
}
|
||||
|
||||
// Converts a column_t to a pv_t
|
||||
static inline void
|
||||
column_to_pv(column_t c, struct pv_t *p)
|
||||
{
|
||||
p->x = c[0][0];
|
||||
p->y = c[1][0];
|
||||
p->z = c[2][0];
|
||||
p->w = c[3][0];
|
||||
}
|
||||
|
||||
// Yeah... I don't have time to worry about
|
||||
// how to calculate the inverse of a matrix.
|
||||
// Like, I know how to do this, but I was spending
|
||||
// too much time writing my own method so f*ck it,
|
||||
// I asked San Google for some help with this one.
|
||||
//
|
||||
// Taken from
|
||||
// https://stackoverflow.com/questions/1148309/inverting-a-4x4-matrix
|
||||
// (I would have referenced the original source for the function
|
||||
// but I couldn't find it)
|
||||
//
|
||||
// Also, I made this inlined since it's only going to be used
|
||||
// in one place. So essentially, this would be the same as
|
||||
// wiriting this function on inv_matrix, but I wanted to separate
|
||||
// this from inv_matrix since I didn't write this myself.
|
||||
inline static bool
|
||||
_inv_matrix(const float m[16], float r[16])
|
||||
{
|
||||
float inv[16], det;
|
||||
int i;
|
||||
|
||||
inv[0] =
|
||||
m[5] * m[10] * m[15] -
|
||||
m[5] * m[11] * m[14] -
|
||||
m[9] * m[6] * m[15] +
|
||||
m[9] * m[7] * m[14] +
|
||||
m[13] * m[6] * m[11] -
|
||||
m[13] * m[7] * m[10];
|
||||
|
||||
inv[4] =
|
||||
-m[4] * m[10] * m[15] +
|
||||
m[4] * m[11] * m[14] +
|
||||
m[8] * m[6] * m[15] -
|
||||
m[8] * m[7] * m[14] -
|
||||
m[12] * m[6] * m[11] +
|
||||
m[12] * m[7] * m[10];
|
||||
|
||||
inv[8] =
|
||||
m[4] * m[9] * m[15] -
|
||||
m[4] * m[11] * m[13] -
|
||||
m[8] * m[5] * m[15] +
|
||||
m[8] * m[7] * m[13] +
|
||||
m[12] * m[5] * m[11] -
|
||||
m[12] * m[7] * m[9];
|
||||
|
||||
inv[12] =
|
||||
-m[4] * m[9] * m[14] +
|
||||
m[4] * m[10] * m[13] +
|
||||
m[8] * m[5] * m[14] -
|
||||
m[8] * m[6] * m[13] -
|
||||
m[12] * m[5] * m[10] +
|
||||
m[12] * m[6] * m[9];
|
||||
|
||||
inv[1] =
|
||||
-m[1] * m[10] * m[15] +
|
||||
m[1] * m[11] * m[14] +
|
||||
m[9] * m[2] * m[15] -
|
||||
m[9] * m[3] * m[14] -
|
||||
m[13] * m[2] * m[11] +
|
||||
m[13] * m[3] * m[10];
|
||||
|
||||
inv[5] =
|
||||
m[0] * m[10] * m[15] -
|
||||
m[0] * m[11] * m[14] -
|
||||
m[8] * m[2] * m[15] +
|
||||
m[8] * m[3] * m[14] +
|
||||
m[12] * m[2] * m[11] -
|
||||
m[12] * m[3] * m[10];
|
||||
|
||||
inv[9] =
|
||||
-m[0] * m[9] * m[15] +
|
||||
m[0] * m[11] * m[13] +
|
||||
m[8] * m[1] * m[15] -
|
||||
m[8] * m[3] * m[13] -
|
||||
m[12] * m[1] * m[11] +
|
||||
m[12] * m[3] * m[9];
|
||||
|
||||
inv[13] =
|
||||
m[0] * m[9] * m[14] -
|
||||
m[0] * m[10] * m[13] -
|
||||
m[8] * m[1] * m[14] +
|
||||
m[8] * m[2] * m[13] +
|
||||
m[12] * m[1] * m[10] -
|
||||
m[12] * m[2] * m[9];
|
||||
|
||||
inv[2] =
|
||||
m[1] * m[6] * m[15] -
|
||||
m[1] * m[7] * m[14] -
|
||||
m[5] * m[2] * m[15] +
|
||||
m[5] * m[3] * m[14] +
|
||||
m[13] * m[2] * m[7] -
|
||||
m[13] * m[3] * m[6];
|
||||
|
||||
inv[6] =
|
||||
-m[0] * m[6] * m[15] +
|
||||
m[0] * m[7] * m[14] +
|
||||
m[4] * m[2] * m[15] -
|
||||
m[4] * m[3] * m[14] -
|
||||
m[12] * m[2] * m[7] +
|
||||
m[12] * m[3] * m[6];
|
||||
|
||||
inv[10] =
|
||||
m[0] * m[5] * m[15] -
|
||||
m[0] * m[7] * m[13] -
|
||||
m[4] * m[1] * m[15] +
|
||||
m[4] * m[3] * m[13] +
|
||||
m[12] * m[1] * m[7] -
|
||||
m[12] * m[3] * m[5];
|
||||
|
||||
inv[14] =
|
||||
-m[0] * m[5] * m[14] +
|
||||
m[0] * m[6] * m[13] +
|
||||
m[4] * m[1] * m[14] -
|
||||
m[4] * m[2] * m[13] -
|
||||
m[12] * m[1] * m[6] +
|
||||
m[12] * m[2] * m[5];
|
||||
|
||||
inv[3] =
|
||||
-m[1] * m[6] * m[11] +
|
||||
m[1] * m[7] * m[10] +
|
||||
m[5] * m[2] * m[11] -
|
||||
m[5] * m[3] * m[10] -
|
||||
m[9] * m[2] * m[7] +
|
||||
m[9] * m[3] * m[6];
|
||||
|
||||
inv[7] =
|
||||
m[0] * m[6] * m[11] -
|
||||
m[0] * m[7] * m[10] -
|
||||
m[4] * m[2] * m[11] +
|
||||
m[4] * m[3] * m[10] +
|
||||
m[8] * m[2] * m[7] -
|
||||
m[8] * m[3] * m[6];
|
||||
|
||||
inv[11] =
|
||||
-m[0] * m[5] * m[11] +
|
||||
m[0] * m[7] * m[9] +
|
||||
m[4] * m[1] * m[11] -
|
||||
m[4] * m[3] * m[9] -
|
||||
m[8] * m[1] * m[7] +
|
||||
m[8] * m[3] * m[5];
|
||||
|
||||
inv[15] =
|
||||
m[0] * m[5] * m[10] -
|
||||
m[0] * m[6] * m[9] -
|
||||
m[4] * m[1] * m[10] +
|
||||
m[4] * m[2] * m[9] +
|
||||
m[8] * m[1] * m[6] -
|
||||
m[8] * m[2] * m[5];
|
||||
|
||||
det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12];
|
||||
|
||||
if (det == 0)
|
||||
return false;
|
||||
|
||||
det = 1.0 / det;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
r[i] = inv[i] * det;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// r = inv(m)
|
||||
// If m doesn't have an inverse, then inv_matrix
|
||||
// will act just like copy_matrix
|
||||
void
|
||||
inv_matrix(matrix_t m, matrix_t r)
|
||||
{
|
||||
bool s;
|
||||
|
||||
s = _inv_matrix((const float *)m, (float *)r);
|
||||
if(s)
|
||||
return;
|
||||
else
|
||||
copy_matrix(m, r);
|
||||
}
|
||||
|
||||
// r = m * x
|
||||
// Matrix times column operation. Do not use
|
||||
// c as r as well. This will cause problems
|
||||
void
|
||||
mxc(matrix_t m, column_t c, column_t r)
|
||||
{
|
||||
r[0][0] = m[0][0] * c[0][0] + m[0][1] * c[1][0] + m[0][2] * c[2][0] + m[0][3] * c[3][0];
|
||||
r[1][0] = m[1][0] * c[0][0] + m[1][1] * c[1][0] + m[1][2] * c[2][0] + m[1][3] * c[3][0];
|
||||
r[2][0] = m[2][0] * c[0][0] + m[2][1] * c[1][0] + m[2][2] * c[2][0] + m[2][3] * c[3][0];
|
||||
r[3][0] = m[3][0] * c[0][0] + m[3][1] * c[1][0] + m[3][2] * c[2][0] + m[3][3] * c[3][0];
|
||||
}
|
||||
|
||||
// r = m * c
|
||||
// Matrix times column operation. Do not use
|
||||
// c as r as well. This will cause problems
|
||||
void
|
||||
mxm(matrix_t m, matrix_t c, matrix_t r)
|
||||
{
|
||||
unsigned char i = 0;
|
||||
|
||||
// I know I didn't NEED to use a loop here, but this is due in
|
||||
// a week
|
||||
for(i = 0; i < 4; i++)
|
||||
{
|
||||
r[0][i] = m[0][0] * c[0][i] + m[0][1] * c[1][i] + m[0][2] * c[2][i] + m[0][3] * c[3][i];
|
||||
r[1][i] = m[1][0] * c[0][i] + m[1][1] * c[1][i] + m[1][2] * c[2][i] + m[1][3] * c[3][i];
|
||||
r[2][i] = m[2][0] * c[0][i] + m[2][1] * c[1][i] + m[2][2] * c[2][i] + m[2][3] * c[3][i];
|
||||
r[3][i] = m[3][0] * c[0][i] + m[3][1] * c[1][i] + m[3][2] * c[2][i] + m[3][3] * c[3][i];
|
||||
}
|
||||
}
|
||||
|
||||
// m = Im
|
||||
void
|
||||
make_identity_matrix(matrix_t m)
|
||||
{
|
||||
m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0;
|
||||
|
||||
m[0][1] = m[0][2] = m[0][3] =
|
||||
m[1][0] = m[1][2] = m[1][3] =
|
||||
m[2][0] = m[2][1] = m[2][3] =
|
||||
m[3][0] = m[3][1] = m[3][2] = 0.0;
|
||||
}
|
||||
|
||||
// m = T(x, y, z)
|
||||
void
|
||||
make_translation_matrix(float x, float y, float z, matrix_t m)
|
||||
{
|
||||
m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0;
|
||||
|
||||
m[0][3] = x;
|
||||
m[1][3] = y;
|
||||
m[2][3] = z;
|
||||
|
||||
m[0][1] = 0.0;
|
||||
m[0][2] = 0.0;
|
||||
|
||||
m[1][0] = 0.0;
|
||||
m[1][2] = 0.0;
|
||||
|
||||
m[2][0] = 0.0;
|
||||
m[2][1] = 0.0;
|
||||
|
||||
m[3][0] = 0.0;
|
||||
m[3][1] = 0.0;
|
||||
m[3][2] = 0.0;
|
||||
}
|
||||
|
||||
// m = S(x, y, z)
|
||||
void
|
||||
make_scaling_matrix(float x, float y, float z, matrix_t m)
|
||||
{
|
||||
m[0][0] = x;
|
||||
m[1][1] = y;
|
||||
m[2][2] = z;
|
||||
m[3][3] = 1.0;
|
||||
|
||||
m[0][1] = 0.0;
|
||||
m[0][2] = 0.0;
|
||||
m[0][3] = 0.0;
|
||||
|
||||
m[1][0] = 0.0;
|
||||
m[1][2] = 0.0;
|
||||
m[1][3] = 0.0;
|
||||
|
||||
m[2][0] = 0.0;
|
||||
m[2][1] = 0.0;
|
||||
m[2][3] = 0.0;
|
||||
|
||||
m[3][0] = 0.0;
|
||||
m[3][1] = 0.0;
|
||||
m[3][2] = 0.0;
|
||||
}
|
||||
|
||||
// m = R(t, u)
|
||||
// t => Thetha: Angle for the rotation
|
||||
// u => Unit Vector: Normal vector indicating the rotation axis(es)
|
||||
void
|
||||
make_rotation_matrix(float t, struct pv_t *u, matrix_t m)
|
||||
{
|
||||
float x2 = .0, y2 = .0, z2 = .0, sint = .0, cost = .0, d = .0;
|
||||
|
||||
x2 = pow2(u->x);
|
||||
y2 = pow2(u->y);
|
||||
z2 = pow2(u->z);
|
||||
|
||||
d = deg2rad(t);
|
||||
cost = cos(d);
|
||||
sint = sin(d);
|
||||
|
||||
m[0][0] = x2 + cost*(1-x2);
|
||||
m[0][1] = u->x * u->y * (1-cost) - u->z*sint;
|
||||
m[0][2] = u->x * u->z * (1-cost) + u->y*sint;
|
||||
m[0][3] = 0.0;
|
||||
|
||||
m[1][0] = u->x * u->y * (1-cost) + u->z*sint;
|
||||
m[1][1] = y2 + cost*(1-y2);
|
||||
m[1][2] = u->y * u->z * (1-cost) - u->x*sint;
|
||||
m[1][3] = 0.0;
|
||||
|
||||
m[2][0] = u->x * u->z * (1-cost) - u->y*sint;
|
||||
m[2][1] = u->y * u->z * (1-cost) + u->x*sint;
|
||||
m[2][2] = z2 + cost*(1-z2);
|
||||
m[2][3] = 0.0;
|
||||
|
||||
m[3][0] = 0.0;
|
||||
m[3][1] = 0.0;
|
||||
m[3][2] = 0.0;
|
||||
m[3][3] = 1.0;
|
||||
}
|
||||
|
||||
// Apply transform matrix m to pv
|
||||
void
|
||||
transform_pv(matrix_t m, struct pv_t *p, struct pv_t *r)
|
||||
{
|
||||
column_t a, c;
|
||||
|
||||
pv_to_column(p, c);
|
||||
mxc(m, c, a);
|
||||
column_to_pv(a, r);
|
||||
}
|
||||
|
||||
// Multiply m by all the pv_t on src and save
|
||||
// the results on dst
|
||||
void
|
||||
transform_pv_arr(matrix_t m, struct pv_t *src, struct pv_t *dst, size_t s)
|
||||
{
|
||||
column_t a, c;
|
||||
|
||||
while(s > 0)
|
||||
{
|
||||
s--;
|
||||
pv_to_column(&src[s], c);
|
||||
mxc(m, c, a);
|
||||
column_to_pv(a, &dst[s]);
|
||||
}
|
||||
}
|
||||
|
||||
// Reflects i around normal n
|
||||
void
|
||||
reflect_pv(struct pv_t *i, struct pv_t *n, struct pv_t *r)
|
||||
{
|
||||
struct pv_t p = {0.0};
|
||||
|
||||
scale_pv(n, dot_product(i, n) * 2.0, &p);
|
||||
substract_pv(i, &p, r);
|
||||
}
|
||||
|
||||
void
|
||||
make_sphere(struct pv_t *center, float radius, struct sphere_t *s)
|
||||
{
|
||||
s->radius = radius;
|
||||
s->radius2 = pow2(radius);
|
||||
s->center = *center;
|
||||
|
||||
s->type = GEOMETRY_SPHERE;
|
||||
|
||||
s->param = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
make_plane(struct pv_t *center, struct pv_t *normal, struct plane_t * plane)
|
||||
{
|
||||
plane->center = *center;
|
||||
plane->normal = *normal;
|
||||
|
||||
plane->type = GEOMETRY_PLANE;
|
||||
}
|
||||
|
||||
void
|
||||
make_triangle(struct pv_t *a, struct pv_t *b, struct pv_t *c, struct triangle_t *t)
|
||||
{
|
||||
// I know I could have used ac instead... but
|
||||
// I also want to be able to understand this in
|
||||
// the future
|
||||
struct pv_t ca, cp;
|
||||
|
||||
t->edges[0] = *a;
|
||||
t->edges[1] = *b;
|
||||
t->edges[2] = *c;
|
||||
|
||||
// Use for intersection check
|
||||
substract_pv(b, a, &t->ba);
|
||||
substract_pv(c,b, &t->cb);
|
||||
substract_pv(a,c, &t->ac);
|
||||
|
||||
substract_pv(c, a, &ca);
|
||||
|
||||
cross_pv(&t->ba, &ca, &cp);
|
||||
normalize_pv(&cp, &t->normal);
|
||||
t->area = dot_product(&cp, &t->normal);
|
||||
|
||||
t->type = GEOMETRY_TRIANGLE;
|
||||
}
|
||||
|
||||
void
|
||||
transform_triangle(struct triangle_t *t, matrix_t m, struct triangle_t *r)
|
||||
{
|
||||
transform_pv(m, &t->edges[0], &t->edges[0]);
|
||||
transform_pv(m, &t->edges[1], &t->edges[1]);
|
||||
transform_pv(m, &t->edges[2], &t->edges[2]);
|
||||
|
||||
make_triangle(&t->edges[0], &t->edges[1], &t->edges[2], r);
|
||||
}
|
||||
|
||||
void
|
||||
new_mesh(struct mesh_t *m, size_t c)
|
||||
{
|
||||
matrix_t i;
|
||||
|
||||
m->triangles = (struct triangle_t *)calloc(c, sizeof(struct triangle_t));
|
||||
m->triangle_count = c;
|
||||
|
||||
make_identity_matrix(i);
|
||||
copy_matrix(i, m->transform);
|
||||
copy_matrix(i, m->inv_transform);
|
||||
}
|
||||
|
||||
void
|
||||
free_mesh(struct mesh_t *m)
|
||||
{
|
||||
if(m->triangles != NULL)
|
||||
free(m->triangles);
|
||||
|
||||
m->triangles = NULL;
|
||||
m->triangle_count = 0;
|
||||
}
|
||||
|
||||
void
|
||||
transform_mesh(struct mesh_t *m, matrix_t t, struct mesh_t *r)
|
||||
{
|
||||
size_t i = 0;
|
||||
matrix_t b;
|
||||
|
||||
for(; i < m->triangle_count; i++)
|
||||
transform_triangle(&m->triangles[i], t, &r->triangles[i]);
|
||||
|
||||
mxm(t, m->transform, b);
|
||||
inv_matrix(b, r->inv_transform);
|
||||
copy_matrix(b, r->transform);
|
||||
}
|
||||
|
||||
void transform_object(struct gobject_t *g, matrix_t t, struct gobject_t *r)
|
||||
{
|
||||
switch (g->type)
|
||||
{
|
||||
case GEOMETRY_SPHERE:
|
||||
transform_pv(t, &g->center, &r->center);
|
||||
break;
|
||||
case GEOMETRY_TRIANGLE:
|
||||
transform_triangle(g, t, r);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
new_rectangle_mesh(struct pv_t *a, struct pv_t *b, struct pv_t *c, struct pv_t *d, struct mesh_t *m)
|
||||
{
|
||||
new_mesh(m, 2);
|
||||
make_triangle(a, b, c, &m->triangles[0]);
|
||||
make_triangle(c, d, a, &m->triangles[1]);
|
||||
m->triangles[0].single_sided = m->triangles[1].single_sided = false;
|
||||
|
||||
m->has_bounding_sphere = true;
|
||||
|
||||
// substract_pv(b, a, &p);
|
||||
// radius = magnitude_pv(&p)/2;
|
||||
// normalize_pv(&p, &p);
|
||||
// scale_pv(&p, radius, &p);
|
||||
// add_pv(a, &p, &p);
|
||||
// make_sphere(&p, radius, &m->bounding_sphere);
|
||||
}
|
||||
|
||||
void
|
||||
new_rectangle_mesh_wh(float width, float height, struct mesh_t *m)
|
||||
{
|
||||
struct pv_t a, b, c;
|
||||
|
||||
a = b = c = PV(0.0, 0.0, 0.0);
|
||||
new_mesh(m, 2);
|
||||
|
||||
a.x = width;
|
||||
c.z = -height;
|
||||
make_triangle(&b, &a, &c, &m->triangles[0]);
|
||||
|
||||
b.z = c.z;
|
||||
b.x = a.x;
|
||||
make_triangle(&a, &b, &c, &m->triangles[1]);
|
||||
|
||||
m->triangles[0].single_sided = m->triangles[1].single_sided = false;
|
||||
}
|
135
src/geometry.h
135
src/geometry.h
|
@ -1,135 +0,0 @@
|
|||
#ifndef GEOMETRY_H__
|
||||
#define GEOMETRY_H__
|
||||
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI ((double)3.14159265358979323846)
|
||||
#endif
|
||||
|
||||
// // Returns p^2
|
||||
// // Because p*p takes too long to write
|
||||
// #define pow2(p) (p)*(p)
|
||||
|
||||
// Converts angle from degrees to radiants
|
||||
#define deg2rad(t) ((t * M_PI)/180.0)
|
||||
|
||||
#define PV(a, b, c) (struct pv_t){.x = a, .y = b, .z = c, .w = 1.0}
|
||||
#define SPHERE(v, r) (struct gobject_t){.type = GEOMETRY_SPHERE, .center = v, .radius = r, .radius2 = pow2(r)}
|
||||
#define DISK(c, n, r) (struct gobject_t){.type = GEOMETRY_DISK, .center = c, .normal = n, .radius = r, .radius2 = pow2(r)}
|
||||
#define PLANE(c, n) (struct gobject_t){.type = GEOMETRY_PLANE, .center = c, .normal = n}
|
||||
#define TRIANGLE(a, b, c, n) (struct gobject_t){.type = GEOMETRY_TRIANGLE, .edges[0] = a, .edges[1] = b, .edges[2] = c, .normal = n}
|
||||
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||
|
||||
typedef uint32_t pixel_t;
|
||||
|
||||
typedef float matrix_t[4][4];
|
||||
typedef float column_t[4][1];
|
||||
|
||||
struct pv_t
|
||||
{ float x,y,z,w; };
|
||||
|
||||
enum gobject_type_t
|
||||
{
|
||||
GEOMETRY_TRIANGLE,
|
||||
GEOMETRY_SPHERE,
|
||||
GEOMETRY_PLANE,
|
||||
GEOMETRY_DISK,
|
||||
};
|
||||
|
||||
struct gobject_t
|
||||
{
|
||||
enum gobject_type_t type;
|
||||
struct pv_t center;
|
||||
|
||||
bool emitter;
|
||||
|
||||
struct pv_t normal;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
float radius;
|
||||
float radius2;
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
struct pv_t edges[3], ba, cb, ac;
|
||||
bool single_sided;
|
||||
float area;
|
||||
};
|
||||
};
|
||||
|
||||
void *param;
|
||||
};
|
||||
#define triangle_t gobject_t
|
||||
#define sphere_t gobject_t
|
||||
#define plane_t gobject_t
|
||||
|
||||
struct mesh_t
|
||||
{
|
||||
struct triangle_t *triangles;
|
||||
size_t triangle_count;
|
||||
matrix_t transform, inv_transform;
|
||||
|
||||
struct gobject_t bounding_sphere;
|
||||
bool has_bounding_sphere;
|
||||
};
|
||||
|
||||
const char* matrix_to_str(matrix_t m);
|
||||
const char* column_to_str(column_t c);
|
||||
const char* pv_to_str(struct pv_t *p);
|
||||
|
||||
void copy_matrix(matrix_t s, matrix_t d);
|
||||
void clear_matrix(matrix_t m);
|
||||
|
||||
float magnitude_pv(struct pv_t *v);
|
||||
|
||||
void reflect_pv(struct pv_t *i, struct pv_t *n, struct pv_t *r);
|
||||
void substract_pv(struct pv_t *a, struct pv_t *b, struct pv_t *r);
|
||||
void add_pv(struct pv_t *a, struct pv_t *b, struct pv_t *r);
|
||||
void scale_pv(struct pv_t * p, float s, struct pv_t *r);
|
||||
void divide_pv(struct pv_t *p, float s, struct pv_t *r);
|
||||
void multiply_pv(struct pv_t *a, struct pv_t *b, struct pv_t *r);
|
||||
void normalize_pv(struct pv_t *v, struct pv_t *r);
|
||||
void inverse_pv(struct pv_t* p, struct pv_t *r);
|
||||
void cross_pv(struct pv_t *a, struct pv_t *b, struct pv_t *r);
|
||||
float dot_product(struct pv_t *a, struct pv_t *b);
|
||||
|
||||
void inv_matrix(matrix_t m, matrix_t r);
|
||||
void mxc(matrix_t m, column_t c, column_t r);
|
||||
void mxm(matrix_t m, matrix_t c, matrix_t r);
|
||||
|
||||
void make_identity_matrix(matrix_t m);
|
||||
void make_translation_matrix(float x, float y, float z, matrix_t m);
|
||||
void make_scaling_matrix(float x, float y, float z, matrix_t m);
|
||||
void make_rotation_matrix(float t, struct pv_t *u, matrix_t m);
|
||||
|
||||
void transform_pv(matrix_t m, struct pv_t *p, struct pv_t *r);
|
||||
void transform_pv_arr(matrix_t m, struct pv_t *src, struct pv_t *dst, size_t s);
|
||||
|
||||
void make_triangle(struct pv_t *a, struct pv_t *b, struct pv_t *c, struct triangle_t *t);
|
||||
void transform_triangle(struct triangle_t *t, matrix_t m, struct triangle_t *r);
|
||||
|
||||
void make_sphere(struct pv_t *center, float radius, struct sphere_t *s);
|
||||
|
||||
void make_plane(struct pv_t *center, struct pv_t *normal, struct plane_t * plane);
|
||||
|
||||
void new_mesh(struct mesh_t *m, size_t c);
|
||||
void free_mesh(struct mesh_t *m);
|
||||
|
||||
void transform_object(struct gobject_t *g, matrix_t t, struct gobject_t *r);
|
||||
void transform_mesh(struct mesh_t *m, matrix_t t, struct mesh_t *r);
|
||||
|
||||
void new_rectangle_mesh(struct pv_t *a, struct pv_t *b, struct pv_t *c, struct pv_t *d, struct mesh_t *m);
|
||||
void new_rectangle_mesh_wh(float width, float height, struct mesh_t *m);
|
||||
|
||||
#endif
|
10
src/main.c
10
src/main.c
|
@ -6,12 +6,20 @@
|
|||
int
|
||||
main(int argc, char const *argv[])
|
||||
{
|
||||
uint64_t next_update = 0;
|
||||
gmema_init();
|
||||
|
||||
cm_init(Mod1Mask);
|
||||
|
||||
while(!wm_process_events())
|
||||
;
|
||||
{
|
||||
if(time_ms() >= next_update)
|
||||
{
|
||||
next_update = time_ms() + 25;
|
||||
cm_render_windows();
|
||||
cm_swap_buffers();
|
||||
}
|
||||
}
|
||||
cm_destroy();
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -10,18 +10,20 @@ GLint error_log_lenght = 0;
|
|||
int
|
||||
shader_compile(GLuint shader, const char * source, const char * err[])
|
||||
{
|
||||
int ret = 0;
|
||||
gmema_init();
|
||||
|
||||
glShaderSource(shader, 1, &source, 0);
|
||||
glCompileShader(shader);
|
||||
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &error_log_lenght);
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &ret);
|
||||
|
||||
if(error_log_buffer)
|
||||
gfree(error_log_buffer);
|
||||
error_log_buffer = gmalloc(sizeof(*error_log_buffer) * error_log_lenght);
|
||||
|
||||
if(error_log_lenght)
|
||||
if(error_log_lenght || ret == GL_FALSE)
|
||||
{
|
||||
glGetShaderInfoLog(shader, error_log_lenght, NULL, error_log_buffer);
|
||||
if(err)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef __UTIL_H__
|
||||
#define __UTIL_H__
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
|
@ -39,6 +40,13 @@
|
|||
typedef unsigned int uint;
|
||||
#endif
|
||||
|
||||
static inline uint64_t
|
||||
time_ms(void)
|
||||
{
|
||||
struct timeval current_time = {0};
|
||||
gettimeofday(¤t_time, 0);
|
||||
return current_time.tv_sec*1000 + current_time.tv_usec/1000;
|
||||
}
|
||||
|
||||
static inline int
|
||||
read_file(const char * file_path, char ** data, size_t *size)
|
||||
|
|
25
src/wm.c
25
src/wm.c
|
@ -10,6 +10,10 @@
|
|||
|
||||
#define XERROR_MSG_LEN 255
|
||||
|
||||
#ifndef XDISPLAY_NAME
|
||||
#define XDISPLAY_NAME ":4.0"
|
||||
#endif
|
||||
|
||||
typedef struct active_window_t
|
||||
{
|
||||
bool defined;
|
||||
|
@ -305,7 +309,14 @@ wm_kill_window( Window window )
|
|||
}
|
||||
|
||||
int
|
||||
wm_init(unsigned int modkey, wm_callbacks_t * callbacks)
|
||||
wm_set_callbacks( wm_callbacks_t callbacks )
|
||||
{
|
||||
wm.callbacks = callbacks;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
wm_init(unsigned int modkey)
|
||||
{
|
||||
unused(wm_display_error);
|
||||
|
||||
|
@ -313,10 +324,7 @@ wm_init(unsigned int modkey, wm_callbacks_t * callbacks)
|
|||
|
||||
clear(&wm);
|
||||
|
||||
if(callbacks)
|
||||
wm.callbacks = *callbacks;
|
||||
|
||||
if((wm.display = XOpenDisplay(NULL)) == NULL)
|
||||
if((wm.display = XOpenDisplay(XDISPLAY_NAME)) == NULL)
|
||||
ftl("cannot open X11 display");
|
||||
|
||||
// Setup X11 error handler
|
||||
|
@ -426,7 +434,7 @@ wm_move_window( Window window, int x, int y )
|
|||
|
||||
err = XMoveWindow(wm.display, window, x, y);
|
||||
|
||||
// dbg("window (%ld) moved to (%d, %d)", window, x, y);
|
||||
dbg("window (%ld) moved to (%d, %d)", window, x, y);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -499,9 +507,12 @@ wm_process_events()
|
|||
}
|
||||
|
||||
window = x_get_event_window(event);
|
||||
if(window == wm.root_window)
|
||||
return 0;
|
||||
|
||||
if(window)
|
||||
node = find_window(window);
|
||||
|
||||
|
||||
switch(event.type)
|
||||
{
|
||||
case CreateNotify:
|
||||
|
|
4
src/wm.h
4
src/wm.h
|
@ -27,9 +27,11 @@ typedef struct wm_callbacks_t
|
|||
void (*on_create_window)(window_node_t * node);
|
||||
} wm_callbacks_t;
|
||||
|
||||
int wm_init( unsigned int modkey, wm_callbacks_t *callbacks );
|
||||
int wm_init( unsigned int modkey );
|
||||
int wm_destroy( void );
|
||||
|
||||
int wm_set_callbacks( wm_callbacks_t callbacks );
|
||||
|
||||
int wm_get_screen( void );
|
||||
Display * wm_get_display( void );
|
||||
Window wm_get_root_window( void );
|
||||
|
|
Loading…
Reference in New Issue