Initial commit; version 0.1

This commit is contained in:
OLEGSHA 2021-03-26 01:37:31 +03:00
commit 1759b2257a
Signed by: OLEGSHA
GPG Key ID: E57A4B08D64AFF7A
8 changed files with 13059 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*.kdev4
build/

31
CMakeLists.txt Normal file
View File

@ -0,0 +1,31 @@
cmake_minimum_required(VERSION 3.0)
cmake_policy(SET CMP0072 NEW)
project(progressiatexturepreviewer)
add_executable(progressiatexturepreviewer
main.cpp
glad/src/gl.c
stb/src/stb_image.c
)
install(TARGETS progressiatexturepreviewer RUNTIME DESTINATION bin)
# Link with GLFW3
find_package(glfw3 3.2 REQUIRED)
target_link_libraries(progressiatexturepreviewer glfw)
# Link with OpenGL
find_package(OpenGL REQUIRED)
target_link_libraries(progressiatexturepreviewer OpenGL::GL)
# Link with GLM
find_package(glm REQUIRED)
target_link_libraries(progressiatexturepreviewer glm)
# Use GLAD
target_include_directories(progressiatexturepreviewer PRIVATE glad/include)
# Use STB Image
target_include_directories(progressiatexturepreviewer PRIVATE stb/include)

View File

