summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsanine-a <sanine.not@pm.me>2020-10-31 18:48:20 -0500
committersanine-a <sanine.not@pm.me>2020-10-31 18:48:20 -0500
commitad75604ec79d70d328595f114e65bac80db9999f (patch)
treec0eefa1a3795db995283418b54b558a8a33ceaec /src
parent3dca6a336c9fd54b0847249b5771d39141daa3ae (diff)
add additional texture types and refactor texture setup and loading
Diffstat (limited to 'src')
-rw-r--r--src/texture/texture.c171
-rw-r--r--src/texture/texture.h81
-rw-r--r--src/window/window.c3
3 files changed, 210 insertions, 45 deletions
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);