From 1f47b685f35455afcc7441389cdc60018f66d159 Mon Sep 17 00:00:00 2001 From: sanine Date: Mon, 22 Aug 2022 15:55:44 -0500 Subject: add textures --- demo/container.jpg | Bin 0 -> 184939 bytes demo/honey.lua | 80 +++++++++++++++++++++++++++++++++---------- src/gl/CMakeLists.txt | 1 + src/gl/gl.c | 2 ++ src/gl/gl.h | 1 + src/gl/shader.c | 11 ++++++ src/gl/texture.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.c | 2 ++ 8 files changed, 172 insertions(+), 18 deletions(-) create mode 100644 demo/container.jpg create mode 100644 src/gl/texture.c diff --git a/demo/container.jpg b/demo/container.jpg new file mode 100644 index 0000000..d07bee4 Binary files /dev/null and b/demo/container.jpg differ diff --git a/demo/honey.lua b/demo/honey.lua index 7f02006..6d2cdfc 100644 --- a/demo/honey.lua +++ b/demo/honey.lua @@ -24,28 +24,35 @@ end) local vertexShaderSource = [[ + #version 330 core layout (location = 0) in vec3 aPos; layout (location = 1) in vec3 aColor; +layout (location = 2) in vec2 aTexCoord; -out vec3 pColor; +out vec3 ourColor; +out vec2 TexCoord; void main() { - pColor = aColor; - gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); + gl_Position = vec4(aPos, 1.0); + ourColor = aColor; + TexCoord = aTexCoord; } ]] local fragmentShaderSource = [[ #version 330 core -in vec3 pColor; -uniform vec4 color; out vec4 FragColor; + +in vec3 ourColor; +in vec2 TexCoord; + +uniform sampler2D ourTexture; void main() { - FragColor = vec4(pColor.rgb, 1); + FragColor = texture(ourTexture, TexCoord); } ]] @@ -64,12 +71,35 @@ gl.shader.delete(vertexShader) gl.shader.delete(fragmentShader) +---------------------------------------------------------------- + +local texture = gl.texture.create() +gl.texture.bind(gl.texture.bindTarget.texture2d, texture) +err = gl.getError() +if err ~= gl.errorType.noError then error(gl.errorName(err)) end + + +local image, width, height, channels = honey.image.load('container.jpg', 0) +gl.texture.bufferImage2d( + gl.texture.bindTarget.texture2d, 0, + gl.texture.format.rgb, + width, height, + gl.texture.format.rgb, gl.dataType.uchar, + image +) +gl.texture.generateMipmaps(gl.texture.bindTarget.texture2d) +err = gl.getError() +if err ~= gl.errorType.noError then error(gl.errorName(err)) end + +honey.image.destroy(image) + + local vertices = { - -- position color - 0.5, 0.5, 0.0, 0, 0, 0, - 0.5, -0.5, 0.0, 1, 0, 0, - -0.5, -0.5, 0.0, 0, 1, 0, - -0.5, 0.5, 0.0, 0, 0, 1 + -- position color uvs + 0.5, 0.5, 0.0, 0, 0, 0, 1, 1, + 0.5, -0.5, 0.0, 1, 0, 0, 1, 0, + -0.5, -0.5, 0.0, 0, 1, 0, 0, 0, + -0.5, 0.5, 0.0, 0, 0, 1, 0, 1 } local indices = { 0, 1, 3, @@ -91,24 +121,38 @@ if gl.getError() ~= gl.errorType.noError then error(gl.getError()) end gl.data.bindBuffer(gl.data.bufferTarget.elementArrayBuffer, elementBuffer) gl.data.bufferData(gl.data.bufferTarget.elementArrayBuffer, gl.dataType.uint, indices, gl.data.bufferUsage.staticDraw) -gl.data.vertexAttribPointer(0, 3, false, 6, 0) +gl.data.vertexAttribPointer(0, 3, false, 8, 0) gl.data.vertexArrayEnableAttrib(0) -gl.data.vertexAttribPointer(1, 3, false, 6, 3) +gl.data.vertexAttribPointer(1, 3, false, 8, 3) gl.data.vertexArrayEnableAttrib(1) +gl.data.vertexAttribPointer(2, 2, false, 8, 6) +gl.data.vertexArrayEnableAttrib(2) gl.data.bindBuffer(gl.data.bufferTarget.arrayBuffer, 0) if gl.getError() ~= gl.errorType.noError then error(gl.getError()) end +gl.shader.use(shader) +local textureLocation = gl.shader.getUniformLocation(shader, "ourTexture") +err = gl.getError() +if err ~= gl.errorType.noError then error(gl.errorName(err)) end +gl.shader.uniform1i(textureLocation, 0) +err = gl.getError() +if err ~= gl.errorType.noError then error(gl.errorName(err)) end + + while not window.shouldClose(w) do gl.draw.setClearColor(0.2, 0.3, 0.3, 1.0) gl.draw.clear(gl.draw.bufferMask.colorBuffer); - gl.shader.use(shader) - local time = window.getTime() - local greenValue = (math.sin(time) / 2) + 0.5 - local colorLocation = gl.shader.getUniformLocation(shader, 'color') - gl.shader.uniform4f(colorLocation, 0, greenValue, 0, 1) + gl.texture.setActiveUnit(0) + err = gl.getError() + if err ~= gl.errorType.noError then error(gl.errorName(err)) end + gl.texture.bind(gl.texture.bindTarget.texture2d, texture) + err = gl.getError() + if err ~= gl.errorType.noError then error(gl.errorName(err)) end + + gl.shader.use(shader) gl.data.bindVertexArray(vertexArray) gl.draw.drawElements(gl.draw.primitiveType.triangles, 6, gl.dataType.uint, 0) diff --git a/src/gl/CMakeLists.txt b/src/gl/CMakeLists.txt index f995ef5..d4bc770 100644 --- a/src/gl/CMakeLists.txt +++ b/src/gl/CMakeLists.txt @@ -7,6 +7,7 @@ target_sources(honey PUBLIC ${GL}/drawing.c ${GL}/shader.c ${GL}/window.c + ${GL}/texture.c ${GL}/gl.c ${GL}/glad/glad.c ) diff --git a/src/gl/gl.c b/src/gl/gl.c index 8f56d33..c4502dc 100644 --- a/src/gl/gl.c +++ b/src/gl/gl.c @@ -21,6 +21,7 @@ int gl_get_error(lua_State *L); void setup_gl(lua_State *L, int honey_index) { int data_types = hs_create_table(L, + hs_str_int("uchar", GL_UNSIGNED_BYTE), hs_str_int("uint", GL_UNSIGNED_INT), hs_str_int("int", GL_INT), hs_str_int("float", GL_FLOAT), @@ -48,6 +49,7 @@ void setup_gl(lua_State *L, int honey_index) setup_shader(L, gl_index); setup_drawing(L, gl_index); setup_data(L, gl_index); + setup_texture(L, gl_index); lua_setfield(L, honey_index, "gl"); } diff --git a/src/gl/gl.h b/src/gl/gl.h index 766fe63..8aa1ef7 100644 --- a/src/gl/gl.h +++ b/src/gl/gl.h @@ -7,6 +7,7 @@ void setup_gl(lua_State *L, int honey_index); void setup_shader(lua_State *L, int gl_index); void setup_drawing(lua_State *L, int gl_index); void setup_data(lua_State *L, int gl_index); +void setup_texture(lua_State *L, int gl_index); void setup_window(lua_State *L, int honey_index); diff --git a/src/gl/shader.c b/src/gl/shader.c index fb64bc0..c3b409c 100644 --- a/src/gl/shader.c +++ b/src/gl/shader.c @@ -14,6 +14,7 @@ int gl_program_link(lua_State *L); int gl_program_use(lua_State *L); int gl_uniform_get_location(lua_State *L); +int gl_uniform_1i(lua_State *L); int gl_uniform_4f(lua_State *L); @@ -36,6 +37,7 @@ void setup_shader(lua_State *L, int gl_index) hs_str_cfunc("use", gl_program_use), hs_str_cfunc("getUniformLocation", gl_uniform_get_location), + hs_str_cfunc("uniform1i", gl_uniform_1i), hs_str_cfunc("uniform4f", gl_uniform_4f), hs_str_tbl("type", shader_types), @@ -141,6 +143,15 @@ int gl_uniform_get_location(lua_State *L) } +int gl_uniform_1i(lua_State *L) +{ + lua_Integer location, v0; + hs_parse_args(L, hs_int(location), hs_int(v0)); + glUniform1i(location, v0); + return 0; +} + + int gl_uniform_4f(lua_State *L) { lua_Integer location; diff --git a/src/gl/texture.c b/src/gl/texture.c new file mode 100644 index 0000000..d0c3a0a --- /dev/null +++ b/src/gl/texture.c @@ -0,0 +1,93 @@ +#include "gl/glad/glad.h" +#include +#include +#include + + +int gl_texture_create(lua_State *L); +int gl_texture_bind(lua_State *L); +int gl_texture_image_2d(lua_State *L); +int gl_texture_generate_mipmaps(lua_State *L); +int gl_texture_set_active(lua_State *L); + + +void setup_texture(lua_State *L, int gl_index) +{ + int bind_targets = hs_create_table(L, + hs_str_int("texture2d", GL_TEXTURE_2D), + ); + + int formats = hs_create_table(L, + hs_str_int("rgb", GL_RGB), + hs_str_int("rgba", GL_RGBA), + ); + + hs_create_table(L, + hs_str_cfunc("create", gl_texture_create), + hs_str_cfunc("bind", gl_texture_bind), + hs_str_cfunc("bufferImage2d", gl_texture_image_2d), + hs_str_cfunc("generateMipmaps", gl_texture_generate_mipmaps), + hs_str_cfunc("setActiveUnit", gl_texture_set_active), + + hs_str_tbl("bindTarget", bind_targets), + hs_str_tbl("format", formats), + ); + + lua_setfield(L, gl_index, "texture"); +} + + +int gl_texture_create(lua_State *L) +{ + unsigned int texture; + glGenTextures(1, &texture); + lua_pushinteger(L, texture); + return 1; +} + + +int gl_texture_bind(lua_State *L) +{ + lua_Integer target, texture; + hs_parse_args(L, hs_int(target), hs_int(texture)); + glBindTexture(target, texture); + return 0; +} + + +int gl_texture_image_2d(lua_State *L) +{ + lua_Integer target, mipmap_level, + internal_format, + width, height, + format, type; + void *data; + hs_parse_args(L, + hs_int(target), hs_int(mipmap_level), + hs_int(internal_format), + hs_int(width), hs_int(height), + hs_int(format), hs_int(type), + hs_light(data) + ); + + glTexImage2D(target, mipmap_level, internal_format, width, height, 0, format, type, data); + return 0; +} + + +int gl_texture_generate_mipmaps(lua_State *L) +{ + lua_Integer target; + hs_parse_args(L, hs_int(target)); + glGenerateMipmap(target); + return 0; +} + + +int gl_texture_set_active(lua_State *L) +{ + lua_Integer unit; + hs_parse_args(L, hs_int(unit)); + glActiveTexture(GL_TEXTURE0 + unit); + return 0; +} diff --git a/src/main.c b/src/main.c index c989dbd..66b1f11 100644 --- a/src/main.c +++ b/src/main.c @@ -3,6 +3,7 @@ #include #include #include "gl/gl.h" +#include "image/image.h" int main(int argc, char **argv) @@ -14,6 +15,7 @@ int main(int argc, char **argv) int honey_index = lua_gettop(L); setup_gl(L, honey_index); setup_window(L, honey_index); + setup_image(L, honey_index); lua_setglobal(L, "honey"); int err = luaL_loadfile(L, "honey.lua"); -- cgit v1.2.1