@ -0,0 +1,290 @@
#ifndef __khrplatform_h_
#define __khrplatform_h_
/*
** Copyright (c) 2008-2018 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/* Khronos platform-specific types and definitions.
*
* The master copy of khrplatform.h is maintained in the Khronos EGL
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
* The last semantic modification to khrplatform.h was at commit ID:
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
*
* Adopters may modify this file to suit their platform. Adopters are
* encouraged to submit platform specific modifications to the Khronos
* group so that they can be included in future versions of this file.
* Please submit changes by filing pull requests or issues on
* the EGL Registry repository linked above.
*
*
* See the Implementer's Guidelines for information about where this file
* should be located on your system and for more details of its use:
* http://www.khronos.org/registry/implementers_guide.pdf
*
* This file should be included as
* #include <KHR/khrplatform.h>
* by Khronos client API header files that use its types and defines.
*
* The types in khrplatform.h should only be used to define API-specific types.
*
* Types defined in khrplatform.h:
* khronos_int8_t signed 8 bit
* khronos_uint8_t unsigned 8 bit
* khronos_int16_t signed 16 bit
* khronos_uint16_t unsigned 16 bit
* khronos_int32_t signed 32 bit
* khronos_uint32_t unsigned 32 bit
* khronos_int64_t signed 64 bit
* khronos_uint64_t unsigned 64 bit
* khronos_intptr_t signed same number of bits as a pointer
* khronos_uintptr_t unsigned same number of bits as a pointer
* khronos_ssize_t signed size
* khronos_usize_t unsigned size
* khronos_float_t signed 32 bit floating point
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
* nanoseconds
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
* khronos_boolean_enum_t enumerated boolean type. This should
* only be used as a base type when a client API's boolean type is
* an enum. Client APIs which use an integer or other type for
* booleans cannot use this as the base type for their boolean.
*
* Tokens defined in khrplatform.h:
*
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
*
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
*
* Calling convention macros defined in this file:
* KHRONOS_APICALL
* KHRONOS_APIENTRY
* KHRONOS_APIATTRIBUTES
*
* These may be used in function prototypes as:
*
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
* int arg1,
* int arg2) KHRONOS_APIATTRIBUTES;
*/
#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
# define KHRONOS_STATIC 1
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APICALL
*-------------------------------------------------------------------------
* This precedes the return type of the function in the function prototype.
*/
#if defined(KHRONOS_STATIC)
/* If the preprocessor constant KHRONOS_STATIC is defined, make the
* header compatible with static linking. */
# define KHRONOS_APICALL
#elif defined(_WIN32)
# define KHRONOS_APICALL __declspec(dllimport)
#elif defined (__SYMBIAN32__)
# define KHRONOS_APICALL IMPORT_C
#elif defined(__ANDROID__)
# define KHRONOS_APICALL __attribute__((visibility("default")))
#else
# define KHRONOS_APICALL
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIENTRY
*-------------------------------------------------------------------------
* This follows the return type of the function and precedes the function
* name in the function prototype.
*/
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
/* Win32 but not WinCE */
# define KHRONOS_APIENTRY __stdcall
#else
# define KHRONOS_APIENTRY
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIATTRIBUTES
*-------------------------------------------------------------------------
* This follows the closing parenthesis of the function prototype arguments.
*/
#if defined (__ARMCC_2__)
#define KHRONOS_APIATTRIBUTES __softfp
#else
#define KHRONOS_APIATTRIBUTES
#endif
/*-------------------------------------------------------------------------
* basic type definitions
*-----------------------------------------------------------------------*/
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
/*
* Using <stdint.h>
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(__VMS ) || defined(__sgi)
/*
* Using <inttypes.h>
*/
#include <inttypes.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
/*
* Win32
*/
typedef __int32 khronos_int32_t;
typedef unsigned __int32 khronos_uint32_t;
typedef __int64 khronos_int64_t;
typedef unsigned __int64 khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(__sun__) || defined(__digital__)
/*
* Sun or Digital
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#if defined(__arch64__) || defined(_LP64)
typedef long int khronos_int64_t;
typedef unsigned long int khronos_uint64_t;
#else
typedef long long int khronos_int64_t;
typedef unsigned long long int khronos_uint64_t;
#endif /* __arch64__ */
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif 0
/*
* Hypothetical platform with no float or int64 support
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#define KHRONOS_SUPPORT_INT64 0
#define KHRONOS_SUPPORT_FLOAT 0
#else
/*
* Generic fallback
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#endif
/*
* Types that are (so far) the same on all platforms
*/
typedef signed char khronos_int8_t;
typedef unsigned char khronos_uint8_t;
typedef signed short int khronos_int16_t;
typedef unsigned short int khronos_uint16_t;
/*
* Types that differ between LLP64 and LP64 architectures - in LLP64,
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
* to be the only LLP64 architecture in current use.
*/
#ifdef _WIN64
typedef signed long long int khronos_intptr_t;
typedef unsigned long long int khronos_uintptr_t;
typedef signed long long int khronos_ssize_t;
typedef unsigned long long int khronos_usize_t;
#else
typedef signed long int khronos_intptr_t;
typedef unsigned long int khronos_uintptr_t;
typedef signed long int khronos_ssize_t;
typedef unsigned long int khronos_usize_t;
#endif
#if KHRONOS_SUPPORT_FLOAT
/*
* Float type
*/
typedef float khronos_float_t;
#endif
#if KHRONOS_SUPPORT_INT64
/* Time types
*
* These types can be used to represent a time interval in nanoseconds or
* an absolute Unadjusted System Time. Unadjusted System Time is the number
* of nanoseconds since some arbitrary system event (e.g. since the last
* time the system booted). The Unadjusted System Time is an unsigned
* 64 bit value that wraps back to 0 every 584 years. Time intervals
* may be either signed or unsigned.
*/
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
typedef khronos_int64_t khronos_stime_nanoseconds_t;
#endif
/*
* Dummy value used to pad enum types to 32 bits.
*/
#ifndef KHRONOS_MAX_ENUM
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
#endif
/*
* Enumerated boolean type
*
* Values other than zero should be considered to be true. Therefore
* comparisons should not be made against KHRONOS_TRUE.
*/
typedef enum {
KHRONOS_FALSE = 0,
KHRONOS_TRUE = 1,
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
} khronos_boolean_enum_t;
#endif /* __khrplatform_h_ */

2842
glad/include/glad/gl.h Normal file

File diff suppressed because it is too large Load Diff

1345
glad/src/gl.c Normal file

File diff suppressed because it is too large Load Diff

783
main.cpp Normal file
View File

