Skip to content

Commit

Permalink
Go back to doing autosprite2 deforms on the CPU.
Browse files Browse the repository at this point in the history
  • Loading branch information
jpcy committed Mar 7, 2016
1 parent f8b15ed commit 7d00a0c
Show file tree
Hide file tree
Showing 7 changed files with 247 additions and 124 deletions.
9 changes: 2 additions & 7 deletions code/renderer_bgfx/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -375,13 +375,8 @@ void Main::registerFont(const char *fontName, int pointSize, fontInfo_t *font)
ri.FS_FreeFile((void **)data);
}

void Main::debugPrint(const char *format, ...)
void Main::debugPrint(const char *text)
{
va_list args;
va_start(args, format);
char text[1024];
util::Vsnprintf(text, sizeof(text), format, args);
va_end(args);
bgfx::dbgTextPrintf(0, debugTextY, 0x4f, text);
debugTextY++;
}
Expand Down Expand Up @@ -989,7 +984,7 @@ void Main::renderCamera(uint8_t visCacheId, vec3 pvsPosition, vec3 position, mat
if (isWorldCamera_)
{
Sky_Render(&drawCalls_, position, visCacheId, zMax);
world::Render(&drawCalls_, visCacheId);
world::Render(sceneRotation_, &drawCalls_, visCacheId);
}

for (auto &entity : sceneEntities_)
Expand Down
2 changes: 1 addition & 1 deletion code/renderer_bgfx/Main.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class Main
void registerFont(const char *fontName, int pointSize, fontInfo_t *font);
void setColor(vec4 c) { stretchPicColor_ = c; }
void setSunLight(const SunLight &sunLight) { sunLight_ = sunLight; }
void debugPrint(const char *format, ...);
void debugPrint(const char *text);
void drawStretchPic(float x, float y, float w, float h, float s1, float t1, float s2, float t2, int materialIndex);
void drawStretchRaw(int x, int y, int w, int h, int cols, int rows, const uint8_t *data, int client, bool dirty);
void uploadCinematic(int w, int h, int cols, int rows, const uint8_t *data, int client, bool dirty);
Expand Down
10 changes: 10 additions & 0 deletions code/renderer_bgfx/Main_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,16 @@ void AddPolyToScene(qhandle_t hShader, int nVerts, const polyVert_t *verts, int
return s_main->addPolyToScene(hShader, nVerts, verts, nPolys);
}

void DebugPrint(const char *format, ...)
{
va_list args;
va_start(args, format);
char text[1024];
util::Vsnprintf(text, sizeof(text), format, args);
va_end(args);
s_main->debugPrint(text);
}

void DrawStretchPic(float x, float y, float w, float h, float s1, float t1, float s2, float t2, int materialIndex)
{
s_main->drawStretchPic(x, y, w, h, s1, t1, s2, t2, materialIndex);
Expand Down
189 changes: 112 additions & 77 deletions code/renderer_bgfx/Material_calculate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,18 @@ bool Material::hasAutoSpriteDeform() const
{
for (auto &ds : deforms)
{
if (ds.deformation == MaterialDeform::Autosprite || ds.deformation == MaterialDeform::Autosprite2)
if (ds.deformation == MaterialDeform::Autosprite)
return true;
}

return false;
}

bool Material::hasAutoSprite2Deform() const
{
for (auto &ds : deforms)
{
if (ds.deformation == MaterialDeform::Autosprite2)
return true;
}

Expand All @@ -571,112 +582,137 @@ bool Material::hasAutoSpriteDeform() const
void Material::setupAutoSpriteDeform(Vertex *vertices, uint32_t nVertices) const
{
assert(vertices);
MaterialDeform deform = MaterialDeform::None;

for (auto &ds : deforms)
if (!hasAutoSpriteDeform())
return;

if ((nVertices % 4) != 0)
{
switch (ds.deformation)
ri.Printf(PRINT_WARNING, "Autosprite material %s had odd vertex count %i\n", name, nVertices);
}

for (uint32_t quadIndex = 0; quadIndex < nVertices / 4; quadIndex++)
{
Vertex *v = &vertices[quadIndex * 4];
const vec3 midpoint = (v[0].pos + v[1].pos + v[2].pos + v[3].pos) * 0.25f;
const float radius = (v[0].pos - midpoint).length() * 0.707f; // / sqrt(2)

for (int i = 0; i < 4; i++)
{
case MaterialDeform::Autosprite:
case MaterialDeform::Autosprite2:
deform = ds.deformation;
break;
v[i].pos = midpoint;
v[i].autoSprite = vec4(0, 0, 0, radius);
}
}
}

void Material::doAutoSprite2Deform(const mat3 &sceneRotation, Vertex *vertices, uint32_t nVertices, uint16_t *indices, uint32_t nIndices) const
{
assert(vertices);

if (deform == MaterialDeform::None)
if (!hasAutoSprite2Deform())
return;

if ((nVertices % 4) != 0)
{
ri.Printf(PRINT_WARNING, "Autosprite material %s had odd vertex count %i\n", name, nVertices);
ri.Printf(PRINT_WARNING, "Autosprite2 material %s had odd vertex count %u\n", name, nVertices);
}

for (uint32_t quadIndex = 0; quadIndex < nVertices / 4; quadIndex++)
if ((nIndices % 6) != 0)
{
ri.Printf(PRINT_WARNING, "Autosprite2 material %s had odd index count %u\n", name, nIndices);
}

vec3 forward, leftDir, upDir;
forward = sceneRotation[0];
leftDir = sceneRotation[1];
upDir = sceneRotation[2];

// Iterate through triangulated quads.
for (size_t quadIndex = 0; quadIndex < nVertices / 4; quadIndex++)
{
Vertex *v = &vertices[quadIndex * 4];

// Find the midpoint.
const vec3 midpoint = (v[0].pos + v[1].pos + v[2].pos + v[3].pos) * 0.25f;
const float radius = (v[0].pos - midpoint).length() * 0.707f; // / sqrt(2)

if (deform == MaterialDeform::Autosprite)
// Store the radius for soft sprites.
for (size_t i = 0; i < nVertices; i++)
{
const float radius = (v[0].pos - midpoint).length() * 0.707f; // / sqrt(2)
v[i].autoSprite = vec4(0, 0, 0, radius);
}

const int edgeVerts[6][2] = { { 0, 1 },{ 0, 2 },{ 0, 3 },{ 1, 2 },{ 1, 3 },{ 2, 3 } };
uint16_t smallestIndex = indices[0];

for (size_t i = 0; i < nIndices; i++)
{
smallestIndex = std::min(smallestIndex, indices[i]);
}

// Identify the two shortest edges.
int nums[2] = {};
float lengths[2];
lengths[0] = lengths[1] = 999999;

for (int i = 0; i < 4; i++)
for (int i = 0; i < 6; i++)
{
const vec3 temp = vec3(v[edgeVerts[i][0]].pos) - vec3(v[edgeVerts[i][1]].pos);
const float l = vec3::dotProduct(temp, temp);

if (l < lengths[0])
{
nums[1] = nums[0];
lengths[1] = lengths[0];
nums[0] = i;
lengths[0] = l;
}
else if (l < lengths[1])
{
v[i].pos = midpoint;
v[i].autoSprite = vec4(0, 0, 0, radius);
nums[1] = i;
lengths[1] = l;
}
}
else if (deform == MaterialDeform::Autosprite2)

// Find the midpoints.
vec3 midpoints[2];

for (int i = 0; i < 2; i++)
{
const int edgeVerts[6][2] = { { 0, 1 },{ 0, 2 },{ 0, 3 },{ 1, 2 },{ 1, 3 },{ 2, 3 } };
midpoints[i] = (v[edgeVerts[nums[i]][0]].pos + v[edgeVerts[nums[i]][1]].pos) * 0.5f;
}

// Identify the two shortest edges.
int nums[2] = {};
float lengths[2];
lengths[0] = lengths[1] = 999999;
// Find the vector of the major axis.
const vec3 major(midpoints[1] - midpoints[0]);

for (int i = 0; i < 6; i++)
{
const vec3 temp = vec3(v[edgeVerts[i][0]].pos) - vec3(v[edgeVerts[i][1]].pos);
const float l = vec3::dotProduct(temp, temp);

if (l < lengths[0])
{
nums[1] = nums[0];
lengths[1] = lengths[0];
nums[0] = i;
lengths[0] = l;
}
else if (l < lengths[1])
{
nums[1] = i;
lengths[1] = l;
}
}
// Cross this with the view direction to get minor axis.
const vec3 minor(vec3::crossProduct(major, forward).normal());

// Find the midpoints.
vec3 midpoints[2];
// Re-project the points.
for (int i = 0; i < 2; i++)
{
// We need to see which direction this edge is used to determine direction of projection.
int j;

for (int i = 0; i < 2; i++)
for (j = 0; j < 5; j++)
{
midpoints[i] = (v[edgeVerts[nums[i]][0]].pos + v[edgeVerts[nums[i]][1]].pos) * 0.5f;
if (indices[j] == smallestIndex + edgeVerts[nums[i]][0] && indices[j + 1] == smallestIndex + edgeVerts[nums[i]][1])
break;
}

// Find the vector of the major axis.
const vec3 major(midpoints[1] - midpoints[0]);
const float l = 0.5f * sqrt(lengths[i]);
vec3 *v1 = &v[edgeVerts[nums[i]][0]].pos;
vec3 *v2 = &v[edgeVerts[nums[i]][1]].pos;

// Cross this with the view direction to get minor axis.
const vec3 cross(vec3::crossProduct(major, v[0].normal).normal());

// From Unvanquished Autosprite2Deform
// update the vertices
for (int j = 0; j < 4; j++)
if (j == 5)
{
*v1 = midpoints[i] + minor * l;
*v2 = midpoints[i] + minor * -l;
}
else
{
lengths[0] = vec3::distance(midpoints[0], v[j].pos);
lengths[1] = vec3::distance(midpoints[1], v[j].pos);

// pick the closer midpoint
int k;

if (lengths[0] <= lengths[1])
k = 0;
else
k = 1;

vec3 minor = v[j].pos - midpoints[k];

if (vec3::dotProduct(cross, minor) * (k ? -1.0f : 1.0f) < 0.0f)
{
v[j].autoSprite = vec4(-major, 0);
}
else
{
v[j].autoSprite = vec4(major, 0);
}

v[j].autoSprite.w = -lengths[k];
v[j].pos = midpoints[k];
*v1 = midpoints[i] + minor * -l;
*v2 = midpoints[i] + minor * l;
}
}
}
Expand All @@ -696,7 +732,6 @@ void Material::setDeformUniforms(Uniforms_Material *uniforms) const
switch (ds.deformation)
{
case MaterialDeform::Autosprite:
case MaterialDeform::Autosprite2:
autoSprite = ds.deformation;
break;

Expand Down
5 changes: 4 additions & 1 deletion code/renderer_bgfx/Precompiled.h
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ namespace main
void AddDynamicLightToScene(const DynamicLight &light);
void AddEntityToScene(const refEntity_t *entity);
void AddPolyToScene(qhandle_t hShader, int nVerts, const polyVert_t *verts, int nPolys);
void DebugPrint(const char *format, ...);
void DrawStretchPic(float x, float y, float w, float h, float s1, float t1, float s2, float t2, int materialIndex);
void DrawStretchRaw(int x, int y, int w, int h, int cols, int rows, const uint8_t *data, int client, bool dirty);
void EndFrame();
Expand Down Expand Up @@ -851,7 +852,9 @@ class Material
float setTime(float time);

bool hasAutoSpriteDeform() const;
bool hasAutoSprite2Deform() const;
void setupAutoSpriteDeform(Vertex *vertices, uint32_t nVertices) const;
void doAutoSprite2Deform(const mat3 &sceneRotation, Vertex *vertices, uint32_t nVertices, uint16_t *indices, uint32_t nIndices) const;
void setDeformUniforms(Uniforms_Material *uniforms) const;

private:
Expand Down Expand Up @@ -1502,7 +1505,7 @@ namespace world
bool CalculatePortalCamera(uint8_t visCacheId, size_t portalSurfaceIndex, vec3 mainCameraPosition, mat3 mainCameraRotation, const mat4 &mvp, const std::vector<Entity> &entities, vec3 *pvsPosition, Transform *portalCamera, bool *isMirror, vec4 *portalPlane);
uint8_t CreateVisCache();
void UpdateVisCache(uint8_t visCacheId, vec3 cameraPosition, const uint8_t *areaMask);
void Render(DrawCallList *drawCallList, uint8_t visCacheId);
void Render(const mat3 &sceneRotation, DrawCallList *drawCallList, uint8_t visCacheId);
}

static const size_t g_funcTableSize = 1024;
Expand Down
Loading

0 comments on commit 7d00a0c

Please sign in to comment.