diff options
-rw-r--r-- | demo/FPSCamera.lua | 7 | ||||
-rw-r--r-- | demo/main.lua | 10 | ||||
-rw-r--r-- | src/texture/texture.c | 171 | ||||
-rw-r--r-- | src/texture/texture.h | 81 | ||||
-rw-r--r-- | src/window/window.c | 3 |
5 files changed, 225 insertions, 47 deletions
diff --git a/demo/FPSCamera.lua b/demo/FPSCamera.lua index 7ee3cf8..7c33242 100644 --- a/demo/FPSCamera.lua +++ b/demo/FPSCamera.lua @@ -42,6 +42,13 @@ function camera:update(dt) movement:setAt(1, 0) movement:normalize() + + if honey.input.key.is_down(honey.input.key.left_shift) then + movement:add(Vector.Vec3.Y_UNIT, movement) + end + if honey.input.key.is_down(honey.input.key.left_control) then + movement:sub(Vector.Vec3.Y_UNIT, movement) + end movement:muls(self.movement_speed*dt, movement) self.position:add(movement, self.position) diff --git a/demo/main.lua b/demo/main.lua index 9ca08be..3c32b6f 100644 --- a/demo/main.lua +++ b/demo/main.lua @@ -49,7 +49,7 @@ uniform sampler2D tex; out vec4 color; void main() { - vec2 texture_coords = UV + (0.01 * time * vec2(1,1)); + vec2 texture_coords = UV + (time * vec2(100,100)); color = vec4(texture(tex, texture_coords).xyz, 1); } ]] @@ -60,15 +60,21 @@ local color1 = Vector.Vec4.new{1,0,0,1} local color2 = Vector.Vec4.new{0,0,1,1} local color = Vector.Vec4.new() +local total_frames = 0 local total_time = 0 function honey.update(dt) total_time = total_time + dt FPSCamera:update(dt) + if total_time > 1 then + print('FPS: '..tostring(total_frames/total_time)) + total_time = 0 + total_frames = 0 + end end function honey.draw() - + total_frames = total_frames + 1 honey.shader.set_mat4(shader, 'model', model.array) honey.shader.set_mat4(shader, 'view', FPSCamera.view.array) honey.shader.set_mat4(shader, 'projection', FPSCamera.projection.array) diff --git a/src/texture/texture.c b/src/texture/texture.c index 1bb798a..6df19a7 100644 --- a/src/texture/texture.c +++ b/src/texture/texture.c @@ -10,12 +10,10 @@ static int honey_lua_texture_load(lua_State* L) { honey_texture* texture; char* texture_path; - bool use_alpha; honey_lua_parse_arguments(L, 3, HONEY_USERDATA, &texture, - HONEY_STRING, &texture_path, - HONEY_BOOLEAN, &use_alpha); - enum honey_texture_result result = honey_texture_load(texture, texture_path, use_alpha); + HONEY_STRING, &texture_path); + enum honey_texture_result result = honey_texture_load(texture, texture_path); if (result != TEXTURE_OK) { char* error; honey_format_string(&error, @@ -53,46 +51,141 @@ void honey_setup_texture(lua_State* L) /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +static void generate_texture(honey_texture* texture, + int width, int height, + int format, int type, + void* data) +{ + unsigned int texture_id; + glGenTextures(1, &texture_id); + glBindTexture(GL_TEXTURE_2D, texture_id); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glTexImage2D(GL_TEXTURE_2D, 0, + format, + width, height, 0, + format, + type, data); + + texture->id = texture_id; + texture->width = width; + texture->height = height; + + switch(format) { + case GL_RED: + texture->type = GREY; + texture->channels = 1; + break; + + case GL_RGB: + texture->type = RGB; + texture->channels = 3; + break; + + case GL_RGBA: + texture->type = RGBA; + texture->channels = 4; + break; + + case GL_DEPTH_COMPONENT: + texture->type = DEPTH; + texture->channels = 1; + break; + + default: + break; + } + + return HONEY_OK; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +void honey_texture_new_greyscale(honey_texture* texture, + int height, int width, + unsigned char* data) +{ + generate_texture(texture, width, height, GL_RED, GL_UNSIGNED_BYTE, data); +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +void honey_texture_new_rgb(honey_texture* texture, + int height, int width, + unsigned char* data) +{ + generate_texture(texture, width, height, GL_RGB, GL_UNSIGNED_BYTE, data); +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +void honey_texture_new_rgba(honey_texture* texture, + int height, int width, + unsigned char* data) +{ + generate_texture(texture, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +void honey_texture_new_depth(honey_texture* texture, + int height, int width, + float* data) +{ + generate_texture(texture, width, height, GL_DEPTH_COMPONENT, GL_FLOAT, data); +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + enum honey_texture_result honey_texture_load(honey_texture* texture, - char* texture_path, - bool alpha_channel) { - unsigned int texture_id; - glGenTextures(1, &texture_id); - glBindTexture(GL_TEXTURE_2D, texture_id); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - int width, height, channels; - unsigned char* image_data = stbi_load(texture_path, &width, &height, &channels, 0); - if (image_data == NULL) { - fprintf(stderr, "ERROR: failed to load '%s'\n", texture_path); - return TEXTURE_FAILED; - } - - if (alpha_channel) { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data); - } - else { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image_data); - } - - glGenerateMipmap(GL_TEXTURE_2D); - stbi_image_free(image_data); - - (*texture).texture_id = texture_id; - (*texture).width = width; - (*texture).height = height; - (*texture).channels = channels; - - return TEXTURE_OK; + char* texture_path) +{ + int width, height, channels; + unsigned char* image_data = stbi_load(texture_path, &width, &height, &channels, 0); + if (image_data == NULL) { + return TEXTURE_FAILED; + } + + switch(channels) { + case 1: + honey_texture_new_greyscale(texture, width, height, image_data); + break; + + case 3: + honey_texture_new_rgb(texture, width, height, image_data); + break; + + case 4: + honey_texture_new_rgba(texture, width, height, image_data); + break; + + default: + return TEXTURE_CHANNEL_ERROR; + } + + glGenerateMipmap(GL_TEXTURE_2D); + stbi_image_free(image_data); + + return TEXTURE_OK; } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ void honey_texture_use(honey_texture texture, int texture_unit) { glActiveTexture(GL_TEXTURE0 + texture_unit); - glBindTexture(GL_TEXTURE_2D, texture.texture_id); + glBindTexture(GL_TEXTURE_2D, texture.id); } + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +//honey_result honey_texture_framebuffer_object_new(unsigned int* destination, +// int width, int height) +//{ +// glGenFramebuffers(1, destination); +// glBindFramebuffer(GL_FRAMEBUFFER, *destination); + + diff --git a/src/texture/texture.h b/src/texture/texture.h index c9d1104..785fef0 100644 --- a/src/texture/texture.h +++ b/src/texture/texture.h @@ -11,18 +11,77 @@ enum honey_texture_result { TEXTURE_OK, TEXTURE_FAILED, + TEXTURE_CHANNEL_ERROR, N_TEXTURE_RESULTS }; typedef struct { - unsigned int texture_id; - int width; - int height; - int channels; + unsigned int id; + enum { + GREY, + RGB, + RGBA, + DEPTH + } type; + int width; + int height; + int channels; } honey_texture; /** @brief Place the honey.texture bindings as a table on the stack. */ void honey_setup_texture(lua_State* L); +/** @brief Create a greyscale texture. + * + * @param[out] texture Pointer to the destination texture. + * @param[in] width The width in pixels of the texture to create. + * @param[in] height The height in pixels of the texture to create. + * @param[in] data The data to populate the texture with, or NULL to leave it unpopulated. + * + * @returns HONEY_OK on success, and appropriate error on failure. + */ +void honey_texture_new_greyscale(honey_texture* texture, + int width, int height, + unsigned char* data); + +/** @brief Create an RGB texture. + * + * @param[out] texture Pointer to the destination texture. + * @param[in] width The width in pixels of the texture to create. + * @param[in] height The height in pixels of the texture to create. + * @param[in] data The data to populate the texture with, or NULL to leave it unpopulated. + * + * @returns HONEY_OK on success, and appropriate error on failure. + */ +void honey_texture_new_rgb(honey_texture* texture, + int width, int height, + unsigned char* data); + +/** @brief Create an RGBA texture. + * + * @param[out] texture Pointer to the destination texture. + * @param[in] width The width in pixels of the texture to create. + * @param[in] height The height in pixels of the texture to create. + * @param[in] data The data to populate the texture with, or NULL to leave it unpopulated. + * + * @returns HONEY_OK on success, and appropriate error on failure. + */ +void honey_texture_new_rgba(honey_texture* texture, + int width, int height, + unsigned char* data); + +/** @brief Create a depth texture. + * + * @param[out] texture Pointer to the destination texture. + * @param[in] width The width in pixels of the texture to create. + * @param[in] height The height in pixels of the texture to create. + * @param[in] data The data to populate the texture with, or NULL to leave it unpopulated. + * + * @returns HONEY_OK on success, and appropriate error on failure. + */ +void honey_texture_new_depth(honey_texture* texture, + int width, int height, + float* data); + /** @brief Load a texture from disk. * * @param[out] texture Pointer to the destination texture @@ -32,8 +91,7 @@ void honey_setup_texture(lua_State* L); * @return Success or failure type */ enum honey_texture_result honey_texture_load(honey_texture* texture, - char* texture_path, - bool alpha_channel); + char* texture_path); /** @brief Load a texture into a texture unit. * @@ -42,4 +100,15 @@ enum honey_texture_result honey_texture_load(honey_texture* texture, */ void honey_texture_use(honey_texture texture, int texture_unit); +/** @brief Create a framebuffer object. + * + * @param[out] destination Pointer to store the resulting OpenGL handle in. + * @param[in] width The width in pixels of the FBO. + * @param[in] height The height in pixels of the FBO. + * + * @returns HONEY_OK on success; appropriate error otherwise. + */ +honey_result honey_texture_framebuffer_object_new(unsigned int* destination, + int width, int height); + #endif diff --git a/src/window/window.c b/src/window/window.c index 37053a4..6a1fe6f 100644 --- a/src/window/window.c +++ b/src/window/window.c @@ -97,6 +97,9 @@ bool honey_setup_window(lua_State* L) // Enable depth testing glEnable(GL_DEPTH_TEST); + // Enable face culling + glEnable(GL_CULL_FACE); + glfwSetWindowSizeCallback(info->window, honey_glfw_window_resize_callback); glfwSetWindowFocusCallback(info->window, honey_glfw_window_focus_callback); |