@ -0,0 +1,783 @@
#include <vector>
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <memory>
#include <glad/gl.h>
#include <GLFW/glfw3.h>
#include <glm/ext.hpp>
#define STBI_ONLY_PNG
#include <stb/stb_image.h>
constexpr const char *NAME = "Progressia Texture Previewer";
constexpr const char *VERSION = "1.0";
void load_textures(int argc, char **argv);
void create_window();
void load_opengl();
void display_window();
void main_loop();
std::string programName;
int main(int argc, char **argv) {
programName = argv[0];
load_textures(argc, argv);
create_window();
load_opengl();
display_window();
main_loop();
return 0;
}
class Texture {
private:
std::string name;
int width, height;
GLvoid *data;
GLuint gl_id;
public:
Texture(const std::string &name) :
name(name),
data(NULL),
gl_id(-1)
{}
Texture(const Texture&) = delete;
Texture& operator=(const Texture&) = delete;
void load_opengl();
void unload_opengl();
bool hasData() const {
return data != NULL;
}
bool hasID() const {
return gl_id != -1;
}
GLuint getId() const {
return gl_id;
}
void load_stb() {
int channels;
data = stbi_load(name.c_str(), &width, &height, &channels, STBI_rgb_alpha);
if (!hasData()) {
std::cerr << programName << ": Could not load image due to format or IO error: " << name << std::endl;
return;
}
std::cout << "Loaded image " << name << std::endl;
}
void unload_stb() {
if (hasData()) {
std::cout << "Freeing STB data for " << name << std::endl;
stbi_image_free(data);
data = NULL;
}
}
~Texture() {
unload_stb();
unload_opengl();
}
};
std::vector<std::unique_ptr<Texture>> LOADED_TEXTURES;
bool loadTexturesIntoOpenGLWhenLoaded = false;
void load_texture(const std::string &path) {
Texture *texture = new Texture(path);
texture->load_stb();
if (!texture->hasData()) {
delete texture;
return;
}
LOADED_TEXTURES.emplace_back(texture);
if (loadTexturesIntoOpenGLWhenLoaded) {
texture->load_opengl();
}
}
void unload_textures();
void load_textures(int argc, char **argv) {
std::vector<std::string> textures;
for (size_t i = 0; i < argc - 1; ++i) {
textures.emplace_back(argv[i + 1]);
if (textures.at(i) == "--help") {
std::cout << NAME << " version " << VERSION << std::endl;
std::cout <<
"Usage: " << programName << " [PATH... | --help | --version]\n"
" PATH adds a texture specified by PATH to the list of displayed textures\n"
" --help displays this message and exits\n"
" --version displays version information and exits"
<< std::endl;
std::exit(EXIT_SUCCESS);
}
if (textures.at(i) == "--version") {
std::cout << NAME << " version " << VERSION << std::endl;
std::exit(EXIT_SUCCESS);
}
}
std::for_each(textures.begin(), textures.end(), &load_texture);
std::cout << "Loaded " << LOADED_TEXTURES.size() << " images" << std::endl;
}
void unload_textures() {
LOADED_TEXTURES.clear();
}
GLFWwindow *window;
enum MODE {
BLOCK, PLANE
} currentMode = BLOCK;
int selection = 0;
bool light_theme = true;
int width, height;
void on_glfw_error(int errorCode, const char *description);
void glfw_shutdown_hook();
void on_key(GLFWwindow* window, int key, int scancode, int action, int mods);
void on_drop(GLFWwindow* window, int count, const char** paths);
void create_window() {
glfwSetErrorCallback(&on_glfw_error);
if (!glfwInit()) {
std::cerr << programName << ": could not initialize GLFW" << std::endl;
std::exit(EXIT_FAILURE);
}
std::atexit(&glfw_shutdown_hook);
std::cout << "GLFW initialized" << std::endl;
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
glfwWindowHint(GLFW_FOCUSED, GLFW_TRUE);
glfwWindowHint(GLFW_MAXIMIZED, GLFW_FALSE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
glfwWindowHint(GLFW_SAMPLES, 4);
window = glfwCreateWindow(800, 600, NAME, NULL, NULL);
glfwSetKeyCallback(window, &on_key);
glfwSetDropCallback(window, &on_drop);
if (window == nullptr) {
std::cerr << programName << ": could not create window" << std::endl;
std::exit(EXIT_FAILURE);
}
}
void on_glfw_error(int errorCode, const char *description) {
std::cerr << programName << ": GLFW has failed: (" << errorCode << ") " << description << std::endl;
std::exit(EXIT_FAILURE);
}
void glfw_shutdown_hook() {
glfwTerminate();
std::cout << "GLFW terminated" << std::endl;
}
void switch_mode();
void switch_theme();
void change_texture(int direction);
void close_texture();
void on_key(GLFWwindow*, int key, int, int action, int mods) {
if (action != GLFW_PRESS) return;
switch (key) {
case GLFW_KEY_SPACE:
if ((mods & GLFW_MOD_SHIFT) != 0) {
switch_theme();
} else {
switch_mode();
}
return;
case GLFW_KEY_LEFT:
change_texture(-1);
return;
case GLFW_KEY_RIGHT:
change_texture(+1);
return;
case GLFW_KEY_DELETE:
close_texture();
return;
default:
// Do nothing
break;
}
}
void on_drop(GLFWwindow*, int count, const char** paths) {
for (size_t i = 0; i < count; i++) {
load_texture(paths[i]);
}
}
void switch_mode() {
if (LOADED_TEXTURES.empty()) return;
switch (currentMode) {
case BLOCK:
currentMode = PLANE;
break;
case PLANE:
currentMode = BLOCK;
break;
}
}
void switch_theme() {
light_theme = !light_theme;
}
void change_texture(int direction) {
if (LOADED_TEXTURES.size() < 2) return;
selection += direction;
}
void close_texture() {
if (LOADED_TEXTURES.empty()) return;
LOADED_TEXTURES.erase(LOADED_TEXTURES.begin() + selection);
selection -= 1;
}
GLuint program;
GLint attrib_coords;
GLint attrib_textureCoords;
GLint attrib_color;
GLint uniform_tranform;
GLint uniform_useTexture;
void unload_opengl();
void check_opengl();
void load_shaders();
void load_model();
void load_opengl() {
glfwMakeContextCurrent(window);
gladLoadGL(glfwGetProcAddress);
glfwSwapInterval(1);
std::atexit(&unload_opengl);
load_shaders();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
check_opengl();
std::cout << "OpenGL initialized" << std::endl;
}
enum VariableType {
ATTRIBUTE, UNIFORM
};
GLint find_shader_variable(const char *name, VariableType);
enum LogType {
SHADER, PROGRAM
};
void log_shader_error(GLuint id, LogType);
void load_shaders() {
GLint compile_ok = GL_FALSE, link_ok = GL_FALSE;
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
const char *vs_source =
R"(#version 120
attribute vec3 coords;
attribute vec2 textureCoords;
attribute vec3 color;
uniform mat4 transform;
varying vec2 textureCoords_var;
varying vec3 color_var;
void main(void) {
gl_Position = transform * vec4(coords, 1.0);
color_var = color;
textureCoords_var = textureCoords;
})";
glShaderSource(vs, 1, &vs_source, NULL);
glCompileShader(vs);
glGetShaderiv(vs, GL_COMPILE_STATUS, &compile_ok);
if (!compile_ok) {
log_shader_error(vs, SHADER);
std::cerr << programName << ": Error in vertex shader" << std::endl;
std::exit(EXIT_FAILURE);
}
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
const char *fs_source =
R"(#version 120
varying vec2 textureCoords_var;
varying vec3 color_var;
uniform bool useTexture;
uniform sampler2D texture;
void main(void) {
if (useTexture) {
gl_FragColor = vec4(color_var, 1.0) * texture2D(texture, textureCoords_var);
} else {
gl_FragColor = vec4(color_var, 1.0);
}
})";
glShaderSource(fs, 1, &fs_source, NULL);
glCompileShader(fs);
glGetShaderiv(fs, GL_COMPILE_STATUS, &compile_ok);
if (!compile_ok) {
log_shader_error(fs, SHADER);
std::cerr << programName << ": Error in fragment shader" << std::endl;
std::exit(EXIT_FAILURE);
}
program = glCreateProgram();
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &link_ok);
if (!link_ok) {
log_shader_error(program, SHADER);
std::cerr << programName << ": Could not link shaders" << std::endl;
std::exit(EXIT_FAILURE);
}
attrib_coords = find_shader_variable("coords", ATTRIBUTE);
attrib_textureCoords = find_shader_variable("textureCoords", ATTRIBUTE);
attrib_color = find_shader_variable("color", ATTRIBUTE);
uniform_tranform = find_shader_variable("transform", UNIFORM);
uniform_useTexture = find_shader_variable("useTexture", UNIFORM);
glUseProgram(program);
glActiveTexture(GL_TEXTURE0);
glUniform1i(find_shader_variable("texture", UNIFORM), 0);
for (auto &texture : LOADED_TEXTURES) {
texture->load_opengl();
}
loadTexturesIntoOpenGLWhenLoaded = true;
check_opengl();
}
GLint find_shader_variable(const char *name, VariableType type) {
GLint result = (type == ATTRIBUTE ? glGetAttribLocation : glGetUniformLocation)(program, name);
if (result < 0) {
std::cerr << programName << ": Could not find " << (type == ATTRIBUTE ? "attribute " : "uniform ") << name << std::endl;
std::exit(EXIT_FAILURE);
}
return result;
}
void log_shader_error(GLuint id, LogType type) {
GLsizei logLength;
(type == SHADER ? glGetShaderiv : glGetProgramiv)(id, GL_INFO_LOG_LENGTH, &logLength);
GLchar *log = new GLchar[logLength];
(type == SHADER ? glGetShaderInfoLog : glGetProgramInfoLog)(id, logLength, NULL, log);
std::cerr << programName << ": OpenGL:\n" << log << std::endl;
delete[] log;
std::exit(EXIT_FAILURE);
}
void unload_opengl() {
if (glIsProgram(program)) glDeleteProgram(program);
std::cout << "OpenGL terminated" << std::endl;
}
void check_opengl() {
GLenum error = glGetError();
if (error != GL_NO_ERROR) {
std::cerr << programName << ": OpenGL error " << std::hex << error << std::endl;
std::exit(EXIT_FAILURE);
}
}
void Texture::load_opengl() {
if (hasData() && !hasID()) {
glGenTextures(1, &gl_id);
glBindTexture(GL_TEXTURE_2D, gl_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGBA,
width,
height,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
data
);
check_opengl();
std::cout << "Loaded into OpenGL " << name << std::endl;
unload_stb();
}
}
void Texture::unload_opengl() {
if (hasID()) {
glDeleteTextures(1, &gl_id);
gl_id = -1;
std::cout << "Unloaded from OpenGL " << name << std::endl;
}
}
void display_window() {
glfwShowWindow(window);
}
void draw_background();
void draw_object();
void draw_block();
void draw_plane();
void bind_coords(const GLfloat*);
void bind_color(const GLfloat*);
void bind_texture_coords(const GLfloat*);
void set_texture(const Texture&);
void set_use_texture(bool);
void set_transform(const glm::mat4&);
void main_loop() {
while (!glfwWindowShouldClose(window)) {
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
glEnableVertexAttribArray(attrib_coords);
glEnableVertexAttribArray(attrib_color);
glEnableVertexAttribArray(attrib_textureCoords);
draw_background();
draw_object();
glDisableVertexAttribArray(attrib_textureCoords);
glDisableVertexAttribArray(attrib_color);
glDisableVertexAttribArray(attrib_coords);
check_opengl();
glfwSwapBuffers(window);
glfwPollEvents();
}
}
namespace background {
constexpr const GLfloat COORDS[] = {
-1.0, -1.0, 0.0,
-1.0, +1.0, 0.0,
+1.0, +1.0, 0.0,
+1.0, -1.0, 0.0,
};
constexpr const GLfloat COLORS_LIGHT[] = {
+0.80, +0.80, +0.85,
+0.95, +0.95, +1.00,
+0.95, +0.95, +1.00,
+0.80, +0.80, +0.85,
};
constexpr const GLfloat COLORS_DARK[] = {
+0.1, +0.1, +0.15,
+0.2, +0.2, +0.25,
+0.2, +0.2, +0.25,
+0.1, +0.1, +0.15,
};
}
namespace block {
constexpr const GLfloat COORDS[] = {
// front
-1.0, -1.0, 1.0,
1.0, -1.0, 1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,
// top
-1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0, -1.0,
-1.0, 1.0, -1.0,
// back
1.0, -1.0, -1.0,
-1.0, -1.0, -1.0,
-1.0, 1.0, -1.0,
1.0, 1.0, -1.0,
// bottom
-1.0, -1.0, -1.0,
1.0, -1.0, -1.0,
1.0, -1.0, 1.0,
-1.0, -1.0, 1.0,
// left
-1.0, -1.0, -1.0,
-1.0, -1.0, 1.0,
-1.0, 1.0, 1.0,
-1.0, 1.0, -1.0,
// right
1.0, -1.0, 1.0,
1.0, -1.0, -1.0,
1.0, 1.0, -1.0,
1.0, 1.0, 1.0,
};
constexpr const GLfloat COLORS[] = {
// front
0.9, 0.9, 0.9,
0.9, 0.9, 0.9,
0.9, 0.9, 0.9,
0.9, 0.9, 0.9,
// top
1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
// back
0.6, 0.6, 0.6,
0.6, 0.6, 0.6,
0.6, 0.6, 0.6,
0.6, 0.6, 0.6,
// bottom
0.4, 0.4, 0.4,
0.4, 0.4, 0.4,
0.4, 0.4, 0.4,
0.4, 0.4, 0.4,
// left
0.8, 0.8, 0.8,
0.8, 0.8, 0.8,
0.8, 0.8, 0.8,
0.8, 0.8, 0.8,
// right
0.7, 0.7, 0.7,
0.7, 0.7, 0.7,
0.7, 0.7, 0.7,
0.7, 0.7, 0.7,
};
constexpr const GLfloat TEX_COORDS[] = {
// front
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
// top
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
// back
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
// bottom
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
// left
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
// right
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
};
}
namespace plane {
constexpr const GLfloat COORDS[] = {
-1.0, -1.0, 0.0,
-1.0, +1.0, 0.0,
+1.0, +1.0, 0.0,
+1.0, -1.0, 0.0,
};
constexpr const GLfloat COLORS[] = {
+1.0, +1.0, +1.0,
+1.0, +1.0, +1.0,
+1.0, +1.0, +1.0,
+1.0, +1.0, +1.0,
};
constexpr const GLfloat TEX_COORDS[] = {
-3.0, -3.0,
-3.0, +3.0,
+3.0, +3.0,
+3.0, -3.0,
};
}
void draw_background() {
bind_coords(background::COORDS);
bind_color(light_theme ? background::COLORS_LIGHT : background::COLORS_DARK);
set_transform(glm::identity<glm::mat4>());
set_use_texture(false);
glDrawArrays(GL_QUADS, 0, 4);
}
void draw_object() {
if (LOADED_TEXTURES.empty()) {
// Do nothing
return;
}
if (selection < 0) selection = LOADED_TEXTURES.size() - 1;
if (selection >= LOADED_TEXTURES.size()) selection = 0;
set_texture(*(LOADED_TEXTURES[selection]));
switch (currentMode) {
case BLOCK:
draw_block();
return;
case PLANE:
draw_plane();
return;
}
}
void draw_block() {
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glClear(GL_DEPTH_BUFFER_BIT);
bind_coords(block::COORDS);
bind_color(block::COLORS);
bind_texture_coords(block::TEX_COORDS);
GLfloat aspectRatio = static_cast<GLfloat>(width) / height;
glm::mat4 transform = glm::identity<glm::mat4>();
transform = glm::scale(transform, glm::vec3(
std::min(1.0f, 1.0f / aspectRatio),
std::min(1.0f, aspectRatio),
1.0f
));
float t = static_cast<float>(glfwGetTime()) / 20;
transform = glm::rotate(transform, t * 3, glm::vec3(1, 0, 0));
transform = glm::rotate(transform, t * 7, glm::vec3(0, 1, 0));
transform = glm::rotate(transform, t * 11, glm::vec3(0, 0, 1));
transform = glm::scale(transform, glm::vec3(0.5));
set_transform(transform);
set_use_texture(true);
glDrawArrays(GL_QUADS, 0, 4*6);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
}
void draw_plane() {
bind_coords(plane::COORDS);
bind_color(plane::COLORS);
bind_texture_coords(plane::TEX_COORDS);
GLfloat aspectRatio = static_cast<GLfloat>(width) / height;
set_transform(glm::scale(glm::identity<glm::mat4>(), glm::vec3(
std::max(1.0f, 1.0f / aspectRatio),
std::max(1.0f, aspectRatio),
1.0f
)));
set_use_texture(true);
glDrawArrays(GL_QUADS, 0, 4);
}
void bind_coords(const GLfloat *data) {
glVertexAttribPointer(
attrib_coords, 3, GL_FLOAT, GL_FALSE, 0,
data
);
}
void bind_color(const GLfloat *data) {
glVertexAttribPointer(
attrib_color, 3, GL_FLOAT, GL_FALSE, 0,
data
);
}
void bind_texture_coords(const GLfloat *data) {
glVertexAttribPointer(
attrib_textureCoords, 2, GL_FLOAT, GL_FALSE, 0,
data
);
}
void set_texture(const Texture &texture) {
glBindTexture(GL_TEXTURE_2D, texture.getId());
}
void set_use_texture(bool use) {
glUniform1i(uniform_useTexture, use ? 1 : 0);
}
void set_transform(const glm::mat4 &m) {
glUniformMatrix4fv(uniform_tranform, 1, false, glm::value_ptr(m));
}

7762
stb/include/stb/stb_image.h Normal file

File diff suppressed because it is too large Load Diff

4
stb/src/stb_image.c Normal file
View File

@ -0,0 +1,4 @@
#define STBI_ONLY_PNG
#define STB_IMAGE_IMPLEMENTATION
#include <stb/stb_image.h>