add jpg library, export as jpg, export animation frames, add pressure support on mac

This commit is contained in:
2017-05-16 21:55:51 +01:00
parent a5c79d5ad8
commit c987b19c83
22 changed files with 11025 additions and 28 deletions

View File

@@ -61,8 +61,8 @@ public:
void update_memory_usage(size_t bytes);
void update(float dt);
void resize(float w, float h);
bool mouse_down(int button, float x, float y);
bool mouse_move(float x, float y);
bool mouse_down(int button, float x, float y, float pressure);
bool mouse_move(float x, float y, float pressure);
bool mouse_up(int button, float x, float y);
bool mouse_scroll(float x, float y, float delta);
bool mouse_cancel(int button);

View File

@@ -11,20 +11,22 @@ void App::resize(float w, float h)
main->update(w , h, zoom);
}
bool App::mouse_down(int button, float x, float y)
bool App::mouse_down(int button, float x, float y, float pressure)
{
MouseEvent e;
e.m_type = button ? kEventType::MouseDownR : kEventType::MouseDownL;
e.m_pos = { x / zoom, y / zoom };
e.m_pressure = pressure;
auto ret = layout[main_id]->on_event(&e);
layout[main_id]->update();
return ret == kEventResult::Consumed;
}
bool App::mouse_move(float x, float y)
bool App::mouse_move(float x, float y, float pressure)
{
MouseEvent e;
e.m_type = kEventType::MouseMove;
e.m_pos = { x / zoom, y / zoom };
e.m_pressure = pressure;
kEventResult ret = kEventResult::Available;
if (auto* main = layout[main_id])
ret = main->on_event(&e);

View File

@@ -165,7 +165,7 @@ ui::StrokeSample ui::Stroke::randomize_sample(const glm::vec2& pos, float pressu
s.angle = (m_brush.m_tip_angle + rnd_nor() * m_brush.m_jitter_angle) * (float)(M_PI * 2.0);
s.pos = pos + (rnd_vec() * m_brush.m_jitter_spread * 100.f);
s.size = 100.f * m_brush.m_tip_size * (1.f - rnd_nor() * m_brush.m_jitter_scale);
s.flow = m_brush.m_tip_flow * (1.f - rnd_nor() * m_brush.m_jitter_flow);
s.flow = m_brush.m_tip_flow * (1.f - rnd_nor() * m_brush.m_jitter_flow) * pressure;
return s;
}
std::vector<ui::StrokeSample> ui::Stroke::compute_samples()

View File

@@ -599,9 +599,12 @@ void ui::Canvas::export_equirectangular(std::string data_path)
auto latlong_data = std::make_unique<uint8_t[]>(m_latlong.bytes());
m_latlong.readTextureData(latlong_data.get());
static char name[128];
sprintf(name, "%s/latlong.png", data_path.c_str());
sprintf(name, "%s/latlong.jpg", data_path.c_str());
LOG("writing %s", name);
int ret = stbi_write_png(name, m_latlong.getWidth(), m_latlong.getHeight(), 4, latlong_data.get(), m_latlong.stride());
jpge::params params;
params.m_quality = 100;
bool saved = jpge::compress_image_to_jpeg_file(name, m_latlong.getWidth(), m_latlong.getHeight(), 4, latlong_data.get(), params);
//int ret = stbi_write_png(name, m_latlong.getWidth(), m_latlong.getHeight(), 4, latlong_data.get(), m_latlong.stride());
}
glDeleteTextures(1, &cube_id);
@@ -626,7 +629,6 @@ void ui::Canvas::export_anim(std::string data_path)
// prepare common states
glViewport(0, 0, m_width, m_height);
glDisable(GL_BLEND);
glActiveTexture(GL_TEXTURE0);
RTT m_latlong;
m_latlong.create(m_width * 4, m_height * 2); // NOTE: w and h must be equal to make sense
@@ -646,19 +648,58 @@ void ui::Canvas::export_anim(std::string data_path)
};
for (auto layer_index : m_order)
{
glViewport(0, 0, m_width, m_height);
for (int i = 0; i < 6; i++)
{
m_layers[layer_index].m_rtt[i].bindFramebuffer();
m_tmp[i].bindFramebuffer();
m_tmp[i].clear({ 1, 1, 1, 1 });
ui::ShaderManager::use(kShader::Checkerboard);
ui::ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
m_plane.draw_fill();
// copy to tmp2 for layer blending
glActiveTexture(GL_TEXTURE0); // TODO: maybe remove this line
m_tex2[i].bind();
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_width, m_height);
m_tex2[i].unbind();
m_layers[layer_index].m_rtt[i].bindTexture();
glActiveTexture(GL_TEXTURE1);
m_tex2[i].bind();
m_sampler.bind(0);
m_sampler_bg.bind(1);
ShaderManager::use(ui::kShader::StrokeLayer);
ShaderManager::u_int(kShaderUniform::TexBG, 1);
ShaderManager::u_float(kShaderUniform::Alpha, 1);
ShaderManager::u_int(kShaderUniform::Tex, 0);
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
m_plane.draw_fill();
m_sampler.unbind();
m_sampler_bg.unbind();
m_tex2[i].unbind();
glActiveTexture(GL_TEXTURE0);
m_layers[layer_index].m_rtt[i].unbindTexture();
// copy result to cubemap
glBindTexture(GL_TEXTURE_CUBE_MAP, cube_id);
glCopyTexImage2D(faces[i], 0, GL_RGBA8, 0, 0, m_width, m_height, 0);
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
m_layers[layer_index].m_rtt[i].unbindFramebuffer();
m_tmp[i].unbindFramebuffer();
// m_layers[layer_index].m_rtt[i].bindFramebuffer();
// // copy result to cubemap
// glBindTexture(GL_TEXTURE_CUBE_MAP, cube_id);
// glCopyTexImage2D(faces[i], 0, GL_RGBA8, 0, 0, m_width, m_height, 0);
// glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
// m_layers[layer_index].m_rtt[i].unbindFramebuffer();
}
glViewport(0, 0, m_latlong.getWidth(), m_latlong.getHeight());
m_latlong.clear({ 1, 1, 1, 1 });
glActiveTexture(GL_TEXTURE0);
m_latlong.bindFramebuffer();
m_latlong.clear({ 1, 1, 1, 1 });
ui::ShaderManager::use(kShader::Equirect);
ui::ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
ui::ShaderManager::u_int(kShaderUniform::Tex, 0);
@@ -672,9 +713,12 @@ void ui::Canvas::export_anim(std::string data_path)
auto latlong_data = std::make_unique<uint8_t[]>(m_latlong.bytes());
m_latlong.readTextureData(latlong_data.get());
static char name[128];
sprintf(name, "%s/latlong-frame%02d.png", data_path.c_str(), layer_index);
sprintf(name, "%s/latlong-frame%02d.jpg", data_path.c_str(), layer_index);
LOG("writing %s", name);
int ret = stbi_write_png(name, m_latlong.getWidth(), m_latlong.getHeight(), 4, latlong_data.get(), m_latlong.stride());
//int ret = stbi_write_png(name, m_latlong.getWidth(), m_latlong.getHeight(), 4, latlong_data.get(), m_latlong.stride());
jpge::params params;
params.m_quality = 100;
bool saved = jpge::compress_image_to_jpeg_file(name, m_latlong.getWidth(), m_latlong.getHeight(), 4, latlong_data.get(), params);
}
}

