mirror of
https://github.com/wiiu-env/Flappy-Bird_GX2.git
synced 2024-09-29 07:08:40 +02:00
322 lines
14 KiB
C++
322 lines
14 KiB
C++
|
#include "GameIcon.h"
|
||
|
#include "GameIconModel.h"
|
||
|
#include "Application.h"
|
||
|
#include "video/CVideo.h"
|
||
|
#include "video/shaders/Shader3D.h"
|
||
|
#include "video/shaders/ShaderFractalColor.h"
|
||
|
|
||
|
static const f32 cfIconMirrorScale = 1.15f;
|
||
|
static const f32 cfIconMirrorAlpha = 0.45f;
|
||
|
|
||
|
GameIcon::GameIcon(const std::string & filename, GuiImageData *preloadImage)
|
||
|
: GuiImageAsync(filename, preloadImage)
|
||
|
{
|
||
|
bSelected = false;
|
||
|
bRenderStroke = true;
|
||
|
bRenderReflection = false;
|
||
|
bIconLast = false;
|
||
|
strokeFractalEnable = 1;
|
||
|
strokeBlurBorder = 0.0f;
|
||
|
distanceFadeout = 0.0f;
|
||
|
rotationX = 0.0f;
|
||
|
reflectionAlpha = 0.4f;
|
||
|
strokeWidth = 2.35f;
|
||
|
colorIntensity = glm::vec4(1.0f);
|
||
|
colorIntensityMirror = colorIntensity;
|
||
|
alphaFadeOutNorm = glm::vec4(0.0f);
|
||
|
alphaFadeOutRefl = glm::vec4(-1.0f, 0.0f, 0.9f, 1.0f);
|
||
|
selectionBlurOuterColorIntensity = glm::vec4(0.09411764f * 1.15f, 0.56862745f * 1.15f, 0.96862745098f * 1.15f, 1.0f);
|
||
|
selectionBlurOuterSize = 1.65f;
|
||
|
selectionBlurOuterBorderSize = 0.5f;
|
||
|
selectionBlurInnerColorIntensity = glm::vec4(0.46666667f, 0.90588235f, 1.0f, 1.0f);
|
||
|
selectionBlurInnerSize = 1.45f;
|
||
|
selectionBlurInnerBorderSize = 0.95f;
|
||
|
|
||
|
vtxCount = sizeof(cfGameIconPosVtxs) / (Shader3D::cuVertexAttrSize);
|
||
|
|
||
|
//! texture and vertex coordinates
|
||
|
posVtxs = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, sizeof(cfGameIconPosVtxs));
|
||
|
texCoords = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, sizeof(cfGameIconTexCoords));
|
||
|
|
||
|
if(posVtxs)
|
||
|
{
|
||
|
memcpy((f32*)posVtxs, cfGameIconPosVtxs, sizeof(cfGameIconPosVtxs));
|
||
|
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, (f32*)posVtxs, sizeof(cfGameIconPosVtxs));
|
||
|
}
|
||
|
if(texCoords)
|
||
|
{
|
||
|
memcpy((f32*)texCoords, cfGameIconTexCoords, sizeof(cfGameIconTexCoords));
|
||
|
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, (f32*)texCoords, sizeof(cfGameIconTexCoords));
|
||
|
}
|
||
|
|
||
|
//! create vertexes for the mirror frame
|
||
|
texCoordsMirror = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, sizeof(cfGameIconTexCoords));
|
||
|
|
||
|
if(texCoordsMirror)
|
||
|
{
|
||
|
for(u32 i = 0; i < vtxCount; i++)
|
||
|
{
|
||
|
texCoordsMirror[i*2 + 0] = texCoords[i*2 + 0] * cfIconMirrorScale - ((cfIconMirrorScale - 1.0f) - (cfIconMirrorScale - 1.0f) * 0.5f);
|
||
|
texCoordsMirror[i*2 + 1] = texCoords[i*2 + 1] * cfIconMirrorScale - ((cfIconMirrorScale - 1.0f) - (cfIconMirrorScale - 1.0f) * 0.5f);
|
||
|
}
|
||
|
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, texCoordsMirror, sizeof(cfGameIconTexCoords));
|
||
|
}
|
||
|
|
||
|
//! setup stroke of the icon
|
||
|
strokePosVtxs = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, sizeof(cfGameIconStrokeVtxs));
|
||
|
if(strokePosVtxs)
|
||
|
{
|
||
|
memcpy(strokePosVtxs, cfGameIconStrokeVtxs, sizeof(cfGameIconStrokeVtxs));
|
||
|
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, strokePosVtxs, sizeof(cfGameIconStrokeVtxs));
|
||
|
}
|
||
|
strokeTexCoords = (f32*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, cuGameIconStrokeVtxCount * Shader::cuTexCoordAttrSize);
|
||
|
if(strokeTexCoords)
|
||
|
{
|
||
|
for(size_t i = 0, n = 0; i < cuGameIconStrokeVtxCount; n += 2, i += 3)
|
||
|
{
|
||
|
strokeTexCoords[n] = (1.0f + strokePosVtxs[i]) * 0.5f;
|
||
|
strokeTexCoords[n+1] = 1.0f - (1.0f + strokePosVtxs[i+1]) * 0.5f;
|
||
|
}
|
||
|
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, strokeTexCoords, cuGameIconStrokeVtxCount * Shader::cuTexCoordAttrSize);
|
||
|
}
|
||
|
strokeColorVtxs = (u8*)memalign(GX2_VERTEX_BUFFER_ALIGNMENT, cuGameIconStrokeVtxCount * Shader::cuColorAttrSize);
|
||
|
if(strokeColorVtxs)
|
||
|
{
|
||
|
for(size_t i = 0; i < (cuGameIconStrokeVtxCount * Shader::cuColorAttrSize); i++)
|
||
|
strokeColorVtxs[i] = 0xff;
|
||
|
GX2Invalidate(GX2_INVALIDATE_CPU_ATTRIB_BUFFER, strokeColorVtxs, cuGameIconStrokeVtxCount * Shader::cuColorAttrSize);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
GameIcon::~GameIcon()
|
||
|
{
|
||
|
//! remove image so it can not be drawn anymore from this point on
|
||
|
imageData = NULL;
|
||
|
|
||
|
//! main image vertexes
|
||
|
if(posVtxs)
|
||
|
{
|
||
|
free((void*)posVtxs);
|
||
|
posVtxs = NULL;
|
||
|
}
|
||
|
if(texCoords)
|
||
|
{
|
||
|
free((void*)texCoords);
|
||
|
texCoords = NULL;
|
||
|
}
|
||
|
//! mirror image vertexes
|
||
|
if(texCoordsMirror)
|
||
|
{
|
||
|
free(texCoordsMirror);
|
||
|
texCoordsMirror = NULL;
|
||
|
}
|
||
|
//! stroke image vertexes
|
||
|
if(strokePosVtxs)
|
||
|
{
|
||
|
free(strokePosVtxs);
|
||
|
strokePosVtxs = NULL;
|
||
|
}
|
||
|
if(strokeTexCoords)
|
||
|
{
|
||
|
free(strokeTexCoords);
|
||
|
strokeTexCoords = NULL;
|
||
|
}
|
||
|
if(strokeColorVtxs)
|
||
|
{
|
||
|
free(strokeColorVtxs);
|
||
|
strokeColorVtxs = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool GameIcon::checkRayIntersection(const glm::vec3 & rayOrigin, const glm::vec3 & rayDirFrac)
|
||
|
{
|
||
|
//! since we always face the camera we can just check the AABB intersection
|
||
|
//! otherwise an OOB intersection would be required
|
||
|
|
||
|
f32 currPosX = getCenterX() * Application::instance()->getVideo()->getWidthScaleFactor() * 2.0f;
|
||
|
f32 currPosY = getCenterY() * Application::instance()->getVideo()->getHeightScaleFactor() * 2.0f;
|
||
|
f32 currPosZ = getDepth() * Application::instance()->getVideo()->getDepthScaleFactor() * 2.0f;
|
||
|
f32 currScaleX = getScaleX() * (f32)getWidth() * Application::instance()->getVideo()->getWidthScaleFactor();
|
||
|
f32 currScaleY = getScaleY() * (f32)getHeight() * Application::instance()->getVideo()->getHeightScaleFactor();
|
||
|
f32 currScaleZ = getScaleZ() * (f32)getWidth() * Application::instance()->getVideo()->getDepthScaleFactor();
|
||
|
//! lb is the corner of AABB with minimal coordinates - left bottom, rt is maximal corner
|
||
|
glm::vec3 lb(currPosX - currScaleX, currPosY - currScaleY, currPosZ - currScaleZ);
|
||
|
glm::vec3 rt(currPosX + currScaleX, currPosY + currScaleY, currPosZ + currScaleZ);
|
||
|
|
||
|
float t1 = (lb.x - rayOrigin.x) * rayDirFrac.x;
|
||
|
float t2 = (rt.x - rayOrigin.x) * rayDirFrac.x;
|
||
|
float t3 = (lb.y - rayOrigin.y) * rayDirFrac.y;
|
||
|
float t4 = (rt.y - rayOrigin.y) * rayDirFrac.y;
|
||
|
float t5 = (lb.z - rayOrigin.z) * rayDirFrac.z;
|
||
|
float t6 = (rt.z - rayOrigin.z) * rayDirFrac.z;
|
||
|
|
||
|
float tmin = std::max(std::max(std::min(t1, t2), std::min(t3, t4)), std::min(t5, t6));
|
||
|
float tmax = std::min(std::min(std::max(t1, t2), std::max(t3, t4)), std::max(t5, t6));
|
||
|
|
||
|
//! if tmax < 0, ray (line) is intersecting AABB, but whole AABB is behing us
|
||
|
if (tmax < 0)
|
||
|
{
|
||
|
//t = tmax;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
//! if tmin > tmax, ray doesn't intersect AABB
|
||
|
if (tmin > tmax)
|
||
|
{
|
||
|
//t = tmax;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
//t = tmin;
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void GameIcon::draw(CVideo *pVideo, const glm::mat4 & projectionMtx, const glm::mat4 & viewMtx, const glm::mat4 & modelView)
|
||
|
{
|
||
|
//! first setup 2D GUI positions
|
||
|
f32 currPosX = getCenterX() * pVideo->getWidthScaleFactor() * 2.0f;
|
||
|
f32 currPosY = getCenterY() * pVideo->getHeightScaleFactor() * 2.0f;
|
||
|
f32 currPosZ = getDepth() * pVideo->getDepthScaleFactor() * 2.0f;
|
||
|
f32 currScaleX = getScaleX() * (f32)getWidth() * pVideo->getWidthScaleFactor();
|
||
|
f32 currScaleY = getScaleY() * (f32)getHeight() * pVideo->getHeightScaleFactor();
|
||
|
f32 currScaleZ = getScaleZ() * (f32)getWidth() * pVideo->getDepthScaleFactor();
|
||
|
f32 strokeScaleX = pVideo->getWidthScaleFactor() * strokeWidth * 0.25f + cfIconMirrorScale;
|
||
|
f32 strokeScaleY = pVideo->getHeightScaleFactor() * strokeWidth * 0.25f + cfIconMirrorScale;
|
||
|
|
||
|
for(int iDraw = 0; iDraw < 2; iDraw++)
|
||
|
{
|
||
|
glm::vec4 * alphaFadeOut;
|
||
|
glm::mat4 m_iconView;
|
||
|
glm::mat4 m_mirrorView;
|
||
|
glm::mat4 m_strokeView;
|
||
|
|
||
|
if(iDraw == RENDER_REFLECTION)
|
||
|
{
|
||
|
//! Reflection render
|
||
|
if(!bRenderReflection)
|
||
|
continue;
|
||
|
m_iconView = glm::translate(modelView, glm::vec3(currPosX, -currScaleY * 2.0f - currPosY, currPosZ + cosf(DegToRad(rotationX)) * currScaleZ * 2.0f));
|
||
|
m_iconView = glm::rotate(m_iconView, DegToRad(rotationX), glm::vec3(1.0f, 0.0f, 0.0f));
|
||
|
m_iconView = glm::scale(m_iconView, glm::vec3(currScaleX, -currScaleY, currScaleZ));
|
||
|
|
||
|
colorIntensity[3] = reflectionAlpha * getAlpha();
|
||
|
selectionBlurOuterColorIntensity[3] = colorIntensity[3] * 0.7f;
|
||
|
selectionBlurInnerColorIntensity[3] = colorIntensity[3] * 0.7f;
|
||
|
alphaFadeOut = &alphaFadeOutRefl;
|
||
|
|
||
|
GX2SetCullOnlyControl(GX2_FRONT_FACE_CCW, GX2_ENABLE, GX2_DISABLE);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//! Normal render
|
||
|
m_iconView = glm::translate(modelView, glm::vec3(currPosX,currPosY, currPosZ));
|
||
|
m_iconView = glm::rotate(m_iconView, DegToRad(rotationX), glm::vec3(1.0f, 0.0f, 0.0f));
|
||
|
m_iconView = glm::scale(m_iconView, glm::vec3(currScaleX, currScaleY, currScaleZ));
|
||
|
|
||
|
colorIntensity[3] = getAlpha();
|
||
|
selectionBlurOuterColorIntensity[3] = colorIntensity[3];
|
||
|
selectionBlurInnerColorIntensity[3] = colorIntensity[3];
|
||
|
alphaFadeOut = &alphaFadeOutNorm;
|
||
|
}
|
||
|
|
||
|
m_mirrorView = glm::scale(m_iconView, glm::vec3(cfIconMirrorScale, cfIconMirrorScale, cfIconMirrorScale));
|
||
|
|
||
|
colorIntensityMirror[3] = cfIconMirrorAlpha * colorIntensity[3];
|
||
|
|
||
|
if(!bIconLast)
|
||
|
{
|
||
|
Shader3D::instance()->setShaders();
|
||
|
Shader3D::instance()->setProjectionMtx(projectionMtx);
|
||
|
Shader3D::instance()->setViewMtx(viewMtx);
|
||
|
Shader3D::instance()->setTextureAndSampler(imageData->getTexture(), imageData->getSampler());
|
||
|
Shader3D::instance()->setAlphaFadeOut(*alphaFadeOut);
|
||
|
Shader3D::instance()->setDistanceFadeOut(distanceFadeout);
|
||
|
|
||
|
//! render the real symbol
|
||
|
Shader3D::instance()->setModelViewMtx(m_iconView);
|
||
|
Shader3D::instance()->setColorIntensity(colorIntensity);
|
||
|
Shader3D::instance()->setAttributeBuffer(vtxCount, posVtxs, texCoords);
|
||
|
Shader3D::instance()->draw(GX2_PRIMITIVE_QUADS, vtxCount);
|
||
|
}
|
||
|
|
||
|
if(bSelected)
|
||
|
{
|
||
|
strokeFractalEnable = 0;
|
||
|
|
||
|
GX2SetDepthOnlyControl(GX2_ENABLE, GX2_DISABLE, GX2_COMPARE_LEQUAL);
|
||
|
m_strokeView = glm::scale(m_iconView, glm::vec3(selectionBlurOuterSize, selectionBlurOuterSize, 0.0f));
|
||
|
ShaderFractalColor::instance()->setShaders();
|
||
|
ShaderFractalColor::instance()->setProjectionMtx(projectionMtx);
|
||
|
ShaderFractalColor::instance()->setViewMtx(viewMtx);
|
||
|
ShaderFractalColor::instance()->setModelViewMtx(m_strokeView);
|
||
|
ShaderFractalColor::instance()->setFractalColor(strokeFractalEnable);
|
||
|
ShaderFractalColor::instance()->setBlurBorder(selectionBlurOuterBorderSize);
|
||
|
ShaderFractalColor::instance()->setColorIntensity(selectionBlurOuterColorIntensity);
|
||
|
ShaderFractalColor::instance()->setAlphaFadeOut(*alphaFadeOut);
|
||
|
ShaderFractalColor::instance()->setAttributeBuffer();
|
||
|
ShaderFractalColor::instance()->draw();
|
||
|
|
||
|
m_strokeView = glm::scale(m_iconView, glm::vec3(selectionBlurInnerSize, selectionBlurInnerSize, 0.0f));
|
||
|
ShaderFractalColor::instance()->setBlurBorder(selectionBlurInnerBorderSize);
|
||
|
ShaderFractalColor::instance()->setColorIntensity(selectionBlurInnerColorIntensity);
|
||
|
ShaderFractalColor::instance()->draw();
|
||
|
GX2SetDepthOnlyControl(GX2_ENABLE, GX2_ENABLE, GX2_COMPARE_LEQUAL);
|
||
|
}
|
||
|
|
||
|
if(iDraw == RENDER_NORMAL && bRenderStroke)
|
||
|
{
|
||
|
strokeFractalEnable = 1;
|
||
|
//! now render the icon stroke
|
||
|
//! make the stroke a little bigger than the mirror, just by the line width on each side
|
||
|
m_strokeView = glm::scale(m_iconView, glm::vec3(strokeScaleX, strokeScaleY, cfIconMirrorScale));
|
||
|
|
||
|
ShaderFractalColor::instance()->setShaders();
|
||
|
ShaderFractalColor::instance()->setLineWidth(strokeWidth);
|
||
|
ShaderFractalColor::instance()->setProjectionMtx(projectionMtx);
|
||
|
ShaderFractalColor::instance()->setViewMtx(viewMtx);
|
||
|
ShaderFractalColor::instance()->setModelViewMtx(m_strokeView);
|
||
|
ShaderFractalColor::instance()->setFractalColor(strokeFractalEnable);
|
||
|
ShaderFractalColor::instance()->setBlurBorder(strokeBlurBorder);
|
||
|
ShaderFractalColor::instance()->setColorIntensity(colorIntensity);
|
||
|
ShaderFractalColor::instance()->setAlphaFadeOut(*alphaFadeOut);
|
||
|
ShaderFractalColor::instance()->setAttributeBuffer(cuGameIconStrokeVtxCount, strokePosVtxs, strokeTexCoords, strokeColorVtxs);
|
||
|
ShaderFractalColor::instance()->draw(GX2_PRIMITIVE_LINE_STRIP, cuGameIconStrokeVtxCount);
|
||
|
|
||
|
}
|
||
|
|
||
|
//! render the background mirror frame
|
||
|
Shader3D::instance()->setShaders();
|
||
|
Shader3D::instance()->setProjectionMtx(projectionMtx);
|
||
|
Shader3D::instance()->setViewMtx(viewMtx);
|
||
|
Shader3D::instance()->setTextureAndSampler(imageData->getTexture(), imageData->getSampler());
|
||
|
Shader3D::instance()->setAlphaFadeOut(*alphaFadeOut);
|
||
|
Shader3D::instance()->setDistanceFadeOut(distanceFadeout);
|
||
|
Shader3D::instance()->setModelViewMtx(m_mirrorView);
|
||
|
Shader3D::instance()->setColorIntensity(colorIntensityMirror);
|
||
|
Shader3D::instance()->setAttributeBuffer(vtxCount, posVtxs, texCoordsMirror);
|
||
|
Shader3D::instance()->draw(GX2_PRIMITIVE_QUADS, vtxCount);
|
||
|
|
||
|
if(bIconLast)
|
||
|
{
|
||
|
Shader3D::instance()->setShaders();
|
||
|
Shader3D::instance()->setProjectionMtx(projectionMtx);
|
||
|
Shader3D::instance()->setViewMtx(viewMtx);
|
||
|
Shader3D::instance()->setTextureAndSampler(imageData->getTexture(), imageData->getSampler());
|
||
|
Shader3D::instance()->setAlphaFadeOut(*alphaFadeOut);
|
||
|
Shader3D::instance()->setDistanceFadeOut(distanceFadeout);
|
||
|
|
||
|
//! render the real symbol
|
||
|
Shader3D::instance()->setModelViewMtx(m_iconView);
|
||
|
Shader3D::instance()->setColorIntensity(colorIntensity);
|
||
|
Shader3D::instance()->setAttributeBuffer(vtxCount, posVtxs, texCoords);
|
||
|
Shader3D::instance()->draw(GX2_PRIMITIVE_QUADS, vtxCount);
|
||
|
}
|
||
|
|
||
|
//! return back normal culling
|
||
|
if(iDraw == RENDER_REFLECTION)
|
||
|
{
|
||
|
GX2SetCullOnlyControl(GX2_FRONT_FACE_CCW, GX2_DISABLE, GX2_ENABLE);
|
||
|
}
|
||
|
}
|
||
|
}
|