added asset loading class, zoom factor, vbo switch, shader version
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -10,3 +10,4 @@ android/build/
|
||||
android/.gradle/
|
||||
android/.externalNativeBuild/
|
||||
|
||||
android/src/main/assets/
|
||||
|
||||
@@ -27,6 +27,7 @@ add_library(
|
||||
src/main/cpp/main.cpp
|
||||
../engine/pch.cpp
|
||||
../engine/util.cpp
|
||||
../engine/asset.cpp
|
||||
../engine/image.cpp
|
||||
../engine/texture.cpp
|
||||
../engine/font.cpp
|
||||
|
||||
3
android/build-run.bat
Normal file
3
android/build-run.bat
Normal file
@@ -0,0 +1,3 @@
|
||||
call gradlew installDebug
|
||||
call adb shell am start -n com.omigamedev/android.app.NativeActivity
|
||||
pause
|
||||
@@ -9,10 +9,13 @@ buildscript {
|
||||
apply plugin: 'android'
|
||||
|
||||
android {
|
||||
compileSdkVersion 'android-19'
|
||||
buildToolsVersion '24.0.3'
|
||||
compileSdkVersion 23
|
||||
buildToolsVersion '23.0.2'
|
||||
|
||||
defaultConfig {
|
||||
applicationId = 'com.omigamedev'
|
||||
minSdkVersion 9
|
||||
targetSdkVersion 23
|
||||
// This block is different from the one you use to link Gradle
|
||||
// to your CMake or ndk-build script.
|
||||
externalNativeBuild {
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
# This file is automatically generated by Android Tools.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file must *NOT* be checked into Version Control Systems,
|
||||
# as it contains information specific to your local configuration.
|
||||
|
||||
# location of the SDK. This is only used by Ant
|
||||
# For customization when using a Version Control System, please read the
|
||||
# header note.
|
||||
sdk.dir=/Users/omimac/android-sdk-macosx
|
||||
ndk.dir=/Users/omimac/android-ndk-r13
|
||||
@@ -3,11 +3,17 @@
|
||||
package="com.omigamedev"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
<application android:label="@string/app_name" android:icon="@drawable/ic_launcher">
|
||||
<application android:label="@string/app_name"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:allowBackup="false"
|
||||
android:hasCode="false"
|
||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
|
||||
<activity android:name="android.app.NativeActivity"
|
||||
android:label="@string/app_name">
|
||||
android:label="@string/app_name"
|
||||
android:configChanges="orientation|keyboardHidden"
|
||||
android:screenOrientation="sensorLandscape">
|
||||
<meta-data android:name="android.app.lib_name"
|
||||
android:value="native-lib" />
|
||||
android:value="native-lib" />
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "pch.h"
|
||||
#include "app.h"
|
||||
#include "..\..\..\..\engine\asset.h"
|
||||
|
||||
/**
|
||||
* Our saved state data.
|
||||
@@ -150,15 +151,13 @@ static int engine_init_display(struct engine* engine) {
|
||||
//glShadeModel(GL_SMOOTH);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
//glEnableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
Asset::m_am = engine->app->activity->assetManager;
|
||||
App::I.width = w;
|
||||
App::I.height = h;
|
||||
App::I.initShaders();
|
||||
|
||||
if (!plane.create<1>(1,1))
|
||||
LOG("Failed to create the plane mesh");
|
||||
App::I.init();
|
||||
|
||||
LOG("All ready");
|
||||
engine->animating = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -167,22 +166,10 @@ static int engine_init_display(struct engine* engine) {
|
||||
* Just the current frame in the display.
|
||||
*/
|
||||
static void engine_draw_frame(struct engine* engine) {
|
||||
if (engine->display == NULL) {
|
||||
// No display.
|
||||
if (engine->display == NULL)
|
||||
return;
|
||||
}
|
||||
|
||||
// Just fill the screen with a color.
|
||||
glClearColor(((float)engine->state.x)/engine->width, engine->state.angle,
|
||||
((float)engine->state.y)/engine->height, 1);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glm::mat4 mvp = glm::ortho<float>(-1, 1, -1, 1, -1, 1);
|
||||
//App::I.update(now - _prevTime);
|
||||
ShaderManager::use(kShader::Color);
|
||||
ShaderManager::u_mat4(kShaderUniform::MVP, mvp);
|
||||
ShaderManager::u_vec4(kShaderUniform::Col, glm::vec4(1, 0, 0, 1));
|
||||
plane.draw_fill();
|
||||
App::I.update(0);
|
||||
|
||||
eglSwapBuffers(engine->display, engine->surface);
|
||||
}
|
||||
@@ -212,12 +199,33 @@ static void engine_term_display(struct engine* engine) {
|
||||
*/
|
||||
static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) {
|
||||
struct engine* engine = (struct engine*)app->userData;
|
||||
if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) {
|
||||
engine->animating = 1;
|
||||
engine->state.x = AMotionEvent_getX(event, 0);
|
||||
engine->state.y = AMotionEvent_getY(event, 0);
|
||||
return 1;
|
||||
}
|
||||
float x = AMotionEvent_getX(event, 0);
|
||||
float y = AMotionEvent_getY(event, 0);
|
||||
MouseEvent e;
|
||||
int32_t eventType = AInputEvent_getType(event);
|
||||
switch (eventType) {
|
||||
case AINPUT_EVENT_TYPE_MOTION:
|
||||
switch (AInputEvent_getSource(event)) {
|
||||
case AINPUT_SOURCE_TOUCHSCREEN:
|
||||
int action = AKeyEvent_getAction(event) & AMOTION_EVENT_ACTION_MASK;
|
||||
switch (action) {
|
||||
case AMOTION_EVENT_ACTION_DOWN:
|
||||
App::I.mouse_down(0, x, y);
|
||||
return 1;
|
||||
case AMOTION_EVENT_ACTION_UP:
|
||||
App::I.mouse_up(0, x, y);
|
||||
return 1;
|
||||
case AMOTION_EVENT_ACTION_MOVE:
|
||||
App::I.mouse_move(x, y);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
} // end switch
|
||||
break;
|
||||
case AINPUT_EVENT_TYPE_KEY:
|
||||
// handle key input...
|
||||
break;
|
||||
} // end switch
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">DummyActivity</string>
|
||||
<string name="app_name">LayoutEngine</string>
|
||||
</resources>
|
||||
|
||||
BIN
data/arial.ttf
Normal file
BIN
data/arial.ttf
Normal file
Binary file not shown.
@@ -283,11 +283,8 @@
|
||||
</border>
|
||||
</node>
|
||||
<!-- content panel -->
|
||||
<border margin="10 0 10 10" border-color=".8" color="1" width="1" grow="1" pad="10" wrap="1" dir="col" justify="center" align="center">
|
||||
<text text="Viewport" font-face="arial" font-size="30" color="0 .1 .1 1"/>
|
||||
<text text="Made in C++11 using OpenGL 3.1" font-face="arial" font-size="11" color="0 .1 .1 1"/>
|
||||
<!--<text text="this is a small description of the useless big text above" font-face="arial" font-size="11" color="0 1 1 1"/>-->
|
||||
<image id="check" margin="10 0 0 0" path="data/meme/nothing-to-do-here.jpg" width="300" height="200"/>
|
||||
<border grow="1" color=".1" pad="10">
|
||||
<viewport grow="1"></viewport>
|
||||
</border>
|
||||
</node>
|
||||
<!-- status bar -->
|
||||
|
||||
@@ -151,6 +151,7 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="engine\app.cpp" />
|
||||
<ClCompile Include="engine\asset.cpp" />
|
||||
<ClCompile Include="engine\font.cpp" />
|
||||
<ClCompile Include="engine\image.cpp" />
|
||||
<ClCompile Include="engine\layout.cpp" />
|
||||
@@ -186,6 +187,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="engine\app.h" />
|
||||
<ClInclude Include="engine\asset.h" />
|
||||
<ClInclude Include="engine\font.h" />
|
||||
<ClInclude Include="engine\image.h" />
|
||||
<ClInclude Include="engine\layout.h" />
|
||||
|
||||
@@ -54,6 +54,9 @@
|
||||
<ClCompile Include="engine\util.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="engine\asset.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="engine\app.h">
|
||||
@@ -83,5 +86,8 @@
|
||||
<ClInclude Include="engine\util.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="engine\asset.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -3,6 +3,15 @@
|
||||
|
||||
App App::I; // singleton
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define SHADER_VERSION "#version 300 es\n"
|
||||
#elif __ANDROID__
|
||||
#define SHADER_VERSION "#version 300 es\n"
|
||||
#elif _WIN32
|
||||
#define SHADER_VERSION "#version 150\n"
|
||||
#endif
|
||||
|
||||
|
||||
void App::create()
|
||||
{
|
||||
width = 800;
|
||||
@@ -12,7 +21,7 @@ void App::create()
|
||||
void App::initShaders()
|
||||
{
|
||||
static const char* shader_v =
|
||||
"#version 300 es\n"
|
||||
SHADER_VERSION
|
||||
"uniform mat4 mvp;"
|
||||
"in vec4 pos;"
|
||||
"in vec2 uvs;"
|
||||
@@ -22,7 +31,7 @@ void App::initShaders()
|
||||
" gl_Position = mvp * vec4(pos.xyz, 1.f);"
|
||||
"}";
|
||||
static const char* shader_f =
|
||||
"#version 300 es\n"
|
||||
SHADER_VERSION
|
||||
"uniform sampler2D tex;"
|
||||
"in vec3 uv;"
|
||||
"out vec4 frag;"
|
||||
@@ -31,7 +40,7 @@ void App::initShaders()
|
||||
" frag = texture(tex, uv.xy);"
|
||||
"}";
|
||||
static const char* shader_uv_f =
|
||||
"#version 300 es\n"
|
||||
SHADER_VERSION
|
||||
"uniform sampler2D tex;"
|
||||
"in vec3 uv;"
|
||||
"out vec4 frag;"
|
||||
@@ -39,7 +48,7 @@ void App::initShaders()
|
||||
" frag = vec4(uv.xy,0,1);"
|
||||
"}";
|
||||
static const char* shader_atlas_v =
|
||||
"#version 300 es\n"
|
||||
SHADER_VERSION
|
||||
"uniform mat4 mvp;"
|
||||
"uniform vec2 tof;"
|
||||
"uniform vec2 tsz;"
|
||||
@@ -51,7 +60,7 @@ void App::initShaders()
|
||||
" gl_Position = mvp * vec4(pos, 0, 1);"
|
||||
"}";
|
||||
static const char* shader_atlas_f =
|
||||
"#version 300 es\n"
|
||||
SHADER_VERSION
|
||||
"uniform sampler2D tex;"
|
||||
"in vec2 uv;"
|
||||
"out vec4 frag;"
|
||||
@@ -59,21 +68,21 @@ void App::initShaders()
|
||||
" frag = texture(tex, uv);"
|
||||
"}";
|
||||
static const char* shader_color_v =
|
||||
"#version 300 es\n"
|
||||
SHADER_VERSION
|
||||
"uniform mat4 mvp;"
|
||||
"in vec4 pos;"
|
||||
"void main(){"
|
||||
" gl_Position = mvp * pos;"
|
||||
"}";
|
||||
static const char* shader_color_f =
|
||||
"#version 300 es\n"
|
||||
SHADER_VERSION
|
||||
"uniform vec4 col;"
|
||||
"out vec4 frag;"
|
||||
"void main(){"
|
||||
" frag = col;"
|
||||
"}";
|
||||
static const char* shader_font_v =
|
||||
"#version 300 es\n"
|
||||
SHADER_VERSION
|
||||
"uniform mat4 mvp;"
|
||||
"in vec2 pos;"
|
||||
"in vec2 uvs;"
|
||||
@@ -83,7 +92,7 @@ void App::initShaders()
|
||||
" gl_Position = mvp * vec4(pos, 0, 1);"
|
||||
"}";
|
||||
static const char* shader_font_f =
|
||||
"#version 300 es\n"
|
||||
SHADER_VERSION
|
||||
"uniform sampler2D tex;"
|
||||
"uniform vec4 col;"
|
||||
"in vec2 uv;"
|
||||
@@ -93,6 +102,7 @@ void App::initShaders()
|
||||
" frag = vec4(col.rgb, a);"
|
||||
"}";
|
||||
|
||||
LOG("initializing shaders");
|
||||
if (!ShaderManager::create(kShader::Texture, shader_v, shader_f))
|
||||
LOG("Failed to create shader Texture");
|
||||
if (!ShaderManager::create(kShader::Color, shader_color_v, shader_color_f))
|
||||
@@ -103,32 +113,36 @@ void App::initShaders()
|
||||
LOG("Failed to create shader Font");
|
||||
if (!ShaderManager::create(kShader::Atlas, shader_atlas_v, shader_atlas_f))
|
||||
LOG("Failed to create shader Atlas");
|
||||
LOG("shaders initialized");
|
||||
}
|
||||
|
||||
void App::initAssets()
|
||||
{
|
||||
#if _WIN32
|
||||
const char* ttf = "C:\\Windows\\Fonts\\arial.ttf";
|
||||
#else
|
||||
const char* ttf = "/Library/Fonts/Arial.ttf";
|
||||
#endif
|
||||
LOG("initializing assets");
|
||||
FontManager::init();
|
||||
FontManager::load(kFont::Arial_11, ttf, 15);
|
||||
FontManager::load(kFont::Arial_30, ttf, 30);
|
||||
LOG("initializing assets loading fonts");
|
||||
FontManager::load(kFont::Arial_11, "data/arial.ttf", 15);
|
||||
FontManager::load(kFont::Arial_30, "data/arial.ttf", 30);
|
||||
|
||||
LOG("initializing assets create sampler");
|
||||
sampler.create(GL_NEAREST);
|
||||
LOG("initializing assets load uvs texture");
|
||||
if (!tex.load("data/uvs.jpg"))
|
||||
LOG("error loading image\n");
|
||||
LOG("initializing assets completed");
|
||||
}
|
||||
|
||||
void App::initLayout()
|
||||
{
|
||||
LOG("initializing layout statics");
|
||||
NodeBorder::static_init();
|
||||
NodeImage::static_init();
|
||||
NodeIcon::static_init();
|
||||
|
||||
layout.on_loaded = [&] {
|
||||
layout[main_id]->update(width, height);
|
||||
LOG("initializing layout updating after load");
|
||||
layout[main_id]->update(width, height, zoom);
|
||||
LOG("initializing layout components");
|
||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-close"))
|
||||
{
|
||||
button->on_click = [] { exit(0); };
|
||||
@@ -191,7 +205,9 @@ void App::initLayout()
|
||||
toolbar->m_flood_events = true;
|
||||
}
|
||||
};
|
||||
layout.load("data/layout2.xml");
|
||||
LOG("initializing layout xml");
|
||||
layout.load("data/layout.xml");
|
||||
LOG("initializing layout completed");
|
||||
}
|
||||
|
||||
void App::init()
|
||||
@@ -219,7 +235,7 @@ void App::init()
|
||||
|
||||
initShaders();
|
||||
initAssets();
|
||||
initLayout();
|
||||
initLayout();
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
@@ -243,6 +259,7 @@ void App::init()
|
||||
GLfloat width_range[2];
|
||||
glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, width_range);
|
||||
LOG("GL line range: %f - %f\n", width_range[0], width_range[1]);
|
||||
LOG("Screen Size: %f %f", width, height);
|
||||
}
|
||||
|
||||
void App::update(float dt)
|
||||
@@ -251,14 +268,17 @@ void App::update(float dt)
|
||||
glViewport(0, 0, (GLsizei)width, (GLsizei)height);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
layout.reload();
|
||||
//layout.reload();
|
||||
if (auto* main = layout[main_id])
|
||||
main->update(width, height, zoom);
|
||||
|
||||
auto observer = [this](Node* n)
|
||||
{
|
||||
if (n && n->m_display)
|
||||
{
|
||||
auto box = n->m_clip;
|
||||
glScissor((int)box.x-1, (int)(height - box.y - box.w)-1, (int)box.z+2, (int)box.w+2);
|
||||
glm::vec4 c = glm::vec4((int)box.x - 1, (int)(height / zoom - box.y - box.w) - 1, (int)box.z + 2, (int)box.w + 2) * zoom;
|
||||
glScissor(c.x, c.y, c.z, c.w);
|
||||
n->draw();
|
||||
}
|
||||
};
|
||||
@@ -275,16 +295,16 @@ void App::resize(float w, float h)
|
||||
width = w;
|
||||
height = h;
|
||||
if (auto* main = layout[main_id])
|
||||
main->update(w, h);
|
||||
main->update(w, h, zoom);
|
||||
}
|
||||
|
||||
void App::mouse_down(int button, float x, float y)
|
||||
{
|
||||
MouseEvent e;
|
||||
e.m_type = button ? kEventType::MouseDownR : kEventType::MouseDownL;
|
||||
e.m_pos = { x, y };
|
||||
e.m_pos = { x / zoom, y / zoom };
|
||||
layout[main_id]->on_event(&e);
|
||||
LOG("mouse click %f %f\n", x, y);
|
||||
LOG("mouse click button%d pos %f %f\n", button, x, y);
|
||||
|
||||
if (popup)
|
||||
{
|
||||
@@ -295,7 +315,7 @@ void App::mouse_down(int button, float x, float y)
|
||||
{
|
||||
popup = (NodePopupMenu*)layout[const_hash("popup-menu")]->m_children[0]->clone();
|
||||
popup->SetPositioning(YGPositionTypeAbsolute);
|
||||
popup->SetPosition(x, y);
|
||||
popup->SetPosition(x / zoom, y / zoom);
|
||||
layout[main_id]->add_child(popup);
|
||||
}
|
||||
layout[main_id]->update();
|
||||
@@ -304,7 +324,7 @@ void App::mouse_move(float x, float y)
|
||||
{
|
||||
MouseEvent e;
|
||||
e.m_type = kEventType::MouseMove;
|
||||
e.m_pos = { x, y };
|
||||
e.m_pos = { x / zoom, y / zoom };
|
||||
if (auto* main = layout[main_id])
|
||||
main->on_event(&e);
|
||||
}
|
||||
@@ -312,7 +332,7 @@ void App::mouse_up(int button, float x, float y)
|
||||
{
|
||||
MouseEvent e;
|
||||
e.m_type = button ? kEventType::MouseUpR : kEventType::MouseUpL;
|
||||
e.m_pos = { x, y };
|
||||
e.m_pos = { x / zoom, y / zoom };
|
||||
layout[main_id]->on_event(&e);
|
||||
layout[main_id]->update();
|
||||
}
|
||||
|
||||
@@ -22,6 +22,11 @@ public:
|
||||
static App I;
|
||||
float width;
|
||||
float height;
|
||||
#ifdef __ANDROID__
|
||||
float zoom = 4.0;
|
||||
#else
|
||||
float zoom = 1.0;
|
||||
#endif // __ANDROID__
|
||||
void init();
|
||||
void initShaders();
|
||||
void initAssets();
|
||||
|
||||
59
engine/asset.cpp
Normal file
59
engine/asset.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
#include "pch.h"
|
||||
#include "asset.h"
|
||||
|
||||
#ifdef __ANDROID__
|
||||
AAssetManager* Asset::m_am;
|
||||
#endif
|
||||
|
||||
bool Asset::open(const char* path)
|
||||
{
|
||||
LOG("Asset::open %s", path);
|
||||
m_current_path = path;
|
||||
#ifdef __ANDROID__
|
||||
if (!(m_asset = AAssetManager_open(m_am, path, AASSET_MODE_RANDOM)))
|
||||
{
|
||||
LOG("AAssetManager_open failed");
|
||||
return false;
|
||||
}
|
||||
m_len = (int)AAsset_getLength(m_asset);
|
||||
m_data = (uint8_t*)AAsset_getBuffer(m_asset);
|
||||
#else
|
||||
if (!(m_fp = fopen(path, "rb")))
|
||||
return false;
|
||||
fseek(m_fp, 0, SEEK_END);
|
||||
m_len = (int)ftell(m_fp);
|
||||
fseek(m_fp, 0, SEEK_SET);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
glm::uint8_t* Asset::read_all()
|
||||
{
|
||||
#ifdef __ANDROID__
|
||||
return m_data;
|
||||
#else
|
||||
if (!m_data)
|
||||
{
|
||||
m_data = new uint8_t[m_len];
|
||||
if (m_len != fread(m_data, 1, m_len, m_fp))
|
||||
{
|
||||
LOG("ASSET READ FAILED for %s", m_current_path.c_str());
|
||||
delete m_data;
|
||||
m_data = nullptr;
|
||||
}
|
||||
}
|
||||
return m_data;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Asset::close()
|
||||
{
|
||||
#ifdef __ANDROID__
|
||||
AAsset_close(m_asset);
|
||||
#else
|
||||
fclose(m_fp);
|
||||
if (m_data)
|
||||
delete m_data;
|
||||
m_data = nullptr;
|
||||
#endif
|
||||
}
|
||||
18
engine/asset.h
Normal file
18
engine/asset.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
class Asset
|
||||
{
|
||||
public:
|
||||
#ifdef __ANDROID__
|
||||
static AAssetManager* m_am;
|
||||
AAsset* m_asset = nullptr;
|
||||
#endif
|
||||
std::string m_current_path;
|
||||
FILE* m_fp = nullptr;
|
||||
int m_len = 0;
|
||||
uint8_t* m_data = nullptr;
|
||||
bool open(const char* path);
|
||||
uint8_t* read_all();
|
||||
void close();
|
||||
};
|
||||
|
||||
@@ -1,26 +1,23 @@
|
||||
#include "pch.h"
|
||||
#include "font.h"
|
||||
#include "shader.h"
|
||||
#include "asset.h"
|
||||
|
||||
std::map<kFont, Font> FontManager::m_fonts;
|
||||
Sampler FontManager::m_sampler;
|
||||
|
||||
bool Font::load(const char* ttf, int font_size)
|
||||
{
|
||||
FILE* font_file = fopen(ttf, "rb");
|
||||
if (font_file)
|
||||
Asset file;
|
||||
LOG("Font::load %s", ttf);
|
||||
if (file.open(ttf) && file.read_all())
|
||||
{
|
||||
fseek(font_file, 0, SEEK_END);
|
||||
long sz = ftell(font_file);
|
||||
auto data = std::make_unique<uint8_t[]>(sz);
|
||||
fseek(font_file, 0, SEEK_SET);
|
||||
auto bytes = fread(data.get(), 1, sz, font_file);
|
||||
assert(bytes==sz);
|
||||
LOG("Font::load loaded");
|
||||
auto bitmap = std::make_unique<uint8_t[]>(w*h);
|
||||
chars.resize(num_chars);
|
||||
int ret = stbtt_BakeFontBitmap(data.get(), 0, (float)font_size, bitmap.get(), w, h, start_char, num_chars, chars.data());
|
||||
font_tex.create(w, h, GL_RED, bitmap.get());
|
||||
fclose(font_file);
|
||||
int ret = stbtt_BakeFontBitmap(file.m_data, 0, (float)font_size, bitmap.get(), w, h, start_char, num_chars, chars.data());
|
||||
font_tex.create(w, h, GL_LUMINANCE, bitmap.get());
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -44,8 +41,8 @@ const Font& FontManager::get(kFont id)
|
||||
bool TextMesh::create()
|
||||
{
|
||||
glGenBuffers(2, font_buffers);
|
||||
#if USE_VBO
|
||||
glGenVertexArrays(1, &font_array);
|
||||
|
||||
glBindVertexArray(font_array);
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
@@ -54,6 +51,7 @@ bool TextMesh::create()
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec4), (GLvoid*)0);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec4), (GLvoid*)(sizeof(float)*2));
|
||||
glBindVertexArray(0);
|
||||
#endif // USE_VBO
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -113,9 +111,21 @@ void TextMesh::draw()
|
||||
f.font_tex.bind();
|
||||
FontManager::m_sampler.bind(0);
|
||||
|
||||
#if USE_VBO
|
||||
glBindVertexArray(font_array);
|
||||
glDrawElements(GL_TRIANGLES, font_array_count, GL_UNSIGNED_SHORT, 0);
|
||||
glBindVertexArray(0);
|
||||
#else
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, font_buffers[1]);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, font_buffers[0]);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec4), (GLvoid*)0);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec4), (GLvoid*)(sizeof(float) * 2));
|
||||
glDrawElements(GL_TRIANGLES, font_array_count, GL_UNSIGNED_SHORT, 0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
#endif // USE_VBO
|
||||
|
||||
f.font_tex.unbind();
|
||||
FontManager::m_sampler.unbind();
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
#include "pch.h"
|
||||
#include "image.h"
|
||||
#include "asset.h"
|
||||
|
||||
#include <stb/stb_image.h>
|
||||
|
||||
bool Image::load(std::string filename)
|
||||
{
|
||||
//stbi_set_flip_vertically_on_load(true);
|
||||
uint8_t* buffer = stbi_load(filename.c_str(), &width, &height, nullptr, 4);
|
||||
Asset file;
|
||||
if (!(file.open(filename.c_str()) && file.read_all()))
|
||||
{
|
||||
file.close();
|
||||
return false;
|
||||
}
|
||||
uint8_t* buffer = stbi_load_from_memory(file.m_data, file.m_len, &width, &height, nullptr, 4);
|
||||
file.close();
|
||||
comp = 4;
|
||||
m_data = std::unique_ptr<uint8_t[]>(buffer);
|
||||
return true;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "pch.h"
|
||||
#include "layout.h"
|
||||
#include "util.h"
|
||||
#include "asset.h"
|
||||
|
||||
Plane NodeBorder::m_plane;
|
||||
Plane NodeImage::m_plane;
|
||||
@@ -11,11 +12,19 @@ kEventResult Node::on_event(Event* e)
|
||||
{
|
||||
kEventResult ret = kEventResult::Available;
|
||||
for (auto it = m_children.rbegin(); it != m_children.rend(); ++it)
|
||||
{
|
||||
if ((*it)->on_event(e) == kEventResult::Consumed)
|
||||
{
|
||||
if (m_flood_events)
|
||||
{
|
||||
ret = kEventResult::Consumed;
|
||||
}
|
||||
else
|
||||
{
|
||||
return kEventResult::Consumed;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ret == kEventResult::Consumed)
|
||||
return ret;
|
||||
switch (e->m_cat)
|
||||
@@ -51,6 +60,8 @@ kEventResult Node::on_event(Event* e)
|
||||
handle_event(&e2);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -80,12 +91,13 @@ void Node::remove_child(Node* n)
|
||||
}
|
||||
}
|
||||
|
||||
void Node::update(float width, float height)
|
||||
void Node::update(float width, float height, float zoom)
|
||||
{
|
||||
YGNodeStyleSetWidth(y_node, width);
|
||||
YGNodeStyleSetHeight(y_node, height);
|
||||
m_zoom = zoom;
|
||||
YGNodeStyleSetWidth(y_node, width / zoom);
|
||||
YGNodeStyleSetHeight(y_node, height / zoom);
|
||||
YGNodeCalculateLayout(y_node, YGUndefined, YGUndefined, YGDirectionLTR);
|
||||
m_proj = glm::ortho(0.f, width, height, 0.f, -1.f, 1.f);
|
||||
m_proj = glm::ortho(0.f, width / zoom, height / zoom, 0.f, -1.f, 1.f);
|
||||
update_internal({ 0, 0 }, m_proj);
|
||||
}
|
||||
|
||||
@@ -462,18 +474,25 @@ void Node::clone_children(Node* dest) const
|
||||
|
||||
bool LayoutManager::load(const char* path)
|
||||
{
|
||||
#ifndef __ANDROID__
|
||||
struct stat tmp_info;
|
||||
if (stat(path, &tmp_info) != 0)
|
||||
return false;
|
||||
if (tmp_info.st_mtime <= m_file_info.st_mtime)
|
||||
return false;
|
||||
m_file_info = tmp_info;
|
||||
#endif // __ANDROID__
|
||||
|
||||
m_path = path;
|
||||
|
||||
auto old = std::move(m_layouts);
|
||||
|
||||
Asset file;
|
||||
if (!(file.open(path) && file.read_all()))
|
||||
return false;
|
||||
tinyxml2::XMLDocument xml;
|
||||
auto ret = xml.LoadFile(path);
|
||||
auto ret = xml.Parse((char*)file.m_data, file.m_len);
|
||||
file.close();
|
||||
if (ret != tinyxml2::XMLError::XML_SUCCESS)
|
||||
return false;
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "util.h"
|
||||
#include "shader.h"
|
||||
#include "font.h"
|
||||
#include "asset.h"
|
||||
|
||||
enum class kAttribute : uint16_t
|
||||
{
|
||||
@@ -126,6 +127,7 @@ public:
|
||||
bool m_flood_events = false;
|
||||
bool m_destroyed = false;
|
||||
|
||||
float m_zoom = 1.f;
|
||||
glm::vec2 m_pos;
|
||||
glm::vec2 m_size;
|
||||
glm::vec4 m_clip;
|
||||
@@ -148,6 +150,7 @@ public:
|
||||
m_pos = o.m_pos;
|
||||
m_size = o.m_size;
|
||||
m_clip = o.m_clip;
|
||||
m_zoom = o.m_zoom;
|
||||
o.y_node = nullptr;
|
||||
o.parent = nullptr;
|
||||
}
|
||||
@@ -203,7 +206,7 @@ public:
|
||||
return o;
|
||||
}
|
||||
|
||||
void update(float width, float height);
|
||||
void update(float width, float height, float zoom);
|
||||
void update();
|
||||
void update_internal(const glm::vec2& origin, const glm::mat4& proj);
|
||||
virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr);
|
||||
@@ -220,6 +223,13 @@ public:
|
||||
c->watch(observer);
|
||||
}
|
||||
void destroy() { m_destroyed = true; }
|
||||
Node* root()
|
||||
{
|
||||
Node* ret = this;
|
||||
while (ret->parent)
|
||||
ret = ret->parent;
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<class T = Node> T* find(const char* ids)
|
||||
{
|
||||
@@ -726,14 +736,22 @@ public:
|
||||
// icons: http://www.famfamfam.com/lab/icons/silk/
|
||||
// regex css -> spritesheet.txt: \.([^{]+) {\s+width: (\d+)px;\s+height: (\d+)px;\s+.*: -(\d+)px -(\d+)px;\s+}\s+
|
||||
// to: "\1",\2,\3,\4,\5\n
|
||||
static char str[256];
|
||||
Asset file;
|
||||
if (!(file.open("data/spritesheet.txt") && file.read_all()))
|
||||
return;
|
||||
char* data = (char*)file.m_data;
|
||||
int size = file.m_len;
|
||||
static char name[256];
|
||||
int x, y, w, h;
|
||||
FILE* f = fopen("data/spritesheet.txt", "r");
|
||||
while (!feof(f) && fscanf(f, "%s %d %d %d %d", str, &w, &h, &x, &y) == 5)
|
||||
char* s = strtok(data, "\n");
|
||||
int i = strlen(s) + 1;
|
||||
while (i < size && sscanf(s, "%s %d %d %d %d", name, &w, &h, &x, &y) == 5)
|
||||
{
|
||||
m_icons[str] = glm::vec4(x, y, x+w, y+h);
|
||||
m_icons[name] = glm::vec4(x, y, x + w, y + h);
|
||||
s = strtok(nullptr, "\n");
|
||||
i += strlen(s) + 1;
|
||||
}
|
||||
fclose(f);
|
||||
file.close();
|
||||
}
|
||||
virtual Node* clone_instantiate() const override { return new NodeIcon(); }
|
||||
virtual void clone_copy(Node* dest) const override
|
||||
@@ -772,11 +790,14 @@ public:
|
||||
std::unique_ptr<Plane> m_faces;
|
||||
std::unique_ptr<Sampler> m_sampler;
|
||||
uint16_t m_tex_id;
|
||||
glm::vec2 drag_start;
|
||||
glm::vec2 drag_end;
|
||||
bool dragging = false;
|
||||
float angle = 0.0f;
|
||||
float angle_old;
|
||||
|
||||
virtual void draw() override
|
||||
{
|
||||
static float angle = 0;
|
||||
angle += 0.05;
|
||||
glm::mat4 cam = glm::lookAt(glm::vec3(sinf(angle)*10, 0, -10), glm::vec3(0, 0, 0), glm::vec3(0, -1, 0));
|
||||
glm::mat4 proj = glm::perspective<float>(glm::radians(45.f), m_clip.z / m_clip.w, .1f, 100);
|
||||
|
||||
@@ -787,8 +808,9 @@ public:
|
||||
|
||||
glClearColor(1, 0, 0, 1);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
auto box = m_clip;
|
||||
glViewport(box.x, (int)(vp[3] - box.y - box.w), box.z, box.w);
|
||||
auto box = m_clip * root()->m_zoom;
|
||||
auto c = glm::vec4(box.x, (int)(vp[3] - box.y - box.w), box.z, box.w);
|
||||
glViewport(c.x, c.y, c.z, c.w);
|
||||
TextureManager::get(m_tex_id).bind();
|
||||
m_sampler->bind(0);
|
||||
glEnable(GL_BLEND);
|
||||
@@ -816,4 +838,29 @@ public:
|
||||
TextureManager::load("data/uvs.jpg");
|
||||
m_tex_id = const_hash("data/uvs.jpg");
|
||||
}
|
||||
virtual kEventResult handle_event(Event* e) override
|
||||
{
|
||||
Node::handle_event(e);
|
||||
switch (e->m_type)
|
||||
{
|
||||
case kEventType::MouseDownL:
|
||||
dragging = true;
|
||||
drag_end = drag_start = ((MouseEvent*)e)->m_pos;
|
||||
angle_old = angle;
|
||||
break;
|
||||
case kEventType::MouseUpL:
|
||||
dragging = false;
|
||||
break;
|
||||
case kEventType::MouseMove:
|
||||
if (dragging)
|
||||
{
|
||||
drag_end = ((MouseEvent*)e)->m_pos;
|
||||
angle = angle_old + (drag_end - drag_start).x * .01f;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return kEventResult::Consumed;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
//#pragma once
|
||||
|
||||
#define USE_VBO 0
|
||||
#define USE_SAMPLER 1
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <OpenGL/gl3.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
@@ -22,7 +22,7 @@ bool Shader::create(const char* vertex, const char* fragment)
|
||||
glGetShaderiv(vs, GL_COMPILE_STATUS, &status);
|
||||
glGetShaderInfoLog(vs, sizeof(infolog), &infolen, infolog);
|
||||
if (infolen > 0)
|
||||
printf("VERTEX SHADER:\n%s", infolog);
|
||||
LOG("VERTEX SHADER:\n%s", infolog);
|
||||
if (status == 0)
|
||||
{
|
||||
glDeleteShader(vs);
|
||||
@@ -41,7 +41,7 @@ bool Shader::create(const char* vertex, const char* fragment)
|
||||
glGetShaderiv(fs, GL_COMPILE_STATUS, &status);
|
||||
glGetShaderInfoLog(fs, sizeof(infolog), &infolen, infolog);
|
||||
if (infolen > 0)
|
||||
printf("FRAGMENT SHADER:\n%s", infolog);
|
||||
LOG("FRAGMENT SHADER:\n%s", infolog);
|
||||
if (status == 0)
|
||||
{
|
||||
glDeleteShader(vs);
|
||||
@@ -68,7 +68,7 @@ bool Shader::create(const char* vertex, const char* fragment)
|
||||
glGetProgramiv(ps, GL_LINK_STATUS, &status);
|
||||
glGetProgramInfoLog(ps, sizeof(infolog), &infolen, infolog);
|
||||
if (infolen > 0)
|
||||
printf("LINK SHADER:\n%s", infolog);
|
||||
LOG("LINK SHADER:\n%s", infolog);
|
||||
if (status == 0)
|
||||
{
|
||||
glDeleteProgram(ps);
|
||||
|
||||
@@ -14,10 +14,10 @@ bool Shape::create_buffers(GLvoid* idx, GLvoid* vertices, int isize, int vsize)
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
#if USE_VBO
|
||||
glGenVertexArrays(2, arrays);
|
||||
if (!(arrays[0] && arrays[1]))
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
glBindVertexArray(arrays[i]);
|
||||
@@ -28,21 +28,43 @@ bool Shape::create_buffers(GLvoid* idx, GLvoid* vertices, int isize, int vsize)
|
||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (GLvoid*)0);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (GLvoid*)offsetof(vertex_t, uvs));
|
||||
}
|
||||
|
||||
glBindVertexArray(0);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
void Shape::draw_fill() const
|
||||
{
|
||||
#if USE_VBO
|
||||
glBindVertexArray(arrays[0]);
|
||||
glDrawElements(GL_TRIANGLES, count[0], GL_UNSIGNED_SHORT, ioff[0]);
|
||||
glBindVertexArray(0);
|
||||
#else
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
|
||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (GLvoid*)0);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (GLvoid*)offsetof(vertex_t, uvs));
|
||||
glDrawElements(GL_TRIANGLES, count[0], GL_UNSIGNED_SHORT, ioff[0]);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
#endif // USE_VBO
|
||||
}
|
||||
void Shape::draw_stroke() const
|
||||
{
|
||||
#if USE_VBO
|
||||
glBindVertexArray(arrays[1]);
|
||||
glDrawElements(GL_LINES, count[1], GL_UNSIGNED_SHORT, ioff[1]);
|
||||
glBindVertexArray(0);
|
||||
#else
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
|
||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (GLvoid*)0);
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (GLvoid*)offsetof(vertex_t, uvs));
|
||||
glDrawElements(GL_LINES, count[1], GL_UNSIGNED_SHORT, ioff[1]);
|
||||
#endif // USE_VBO
|
||||
}
|
||||
|
||||
bool RectShape::create(float w, float h)
|
||||
|
||||
@@ -16,7 +16,9 @@ public:
|
||||
~Shape()
|
||||
{
|
||||
glDeleteBuffers(2, buffers);
|
||||
#if USE_VBO
|
||||
glDeleteVertexArrays(2, arrays);
|
||||
#endif // USE_VBO
|
||||
}
|
||||
protected:
|
||||
glm::vec2 quad_mid_point(glm::vec2 a, glm::vec2 b, glm::vec2 c, glm::vec2 d)
|
||||
|
||||
@@ -33,7 +33,7 @@ bool Texture2D::create(int width, int height, GLint format, const uint8_t* data)
|
||||
}
|
||||
bool Texture2D::create(const Image& img)
|
||||
{
|
||||
static GLint formats[] = { GL_RED, GL_RG, GL_RGB, GL_RGBA };
|
||||
static GLint formats[] = { 0, 0, GL_RGB, GL_RGBA };
|
||||
return create(img.width, img.height, formats[img.comp - 1], img.data());
|
||||
}
|
||||
bool Texture2D::load(std::string filename)
|
||||
@@ -56,7 +56,9 @@ glm::vec2 Texture2D::size() const
|
||||
|
||||
bool Sampler::create(GLint filter /*= GL_LINEAR*/, GLint wrap /*= GL_CLAMP_TO_EDGE*/)
|
||||
{
|
||||
#if USE_SAMPLER
|
||||
glGenSamplers(1, &id);
|
||||
#endif // USE_SAMPLER
|
||||
if (id == 0)
|
||||
return false;
|
||||
set(filter, wrap);
|
||||
@@ -64,18 +66,24 @@ bool Sampler::create(GLint filter /*= GL_LINEAR*/, GLint wrap /*= GL_CLAMP_TO_ED
|
||||
}
|
||||
void Sampler::set(GLint filter /*= GL_LINEAR*/, GLint wrap /*= GL_CLAMP_TO_EDGE*/)
|
||||
{
|
||||
#if USE_SAMPLER
|
||||
glSamplerParameteri(id, GL_TEXTURE_WRAP_S, wrap);
|
||||
glSamplerParameteri(id, GL_TEXTURE_WRAP_T, wrap);
|
||||
glSamplerParameteri(id, GL_TEXTURE_MIN_FILTER, filter);
|
||||
glSamplerParameteri(id, GL_TEXTURE_MAG_FILTER, filter);
|
||||
#endif // USE_SAMPLER
|
||||
}
|
||||
void Sampler::bind(int unit)
|
||||
{
|
||||
current_unit = unit;
|
||||
#if USE_SAMPLER
|
||||
glBindSampler(unit, id);
|
||||
#endif // USE_SAMPLER
|
||||
}
|
||||
void Sampler::unbind()
|
||||
{
|
||||
#if USE_SAMPLER
|
||||
glBindSampler(current_unit, 0);
|
||||
#endif // USE_SAMPLER
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user