diff --git a/CMakeLists.txt b/CMakeLists.txt index b4f5317..8a908df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,9 @@ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${CMAKE_BUILD_TYPE_VALUES}) cmake_minimum_required(VERSION 3.0) -project(glez LANGUAGES C VERSION 0.0.1) +project(glez VERSION 0.0.1) + +set(CMAKE_CXX_STANDARD 11) set(export_dest "lib/${PROJECT_NAME}-${PROJECT_VERSION}") set(include_dest "include/${PROJECT_NAME}-${PROJECT_VERSION}") diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index c8f6547..0b989b3 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -1,4 +1,5 @@ target_sources(glez PRIVATE "${CMAKE_CURRENT_LIST_DIR}/glez.h") -add_subdirectory(internal) \ No newline at end of file +add_subdirectory(internal) +add_subdirectory(glez) \ No newline at end of file diff --git a/include/glez/CMakeLists.txt b/include/glez/CMakeLists.txt new file mode 100644 index 0000000..f07f4c2 --- /dev/null +++ b/include/glez/CMakeLists.txt @@ -0,0 +1,5 @@ +target_sources(glez PRIVATE + "${CMAKE_CURRENT_LIST_DIR}/glez.hpp" + "${CMAKE_CURRENT_LIST_DIR}/types.hpp") + +add_subdirectory(detail) \ No newline at end of file diff --git a/include/glez/detail/CMakeLists.txt b/include/glez/detail/CMakeLists.txt new file mode 100644 index 0000000..acc2367 --- /dev/null +++ b/include/glez/detail/CMakeLists.txt @@ -0,0 +1,5 @@ +target_sources(glez PRIVATE + "${CMAKE_CURRENT_LIST_DIR}/font.hpp" + "${CMAKE_CURRENT_LIST_DIR}/texture.hpp" + "${CMAKE_CURRENT_LIST_DIR}/render.hpp" + "${CMAKE_CURRENT_LIST_DIR}/program.hpp") \ No newline at end of file diff --git a/include/glez/detail/font.hpp b/include/glez/detail/font.hpp new file mode 100644 index 0000000..a8b4f3e --- /dev/null +++ b/include/glez/detail/font.hpp @@ -0,0 +1,28 @@ +/* + Created by Jenny White on 30.04.18. + Copyright (c) 2018 nullworks. All rights reserved. +*/ + +#pragma once + +#include +#include +#include + +namespace glez::detail::font +{ + +struct font +{ + bool init{ false }; + + texture_font_t *font{ nullptr }; + texture_atlas_t *atlas{ nullptr }; +}; + +void init(); +void shutdown(); + +font *get(glez::types::handle_type handle); + +} \ No newline at end of file diff --git a/include/glez/detail/program.hpp b/include/glez/detail/program.hpp new file mode 100644 index 0000000..7af16c6 --- /dev/null +++ b/include/glez/detail/program.hpp @@ -0,0 +1,28 @@ +/* + Created by Jenny White on 30.04.18. + Copyright (c) 2018 nullworks. All rights reserved. +*/ + +#pragma once + +namespace glez::detail::program +{ + +enum class mode +{ + PLAIN = 1, + TEXTURED, + FREETYPE +}; + +void init(int width, int height); +void shutdown(); + +void resize(int width, int height); + +void draw(); +void reset(); + +unsigned next_index(); + +}; \ No newline at end of file diff --git a/include/glez/detail/render.hpp b/include/glez/detail/render.hpp new file mode 100644 index 0000000..366b338 --- /dev/null +++ b/include/glez/detail/render.hpp @@ -0,0 +1,27 @@ +/* + Created by Jenny White on 30.04.18. + Copyright (c) 2018 nullworks. All rights reserved. +*/ + +#pragma once + +#include +#include "glez/types.hpp" + +namespace glez::detail::render +{ + +struct vertex +{ + ftgl::vec2 position; + ftgl::vec2 uv; + types::rgba color; + int mode; +}; + +void begin(); +void end(); + +void bind(GLuint texture); + +} \ No newline at end of file diff --git a/include/glez/detail/texture.hpp b/include/glez/detail/texture.hpp new file mode 100644 index 0000000..d423825 --- /dev/null +++ b/include/glez/detail/texture.hpp @@ -0,0 +1,38 @@ +/* + Created by Jenny White on 30.04.18. + Copyright (c) 2018 nullworks. All rights reserved. +*/ + +#pragma once + +#include +#include +#include +#include + +namespace glez::detail::texture +{ + +struct texture +{ + void bind(); + bool load(const std::string& type); + + bool init{ false }; + bool bound{ false }; + + GLuint id; + GLubyte *data; + + int width{ 0 }; + int height{ 0 }; + + char filename[256]; +}; + +void init(); +void shutdown(); + +texture& get(glez::types::handle_type handle); + +} \ No newline at end of file diff --git a/include/glez/glez.hpp b/include/glez/glez.hpp new file mode 100644 index 0000000..8e5a5c2 --- /dev/null +++ b/include/glez/glez.hpp @@ -0,0 +1,36 @@ +/* + Created by Jenny White on 30.04.18. + Copyright (c) 2018 nullworks. All rights reserved. +*/ + +#pragma once + +#include + +namespace glez +{ + +constexpr unsigned max_textures = 32; +constexpr unsigned max_fonts = 32; + +void init(int width, int height); +void shutdown(); + +void resize(int width, int height); + +void begin(); +void end(); + +namespace draw +{ + +void line(int x, int y, int dx, int dy, int color, int thickness); +void rect(int x, int y, int w, int h, int color); +void rect_outline(int x, int y, int w, int h, int color, int thickness); +void circle(int x, int y, int radius, int color, int thickness, int steps); + +void string(int x, int y, const std::string& string, int color, int *width, int *height); +void outlined_string(int x, int y, const std::string& string, int color, int *width, int *height); + +} +}; \ No newline at end of file diff --git a/include/glez/types.hpp b/include/glez/types.hpp new file mode 100644 index 0000000..b6f201b --- /dev/null +++ b/include/glez/types.hpp @@ -0,0 +1,31 @@ +/* + Created by Jenny White on 30.04.18. + Copyright (c) 2018 nullworks. All rights reserved. +*/ + +#pragma once + +#include + +namespace glez::types +{ + +struct rgba +{ + union + { + struct + { + float r; + float g; + float b; + float a; + }; + float data[4]; + }; +}; + +using handle_type = unsigned; +constexpr handle_type undefined = std::numeric_limits::max(); + +} \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bc1b40e..8be8c87 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,4 +3,9 @@ target_sources(glez PRIVATE "${CMAKE_CURRENT_LIST_DIR}/fonts.c" "${CMAKE_CURRENT_LIST_DIR}/glez.c" "${CMAKE_CURRENT_LIST_DIR}/program.c" - "${CMAKE_CURRENT_LIST_DIR}/textures.c") \ No newline at end of file + "${CMAKE_CURRENT_LIST_DIR}/textures.c" + + "${CMAKE_CURRENT_LIST_DIR}/glez.cpp" + "${CMAKE_CURRENT_LIST_DIR}/texture.cpp" + "${CMAKE_CURRENT_LIST_DIR}/render.cpp" + "${CMAKE_CURRENT_LIST_DIR}/program.cpp") \ No newline at end of file diff --git a/src/glez.cpp b/src/glez.cpp new file mode 100644 index 0000000..17f725d --- /dev/null +++ b/src/glez.cpp @@ -0,0 +1,43 @@ +/* + Created by Jenny White on 30.04.18. + Copyright (c) 2018 nullworks. All rights reserved. +*/ + +#include +#include +#include +#include + +namespace glez +{ + +void init(int width, int height) +{ + detail::font::init(); + detail::program::init(width, height); + detail::texture::init(); +} + +void shutdown() +{ + detail::font::shutdown(); + detail::program::shutdown(); + detail::texture::shutdown(); +} + +void resize(int width, int height) +{ + detail::program::resize(width, height); +} + +void begin() +{ + detail::render::begin(); +} + +void end() +{ + detail::render::end(); +} + +} \ No newline at end of file diff --git a/src/program.cpp b/src/program.cpp new file mode 100644 index 0000000..0ef3bfe --- /dev/null +++ b/src/program.cpp @@ -0,0 +1,166 @@ +/* + Created by Jenny White on 30.04.18. + Copyright (c) 2018 nullworks. All rights reserved. +*/ + +#include +#include +#include +#include +#include +#include +#include + +static const char *shader_vertex = R"END( +#version 130 + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +in vec2 vertex; +in vec2 tex_coord; +in vec4 color; +in int drawmode; + +flat out int frag_DrawMode; + +out vec4 frag_Color; +out vec4 frag_TexCoord; + +void main() +{ + frag_TexCoord = tex_coord; + frag_Color = color; + frag_DrawMode = drawmode; + gl_Position = projection * (view * (model * vec4(vertex, 0.0, 1.0))); +} +)END"; + +static const char *shader_fragment = R"END( +#version 130 + +uniform sampler2D texture; +in vec4 frag_Color; +in vec2 frag_TexCoord; +flat in int frag_DrawMode; + +void main() +{ + if (frag_DrawMode == 1) + gl_FragColor = frag_Color; + else + { + vec4 tex = texture2D(texture, frag_TexCoord); + if (frag_DrawMode == 2) + gl_FragColor = frag_Color * tex; + else if (frag_DrawMode == 3) + { + gl_FragColor = vec4(frag_Color.rgb, frag_Color.a * tex.r); + } + else + gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); + } +} +)END"; + +static vertex_buffer_t *buffer{ nullptr }; +static GLuint shader{ 0 }; + +GLuint compile(const char *source, GLenum type) +{ + GLint status; + GLuint result = glCreateShader(type); + + glShaderSource(shader, 1, &source, 0); + glCompileShader(shader); + glGetShaderiv(shader, GL_COMPILE_STATUS, &status); + + if (status != GL_TRUE) + { + char error[512]; + GLsizei length; + glGetShaderInfoLog(shader, 512, &length, error); + fprintf(stderr, "GLEZ: Shader compile error: %s\n", error); + throw std::runtime_error("Shader compile error"); + } + + return result; +} + +GLuint link(GLuint vertex, GLuint fragment) +{ + GLuint result = glCreateProgram(); + GLint status; + + glAttachShader(result, vertex); + glAttachShader(result, fragment); + + glDeleteShader(vertex); + glDeleteShader(fragment); + + glLinkProgram(result); + glGetProgramiv(result, GL_LINK_STATUS, &status); + + assert(status == GL_TRUE); + + return result; +} + +namespace glez::detail::program +{ + +void init(int width, int height) +{ + buffer = ftgl::vertex_buffer_new("vertex:2f,tex_coord:2f,color:4f,drawmode:1i"); + shader = link(compile(shader_vertex, GL_VERTEX_SHADER), compile(shader_fragment, GL_FRAGMENT_SHADER)); + + + ftgl::mat4 model, view; + + mat4_set_identity(&model); + mat4_set_identity(&view); + + resize(width, height); + glUseProgram(shader); + + glUniformMatrix4fv(glGetUniformLocation(shader, "model"), 1, 0, model.data); + glUniformMatrix4fv(glGetUniformLocation(shader, "view"), 1, 0, view.data); + glUniform1i(glGetUniformLocation(shader, "texture"), 0); + glUseProgram(0); +} + +void shutdown() +{ + ftgl::vertex_buffer_delete(buffer); + glDeleteProgram(shader); +} + +void resize(int width, int height) +{ + glUseProgram(shader); + ftgl::mat4 projection; + ftgl::mat4_set_identity(&projection); + ftgl::mat4_set_orthographic(&projection, 0, width, height, 0, -1, 1); + glUniformMatrix4fv(glGetUniformLocation(shader, "projection"), 1, 0, projection.data); + glUseProgram(0); +} + +void draw() +{ + glUseProgram(shader); + vertex_buffer_render(buffer, GL_TRIANGLES); + glUseProgram(0); +} + +void reset() +{ + ftgl::vertex_buffer_clear(buffer); +} + +unsigned next_index() +{ + return buffer->vertices->size; +} + +} \ No newline at end of file diff --git a/src/render.cpp b/src/render.cpp new file mode 100644 index 0000000..4dfb8bd --- /dev/null +++ b/src/render.cpp @@ -0,0 +1,60 @@ +/* + Created by Jenny White on 30.04.18. + Copyright (c) 2018 nullworks. All rights reserved. +*/ + +#include +#include +#include + +static struct +{ + GLuint texture{ 0 }; + glez::detail::font::font::handle_type font{ glez::detail::font::font::undefined }; +} state; + +namespace glez::detail::render +{ + +void begin() +{ + glPushAttrib(GL_CURRENT_BIT | GL_ENABLE_BIT | GL_TEXTURE_BIT | + GL_COLOR_BUFFER_BIT); + + glEnable(GL_BLEND); + glEnable(GL_TEXTURE_2D); + glDisable(GL_ALPHA_TEST); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + glDisable(GL_STENCIL_TEST); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS); + + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_EDGE_FLAG_ARRAY); + glDisableClientState(GL_FOG_COORD_ARRAY); + glDisableClientState(GL_SECONDARY_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_INDEX_ARRAY); + + state.texture = 0; + state.font = +} + +void end() +{ + glPopClientAttrib(); + glPopAttrib(); +} + +void bind(GLuint texture) +{ + +} + +} \ No newline at end of file diff --git a/src/texture.cpp b/src/texture.cpp new file mode 100644 index 0000000..b9c57ac --- /dev/null +++ b/src/texture.cpp @@ -0,0 +1,55 @@ +/* + Created by Jenny White on 30.04.18. + Copyright (c) 2018 nullworks. All rights reserved. +*/ + +#include +#include +#include +#include + +static glez::detail::texture::texture cache[glez::max_textures] {}; + +namespace glez::detail::texture +{ + +void init() +{ +} + +void shutdown() +{ +} + +void texture::bind() +{ + if (not bound) + { + glGenTextures(1, &id); + glBindTexture(GL_TEXTURE_2D, &id); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, + 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } + + render::bind(id); +} + +bool texture::load(const std::string &type) +{ + +} + +texture& get(glez::types::handle_type handle) +{ + assert(handle < glez::max_textures); + assert(cache[handle].init); + + return cache[handle]; +} + +} \ No newline at end of file diff --git a/src/textures.c b/src/textures.c index 8df8332..caca967 100644 --- a/src/textures.c +++ b/src/textures.c @@ -110,15 +110,15 @@ int internal_texture_load_png_rgba(const char *name, internal_texture_t *out) return 0; } -internal_texture_t *internal_texture_get(glez_texture_t handle) +/*internal_texture_t *internal_texture_get(glez_texture_t handle) { assert(handle < GLEZ_TEXTURE_COUNT); assert(loaded_textures[handle].init); return &loaded_textures[handle]; -} +}*/ -void internal_texture_bind(glez_texture_t handle) +/*void internal_texture_bind(glez_texture_t handle) { internal_texture_t *texture = internal_texture_get(handle); @@ -137,7 +137,7 @@ void internal_texture_bind(glez_texture_t handle) } ds_bind_texture(texture->texture_id); -} +}*/ glez_texture_t glez_texture_load_png_rgba(const char *path) {