mirror of
https://github.com/wiiu-env/libgui.git
synced 2024-12-26 16:21:49 +01:00
203 lines
6.6 KiB
C
203 lines
6.6 KiB
C
|
/****************************************************************************
|
||
|
* Copyright (C) 2015 Dimok
|
||
|
*
|
||
|
* This program is free software: you can redistribute it and/or modify
|
||
|
* it under the terms of the GNU General Public License as published by
|
||
|
* the Free Software Foundation, either version 3 of the License, or
|
||
|
* (at your option) any later version.
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* GNU General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
****************************************************************************/
|
||
|
#ifndef __CVIDEO_H_
|
||
|
#define __CVIDEO_H_
|
||
|
|
||
|
#include <dynamic_libs/gx2_functions.h>
|
||
|
#include "shaders/Shader.h"
|
||
|
|
||
|
class CVideo
|
||
|
{
|
||
|
public:
|
||
|
CVideo(s32 forceTvScanMode = -1, s32 forceDrcScanMode = -1);
|
||
|
virtual ~CVideo();
|
||
|
|
||
|
void prepareTvRendering(void) {
|
||
|
currContextState = tvContextState;
|
||
|
currColorBuffer = &tvColorBuffer;
|
||
|
currDepthBuffer = &tvDepthBuffer;
|
||
|
prepareRendering();
|
||
|
}
|
||
|
|
||
|
void prepareDrcRendering(void) {
|
||
|
currContextState = drcContextState;
|
||
|
currColorBuffer = &drcColorBuffer;
|
||
|
currDepthBuffer = &drcDepthBuffer;
|
||
|
prepareRendering();
|
||
|
}
|
||
|
|
||
|
void prepareRendering(void) {
|
||
|
GX2ClearColor(currColorBuffer, 0.0f, 0.0f, 0.0f, 1.0f);
|
||
|
GX2ClearDepthStencilEx(currDepthBuffer, currDepthBuffer->clear_depth, currDepthBuffer->clear_stencil, GX2_CLEAR_BOTH);
|
||
|
|
||
|
GX2SetContextState(currContextState);
|
||
|
GX2SetViewport(0.0f, 0.0f, currColorBuffer->surface.width, currColorBuffer->surface.height, 0.0f, 1.0f);
|
||
|
GX2SetScissor(0, 0, currColorBuffer->surface.width, currColorBuffer->surface.height);
|
||
|
|
||
|
GX2SetDepthOnlyControl(GX2_ENABLE, GX2_ENABLE, GX2_COMPARE_LEQUAL);
|
||
|
GX2SetColorControl(GX2_LOGIC_OP_COPY, 1, GX2_DISABLE, GX2_ENABLE);
|
||
|
GX2SetBlendControl(GX2_RENDER_TARGET_0, GX2_BLEND_SRC_ALPHA, GX2_BLEND_ONE_MINUS_SRC_ALPHA, GX2_BLEND_COMBINE_ADD, GX2_ENABLE, GX2_BLEND_SRC_ALPHA, GX2_BLEND_ONE_MINUS_SRC_ALPHA, GX2_BLEND_COMBINE_ADD);
|
||
|
GX2SetCullOnlyControl(GX2_FRONT_FACE_CCW, GX2_DISABLE, GX2_ENABLE);
|
||
|
}
|
||
|
|
||
|
void setStencilRender(bool bEnable)
|
||
|
{
|
||
|
if(bEnable)
|
||
|
{
|
||
|
GX2SetStencilMask(0xff, 0xff, 0x01, 0xff, 0xff, 0x01);
|
||
|
GX2SetDepthStencilControl(GX2_DISABLE, GX2_DISABLE, GX2_COMPARE_LEQUAL, GX2_ENABLE, GX2_ENABLE, GX2_COMPARE_ALWAYS, GX2_STENCIL_KEEP, GX2_STENCIL_KEEP, GX2_STENCIL_REPLACE,
|
||
|
GX2_COMPARE_ALWAYS, GX2_STENCIL_KEEP, GX2_STENCIL_KEEP, GX2_STENCIL_REPLACE);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
GX2SetStencilMask(0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
|
||
|
GX2SetDepthStencilControl(GX2_ENABLE, GX2_ENABLE, GX2_COMPARE_LEQUAL, GX2_DISABLE, GX2_DISABLE, GX2_COMPARE_NEVER, GX2_STENCIL_KEEP, GX2_STENCIL_KEEP, GX2_STENCIL_KEEP,
|
||
|
GX2_COMPARE_NEVER, GX2_STENCIL_KEEP, GX2_STENCIL_KEEP, GX2_STENCIL_KEEP);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void drcDrawDone(void) {
|
||
|
//! on DRC we do a hardware AA because FXAA does not look good
|
||
|
//renderFXAA(&drcAaTexture, &aaSampler);
|
||
|
GX2CopyColorBufferToScanBuffer(&drcColorBuffer, GX2_SCAN_TARGET_DRC_FIRST);
|
||
|
}
|
||
|
|
||
|
void tvDrawDone(void) {
|
||
|
renderFXAA(&tvAaTexture, &aaSampler);
|
||
|
GX2CopyColorBufferToScanBuffer(&tvColorBuffer, GX2_SCAN_TARGET_TV);
|
||
|
GX2SwapScanBuffers();
|
||
|
GX2Flush();
|
||
|
}
|
||
|
|
||
|
void waitForVSync(void) {
|
||
|
GX2WaitForVsync();
|
||
|
frameCount++;
|
||
|
}
|
||
|
|
||
|
void tvEnable(bool bEnable) {
|
||
|
if(tvEnabled != bEnable)
|
||
|
{
|
||
|
GX2SetTVEnable(bEnable ? GX2_ENABLE : GX2_DISABLE);
|
||
|
tvEnabled = bEnable;
|
||
|
}
|
||
|
}
|
||
|
void drcEnable(bool bEnable) {
|
||
|
if(drcEnabled != bEnable)
|
||
|
{
|
||
|
GX2SetDRCEnable(bEnable ? GX2_ENABLE : GX2_DISABLE);
|
||
|
drcEnabled = bEnable;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
u32 getFrameCount(void) const {
|
||
|
return frameCount;
|
||
|
}
|
||
|
|
||
|
u32 getTvWidth(void) const {
|
||
|
return tvColorBuffer.surface.width;
|
||
|
}
|
||
|
u32 getTvHeight(void) const {
|
||
|
return tvColorBuffer.surface.height;
|
||
|
}
|
||
|
|
||
|
u32 getDrcWidth(void) const {
|
||
|
return drcColorBuffer.surface.width;
|
||
|
}
|
||
|
u32 getDrcHeight(void) const {
|
||
|
return drcColorBuffer.surface.height;
|
||
|
}
|
||
|
|
||
|
const glm::mat4 & getProjectionMtx(void) const {
|
||
|
return projectionMtx;
|
||
|
}
|
||
|
const glm::mat4 & getViewMtx(void) const {
|
||
|
return viewMtx;
|
||
|
}
|
||
|
|
||
|
f32 getWidthScaleFactor(void) const {
|
||
|
return widthScaleFactor;
|
||
|
}
|
||
|
f32 getHeightScaleFactor(void) const {
|
||
|
return heightScaleFactor;
|
||
|
}
|
||
|
f32 getDepthScaleFactor(void) const {
|
||
|
return depthScaleFactor;
|
||
|
}
|
||
|
|
||
|
void screenPosToWorldRay(f32 posX, f32 posY, glm::vec3 & rayOrigin, glm::vec3 & rayDirection)
|
||
|
{
|
||
|
//! normalize positions
|
||
|
posX = 2.0f * posX * getWidthScaleFactor();
|
||
|
posY = 2.0f * posY * getHeightScaleFactor();
|
||
|
|
||
|
glm::vec4 rayStart(posX, posY, 0.0f, 1.0f);
|
||
|
glm::vec4 rayEnd(posX, posY, 1.0f, 1.0f);
|
||
|
|
||
|
glm::mat4 IMV = glm::inverse(projectionMtx * viewMtx);
|
||
|
glm::vec4 rayStartWorld = IMV * rayStart;
|
||
|
rayStartWorld /= rayStartWorld.w;
|
||
|
|
||
|
glm::vec4 rayEndWorld = IMV * rayEnd;
|
||
|
rayEndWorld /= rayEndWorld.w;
|
||
|
|
||
|
glm::vec3 rayDirectionWorld(rayEndWorld - rayStartWorld);
|
||
|
rayDirectionWorld = glm::normalize(rayDirectionWorld);
|
||
|
|
||
|
rayOrigin = glm::vec3(rayStartWorld);
|
||
|
rayDirection = glm::normalize(rayDirectionWorld);
|
||
|
}
|
||
|
private:
|
||
|
static void *GX2RAlloc(u32 flags, u32 size, u32 align);
|
||
|
static void GX2RFree(u32 flags, void* p);
|
||
|
|
||
|
void renderFXAA(const GX2Texture * texture, const GX2Sampler *sampler);
|
||
|
|
||
|
void *gx2CommandBuffer;
|
||
|
|
||
|
void *tvScanBuffer;
|
||
|
void *drcScanBuffer;
|
||
|
|
||
|
u32 frameCount;
|
||
|
f32 widthScaleFactor;
|
||
|
f32 heightScaleFactor;
|
||
|
f32 depthScaleFactor;
|
||
|
|
||
|
bool tvEnabled;
|
||
|
bool drcEnabled;
|
||
|
|
||
|
GX2ColorBuffer tvColorBuffer;
|
||
|
GX2DepthBuffer tvDepthBuffer;
|
||
|
GX2ColorBuffer drcColorBuffer;
|
||
|
GX2DepthBuffer drcDepthBuffer;
|
||
|
|
||
|
GX2ContextState *tvContextState;
|
||
|
GX2ContextState *drcContextState;
|
||
|
|
||
|
GX2ContextState *currContextState;
|
||
|
GX2ColorBuffer *currColorBuffer;
|
||
|
GX2DepthBuffer *currDepthBuffer;
|
||
|
|
||
|
GX2Texture tvAaTexture;
|
||
|
GX2Sampler aaSampler;
|
||
|
|
||
|
glm::mat4 projectionMtx;
|
||
|
glm::mat4 viewMtx;
|
||
|
glm::vec2 resolution;
|
||
|
};
|
||
|
|
||
|
#endif // __GX2_VIDEO_H_
|