View File

@@ -71,7 +71,7 @@ void CanvasModePen::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
switch (me->m_type)
{
case kEventType::MouseDownL:
canvas->stroke_start(loc, 1.f, node->m_brush);
canvas->stroke_start(loc, me->m_pressure, node->m_brush);
m_dragging = true;
node->mouse_capture();
break;
@@ -82,7 +82,7 @@ void CanvasModePen::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
break;
case kEventType::MouseMove:
if (m_dragging)
canvas->stroke_update(loc, 1.f);
canvas->stroke_update(loc, me->m_pressure);
break;
case kEventType::MouseCancel:
canvas->stroke_cancel();

View File

@@ -58,6 +58,7 @@ class MouseEvent : public Event
public:
MouseEvent() { m_cat = kEventCategory::MouseEvent; }
glm::vec2 m_pos;
float m_pressure;
float m_scroll_delta;
};

View File

@@ -202,14 +202,14 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime
{
CGLLockContext([[self openGLContext] CGLContextObj]);
auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
App::I.mouse_down(0, mouseLoc.x, App::I.height - mouseLoc.y - 1);
App::I.mouse_down(0, mouseLoc.x, App::I.height - mouseLoc.y - 1, theEvent.pressure);
CGLUnlockContext([[self openGLContext] CGLContextObj]);
}
- (void)rightMouseDown:(NSEvent *)theEvent
{
CGLLockContext([[self openGLContext] CGLContextObj]);
auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
App::I.mouse_down(1, mouseLoc.x, App::I.height - mouseLoc.y - 1);
App::I.mouse_down(1, mouseLoc.x, App::I.height - mouseLoc.y - 1, theEvent.pressure);
CGLUnlockContext([[self openGLContext] CGLContextObj]);
}
- (void)mouseUp:(NSEvent *)theEvent
@@ -230,21 +230,21 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime
{
CGLLockContext([[self openGLContext] CGLContextObj]);
auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
App::I.mouse_move(mouseLoc.x, App::I.height - mouseLoc.y - 1);
App::I.mouse_move(mouseLoc.x, App::I.height - mouseLoc.y - 1, theEvent.pressure);
CGLUnlockContext([[self openGLContext] CGLContextObj]);
}
-(void)mouseDragged:(NSEvent *)theEvent
{
CGLLockContext([[self openGLContext] CGLContextObj]);
auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
App::I.mouse_move(mouseLoc.x, App::I.height - mouseLoc.y - 1);
App::I.mouse_move(mouseLoc.x, App::I.height - mouseLoc.y - 1, theEvent.pressure);
CGLUnlockContext([[self openGLContext] CGLContextObj]);
}
- (void)rightMouseDragged:(NSEvent *)theEvent
{
CGLLockContext([[self openGLContext] CGLContextObj]);
auto mouseLoc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
App::I.mouse_move(mouseLoc.x, App::I.height - mouseLoc.y - 1);
App::I.mouse_move(mouseLoc.x, App::I.height - mouseLoc.y - 1, theEvent.pressure);
CGLUnlockContext([[self openGLContext] CGLContextObj]);
}
- (void)scrollWheel:(NSEvent *)theEvent
@@ -269,14 +269,6 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTime
auto chars = [theEvent characters];
App::I.key_up(convert_key(keyCode));
CGLUnlockContext([[self openGLContext] CGLContextObj]);
}
- (void)tabletPoint:(NSEvent *)theEvent
{
}
- (void)tabletProximity:(NSEvent *)theEvent
{
}
@end

View File

@@ -84,6 +84,8 @@
#include <glm/gtx/euler_angles.hpp>
#include <tinyxml2.h>
#include <jpge.h>
#include <jpgd.h>
#endif
#include <yoga/Yoga.h>