render implement thread, wrap GL commands into tasks
This commit is contained in:
326
src/shape.cpp
326
src/shape.cpp
@@ -1,6 +1,7 @@
|
||||
#include "pch.h"
|
||||
#include "log.h"
|
||||
#include "shape.h"
|
||||
#include "app.h"
|
||||
|
||||
bool Shape::create_buffers(GLushort * idx, GLvoid * vertices, int isize, int vsize)
|
||||
{
|
||||
@@ -20,79 +21,99 @@ bool Shape::create_buffers_imp(GLvoid* idx, GLvoid* vertices, int isize, int vsi
|
||||
{
|
||||
use_idx = true;
|
||||
|
||||
destroy();
|
||||
|
||||
glGenBuffers(2, buffers);
|
||||
if (!(buffers[0] && buffers[1]))
|
||||
return false;
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, isize, idx, GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, vsize, vertices, GL_STATIC_DRAW);
|
||||
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++)
|
||||
bool ret = false;
|
||||
App::I.render_task([&]
|
||||
{
|
||||
glBindVertexArray(arrays[i]);
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glEnableVertexAttribArray(2);
|
||||
glEnableVertexAttribArray(3);
|
||||
destroy();
|
||||
|
||||
glGenBuffers(2, buffers);
|
||||
if (!(buffers[0] && buffers[1]))
|
||||
{
|
||||
ret = false;
|
||||
return;
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, isize, idx, GL_STATIC_DRAW);
|
||||
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));
|
||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (GLvoid*)offsetof(vertex_t, uvs2));
|
||||
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (GLvoid*)offsetof(vertex_t, nor));
|
||||
}
|
||||
glBindVertexArray(0);
|
||||
glBufferData(GL_ARRAY_BUFFER, vsize, vertices, GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
#if USE_VBO
|
||||
glGenVertexArrays(2, arrays);
|
||||
if (!(arrays[0] && arrays[1]))
|
||||
{
|
||||
ret = false;
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
glBindVertexArray(arrays[i]);
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glEnableVertexAttribArray(2);
|
||||
glEnableVertexAttribArray(3);
|
||||
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));
|
||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (GLvoid*)offsetof(vertex_t, uvs2));
|
||||
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (GLvoid*)offsetof(vertex_t, nor));
|
||||
}
|
||||
glBindVertexArray(0);
|
||||
#endif
|
||||
return true;
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
bool Shape::create_buffers(GLvoid* vertices, int vsize)
|
||||
{
|
||||
use_idx = false;
|
||||
|
||||
destroy();
|
||||
bool ret = false;
|
||||
App::I.render_task([&]
|
||||
{
|
||||
destroy();
|
||||
|
||||
glGenBuffers(1, buffers);
|
||||
if (!buffers[0])
|
||||
{
|
||||
ret = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (vsize)
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, vsize, vertices, GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
glGenBuffers(1, buffers);
|
||||
if (!buffers[0])
|
||||
return false;
|
||||
|
||||
if (vsize)
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, vsize, vertices, GL_STATIC_DRAW);
|
||||
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]);
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glEnableVertexAttribArray(2);
|
||||
glEnableVertexAttribArray(3);
|
||||
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));
|
||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (GLvoid*)offsetof(vertex_t, uvs2));
|
||||
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (GLvoid*)offsetof(vertex_t, nor));
|
||||
}
|
||||
glBindVertexArray(0);
|
||||
glGenVertexArrays(2, arrays);
|
||||
if (!(arrays[0] && arrays[1]))
|
||||
{
|
||||
ret = false;
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
glBindVertexArray(arrays[i]);
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glEnableVertexAttribArray(2);
|
||||
glEnableVertexAttribArray(3);
|
||||
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));
|
||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (GLvoid*)offsetof(vertex_t, uvs2));
|
||||
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (GLvoid*)offsetof(vertex_t, nor));
|
||||
}
|
||||
glBindVertexArray(0);
|
||||
#endif
|
||||
return true;
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
void Shape::draw_fill() const
|
||||
{
|
||||
@@ -103,31 +124,34 @@ void Shape::draw_fill() const
|
||||
type = GL_POINTS;
|
||||
if (count[0] == 2)
|
||||
type = GL_LINES;
|
||||
#if USE_VBO
|
||||
glBindVertexArray(arrays[0]);
|
||||
if (use_idx)
|
||||
glDrawElements(type, count[0], index_type, ioff[0]);
|
||||
else
|
||||
glDrawArrays(type, 0, count[0]);
|
||||
glBindVertexArray(0);
|
||||
#else
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(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));
|
||||
if (use_idx)
|
||||
App::I.render_task([=]
|
||||
{
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]);
|
||||
glDrawElements(type, count[0], GL_UNSIGNED_SHORT, ioff[0]);
|
||||
}
|
||||
else
|
||||
glDrawArrays(type, 0, count[0]);
|
||||
glDisableVertexAttribArray(0);
|
||||
glDisableVertexAttribArray(1);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
#if USE_VBO
|
||||
glBindVertexArray(arrays[0]);
|
||||
if (use_idx)
|
||||
glDrawElements(type, count[0], index_type, ioff[0]);
|
||||
else
|
||||
glDrawArrays(type, 0, count[0]);
|
||||
glBindVertexArray(0);
|
||||
#else
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(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));
|
||||
if (use_idx)
|
||||
{
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]);
|
||||
glDrawElements(type, count[0], GL_UNSIGNED_SHORT, ioff[0]);
|
||||
}
|
||||
else
|
||||
glDrawArrays(type, 0, count[0]);
|
||||
glDisableVertexAttribArray(0);
|
||||
glDisableVertexAttribArray(1);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
#endif // USE_VBO
|
||||
});
|
||||
}
|
||||
void Shape::draw_stroke() const
|
||||
{
|
||||
@@ -136,32 +160,61 @@ void Shape::draw_stroke() const
|
||||
GLenum type = GL_LINES;
|
||||
if (count[1] == 1)
|
||||
type = GL_POINTS;
|
||||
#if USE_VBO
|
||||
glBindVertexArray(arrays[1]);
|
||||
if (use_idx)
|
||||
glDrawElements(type, count[1], index_type, ioff[1]);
|
||||
else
|
||||
glDrawArrays(type, 0, count[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));
|
||||
if (use_idx)
|
||||
App::I.render_task([=]
|
||||
{
|
||||
#if USE_VBO
|
||||
glBindVertexArray(arrays[1]);
|
||||
if (use_idx)
|
||||
glDrawElements(type, count[1], index_type, ioff[1]);
|
||||
else
|
||||
glDrawArrays(type, 0, count[1]);
|
||||
glBindVertexArray(0);
|
||||
#else
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]);
|
||||
glDrawElements(type, count[1], GL_UNSIGNED_SHORT, ioff[1]);
|
||||
}
|
||||
else
|
||||
glDrawArrays(type, 0, count[1]);
|
||||
glDisableVertexAttribArray(0);
|
||||
glDisableVertexAttribArray(1);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
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));
|
||||
if (use_idx)
|
||||
{
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]);
|
||||
glDrawElements(type, count[1], GL_UNSIGNED_SHORT, ioff[1]);
|
||||
}
|
||||
else
|
||||
glDrawArrays(type, 0, count[1]);
|
||||
glDisableVertexAttribArray(0);
|
||||
glDisableVertexAttribArray(1);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
#endif // USE_VBO
|
||||
});
|
||||
}
|
||||
|
||||
void Shape::destroy()
|
||||
{
|
||||
App::I.render_task_async([b1=buffers[0],b2=buffers[1],a1=arrays[0],a2=arrays[1]]
|
||||
{
|
||||
if (b1 || b2)
|
||||
{
|
||||
glDeleteBuffers(1, &b1);
|
||||
glDeleteBuffers(1, &b2);
|
||||
}
|
||||
#if USE_VBO
|
||||
if (a1 || a2)
|
||||
{
|
||||
glDeleteVertexArrays(1, &a1);
|
||||
glDeleteVertexArrays(1, &a2);
|
||||
}
|
||||
#endif // USE_VBO
|
||||
});
|
||||
buffers[0] = buffers[1] = 0;
|
||||
arrays[0] = arrays[1] = 0;
|
||||
}
|
||||
|
||||
Shape::~Shape()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
bool RectShape::create(float w, float h)
|
||||
@@ -437,21 +490,24 @@ void Plane::update_vertices(const glm::vec4* data, const glm::vec2* uvs, const g
|
||||
vertices[i].pos.z = q;
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||
static GLushort idx[6 + 8]{
|
||||
0, 1, 2,
|
||||
0, 2, 3,
|
||||
0, 1,
|
||||
1, 2,
|
||||
2, 3,
|
||||
3, 0,
|
||||
};
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(idx), idx, GL_STATIC_DRAW);
|
||||
App::I.render_task([this]
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||
static GLushort idx[6 + 8]{
|
||||
0, 1, 2,
|
||||
0, 2, 3,
|
||||
0, 1,
|
||||
1, 2,
|
||||
2, 3,
|
||||
3, 0,
|
||||
};
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(idx), idx, GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
});
|
||||
}
|
||||
void Circle::create_impl(float radius, int div, GLushort* idx, vertex_t* vertices)
|
||||
{
|
||||
@@ -704,18 +760,24 @@ void Sphere::create_impl(int rings, int sectors, float radius,
|
||||
}
|
||||
void LineSegment::update_vertices(const glm::vec4 data[2])
|
||||
{
|
||||
static vertex_t vertices[2];
|
||||
vertices[0] = { data[0], { 0, 0 } }; // A
|
||||
vertices[1] = { data[1], { 0, 1 } }; // B
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
App::I.render_task([&]
|
||||
{
|
||||
static vertex_t vertices[2];
|
||||
vertices[0] = { data[0], { 0, 0 } }; // A
|
||||
vertices[1] = { data[1], { 0, 1 } }; // B
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
});
|
||||
}
|
||||
void DynamicShape::update_vertices(vertex_t* vertices, int vcount)
|
||||
{
|
||||
count[0] = vcount;
|
||||
count[1] = vcount;
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_t) * vcount, vertices, GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
App::I.render_task([&]
|
||||
{
|
||||
count[0] = vcount;
|
||||
count[1] = vcount;
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_t) * vcount, vertices, GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user