A little clean up

This commit is contained in:
Ilusha 2024-03-17 21:44:19 +03:00 committed by IlyaShurupov
parent 0f6fa035aa
commit 11402f577a
8 changed files with 234 additions and 407 deletions

View file

@ -3,72 +3,74 @@
using namespace tp;
Stroke::GLHandles::GLHandles() {
StrokeGPUHandles::StrokeGPUHandles() {
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
glGenBuffers(1, &vertexbuffer);
}
void Stroke::GLHandles::sendDataToGPU(tp::Buffer<Point>* mPoints) {
void StrokeGPUHandles::sendDataToGPU(Buffer<StrokePoint>* mPoints) {
glBindVertexArray(VertexArrayID);
vbo_len = mPoints->size();
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(mPoints[0]) * vbo_len, mPoints->getBuff(), GL_STATIC_DRAW);
}
Stroke::GLHandles::~GLHandles() {
StrokeGPUHandles::~StrokeGPUHandles() {
glDeleteBuffers(1, &vertexbuffer);
glDeleteVertexArrays(1, &VertexArrayID);
}
Stroke::Stroke() {}
Stroke::Stroke() = default;
tp::Buffer<Stroke::Point>& Stroke::buff() {
return mPoints;
}
Buffer<StrokePoint>& Stroke::getPoints() { return mPoints; }
void Stroke::updateGpuBuffers() {
mGl.sendDataToGPU(&mPoints);
}
const Buffer<StrokePoint>& Stroke::getPoints() const { return mPoints; }
void Stroke::denoisePos(tp::halni passes) {
for (auto pass : tp::Range(passes)) {
for (auto pi : tp::Range(mPoints.size() - 2)) {
void Stroke::setColor(const RGBA& col) { mColor = col; }
const RGBA& Stroke::getColor() const { return mColor; }
void Stroke::updateGpuBuffers() { mGPUHandles.sendDataToGPU(&mPoints); }
void Stroke::denoisePos(halni passes) {
for (auto pass : Range(passes)) {
for (auto pi : Range(mPoints.size() - 2)) {
mPoints[pi + 1].pos = (mPoints[pi + 1].pos + mPoints[pi].pos + mPoints[pi + 2].pos) / 3.f;
}
}
}
void Stroke::denoiseThickness(tp::halni passes) {
for (auto pass : tp::Range(passes)) {
for (auto pi : tp::Range(mPoints.size() - 2)) {
void Stroke::denoiseThickness(halni passes) {
for (auto pass : Range(passes)) {
for (auto pi : Range(mPoints.size() - 2)) {
mPoints[pi + 1].thickness = (mPoints[pi].thickness + mPoints[pi + 2].thickness) / 2.f;
}
}
}
void Stroke::compress(tp::halnf factor) {
void Stroke::compress(halnf factor) {
if (mPoints.size() < 3) {
return;
}
tp::List<Point> passed_poits;
List<StrokePoint> passed_poits;
for (auto idx : tp::Range(mPoints.size())) {
for (auto idx : Range(mPoints.size())) {
passed_poits.pushBack(mPoints[idx]);
}
tp::List<Point>::Node* min_node = NULL;
List<StrokePoint>::Node* min_node = NULL;
do {
min_node = NULL;
tp::halnf min_factor = factor;
halnf min_factor = factor;
tp::List<Point>::Node* iter = passed_poits.first()->next;
List<StrokePoint>::Node* iter = passed_poits.first()->next;
for (; iter->next; iter = iter->next) {
tp::Vec3F dir1 = (iter->data.pos - iter->prev->data.pos).normalize();
tp::Vec3F dir2 = (iter->next->data.pos - iter->data.pos).normalize();
tp::halnf factor = 1 - dir1.dot(dir2);
Vec3F dir1 = (iter->data.pos - iter->prev->data.pos).normalize();
Vec3F dir2 = (iter->next->data.pos - iter->data.pos).normalize();
halnf factor = 1 - dir1.dot(dir2);
if (factor < min_factor) {
min_node = iter;
@ -83,29 +85,30 @@ void Stroke::compress(tp::halnf factor) {
mPoints.reserve(passed_poits.length());
tp::ualni idx = 0;
ualni idx = 0;
for (auto point : passed_poits) {
mPoints[idx] = point.data();
idx++;
}
}
void Stroke::subdiv(tp::halnf precision, tp::Camera* cam, tp::halni passes) {
void Stroke::subdiv(halnf precision, const Camera* cam, halni passes) {
// TODO
if (mPoints.size() < 4) {
return;
}
tp::List<Point> new_points;
for (auto idx : tp::Range(mPoints.size())) {
List<StrokePoint> new_points;
for (auto idx : Range(mPoints.size())) {
new_points.pushBack(mPoints[idx]);
}
auto viewmat = cam->calculateViewMatrix();
auto projmat = cam->calculateProjectionMatrix();
for (auto i : tp::Range(passes)) {
for (auto i : Range(passes)) {
auto n_points = new_points.length();
@ -129,9 +132,9 @@ void Stroke::subdiv(tp::halnf precision, tp::Camera* cam, tp::halni passes) {
auto const ab = a.dot(b);
auto const la = l.dot(a);
auto const lb = l.dot(b);
tp::Vec3F mid;
Vec3F mid;
if (1 - tp::abs(ab) < 0.001f) {
if (1 - abs(ab) < 0.001f) {
goto SKIP;
}
@ -189,7 +192,7 @@ void Stroke::subdiv(tp::halnf precision, tp::Camera* cam, tp::halni passes) {
if (new_points.length() != mPoints.size()) {
mPoints.reserve(new_points.length());
tp::ualni idx = 0;
ualni idx = 0;
for (auto point : new_points) {
mPoints[idx] = point.data();
idx++;
@ -201,11 +204,11 @@ PencilBrush::PencilBrush() {
mType = "pencil";
}
void PencilBrush::unsureReady(Stroke* stroke, tp::Camera* cam, bool debug) {
if (stroke->buff().size() == 1) {
auto new_point = stroke->buff()[0];
void PencilBrush::ensureReady(Stroke* stroke, const Camera* cam, bool debug) const {
if (stroke->getPoints().size() == 1) {
auto new_point = stroke->getPoints()[0];
new_point.pos += 0.00001f;
stroke->buff().append(new_point);
stroke->getPoints().append(new_point);
}
if (mEnableCompression && !debug) {
@ -217,24 +220,24 @@ void PencilBrush::unsureReady(Stroke* stroke, tp::Camera* cam, bool debug) {
stroke->updateGpuBuffers();
}
void PencilBrush::sample(Project* proj, tp::Vec2F crs, tp::halnf pressure) {
void PencilBrush::sample(Project* proj, Vec2F crs, halnf pressure) {
if (proj->mActiveLayer == -1) {
return;
}
bool max_level = mStroke && mStroke->mPoints.size() > mMaxPoints;
bool max_level = mStroke && mStroke->getPoints().size() > mMaxPoints;
if (!pressure || max_level) {
if (mStroke) {
unsureReady(mStroke, &proj->mCamera);
ensureReady(mStroke, &proj->mCamera);
proj->mLayers[proj->mActiveLayer]->strokes.pushBack(mStroke);
mStroke = NULL;
}
if (max_level) {
mStroke = new Stroke();
mStroke->mCol = mCol;
mStroke->setColor(mCol);
mStroke->mPoints.append(proj->mLayers[proj->mActiveLayer]->strokes.last()->data->mPoints.last());
mStroke->getPoints().append(proj->mLayers[proj->mActiveLayer]->strokes.last()->data->getPoints().last());
}
if (!pressure) {
@ -245,8 +248,8 @@ void PencilBrush::sample(Project* proj, tp::Vec2F crs, tp::halnf pressure) {
auto thickness = pressure * (proj->mCamera.project({ 0.f, 0.f }) - proj->mCamera.project({ mSize, 0.f })).length();
bool point_passed = true;
if (mStroke && mStroke->buff().size()) {
auto last_point_2d = proj->mCamera.project(mStroke->buff().last().pos);
if (mStroke && mStroke->getPoints().size()) {
auto last_point_2d = proj->mCamera.project(mStroke->getPoints().last().pos);
point_passed = (crs - last_point_2d).length() > mPrecision;
}
@ -256,21 +259,24 @@ void PencilBrush::sample(Project* proj, tp::Vec2F crs, tp::halnf pressure) {
if (!mStroke) {
mStroke = new Stroke();
mStroke->mCol = mCol;
mStroke->setColor(mCol);
}
auto point_coords = proj->mCamera.project(crs);
mStroke->buff().append({ point_coords, (tp::halnf) thickness });
mStroke->updateGpuBuffers();
mStroke->getPoints().append({ point_coords, (halnf) thickness });
// mStroke->updateGpuBuffers();
}
void PencilBrush::draw(Renderer* render, tp::Camera* camera) {
void PencilBrush::draw(Renderer* render, const Camera* camera) const {
if (mStroke) {
if (mEnableCompression) {
mShowStroke.buff() = mStroke->buff();
mShowStroke.mCol = mStroke->mCol;
unsureReady(&mShowStroke, camera, 0);
render->drawStroke(&mShowStroke, camera);
Stroke tempDisplayStroke;
tempDisplayStroke.getPoints() = mStroke->getPoints();
tempDisplayStroke.setColor(mStroke->getColor());
ensureReady(&tempDisplayStroke, camera, 0);
render->drawStroke(&tempDisplayStroke, camera);
} else {
render->drawStroke(mStroke, camera);
}
@ -281,7 +287,7 @@ PencilBrush::~PencilBrush() {
if (mStroke) delete mStroke;
}
Project::Layer::~Layer() {
Layer::~Layer() {
for (auto str : strokes) {
delete str.data();
}
@ -301,7 +307,7 @@ Project::Project() {
mActiveBrush = "pencil";
Stroke* debug = new Stroke();
debug->mPoints = { { { 0, 0, 0 }, 1 }, { { 1, 1, 1 } , 1} };
debug->getPoints() = { { { 0, 0, 0 }, 1 }, { { 1, 1, 1 }, 1 } };
debug->updateGpuBuffers();
mLayers.last()->strokes.pushBack(debug);
@ -311,17 +317,34 @@ Project::Project() {
vec = mCamera.project({1, 0, 0});
}
void Project::sample(halnf pressure, halnf cameraRatio, Vec2F relativeCameraPos) {
mCamera.setRatio(cameraRatio);
auto idx = mBrushes.presents(mActiveBrush);
if (idx) {
auto brush = mBrushes.getSlotVal(idx);
if (brush->mType == "pencil") {
((tp::PencilBrush*) brush)->mCol = RGBA(1.f);
}
brush->sample(this, relativeCameraPos, pressure);
}
}
Project::~Project() {
for (auto brush : mBrushes) {
delete brush->val;
}
}
Renderer::Renderer(tp::Vec2F size) :
Renderer::Renderer(Vec2F size) :
mBuffer(size, 4),
mBufferDowncast(size),
mShader(".\\rsc\\shaders\\stroke.vert", ".\\rsc\\shaders\\stroke.geom", ".\\rsc\\shaders\\stroke.frag")
{
mMaxSize = size;
mMatrixUniform = mShader.getu("MVP");
mColorUniform = mShader.getu("Color");
mRatioUniform = mShader.getu("Ratio");
@ -329,16 +352,40 @@ Renderer::Renderer(tp::Vec2F size) :
mBGColUniform = mShader.getu("BGCol");
}
void Renderer::renderToTexture(const Project* project, Vec2F size) {
size.clamp({ 1, 1 }, mMaxSize);
setViewport({ 0, 0, size.x, size.y });
setClearCol(project->mBackgroundColor);
renderBegin();
for (auto lay : project->mLayers) {
if (lay.data()->enabled) {
for (auto str : lay.data()->strokes) {
drawStroke(str.data(), &project->mCamera);
}
}
}
auto idx = project->mBrushes.presents(project->mActiveBrush);
if (idx) {
auto brush = project->mBrushes.getSlotVal(idx);
brush->draw(this, &project->mCamera);
}
renderEnd();
}
void Renderer::renderBegin() {
mBuffer.beginDraw();
mBuffer.clear();
}
void Renderer::setViewport(tp::RectF viewport) {
void Renderer::setViewport(RectF viewport) {
mBuffer.setViewport(viewport);
}
void Renderer::drawStroke(Stroke* str, tp::Camera* camera) {
void Renderer::drawStroke(const Stroke* str, const Camera* camera) {
//return;
glEnable(GL_DEPTH_TEST);
@ -347,30 +394,30 @@ void Renderer::drawStroke(Stroke* str, tp::Camera* camera) {
GLint val;
glGetIntegerv(GL_SAMPLES, &val);
glBindVertexArray(str->mGl.VertexArrayID);
glBindVertexArray(str->mGPUHandles.VertexArrayID);
mShader.bind();
auto cam_mat = camera->calculateTransformationMatrix().transpose();
glUniformMatrix4fv(mMatrixUniform, 1, GL_FALSE, &cam_mat[0][0]);
glUniform4fv(mColorUniform, 1, &str->mCol.r);
glUniform4fv(mColorUniform, 1, &str->mColor.r);
glUniform4fv(mBGColUniform, 1, &mBuffer.mClearCol.r);
auto ratio = camera->getRatio();
glUniform1fv(mRatioUniform, 1, &ratio);
auto target = tp::halnf(((camera->getTarget() - camera->getPos()).length() - camera->getNear())
auto target = halnf(((camera->getTarget() - camera->getPos()).length() - camera->getNear())
/ (camera->getFar() - camera->getNear()));
glUniform1fv(mTargetUniform, 1, &target);
// 1st attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, str->mGl.vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, str->mGPUHandles.vertexbuffer);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, (void*)0);
glDrawArrays(GL_LINE_STRIP, 0, str->mGl.vbo_len);
glDrawArrays(GL_LINE_STRIP, 0, str->mGPUHandles.vbo_len);
glDisableVertexAttribArray(0);
@ -393,15 +440,15 @@ void Renderer::renderEnd() {
mBufferDowncast.endDraw();
}
tp::uhalni Renderer::getTextudeId() {
uhalni Renderer::getTextudeId() {
return mBufferDowncast.texId();
}
tp::RenderBuffer* Renderer::getBuff() {
RenderBuffer* Renderer::getBuff() {
return &mBufferDowncast;
}
void Renderer::setClearCol(tp::RGBA col) {
void Renderer::setClearCol(RGBA col) {
mBuffer.mClearCol = col;
mBufferDowncast.mClearCol = col;
}