-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
320 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
#include <glisy/texture.h> | ||
#include <glisy/gl.h> | ||
#include <string.h> | ||
#include <math.h> | ||
|
||
static GLuint | ||
channel(GLenum format) { | ||
switch (format) { | ||
case GL_DEPTH_COMPONENT: | ||
case GL_ALPHA: | ||
return 1; | ||
case GL_RGB: | ||
return 3; | ||
default: | ||
return 4; | ||
} | ||
} | ||
|
||
static void | ||
texImage2D(GlisyTexture *texture, | ||
GLuint target, | ||
GLvoid *pixels, | ||
GLsizei size, | ||
GLuint *offset, | ||
GLuint level) { | ||
GLuint height = texture->shape[0]; | ||
GLuint width = texture->shape[0]; | ||
|
||
if (offset) { | ||
if (texture->compressed) { | ||
glCompressedTexSubImage2D(target, | ||
level, | ||
offset[0], | ||
offset[1], | ||
width, | ||
height, | ||
texture->format, | ||
size, | ||
pixels); | ||
} else { | ||
glTexSubImage2D(target, | ||
level, | ||
offset[0], | ||
offset[1], | ||
width, | ||
height, | ||
texture->format, | ||
texture->type, | ||
pixels); | ||
} | ||
} else { | ||
if (texture->compressed) { | ||
glCompressedTexImage2D(target, | ||
level, | ||
texture->format, | ||
width, | ||
height, | ||
0, | ||
size, | ||
pixels); | ||
} else { | ||
glTexImage2D(target, | ||
level, | ||
texture->format, | ||
width, | ||
height, | ||
0, | ||
texture->format, | ||
texture->type, | ||
pixels); | ||
} | ||
} | ||
} | ||
|
||
void | ||
glisyTextureInit(GlisyTexture *texture, GLenum target) { | ||
if (!texture) return; | ||
if (texture->handle) glisyTextureDispose(texture); | ||
memset(texture, 0, sizeof(GlisyTexture)); | ||
|
||
texture->name = ""; | ||
texture->type = GL_UNSIGNED_BYTE; | ||
texture->wrapS = GL_CLAMP_TO_EDGE; | ||
texture->wrapT = GL_CLAMP_TO_EDGE; | ||
texture->handle = 0; | ||
texture->format = GL_RGB; | ||
texture->target = target; | ||
texture->mapping = GLISY_UV_MAPPING; | ||
texture->channels = channel(texture->format); | ||
texture->minFilter = GL_LINEAR; | ||
texture->magFilter = GL_LINEAR; | ||
texture->shape[0] = 0; | ||
texture->shape[1] = 0; | ||
texture->shape[2] = channel(texture->format); | ||
texture->compressed = GL_FALSE; | ||
texture->unpackAlignment = 1; | ||
|
||
glGenTextures(1, &texture->handle); | ||
} | ||
|
||
void | ||
glisyTextureBind(GlisyTexture *texture) { | ||
if (!texture || !texture->handle || !texture->target) return; | ||
glBindTexture(texture->handle, texture->target); | ||
} | ||
|
||
void | ||
glisyTextureBindSlot(GlisyTexture *texture, GLuint slot) { | ||
if (!texture || !texture->handle || !texture->target) return; | ||
glisyTextureActive(texture, slot); | ||
glisyTextureBind(texture); | ||
} | ||
|
||
void | ||
glisyTextureUnbind(GlisyTexture *texture) { | ||
if (!texture || !texture->target) return; | ||
glBindTexture(texture->target, 0); | ||
} | ||
|
||
void | ||
glisyTextureDispose(GlisyTexture *texture) { | ||
if (!texture || !texture->handle) return; | ||
glDeleteTextures(1, &texture->handle); | ||
} | ||
|
||
void | ||
glisyTextureActive(GlisyTexture *texture, GLuint slot) { | ||
glActiveTexture(GL_TEXTURE0 + slot); | ||
} | ||
|
||
void | ||
glisyTextureGenerateMipmap(GlisyTexture *texture) { | ||
if (!texture || !texture->handle) return; | ||
glisyTextureBind(texture); | ||
glGenerateMipmap(texture->target); | ||
} | ||
|
||
void | ||
glisyTextureUpdate(GlisyTexture *texture, | ||
GLvoid **pixels, | ||
GLuint *shape, | ||
GLsizei size, | ||
GLuint *offset, | ||
GLuint level) { | ||
if (!texture) return; | ||
|
||
// bind current | ||
glisyTextureBind(texture); | ||
glPixelStorei(GL_UNPACK_ALIGNMENT, texture->unpackAlignment); | ||
|
||
if (!level) { | ||
switch (texture->target) { | ||
case GL_TEXTURE_2D: | ||
// update shape if given | ||
if (shape) { | ||
texture->shape[0] = shape[0]; | ||
texture->shape[1] = shape[1]; | ||
} | ||
|
||
// update format channel count | ||
texture->shape[2] = channel(texture->format); | ||
|
||
// set texture wrap | ||
glTexParameteri(texture->target, GL_TEXTURE_WRAP_S, texture->wrapS); | ||
glTexParameteri(texture->target, GL_TEXTURE_WRAP_T, texture->wrapT); | ||
|
||
// Set texture filtering | ||
glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, texture->minFilter); | ||
glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, texture->magFilter); | ||
break; | ||
|
||
case GL_TEXTURE_CUBE_MAP: | ||
if (shape) { | ||
texture->shape[0] = shape[0]; | ||
texture->shape[1] = shape[1]; | ||
} | ||
|
||
// set face count | ||
texture->shape[2] = 6; | ||
|
||
// update format channel count | ||
texture->shape[3] = channel(texture->format); | ||
break; | ||
} | ||
} | ||
|
||
switch (texture->target) { | ||
case GL_TEXTURE_2D: | ||
texImage2D(texture, texture->target, pixels, size, offset, level); | ||
break; | ||
|
||
case GL_TEXTURE_CUBE_MAP: | ||
for (int i = 0; i < 6; ++i) { | ||
GLuint target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + i; | ||
texImage2D(texture, target, pixels[i], size, offset, level); | ||
} | ||
break; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
#ifndef GLISY_TEXTURE_H | ||
#define GLISY_TEXTURE_H | ||
|
||
#include <glisy/gl.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
/** | ||
* Texture mapping types. | ||
*/ | ||
|
||
enum { | ||
GLISY_UV_MAPPING = 1, | ||
}; | ||
|
||
/** | ||
* GlisyTexture struct type. | ||
*/ | ||
|
||
typedef struct GlisyTexture GlisyTexture; | ||
struct GlisyTexture { | ||
GLchar *name; | ||
|
||
GLuint handle; | ||
GLuint mapping; | ||
GLuint shape[4]; | ||
GLuint channels; | ||
GLuint anisotropy; | ||
GLuint unpackAlignment; | ||
|
||
GLenum type; | ||
GLenum wrapS; | ||
GLenum wrapT; | ||
GLenum target; | ||
GLenum format; | ||
GLenum minFilter; | ||
GLenum magFilter; | ||
|
||
GLboolean compressed; | ||
}; | ||
|
||
/** | ||
* Initializes a GlisyTexture with target where target is one of: | ||
* - GL_TEXTURE_1D | ||
* - GL_TEXTURE_2D | ||
* - GL_TEXTURE_3D | ||
*/ | ||
|
||
void | ||
glisyTextureInit(GlisyTexture *texture, GLenum taret); | ||
|
||
/** | ||
* Binds a GlisyTexture with glBindTexture using the handle | ||
* created with glGenTextures and the texture set with | ||
* glisyTextureInit. | ||
*/ | ||
|
||
void | ||
glisyTextureBind(GlisyTexture *texture); | ||
|
||
/** | ||
* Binds texture at slot index. | ||
*/ | ||
|
||
|
||
void | ||
glisyTextureBindSlot(GlisyTexture *texture, GLuint slot); | ||
|
||
/** | ||
* Unbinds texture. | ||
*/ | ||
|
||
void | ||
glisyTextureUnbind(GlisyTexture *texture); | ||
|
||
/** | ||
* Disposes of a GlisyTexture and the internal handle | ||
* created by glGenTextures. This will reset the handle | ||
* value and texture. | ||
*/ | ||
|
||
void | ||
glisyTextureDispose(GlisyTexture *texture); | ||
|
||
/** | ||
* Sets texture to active texture at slot. | ||
*/ | ||
|
||
void | ||
glisyTextureActive(GlisyTexture *texture, GLuint slot); | ||
|
||
/** | ||
* Generates mipmaps based on the current shape and calls | ||
* glGenerateMipmap on the internal texture texture. | ||
*/ | ||
|
||
void | ||
glisyTextureGenerateMipmap(GlisyTexture *texture); | ||
|
||
/** | ||
* Updates a GlisyTexture with pixel data, shape (width, height), | ||
* size, offset, and level. | ||
*/ | ||
|
||
void | ||
glisyTextureUpdate(GlisyTexture *texture, | ||
GLvoid **pixels, | ||
GLuint *shape, | ||
GLsizei size, | ||
GLuint *offset, | ||
GLuint level); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters