diff options
| author | sanine-a <sanine.not@pm.me> | 2020-10-31 18:48:20 -0500 | 
|---|---|---|
| committer | sanine-a <sanine.not@pm.me> | 2020-10-31 18:48:20 -0500 | 
| commit | ad75604ec79d70d328595f114e65bac80db9999f (patch) | |
| tree | c0eefa1a3795db995283418b54b558a8a33ceaec /src/texture | |
| parent | 3dca6a336c9fd54b0847249b5771d39141daa3ae (diff) | |
add additional texture types and refactor texture setup and loading
Diffstat (limited to 'src/texture')
| -rw-r--r-- | src/texture/texture.c | 171 | ||||
| -rw-r--r-- | src/texture/texture.h | 81 | 
2 files changed, 207 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 | 
