mirror of
https://git.shylie.info/shylie/glerminal.git
synced 2025-10-26 14:50:09 +00:00
Compare commits
12 Commits
20fad92e4f
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| fb3eeb6ec9 | |||
| 263cf68ca2 | |||
| b8e616c8d6 | |||
| 1bfbab7a96 | |||
| d156005441 | |||
| 82389b8c12 | |||
| 0a9d211942 | |||
| 937693ce6a | |||
| 365cad551b | |||
| 5fbeb1e4e9 | |||
| 11ffc40bbb | |||
| db46885ee9 |
@@ -5,7 +5,7 @@ on: push
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-app:
|
build-app:
|
||||||
runs-on: linux_amd64
|
runs-on: shy-server
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout current
|
- name: Checkout current
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -20,7 +20,7 @@ jobs:
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
lfs: true
|
lfs: true
|
||||||
- run: cd prev && git checkout 7c0c02b9af
|
- run: cd prev && git checkout 263cf68ca2
|
||||||
- name: Build current
|
- name: Build current
|
||||||
run: cmake -S curr -B curr/build -DGLERMINAL_TEST=ON && cmake --build curr/build
|
run: cmake -S curr -B curr/build -DGLERMINAL_TEST=ON && cmake --build curr/build
|
||||||
- name: Build previous
|
- name: Build previous
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
|||||||
build/
|
build/
|
||||||
cmake-build-*/
|
cmake-build-*/
|
||||||
.idea/
|
.idea/
|
||||||
|
.cache/
|
||||||
|
|||||||
5
.gitmodules
vendored
5
.gitmodules
vendored
@@ -1,6 +1,3 @@
|
|||||||
[submodule "glfw"]
|
[submodule "glfw"]
|
||||||
path = glfw
|
path = glfw
|
||||||
url = https://git.shylie.info/mirror/glfw.git
|
url = https://github.com/glfw/glfw.git
|
||||||
[submodule "Lua"]
|
|
||||||
path = Lua
|
|
||||||
url = https://git.shylie.info/mirror/Lua.git
|
|
||||||
|
|||||||
@@ -11,13 +11,13 @@ set(GLERMINAL_GRID_WIDTH 40 CACHE STRING "")
|
|||||||
set(GLERMINAL_GRID_HEIGHT 25 CACHE STRING "")
|
set(GLERMINAL_GRID_HEIGHT 25 CACHE STRING "")
|
||||||
set(GLERMINAL_LAYER_COUNT 64 CACHE STRING "")
|
set(GLERMINAL_LAYER_COUNT 64 CACHE STRING "")
|
||||||
set(GLERMINAL_CELL_SCALE 4 CACHE STRING "")
|
set(GLERMINAL_CELL_SCALE 4 CACHE STRING "")
|
||||||
|
set(GLERMINAL_CELL_SIZE 8 CACHE STRING "")
|
||||||
|
|
||||||
configure_file(source/glerminal-config.h.in glerminal-config.h @ONLY)
|
configure_file(source/glerminal-config.h.in glerminal-config.h @ONLY)
|
||||||
|
|
||||||
add_subdirectory(glfw)
|
add_subdirectory(glfw)
|
||||||
add_subdirectory(Lua)
|
|
||||||
|
|
||||||
add_library(glerminallib STATIC
|
add_library(glerminal STATIC
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/glerminal-config.h
|
${CMAKE_CURRENT_BINARY_DIR}/glerminal-config.h
|
||||||
include/glerminal.h
|
include/glerminal.h
|
||||||
|
|
||||||
@@ -33,12 +33,12 @@ add_library(glerminallib STATIC
|
|||||||
source/miniaudio.c
|
source/miniaudio.c
|
||||||
)
|
)
|
||||||
|
|
||||||
set_target_properties(glerminallib
|
set_target_properties(glerminal
|
||||||
PROPERTIES
|
PROPERTIES
|
||||||
CXX_STANDARD 11
|
CXX_STANDARD 11
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(glerminallib
|
target_include_directories(glerminal
|
||||||
PUBLIC
|
PUBLIC
|
||||||
include
|
include
|
||||||
${CMAKE_CURRENT_BINARY_DIR}
|
${CMAKE_CURRENT_BINARY_DIR}
|
||||||
@@ -46,12 +46,12 @@ target_include_directories(glerminallib
|
|||||||
source
|
source
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(glerminallib
|
target_link_libraries(glerminal
|
||||||
PUBLIC
|
PUBLIC
|
||||||
glfw
|
glfw
|
||||||
)
|
)
|
||||||
|
|
||||||
target_compile_definitions(glerminallib
|
target_compile_definitions(glerminal
|
||||||
PUBLIC
|
PUBLIC
|
||||||
GLERMINAL_VERSION=${PROJECT_VERSION}
|
GLERMINAL_VERSION=${PROJECT_VERSION}
|
||||||
GLERMINAL_VERSION_MAJOR=${PROJECT_VERSION_MAJOR}
|
GLERMINAL_VERSION_MAJOR=${PROJECT_VERSION_MAJOR}
|
||||||
@@ -59,23 +59,6 @@ target_compile_definitions(glerminallib
|
|||||||
GLERMINAL_VERSION_PATCH=${PROJECT_VERSION_PATCH}
|
GLERMINAL_VERSION_PATCH=${PROJECT_VERSION_PATCH}
|
||||||
)
|
)
|
||||||
|
|
||||||
if (MSVC)
|
|
||||||
target_link_options(glerminallib
|
|
||||||
PUBLIC
|
|
||||||
"/ENTRY:mainCRTStartup"
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_executable(glerminal WIN32
|
|
||||||
source/glerminal-main.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(glerminal
|
|
||||||
PRIVATE
|
|
||||||
glerminallib
|
|
||||||
lua_static
|
|
||||||
)
|
|
||||||
|
|
||||||
if(PROJECT_IS_TOP_LEVEL)
|
if(PROJECT_IS_TOP_LEVEL)
|
||||||
add_subdirectory(examples examples)
|
add_subdirectory(examples examples)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
1
Lua
1
Lua
Submodule Lua deleted from 88246d621a
37
PROJECT_RETROSPECTIVE.md
Normal file
37
PROJECT_RETROSPECTIVE.md
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# A look back on what I learned
|
||||||
|
|
||||||
|
## why?
|
||||||
|
|
||||||
|
I came across an art/rendering style called "sprite stacking".
|
||||||
|
I found sprite stacking very interesting in comparison to traditional methods,
|
||||||
|
and wanted to experiment with the style.
|
||||||
|
|
||||||
|
## challenge
|
||||||
|
|
||||||
|
This was my first big graphics-based project. Computer graphics
|
||||||
|
at the low-level was new to me. I took this as an opportunity to
|
||||||
|
learn the basics of OpenGL. This learning process was the most
|
||||||
|
difficult part of the project, especially the domain-specific
|
||||||
|
rendering techniques used.
|
||||||
|
|
||||||
|
## how?
|
||||||
|
|
||||||
|
I found some [great tutorials](https://learnopengl.com) to get started,
|
||||||
|
and though these helped, I also did a lot of individual
|
||||||
|
learning through experimentation and discussion with peers.
|
||||||
|
|
||||||
|
## results
|
||||||
|
|
||||||
|
In the end, the library had most of the functionality
|
||||||
|
I originally wanted. The library can draw up to 256 layers of icons in a grid,
|
||||||
|
with optional offsets and tints per icon. Here's an example with only 7 library calls:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## evaluation
|
||||||
|
|
||||||
|
Besides learning the basics of OpenGL, I also learned
|
||||||
|
how to use CMake to help build the library. Also, I set up
|
||||||
|
continuous integration for automated testing on a git commit.
|
||||||
|
If I were to rewrite this library, I would definitely invest more
|
||||||
|
into the automated testing process.
|
||||||
@@ -1,2 +1,4 @@
|
|||||||
# termg
|
# glerminal
|
||||||
|
|
||||||
|
glerminal is a tile-based graphics library created
|
||||||
|
with the intent to use a sprite-stacking art style.
|
||||||
|
|||||||
BIN
example.gif
Normal file
BIN
example.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.1 MiB |
@@ -36,5 +36,5 @@ list(TRANSFORM EXAMPLE_RESOURCES PREPEND ${CMAKE_CURRENT_BINARY_DIR}/)
|
|||||||
foreach(SOURCE_FILE ${EXAMPLE_SOURCES})
|
foreach(SOURCE_FILE ${EXAMPLE_SOURCES})
|
||||||
get_filename_component(SOURCE_FILENAME ${SOURCE_FILE} NAME_WLE)
|
get_filename_component(SOURCE_FILENAME ${SOURCE_FILE} NAME_WLE)
|
||||||
add_executable(${SOURCE_FILENAME} WIN32 ${SOURCE_FILE} ${EXAMPLE_RESOURCES})
|
add_executable(${SOURCE_FILENAME} WIN32 ${SOURCE_FILE} ${EXAMPLE_RESOURCES})
|
||||||
target_link_libraries(${SOURCE_FILENAME} PRIVATE glerminallib)
|
target_link_libraries(${SOURCE_FILENAME} PRIVATE glerminal)
|
||||||
endforeach()
|
endforeach()
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
local time = 0
|
|
||||||
|
|
||||||
function glerminal.init()
|
|
||||||
if not glerminal.sprites('sprites.png') then
|
|
||||||
print('failed to load sprites')
|
|
||||||
end
|
|
||||||
|
|
||||||
for i = 1, 40 do
|
|
||||||
for j = 1, 25 do
|
|
||||||
glerminal.set(i, j, 1, 2)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
glerminal.tint(1, 0xA0FFFFFF)
|
|
||||||
|
|
||||||
glerminal.flush()
|
|
||||||
end
|
|
||||||
|
|
||||||
function glerminal.main(dt)
|
|
||||||
time = time + dt / 2
|
|
||||||
|
|
||||||
for i = 1, 40 do
|
|
||||||
for j = 1, 25 do
|
|
||||||
glerminal.offset(i, j, 1, math.cos(time * i / math.pi), math.sin(time * j / math.pi))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
glerminal.flush()
|
|
||||||
end
|
|
||||||
|
|
||||||
function glerminal.keypresse(key) end
|
|
||||||
function glerminal.keyrelease(key) end
|
|
||||||
function glerminal.mousemove(x, y) end
|
|
||||||
function glerminal.mousepress(button, x, y) end
|
|
||||||
function glerminal.mouserelease(button, x, y) end
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
version https://git-lfs.github.com/spec/v1
|
|
||||||
oid sha256:6dee3efcdfa72e54a602f69643907bb8e8a3328d2b40c2116dce22ff179d8892
|
|
||||||
size 182
|
|
||||||
@@ -16,7 +16,8 @@ enum
|
|||||||
GRID_WIDTH = @GLERMINAL_GRID_WIDTH@,
|
GRID_WIDTH = @GLERMINAL_GRID_WIDTH@,
|
||||||
GRID_HEIGHT = @GLERMINAL_GRID_HEIGHT@,
|
GRID_HEIGHT = @GLERMINAL_GRID_HEIGHT@,
|
||||||
LAYER_COUNT = @GLERMINAL_LAYER_COUNT@,
|
LAYER_COUNT = @GLERMINAL_LAYER_COUNT@,
|
||||||
CELL_SCALE = @GLERMINAL_CELL_SCALE@
|
CELL_SCALE = @GLERMINAL_CELL_SCALE@,
|
||||||
|
CELL_SIZE = @GLERMINAL_CELL_SIZE@
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -1,372 +0,0 @@
|
|||||||
#include <glerminal.h>
|
|
||||||
#define GLFW_INCLUDE_NONE
|
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#include <lualib.h>
|
|
||||||
#include <lauxlib.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
#define WINDOWS_LEAN_AND_MEAN
|
|
||||||
#include <Windows.h>
|
|
||||||
#define CHANGE_WORKING_DIRECTORY(path) !(SetCurrentDirectory(path))
|
|
||||||
#else
|
|
||||||
#include <unistd.h>
|
|
||||||
#define CHANGE_WORKING_DIRECTORY(path) chdir(path)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
int lglerminal_quit(lua_State* L)
|
|
||||||
{
|
|
||||||
glerminal_quit();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lglerminal_flush(lua_State* L)
|
|
||||||
{
|
|
||||||
glerminal_flush();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lglerminal_set(lua_State* L)
|
|
||||||
{
|
|
||||||
const int x = luaL_checkinteger(L, 1);
|
|
||||||
const int y = luaL_checkinteger(L, 2);
|
|
||||||
const int layer = luaL_checkinteger(L, 3) - 1;
|
|
||||||
const unsigned short sprite = luaL_checkinteger(L, 4) - 1;
|
|
||||||
glerminal_set(x, y, layer, sprite);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lglerminal_get(lua_State* L)
|
|
||||||
{
|
|
||||||
const int x = luaL_checkinteger(L, 1);
|
|
||||||
const int y = luaL_checkinteger(L, 2);
|
|
||||||
const int layer = luaL_checkinteger(L, 3) - 1;
|
|
||||||
lua_pushnumber(L, glerminal_get(x, y, layer) + 1);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lglerminal_offset(lua_State* L)
|
|
||||||
{
|
|
||||||
const int x = luaL_checkinteger(L, 1);
|
|
||||||
const int y = luaL_checkinteger(L, 2);
|
|
||||||
const int layer = luaL_checkinteger(L, 3) - 1;
|
|
||||||
const float ox = luaL_checknumber(L, 4);
|
|
||||||
const float oy = luaL_checknumber(L, 5);
|
|
||||||
glerminal_offset(x, y, layer, ox, oy);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lglerminal_layer_color(lua_State* L)
|
|
||||||
{
|
|
||||||
const int x = luaL_checkinteger(L, 1);
|
|
||||||
const int y = luaL_checkinteger(L, 2);
|
|
||||||
const int layer = luaL_checkinteger(L, 3) - 1;
|
|
||||||
const float r = luaL_checknumber(L, 4);
|
|
||||||
const float g = luaL_checknumber(L, 5);
|
|
||||||
const float b = luaL_checknumber(L, 6);
|
|
||||||
const float a = luaL_optnumber(L, 7, 1.0f);
|
|
||||||
|
|
||||||
int ri = 255 * r;
|
|
||||||
int gi = 255 * g;
|
|
||||||
int bi = 255 * b;
|
|
||||||
int ai = 255 * a;
|
|
||||||
|
|
||||||
if (ri > 255) { ri = 255; }
|
|
||||||
if (ri < 0) { ri = 0; }
|
|
||||||
|
|
||||||
if (gi > 255) { gi = 255; }
|
|
||||||
if (gi < 0) { gi = 0; }
|
|
||||||
|
|
||||||
if (bi > 255) { bi = 255; }
|
|
||||||
if (bi < 0) { bi = 0; }
|
|
||||||
|
|
||||||
if (ai > 255) { ai = 255; }
|
|
||||||
if (ai < 0) { ai = 0; }
|
|
||||||
|
|
||||||
const unsigned int color = ri | (gi << 8) | (bi << 16) | (ai << 24);
|
|
||||||
|
|
||||||
glerminal_color(x, y, layer, color);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lglerminal_layer_scale(lua_State* L)
|
|
||||||
{
|
|
||||||
const int x = luaL_checkinteger(L, 1);
|
|
||||||
const int y = luaL_checkinteger(L, 2);
|
|
||||||
const int layer = luaL_checkinteger(L, 3) - 1;
|
|
||||||
const float scale = luaL_checknumber(L, 4);
|
|
||||||
glerminal_scale(x, y, layer, scale);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lglerminal_load_sprites_file(lua_State* L)
|
|
||||||
{
|
|
||||||
const char* path = luaL_checkstring(L, 1);
|
|
||||||
lua_pushboolean(L, glerminal_load_sprites_file(path));
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lglerminal_play_sound(lua_State* L)
|
|
||||||
{
|
|
||||||
const char* name = luaL_checkstring(L, 1);
|
|
||||||
glerminal_sound(name);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const luaL_Reg lglerminal_methods[] =
|
|
||||||
{
|
|
||||||
{ "quit", lglerminal_quit },
|
|
||||||
{ "flush", lglerminal_flush },
|
|
||||||
{ "set", lglerminal_set },
|
|
||||||
{ "get", lglerminal_get },
|
|
||||||
{ "offset", lglerminal_offset },
|
|
||||||
{ "tint", lglerminal_layer_color },
|
|
||||||
{ "scale", lglerminal_layer_scale },
|
|
||||||
{ "sprites", lglerminal_load_sprites_file },
|
|
||||||
{ "sound", lglerminal_play_sound },
|
|
||||||
{ nullptr, nullptr }
|
|
||||||
};
|
|
||||||
|
|
||||||
int message_handler(lua_State* L)
|
|
||||||
{
|
|
||||||
luaL_traceback(L, L, lua_tostring(L, -1), 1);
|
|
||||||
lua_remove(L, -2);
|
|
||||||
|
|
||||||
glerminal_quit();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
lua_State* L;
|
|
||||||
|
|
||||||
void init()
|
|
||||||
{
|
|
||||||
lua_pushcfunction(L, message_handler);
|
|
||||||
const int handler = lua_gettop(L);
|
|
||||||
lua_getglobal(L, "glerminal");
|
|
||||||
lua_getfield(L, -1, "init");
|
|
||||||
lua_remove(L, -2);
|
|
||||||
if (lua_pcall(L, 0, 0, handler) != LUA_OK)
|
|
||||||
{
|
|
||||||
std::cout << lua_tostring(L, -1) << std::endl;
|
|
||||||
lua_pop(L, 1);
|
|
||||||
}
|
|
||||||
lua_remove(L, handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mainloop(double dt)
|
|
||||||
{
|
|
||||||
lua_pushcfunction(L, message_handler);
|
|
||||||
const int handler = lua_gettop(L);
|
|
||||||
lua_getglobal(L, "glerminal");
|
|
||||||
lua_getfield(L, -1, "main");
|
|
||||||
lua_remove(L, -2);
|
|
||||||
lua_pushnumber(L, dt);
|
|
||||||
if (lua_pcall(L, 1, 0, handler) != LUA_OK)
|
|
||||||
{
|
|
||||||
std::cout << lua_tostring(L, -1) << std::endl;
|
|
||||||
lua_pop(L, 1);
|
|
||||||
}
|
|
||||||
lua_remove(L, handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
void keypressed(int key)
|
|
||||||
{
|
|
||||||
const char* const name = glfwGetKeyName(key, 0);
|
|
||||||
if (name)
|
|
||||||
{
|
|
||||||
lua_pushcfunction(L, message_handler);
|
|
||||||
const int handler = lua_gettop(L);
|
|
||||||
lua_getglobal(L, "glerminal");
|
|
||||||
lua_getfield(L, -1, "keypress");
|
|
||||||
lua_remove(L, -2);
|
|
||||||
lua_pushstring(L, name);
|
|
||||||
if (lua_pcall(L, 1, 0, handler) != LUA_OK)
|
|
||||||
{
|
|
||||||
std::cout << lua_tostring(L, -1) << std::endl;
|
|
||||||
lua_pop(L, 1);
|
|
||||||
}
|
|
||||||
lua_remove(L, handler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void keyrelease(int key)
|
|
||||||
{
|
|
||||||
const char* const name = glfwGetKeyName(key, 0);
|
|
||||||
if (name)
|
|
||||||
{
|
|
||||||
lua_pushcfunction(L, message_handler);
|
|
||||||
const int handler = lua_gettop(L);
|
|
||||||
lua_getglobal(L, "glerminal");
|
|
||||||
lua_getfield(L, -1, "keyrelease");
|
|
||||||
lua_remove(L, -2);
|
|
||||||
lua_pushstring(L, name);
|
|
||||||
if (lua_pcall(L, 1, 0, handler) != LUA_OK)
|
|
||||||
{
|
|
||||||
std::cout << lua_tostring(L, -1) << std::endl;
|
|
||||||
lua_pop(L, 1);
|
|
||||||
}
|
|
||||||
lua_remove(L, handler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void mousemove(double x, double y)
|
|
||||||
{
|
|
||||||
lua_pushcfunction(L, message_handler);
|
|
||||||
const int handler = lua_gettop(L);
|
|
||||||
lua_getglobal(L, "glerminal");
|
|
||||||
lua_getfield(L, -1, "mousemove");
|
|
||||||
lua_remove(L, -2);
|
|
||||||
lua_pushnumber(L, x);
|
|
||||||
lua_pushnumber(L, y);
|
|
||||||
if (lua_pcall(L, 2, 0, handler) != LUA_OK)
|
|
||||||
{
|
|
||||||
std::cout << lua_tostring(L, -1) << std::endl;
|
|
||||||
lua_pop(L, 1);
|
|
||||||
}
|
|
||||||
lua_remove(L, handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mousepress(int button, double x, double y)
|
|
||||||
{
|
|
||||||
const char* button_name = nullptr;
|
|
||||||
switch (button)
|
|
||||||
{
|
|
||||||
case GLFW_MOUSE_BUTTON_LEFT:
|
|
||||||
button_name = "left";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GLFW_MOUSE_BUTTON_RIGHT:
|
|
||||||
button_name = "right";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GLFW_MOUSE_BUTTON_MIDDLE:
|
|
||||||
button_name = "middle";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (button_name)
|
|
||||||
{
|
|
||||||
lua_pushcfunction(L, message_handler);
|
|
||||||
const int handler = lua_gettop(L);
|
|
||||||
lua_getglobal(L, "glerminal");
|
|
||||||
lua_getfield(L, -1, "mousepress");
|
|
||||||
lua_remove(L, -2);
|
|
||||||
lua_pushstring(L, button_name);
|
|
||||||
lua_pushnumber(L, x);
|
|
||||||
lua_pushnumber(L, y);
|
|
||||||
if (lua_pcall(L, 3, 0, handler) != LUA_OK)
|
|
||||||
{
|
|
||||||
std::cout << lua_tostring(L, -1) << std::endl;
|
|
||||||
lua_pop(L, 1);
|
|
||||||
}
|
|
||||||
lua_remove(L, handler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void mouserelease(int button, double x, double y)
|
|
||||||
{
|
|
||||||
const char* button_name = nullptr;
|
|
||||||
switch (button)
|
|
||||||
{
|
|
||||||
case GLFW_MOUSE_BUTTON_LEFT:
|
|
||||||
button_name = "left";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GLFW_MOUSE_BUTTON_RIGHT:
|
|
||||||
button_name = "right";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GLFW_MOUSE_BUTTON_MIDDLE:
|
|
||||||
button_name = "middle";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (button_name)
|
|
||||||
{
|
|
||||||
lua_pushcfunction(L, message_handler);
|
|
||||||
const int handler = lua_gettop(L);
|
|
||||||
lua_getglobal(L, "glerminal");
|
|
||||||
lua_getfield(L, -1, "mouserelease");
|
|
||||||
lua_remove(L, -2);
|
|
||||||
lua_pushstring(L, button_name);
|
|
||||||
lua_pushnumber(L, x);
|
|
||||||
lua_pushnumber(L, y);
|
|
||||||
if (lua_pcall(L, 3, 0, handler) != LUA_OK)
|
|
||||||
{
|
|
||||||
std::cout << lua_tostring(L, -1) << std::endl;
|
|
||||||
lua_pop(L, 1);
|
|
||||||
}
|
|
||||||
lua_remove(L, handler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
if (argc == 1)
|
|
||||||
{
|
|
||||||
std::cout << "Usage: " << argv[0] << " <project directory>" << std::endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CHANGE_WORKING_DIRECTORY(argv[1]))
|
|
||||||
{
|
|
||||||
std::cout << "Failed to find project directory" << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
L = luaL_newstate();
|
|
||||||
luaL_openlibs(L);
|
|
||||||
|
|
||||||
luaL_newlib(L, lglerminal_methods);
|
|
||||||
lua_setglobal(L, "glerminal");
|
|
||||||
|
|
||||||
lua_pushcfunction(L, message_handler);
|
|
||||||
const int handler = lua_gettop(L);
|
|
||||||
if (luaL_loadfile(L, "main.lua") != LUA_OK)
|
|
||||||
{
|
|
||||||
const char* str = lua_tostring(L, -1);
|
|
||||||
std::cout << str << std::endl;
|
|
||||||
lua_pop(L, 1);
|
|
||||||
}
|
|
||||||
else if (lua_pcall(L, 0, LUA_MULTRET, handler) != LUA_OK)
|
|
||||||
{
|
|
||||||
const char* str = lua_tostring(L, -1);
|
|
||||||
std::cout << str << std::endl;
|
|
||||||
lua_pop(L, 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
glerminal_init_params params;
|
|
||||||
params.init = init;
|
|
||||||
params.main = mainloop;
|
|
||||||
params.keypress = keypressed;
|
|
||||||
params.keyrelease = keyrelease;
|
|
||||||
params.moved = mousemove;
|
|
||||||
params.mousepress = mousepress;
|
|
||||||
params.mouserelease = mouserelease;
|
|
||||||
glerminal_run(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
lua_close(L);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -9,20 +9,18 @@
|
|||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace glerminal
|
namespace glerminal
|
||||||
{
|
{
|
||||||
constexpr unsigned int CELL_SIZE = 8;
|
|
||||||
constexpr unsigned int MAX_SPRITES_ROW = 64;
|
constexpr unsigned int MAX_SPRITES_ROW = 64;
|
||||||
constexpr unsigned int MAX_SPRITES = MAX_SPRITES_ROW * MAX_SPRITES_ROW;
|
constexpr unsigned int MAX_SPRITES = MAX_SPRITES_ROW * MAX_SPRITES_ROW;
|
||||||
constexpr unsigned int GRID_WIDTH = ::GRID_WIDTH;
|
constexpr unsigned int GRID_WIDTH = ::GRID_WIDTH;
|
||||||
constexpr unsigned int GRID_HEIGHT = ::GRID_HEIGHT;
|
constexpr unsigned int GRID_HEIGHT = ::GRID_HEIGHT;
|
||||||
constexpr unsigned int LAYER_COUNT = ::LAYER_COUNT;
|
constexpr unsigned int LAYER_COUNT = ::LAYER_COUNT;
|
||||||
constexpr unsigned int CELL_SCALE = ::CELL_SCALE;
|
constexpr unsigned int CELL_SCALE = ::CELL_SCALE;
|
||||||
|
constexpr unsigned int CELL_SIZE = ::CELL_SIZE;
|
||||||
constexpr unsigned int GRID_AREA = GRID_WIDTH * GRID_HEIGHT;
|
constexpr unsigned int GRID_AREA = GRID_WIDTH * GRID_HEIGHT;
|
||||||
constexpr unsigned int SCREEN_WIDTH = GRID_WIDTH * CELL_SIZE * CELL_SCALE;
|
constexpr unsigned int SCREEN_WIDTH = GRID_WIDTH * CELL_SIZE * CELL_SCALE;
|
||||||
constexpr unsigned int SCREEN_HEIGHT = GRID_HEIGHT * CELL_SIZE * CELL_SCALE;
|
constexpr unsigned int SCREEN_HEIGHT = GRID_HEIGHT * CELL_SIZE * CELL_SCALE;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#define LAYERS_UNIFORM_NAME "layers"
|
#define LAYERS_UNIFORM_NAME "layers"
|
||||||
#define LAYER_COUNT_UNIFORM_NAME "layer_count"
|
#define LAYER_COUNT_UNIFORM_NAME "layer_count"
|
||||||
#define ATLAS_WIDTH_UNIFORM_NAME "atlas_width"
|
#define ATLAS_WIDTH_UNIFORM_NAME "atlas_width"
|
||||||
|
#define CELL_SIZE_UNIFORM_NAME "cell_size"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@@ -33,6 +34,7 @@ namespace
|
|||||||
"layout (location = 2) in int sprite;\n"
|
"layout (location = 2) in int sprite;\n"
|
||||||
"layout (location = 3) in vec4 color;\n"
|
"layout (location = 3) in vec4 color;\n"
|
||||||
"layout (location = 4) in float scale;\n"
|
"layout (location = 4) in float scale;\n"
|
||||||
|
"uniform float " CELL_SIZE_UNIFORM_NAME ";\n"
|
||||||
"uniform vec4 " GRID_SIZE_UNIFORM_NAME ";\n"
|
"uniform vec4 " GRID_SIZE_UNIFORM_NAME ";\n"
|
||||||
"uniform int " ATLAS_WIDTH_UNIFORM_NAME ";\n"
|
"uniform int " ATLAS_WIDTH_UNIFORM_NAME ";\n"
|
||||||
"out VS_OUT {\n"
|
"out VS_OUT {\n"
|
||||||
@@ -48,7 +50,7 @@ namespace
|
|||||||
" vs_out.sprite = sprite;\n"
|
" vs_out.sprite = sprite;\n"
|
||||||
" vs_out.layer = layer;\n"
|
" vs_out.layer = layer;\n"
|
||||||
" vs_out.layer_color = color;\n"
|
" vs_out.layer_color = color;\n"
|
||||||
" vs_out.texcoord = vec2(sprite % " ATLAS_WIDTH_UNIFORM_NAME " + position.x + 1, (sprite / " ATLAS_WIDTH_UNIFORM_NAME ") - position.y) / vec2(" ATLAS_WIDTH_UNIFORM_NAME ") + vec2(-(2 * position.x + 1) * " GRID_SIZE_UNIFORM_NAME ".z / 16, (2 * position.y + 1) * " GRID_SIZE_UNIFORM_NAME ".z / 16);\n"
|
" vs_out.texcoord = vec2(sprite % " ATLAS_WIDTH_UNIFORM_NAME " + position.x + 1, (sprite / " ATLAS_WIDTH_UNIFORM_NAME ") - position.y) / vec2(" ATLAS_WIDTH_UNIFORM_NAME ") + vec2(-(2 * position.x + 1) * " GRID_SIZE_UNIFORM_NAME ".z / (2 * " CELL_SIZE_UNIFORM_NAME "), (2 * position.y + 1) * " GRID_SIZE_UNIFORM_NAME ".z / (2 * " CELL_SIZE_UNIFORM_NAME "));\n"
|
||||||
" vec2 cell_position = vec2(scale + (gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) - " GRID_SIZE_UNIFORM_NAME ".x * floor((gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) / " GRID_SIZE_UNIFORM_NAME ".x), -floor((gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) / " GRID_SIZE_UNIFORM_NAME ".x));\n"
|
" vec2 cell_position = vec2(scale + (gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) - " GRID_SIZE_UNIFORM_NAME ".x * floor((gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) / " GRID_SIZE_UNIFORM_NAME ".x), -floor((gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) / " GRID_SIZE_UNIFORM_NAME ".x));\n"
|
||||||
" vec2 temp = ((position + vec2(-0.5, 0.5)) * scale + cell_position + vec2(-0.5, 0.5)) * " GRID_SIZE_UNIFORM_NAME ".zw * 2 + vec2(-1, 1);\n"
|
" vec2 temp = ((position + vec2(-0.5, 0.5)) * scale + cell_position + vec2(-0.5, 0.5)) * " GRID_SIZE_UNIFORM_NAME ".zw * 2 + vec2(-1, 1);\n"
|
||||||
" gl_Position = vec4(scaled_offset.x + temp.x, scaled_offset.y - temp.y, 0, 1);\n"
|
" gl_Position = vec4(scaled_offset.x + temp.x, scaled_offset.y - temp.y, 0, 1);\n"
|
||||||
@@ -64,6 +66,7 @@ namespace
|
|||||||
"layout (location = 2) in int sprite;\n"
|
"layout (location = 2) in int sprite;\n"
|
||||||
"layout (location = 3) in vec4 color;\n"
|
"layout (location = 3) in vec4 color;\n"
|
||||||
"layout (location = 4) in float scale;\n"
|
"layout (location = 4) in float scale;\n"
|
||||||
|
"uniform float " CELL_SIZE_UNIFORM_NAME ";\n"
|
||||||
"uniform vec4 " GRID_SIZE_UNIFORM_NAME ";\n"
|
"uniform vec4 " GRID_SIZE_UNIFORM_NAME ";\n"
|
||||||
"uniform int " ATLAS_WIDTH_UNIFORM_NAME ";\n"
|
"uniform int " ATLAS_WIDTH_UNIFORM_NAME ";\n"
|
||||||
"out VS_OUT {\n"
|
"out VS_OUT {\n"
|
||||||
@@ -77,7 +80,7 @@ namespace
|
|||||||
" gl_Layer = layer;\n"
|
" gl_Layer = layer;\n"
|
||||||
" vec2 scaled_offset = 2 * offset * " GRID_SIZE_UNIFORM_NAME ".zw;\n"
|
" vec2 scaled_offset = 2 * offset * " GRID_SIZE_UNIFORM_NAME ".zw;\n"
|
||||||
" vs_out.sprite = sprite;\n"
|
" vs_out.sprite = sprite;\n"
|
||||||
" vs_out.texcoord = vec2(sprite % " ATLAS_WIDTH_UNIFORM_NAME " + position.x + 1, (sprite / " ATLAS_WIDTH_UNIFORM_NAME ") - position.y) / vec2(" ATLAS_WIDTH_UNIFORM_NAME ") + vec2(-(2 * position.x + 1) * " GRID_SIZE_UNIFORM_NAME ".z / 16, (2 * position.y + 1) * " GRID_SIZE_UNIFORM_NAME ".z / 16);\n"
|
" vs_out.texcoord = vec2(sprite % " ATLAS_WIDTH_UNIFORM_NAME " + position.x + 1, (sprite / " ATLAS_WIDTH_UNIFORM_NAME ") - position.y) / vec2(" ATLAS_WIDTH_UNIFORM_NAME ") + vec2(-(2 * position.x + 1) * " GRID_SIZE_UNIFORM_NAME ".z / (2 * " CELL_SIZE_UNIFORM_NAME "), (2 * position.y + 1) * " GRID_SIZE_UNIFORM_NAME ".z / (2 * " CELL_SIZE_UNIFORM_NAME "));\n"
|
||||||
" vs_out.layer_color = color;\n"
|
" vs_out.layer_color = color;\n"
|
||||||
" vec2 cell_position = vec2(scale + (gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) - " GRID_SIZE_UNIFORM_NAME ".x * floor((gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) / " GRID_SIZE_UNIFORM_NAME ".x), -floor((gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) / " GRID_SIZE_UNIFORM_NAME ".x));\n"
|
" vec2 cell_position = vec2(scale + (gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) - " GRID_SIZE_UNIFORM_NAME ".x * floor((gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) / " GRID_SIZE_UNIFORM_NAME ".x), -floor((gl_InstanceID % int(" GRID_SIZE_UNIFORM_NAME ".y)) / " GRID_SIZE_UNIFORM_NAME ".x));\n"
|
||||||
" vec2 temp = ((position + vec2(-0.5, 0.5)) * scale + cell_position + vec2(-0.5, 0.5)) * " GRID_SIZE_UNIFORM_NAME ".zw * 2 + vec2(-1, 1);\n"
|
" vec2 temp = ((position + vec2(-0.5, 0.5)) * scale + cell_position + vec2(-0.5, 0.5)) * " GRID_SIZE_UNIFORM_NAME ".zw * 2 + vec2(-1, 1);\n"
|
||||||
@@ -285,7 +288,9 @@ namespace glerminal
|
|||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||||
|
|
||||||
glBlitNamedFramebuffer(m_screen_framebuffer, 0, 0, 0, GRID_WIDTH * CELL_SIZE, GRID_HEIGHT * CELL_SIZE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
glBlitNamedFramebuffer(m_screen_framebuffer, 0, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
glfwSwapBuffers(m_window);
|
glfwSwapBuffers(m_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -503,7 +508,7 @@ namespace glerminal
|
|||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
glViewport(0, 0, GRID_WIDTH * CELL_SIZE, GRID_HEIGHT * CELL_SIZE);
|
glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||||
|
|
||||||
// -- setup vertex data --
|
// -- setup vertex data --
|
||||||
// create vertex buffer object
|
// create vertex buffer object
|
||||||
@@ -652,6 +657,7 @@ namespace glerminal
|
|||||||
|
|
||||||
// setup uniforms
|
// setup uniforms
|
||||||
glUseProgram(m_program);
|
glUseProgram(m_program);
|
||||||
|
glUniform1f(glGetUniformLocation(m_program, CELL_SIZE_UNIFORM_NAME), CELL_SIZE);
|
||||||
glUniform4f(glGetUniformLocation(m_program, GRID_SIZE_UNIFORM_NAME), GRID_WIDTH + 2, GRID_AREA_2, 1.0f / GRID_WIDTH, 1.0f / GRID_HEIGHT);
|
glUniform4f(glGetUniformLocation(m_program, GRID_SIZE_UNIFORM_NAME), GRID_WIDTH + 2, GRID_AREA_2, 1.0f / GRID_WIDTH, 1.0f / GRID_HEIGHT);
|
||||||
glUniform1i(glGetUniformLocation(m_program, ATLAS_WIDTH_UNIFORM_NAME), MAX_SPRITES_ROW);
|
glUniform1i(glGetUniformLocation(m_program, ATLAS_WIDTH_UNIFORM_NAME), MAX_SPRITES_ROW);
|
||||||
|
|
||||||
@@ -750,7 +756,7 @@ namespace glerminal
|
|||||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 0);
|
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 0);
|
||||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 0);
|
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 0);
|
||||||
|
|
||||||
glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, GRID_WIDTH * CELL_SIZE, GRID_HEIGHT * CELL_SIZE, LAYER_COUNT);
|
glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, SCREEN_WIDTH, SCREEN_HEIGHT, LAYER_COUNT);
|
||||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_framebuffer_backing_texture, 0);
|
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_framebuffer_backing_texture, 0);
|
||||||
|
|
||||||
glBindTextureUnit(1, m_framebuffer_backing_texture);
|
glBindTextureUnit(1, m_framebuffer_backing_texture);
|
||||||
@@ -771,7 +777,7 @@ namespace glerminal
|
|||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||||
|
|
||||||
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, GRID_WIDTH * CELL_SIZE, GRID_HEIGHT * CELL_SIZE);
|
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||||
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_screen_framebuffer_backing_texture, 0);
|
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_screen_framebuffer_backing_texture, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ target_include_directories(test-common
|
|||||||
${CMAKE_SOURCE_DIR}/source
|
${CMAKE_SOURCE_DIR}/source
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(test-common PRIVATE glerminallib)
|
target_link_libraries(test-common PRIVATE glerminal)
|
||||||
|
|
||||||
file(GLOB_RECURSE
|
file(GLOB_RECURSE
|
||||||
TEST_RESOURCES
|
TEST_RESOURCES
|
||||||
@@ -52,5 +52,5 @@ list(TRANSFORM TEST_RESOURCES PREPEND ${CMAKE_CURRENT_BINARY_DIR}/)
|
|||||||
foreach(SOURCE_FILE ${TEST_SOURCES})
|
foreach(SOURCE_FILE ${TEST_SOURCES})
|
||||||
get_filename_component(SOURCE_FILENAME ${SOURCE_FILE} NAME_WLE)
|
get_filename_component(SOURCE_FILENAME ${SOURCE_FILE} NAME_WLE)
|
||||||
add_executable(test-${SOURCE_FILENAME} WIN32 ${SOURCE_FILE} ${TEST_RESOURCES})
|
add_executable(test-${SOURCE_FILENAME} WIN32 ${SOURCE_FILE} ${TEST_RESOURCES})
|
||||||
target_link_libraries(test-${SOURCE_FILENAME} PRIVATE glerminallib test-common)
|
target_link_libraries(test-${SOURCE_FILENAME} PRIVATE glerminal test-common)
|
||||||
endforeach()
|
endforeach()
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
unsigned char pixels[(GRID_WIDTH * 8) * (GRID_HEIGHT * 8) * 3];
|
unsigned char pixels[(GRID_WIDTH * CELL_SIZE * CELL_SCALE) * (GRID_HEIGHT * CELL_SIZE * CELL_SCALE) * 3];
|
||||||
}
|
}
|
||||||
|
|
||||||
void glerminal_test_save_image()
|
void glerminal_test_save_image()
|
||||||
@@ -21,5 +21,5 @@ void glerminal_test_save_image()
|
|||||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
|
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
|
||||||
|
|
||||||
stbi_flip_vertically_on_write(true);
|
stbi_flip_vertically_on_write(true);
|
||||||
stbi_write_png("image.png", GRID_WIDTH * 8, GRID_HEIGHT * 8, 3, pixels, GRID_WIDTH * 8 * 3);
|
stbi_write_png("image.png", GRID_WIDTH * CELL_SIZE * CELL_SCALE, GRID_HEIGHT * CELL_SIZE * CELL_SCALE, 3, pixels, GRID_WIDTH * CELL_SIZE * CELL_SCALE * 3);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user