add uv layout type for Circle shape

This commit is contained in:
Omar Mohamed Ali Mudhir
2017-01-17 20:02:15 +00:00
parent d5fed78bf5
commit f1e6fb7716
3 changed files with 32 additions and 21 deletions

View File

@@ -55,10 +55,10 @@ void App::init()
shader_color.create(shader_color_v, shader_color_f);
shader_uv.create(shader_v, shader_uv_f);
plane.create<5>(50, 50);
circle.create<6>(25);
circle2.create<15>(25, 12);
circle.create<10>(25, Circle::kUVMapping::Tube);
circle2.create<10>(25, 12, Circle::kUVMapping::Tube);
rounded.create<3>(50, 50, 10);
slice.create(50, 50, 10);
slice.create(50, 50, 10, .3);
if (!tex.load("data/uvs.jpg"))
printf("error loading image\n");

View File

@@ -94,7 +94,7 @@ void Plane::create_impl(float w, float h, int div, GLushort *idx, Shape::vertex_
*idx++ = 0; // A
}
void Circle::create_impl(float radius, int div, GLushort* idx, Shape::vertex_t* vertices)
void Circle::create_impl(float radius, int div, GLushort* idx, vertex_t* vertices, kUVMapping map)
{
count[0] = div * 3;
count[1] = div * 2;
@@ -109,7 +109,7 @@ void Circle::create_impl(float radius, int div, GLushort* idx, Shape::vertex_t*
float theta = (float)i / div * M_PI * 2.f;
glm::vec2 uv = { sinf(theta), cosf(theta) };
v.pos = glm::vec4(uv * radius, 0, 1);
v.uvs = uv * 0.5f + 0.5f;
v.uvs = (map == kUVMapping::Planar) ? (uv * 0.5f + 0.5f) : glm::vec2((float)i / div, 1.f);
vertices[i+1] = v;
*pidx++ = 0;
@@ -120,10 +120,10 @@ void Circle::create_impl(float radius, int div, GLushort* idx, Shape::vertex_t*
*pidx2++ = 1 + ((i+1) % div);
}
vertices[0].pos = { 0, 0, 0, 1 };
vertices[0].uvs = { 0.5f, 0.5f };
vertices[0].uvs = (map == kUVMapping::Planar) ? glm::vec2(0.5f, 0.5f) : glm::vec2(0.f, 0.f);
}
void Circle::create_impl(float radius_out, float radius_in, int div, GLushort* idx, Shape::vertex_t* vertices)
void Circle::create_impl(float radius_out, float radius_in, int div, GLushort* idx, vertex_t* vertices, kUVMapping map)
{
count[0] = div * 6;
count[1] = div * 4;
@@ -134,12 +134,20 @@ void Circle::create_impl(float radius_out, float radius_in, int div, GLushort* i
auto pidx2 = idx + count[0];
for (int i = 0; i < div; i++)
{
float theta = (float)i / div * M_PI * 2.f;
float theta = (float)(i%(div-1)) / (div-1) * M_PI * 2.f;
glm::vec2 uv = { sinf(theta), cosf(theta) };
if (map == kUVMapping::Planar)
{
vertices[i*2].uvs = uv * (radius_in/radius_out) * 0.5f + 0.5f;
vertices[i*2+1].uvs = uv * 0.5f + 0.5f;
}
else
{
vertices[i*2].uvs = { (float)i / div, 0.f };
vertices[i*2+1].uvs = { (float)i / div, 1.f};
}
vertices[i*2].pos = glm::vec4(uv * radius_in, 0, 1);
vertices[i*2].uvs = uv * (radius_in/radius_out) * 0.5f + 0.5f;
vertices[i*2+1].pos = glm::vec4(uv * radius_out, 0, 1);
vertices[i*2+1].uvs = uv * 0.5f + 0.5f;
*pidx++ = i*2; // A
*pidx++ = i*2+1; // B
@@ -237,7 +245,7 @@ void Rounded::create_impl(float w, float h, float r, int div, GLushort* idx, GLu
*idx2++ = 2;
}
void Slice9::create_impl(float w, float h, float r, GLushort *idx, Shape::vertex_t *vertices)
void Slice9::create_impl(float w, float h, float r, float tr, GLushort *idx, Shape::vertex_t *vertices)
{
count[0] = 3 * 3 * 6;
count[1] = 4 * 2;
@@ -246,9 +254,10 @@ void Slice9::create_impl(float w, float h, float r, GLushort *idx, Shape::vertex
float X[] = { -w/2, -w/2+r, w/2-r, w/2 };
float Y[] = { -h/2, -h/2+r, h/2-r, h/2 };
float T[] = { 0, tr, 1-tr, 1 };
auto V = [&](int x, int y) -> Shape::vertex_t {
return { glm::vec4(X[x], Y[y], 0, 1), glm::vec2(X[x]/w, Y[y]/h) + 0.5f };
return { glm::vec4(X[x], Y[y], 0, 1), glm::vec2(T[x], T[y]) };
};
for (int y = 0; y < 4; y++)

View File

@@ -30,25 +30,27 @@ public:
class Circle : public Shape
{
void create_impl(float radius, int div, GLushort* idx, vertex_t* vertices);
void create_impl(float radius_out, float radius_in, int div, GLushort* idx, vertex_t* vertices);
public:
enum class kUVMapping: uint8_t { Planar, Tube };
template<int div>
bool create(float radius)
bool create(float radius, kUVMapping map)
{
static GLushort idx[div * 3 + div * 2];
static vertex_t vertices[div + 1];
create_impl(radius, div, idx, vertices);
create_impl(radius, div, idx, vertices, map);
return create_buffers(idx, vertices, sizeof(idx), sizeof(vertices));
}
template<int div>
bool create(float radius_out, float radius_in)
bool create(float radius_out, float radius_in, kUVMapping map)
{
static GLushort idx[div*6 + div*4];
static vertex_t vertices[div * 2];
create_impl(radius_out, radius_in, div, idx, vertices);
create_impl(radius_out, radius_in, div, idx, vertices, map);
return create_buffers(idx, vertices, sizeof(idx), sizeof(vertices));
}
private:
void create_impl(float radius, int div, GLushort* idx, vertex_t* vertices, kUVMapping map);
void create_impl(float radius_out, float radius_in, int div, GLushort* idx, vertex_t* vertices, kUVMapping map);
};
class Rounded : public Shape
@@ -68,13 +70,13 @@ public:
class Slice9 : public Shape
{
void create_impl(float w, float h, float r, GLushort* idx, vertex_t* vertices);
void create_impl(float w, float h, float r, float tr, GLushort* idx, vertex_t* vertices);
public:
bool create(float w, float h, float r)
bool create(float w, float h, float r, float tr)
{
static GLushort idx[3 * 3 * 6 + 4 * 2];
static vertex_t vertices[4 * 4];
create_impl(w, h, r, idx, vertices);
create_impl(w, h, r, tr, idx, vertices);
return create_buffers(idx, vertices, sizeof(idx), sizeof(vertices));
}
};