diff --git a/engine.vcxproj b/engine.vcxproj
index b8f2c16..590d27a 100644
--- a/engine.vcxproj
+++ b/engine.vcxproj
@@ -203,6 +203,7 @@
+
@@ -311,6 +312,7 @@
+
diff --git a/engine.vcxproj.filters b/engine.vcxproj.filters
index 9fac23a..7aeba11 100644
--- a/engine.vcxproj.filters
+++ b/engine.vcxproj.filters
@@ -219,6 +219,9 @@
Source Files\libs\poly2tri
+
+ Source Files\ui
+
@@ -389,6 +392,9 @@
Header Files\ui
+
+ Header Files\ui
+
diff --git a/engine/app.cpp b/engine/app.cpp
index 65f372c..61880b1 100644
--- a/engine/app.cpp
+++ b/engine/app.cpp
@@ -12,6 +12,10 @@
void android_async_lock(struct engine* engine);
void android_async_swap(struct engine* engine);
void android_async_unlock(struct engine* engine);
+#elif _WIN32
+void async_lock();
+void async_swap();
+void async_unlock();
#endif
using namespace ui;
@@ -59,6 +63,43 @@ void App::initLog()
LogRemote::I.file_init();
}
+static size_t curl_data_handler(void *contents, size_t size, size_t nmemb, void *userp)
+{
+ auto buffer = reinterpret_cast(userp);
+ buffer->append((char*)contents, size * nmemb);
+ return size * nmemb;
+}
+
+void App::upload(std::string filename)
+{
+ CURL *curl;
+
+ struct curl_httppost *formpost = NULL;
+ struct curl_httppost *lastptr = NULL;
+
+ //curl_global_init(CURL_GLOBAL_ALL);
+
+ curl_formadd(&formpost,
+ &lastptr,
+ CURLFORM_COPYNAME, "fileToUpload",
+ CURLFORM_FILE, filename.c_str(),
+ CURLFORM_END);
+
+ curl = curl_easy_init();
+ std::string res;
+
+ if (curl)
+ {
+ curl_easy_setopt(curl, CURLOPT_URL, "http://omigamedev.ddns.net:8080/upload/upl.php");
+ curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &res);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_data_handler);
+ auto err = curl_easy_perform(curl); //here it crashes
+ std::cout << "\n\nUPLOAD RESULT\n" << res << "\n\n\n";
+ curl_easy_cleanup(curl);
+ }
+}
+
void App::init()
{
#ifdef _WIN32
@@ -133,6 +174,9 @@ void App::async_start()
[ios_view async_lock];
#elif __ANDROID__
android_async_lock(and_engine);
+#elif _WIN32
+ async_lock();
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
#endif
}
@@ -140,6 +184,8 @@ void App::async_update()
{
#if __IOS__
[ios_view->glview bindDrawable];
+#elif _WIN32
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
#endif
redraw = true;
clear();
@@ -151,6 +197,8 @@ void App::async_update()
[ios_view async_swap];
#elif __ANDROID__
android_async_swap(and_engine);
+#elif _WIN32
+ async_swap();
#endif
}
@@ -162,11 +210,16 @@ void App::async_end()
[ios_view async_unlock];
#elif __ANDROID__
android_async_unlock(and_engine);
+#elif _WIN32
+ async_unlock();
#endif
}
void App::update(float dt)
{
+ static std::mutex m;
+ std::lock_guard _lock(m);
+
// update offscreen stuff
if (canvas && canvas->m_canvas)
canvas->m_canvas->stroke_draw();
diff --git a/engine/app.h b/engine/app.h
index 44f9697..8a84458 100644
--- a/engine/app.h
+++ b/engine/app.h
@@ -92,6 +92,7 @@ public:
void initShaders();
void initAssets();
void initLayout();
+ void upload(std::string filename);
void create();
void terminate();
void clear();
diff --git a/engine/canvas.cpp b/engine/canvas.cpp
index d8bbf6a..8f8e411 100644
--- a/engine/canvas.cpp
+++ b/engine/canvas.cpp
@@ -1213,6 +1213,10 @@ void ui::Canvas::project_save_thread(std::string data_path)
}
fclose(fp);
LOG("project saved to %s", data_path.c_str());
+
+ App::I.upload(data_path);
+ LOG("uploaded");
+
App::I.async_start();
pb->destroy();
App::I.async_update();
@@ -1284,7 +1288,6 @@ void ui::Canvas::project_open_thread(std::string data_path)
{
int n_order;
fread(&n_order, sizeof(int), 1, fp);
- m_order.push_back(n_order);
int name_len;
fread(&name_len, sizeof(int), 1, fp);
@@ -1327,6 +1330,7 @@ void ui::Canvas::project_open_thread(std::string data_path)
m_layers.emplace_back();
m_layers.back().create(m_width, m_height, name.c_str());
m_layers.back().restore(snap);
+ m_order.push_back(n_order);
App::I.async_end();
}
fclose(fp);
diff --git a/engine/canvas_modes.cpp b/engine/canvas_modes.cpp
index 9bb6f74..1fb4699 100644
--- a/engine/canvas_modes.cpp
+++ b/engine/canvas_modes.cpp
@@ -146,7 +146,7 @@ void CanvasModePen::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const
ui::ShaderManager::u_float(ui::kShaderUniform::Alpha, node->m_brush.m_tip_flow);
auto tip_color = glm::vec4(glm::vec3(node->m_brush.m_tip_color), 1);
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, tip_color);
- ui::ShaderManager::u_int(ui::kShaderUniform::Highlight, 0);
+ //ui::ShaderManager::u_int(ui::kShaderUniform::Highlight, 0);
float tip_scale = 1.f / glm::tan(glm::radians(ui::Canvas::I->m_cam_fov * 0.5f));
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP,
glm::scale(glm::vec3(1, -1, 1)) *
diff --git a/engine/main.cpp b/engine/main.cpp
index 70fdb85..587cde7 100644
--- a/engine/main.cpp
+++ b/engine/main.cpp
@@ -19,10 +19,74 @@ HDC hDC;
HGLRC hRC;
wchar_t* className;
bool keys[256];
+std::mutex gl_mutex;
+std::mutex async_mutex;
+std::thread::id gl_thread;
+int gl_count = 0;
#include
#include "wacom.h"
+//Returns the last Win32 error, in string format. Returns an empty string if there is no error.
+std::string GetLastErrorAsString()
+{
+ //Get the error message, if any.
+ DWORD errorMessageID = ::GetLastError();
+ if (errorMessageID == 0)
+ return std::string(); //No error message has been recorded
+
+ LPSTR messageBuffer = nullptr;
+ size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
+
+ std::string message(messageBuffer, size);
+
+ //Free the buffer.
+ LocalFree(messageBuffer);
+
+ return message;
+}
+
+void async_lock()
+{
+ //std::lock_guard _lock(async_mutex);
+ if (gl_count == 0 || gl_thread != std::this_thread::get_id())
+ {
+ gl_mutex.lock();
+ bool ret = wglMakeCurrent(hDC, hRC);
+ if (ret == false)
+ LOG("FAILED wglMakeCurrent: %s", GetLastErrorAsString().c_str());
+ gl_thread = std::this_thread::get_id();
+ //LOG("lock");
+ }
+ gl_count++;
+ //assert(ret == true);
+}
+
+void async_swap()
+{
+ SwapBuffers(hDC);
+ //LOG("swap");
+}
+
+void async_unlock()
+{
+ //std::lock_guard _lock(async_mutex);
+ gl_count--;
+ if (gl_count == 0)
+ {
+ //LOG("unlock");
+ wglMakeCurrent(0, 0);
+ gl_mutex.unlock();
+ }
+}
+
+struct async_locker
+{
+ async_locker() { async_lock(); }
+ ~async_locker() { async_unlock(); }
+};
+
int read_WMI_info()
{
// see: http://win32easy.blogspot.co.uk/2011/03/wmi-in-c-query-everyting-from-your-os.html
@@ -303,9 +367,14 @@ int main(int argc, char** argv)
t0 = t1;
if (App::I.redraw)
{
+ async_lock();
+ App::I.redraw = true;
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
App::I.clear();
App::I.update((float)(t1 - t0) / 1000.0f);
SwapBuffers(hDC);
+ async_unlock();
+ //LOG("swap main");
}
}
// else
@@ -323,6 +392,7 @@ int main(int argc, char** argv)
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
+ async_locker lock;
static bool leftDown = false;
static DWORD lastTime;
static POINT lastPoint;
@@ -368,7 +438,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
App::I.key_up(convert_key((int)wp));
break;
case WM_CHAR:
- //App::I.key_char((int)wp);
+ App::I.key_char((int)wp);
break;
case WM_MOUSEMOVE:
//TODO: find a way to check if event is mouse/stylus. For now use Mouse for all
diff --git a/engine/util.h b/engine/util.h
index 5941869..90e6f65 100644
--- a/engine/util.h
+++ b/engine/util.h
@@ -158,7 +158,7 @@ struct gl_state
glBindSampler(i, sampler[i]);
}
glActiveTexture(active_tex);
- glBindTexture(GL_TEXTURE_BINDING_CUBE_MAP, cube);
+ glBindTexture(GL_TEXTURE_CUBE_MAP, cube);
}
};