-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathopenglapp_simple_brush.h
162 lines (126 loc) · 5.37 KB
/
openglapp_simple_brush.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#ifndef OPENGLAPP_SIMPLEIMAGEEDITOR_H
#define OPENGLAPP_SIMPLEIMAGEEDITOR_H
#include "application.h"
#include "graphics/gl_shader.h"
#include "graphics/visualobject.h"
#include "graphics/gl_rendermanager.h"
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/string_cast.hpp>
namespace fs = std::filesystem;
static fs::path projectDir(PROJECT_DIR);
static const std::string shaderBrush_VS = R"(
#version 330 core
layout(location = 0) in vec3 position;
layout(location = 1) in vec2 uv;
out VS_OUT
{
vec2 brushUV;
vec2 imageUV;
}
vs;
uniform mat4 cameraView;
uniform mat4 modelWorld;
uniform mat4 imageViewMatrix;
void main()
{
vec4 pos = vec4(position, 1);
gl_Position = cameraView * modelWorld * pos;
vs.brushUV = uv;
vs.imageUV = (imageViewMatrix * modelWorld * pos).xy;
vs.imageUV = vs.imageUV * 0.5 + 0.5;
}
)";
static const std::string shaderBrush_FS = R"(
#version 330 core
out vec4 FragColor;
// uniform vec4 color;
uniform sampler2D backgroundTexture;
in VS_OUT
{
vec2 brushUV;
vec2 imageUV;
}
vs;
void main()
{
vec4 imageColor = texture2D(backgroundTexture, vs.imageUV);
FragColor = imageColor;
}
)";
class OpenGLApp2D : public Application {
VisualObjectSprite2D m_spriteImage, m_spriteBrush;
GLFrameBuffer m_frameBufferImage;
GLShader m_shaderDefault2d, m_shaderBrush;
CameraOrtho m_cameraView;
CameraRect m_cameraImage;
const float m_brushRadius = 30;
const float m_imageHalfSize = 512;
public:
void init() override
{
m_cameraView.setViewportSize(m_window.getSize());
m_cameraView.setScale(1.f);
///////////////////////////////////////////////////
addFileInteractionInfo("Primary", "png,jpg", nullptr, nullptr);
// open file
m_window.addKeyDownEvent(SDLK_o, KMOD_CTRL,
std::bind(&Application::openFileDialog, this, "Primary"));
// save file
m_window.addKeyDownEvent(SDLK_s, KMOD_CTRL,
std::bind(&Application::saveFileOptionalDialog, this, "Primary", false));
// save file as
m_window.addKeyDownEvent(SDLK_s, KMOD_CTRL | KMOD_SHIFT,
std::bind(&Application::saveFileOptionalDialog, this, "Primary", true));
///////////////////////////////////////////////////
m_window.setMouseScrollEvent( // zoom on scroll
[this](float diff, glm::ivec2 mousePos) {
float scaleFactor = pow(1.1f, -diff);
m_cameraView.multiplyScaleOffseted(scaleFactor, mousePos);
});
m_window.setMouseDragEvent(MouseButton::Middle, // drag on MMB
[this](glm::ivec2 startPos, glm::ivec2 currentPos, glm::ivec2 currentDelta, DragState dragState) {
m_cameraView.addOffset_View(glm::vec2(-currentDelta));
});
m_window.setMouseDragEvent(MouseButton::Left, // drag on MMB
[this](glm::ivec2 startPos, glm::ivec2 currentPos, glm::ivec2 currentDelta, DragState dragState) {
GLRenderManager::draw(&m_frameBufferImage, &m_shaderBrush, &m_cameraImage, &m_spriteBrush);
});
m_window.setMouseMoveEvent(MouseButton::Left,
[this](glm::ivec2 currentScreenPos, glm::ivec2 delta) {
glm::vec2 normalizedScreenPos = m_window.toNormalizedPos(currentScreenPos, true);
glm::vec2 spritePosWorld = glm::inverse(m_cameraView.getViewMatrix()) * glm::vec4(normalizedScreenPos, 0.f, 1.f);
m_spriteBrush.setPos(spritePosWorld);
});
m_window.setScreenResizeEvent( // window resize
[this](glm::ivec2 oldSize, glm::ivec2 newSize) {
m_cameraView.setViewportSize(glm::vec2(newSize));
});
m_window.setClearColor({ .13f, .14f, .15f, 1.f });
m_shaderDefault2d = GLShader::FromFile("default2d.vert", "default2d.frag");
m_shaderBrush = GLShader(shaderBrush_VS, shaderBrush_FS);
m_frameBufferImage.create({ 2048, 2048 }, TexelFormat::RGBA_8);
m_frameBufferImage.getTexture()->setFiltering(GLTexture2D::Filtering::LinearMipmap);
m_frameBufferImage.getTexture()->setWrapping(GLTexture2D::Wrapping::ClampEdge);
m_frameBufferImage.setClearColor({ .23f, .24f, .25f, 1.f });
glm::vec4 imageRect(-m_imageHalfSize, -m_imageHalfSize, m_imageHalfSize, m_imageHalfSize);
m_spriteImage.setRectSize(imageRect);
m_spriteImage.setUniform("texture0", m_frameBufferImage.getTexture());
m_cameraImage.setViewRect(imageRect);
m_spriteBrush.setRectSize(glm::vec2(-m_brushRadius), glm::vec2(m_brushRadius));
m_spriteBrush.setUniform("color", glm::vec4(0, 1, 0, 1));
auto texLiza = std::make_shared<GLTexture2D>(Image(projectDir / "resources" / "mona_liza.jpg"));
texLiza->setWrapping(GLTexture2D::Wrapping::ClampEdge);
m_spriteBrush.setUniform("backgroundTexture", texLiza);
m_spriteBrush.setUniform("imageViewMatrix", (m_cameraImage.getViewMatrix()));
// m_spriteBrush.setUniform("imageViewMatrix", glm::inverse(m_spriteImage.getModelMatrix()));
}
void updateWindow(float dt) override
{
m_window.clear();
GLRenderManager::draw(&m_window, &m_shaderDefault2d, &m_cameraView, &m_spriteImage);
GLRenderManager::draw(&m_window, &m_shaderBrush, &m_cameraView, &m_spriteBrush);
}
};
typedef OpenGLApp2D App;
#endif // OPENGLAPP_SIMPLEIMAGEEDITOR_H