forked from Mirrors/openclonk
Remove other usages of built-in GL matrices
Primarily for the FoW rendering, which now also uses (simple) shaders without ftransform() everywhere. This also removes all GLU calls.shapetextures
parent
eaf66850b1
commit
8766f5123b
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* OpenClonk, http://www.openclonk.org
|
||||
*
|
||||
* Copyright (c) 2015, The OpenClonk Team and contributors
|
||||
*
|
||||
* Distributed under the terms of the ISC license; see accompanying file
|
||||
* "COPYING" for details.
|
||||
*
|
||||
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
|
||||
* See accompanying file "TRADEMARK" for details.
|
||||
*
|
||||
* To redistribute this file separately, substitute the full license texts
|
||||
* for the above references.
|
||||
*/
|
||||
|
||||
// Default Vertex Shader for the landscape.
|
||||
|
||||
uniform mat4 projectionMatrix;
|
||||
|
||||
slice(position)
|
||||
{
|
||||
// model-view matrix is always the identity matrix
|
||||
gl_Position = projectionMatrix * gl_Vertex;
|
||||
}
|
|
@ -169,43 +169,10 @@ bool CStdGL::UpdateClipper()
|
|||
ClipAll=false;
|
||||
// set it
|
||||
glViewport(clipRect.x, RenderTarget->Hgt-clipRect.y-clipRect.Hgt, clipRect.Wdt, clipRect.Hgt);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
|
||||
gluOrtho2D((GLdouble) clipRect.x, (GLdouble) (clipRect.x + clipRect.Wdt), (GLdouble) (clipRect.y + clipRect.Hgt), (GLdouble) clipRect.y);
|
||||
UpdateProjectionMatrix();
|
||||
ProjectionMatrix = StdProjectionMatrix::Orthographic(clipRect.x, clipRect.x + clipRect.Wdt, clipRect.y + clipRect.Hgt, clipRect.y);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CStdGL::UpdateProjectionMatrix()
|
||||
{
|
||||
const C4Rect clipRect = GetClipRect();
|
||||
|
||||
const float left = clipRect.x;
|
||||
const float right = clipRect.x + clipRect.Wdt;
|
||||
const float bottom = clipRect.y + clipRect.Hgt;
|
||||
const float top = clipRect.y;
|
||||
const float nearVal = -1.0f;
|
||||
const float farVal = +1.0f;
|
||||
|
||||
ProjectionMatrix(0,0) = 2.0f / (right - left);
|
||||
ProjectionMatrix(0,1) = 0.0f;
|
||||
ProjectionMatrix(0,2) = 0.0f;
|
||||
ProjectionMatrix(0,3) = -(right + left) / (right - left);
|
||||
ProjectionMatrix(1,0) = 0.0f;
|
||||
ProjectionMatrix(1,1) = 2.0f / (top - bottom);
|
||||
ProjectionMatrix(1,2) = 0.0f;
|
||||
ProjectionMatrix(1,3) = -(top + bottom) / (top - bottom);
|
||||
ProjectionMatrix(2,0) = 0.0f;
|
||||
ProjectionMatrix(2,1) = 0.0f;
|
||||
ProjectionMatrix(2,2) = -2.0f / (farVal - nearVal);
|
||||
ProjectionMatrix(2,3) = -(farVal + nearVal) / (farVal - nearVal);
|
||||
ProjectionMatrix(3,0) = 0.0f;
|
||||
ProjectionMatrix(3,1) = 0.0f;
|
||||
ProjectionMatrix(3,2) = 0.0f;
|
||||
ProjectionMatrix(3,3) = 1.0f;
|
||||
}
|
||||
|
||||
bool CStdGL::PrepareRendering(C4Surface * sfcToSurface)
|
||||
{
|
||||
// call from gfx thread only!
|
||||
|
@ -287,12 +254,12 @@ bool CStdGL::PrepareSpriteShader(C4Shader& shader, const char* name, int ssc, C4
|
|||
for (const char* const* define = additionalDefines; *define != NULL; ++define)
|
||||
shader.AddFragmentSlice(-1, FormatString("#define %s", *define).getData());
|
||||
|
||||
shader.LoadSlices(pGroups, "CommonShader.glsl");
|
||||
shader.LoadSlices(pGroups, "ObjectShader.glsl");
|
||||
shader.LoadFragmentSlices(pGroups, "CommonShader.glsl");
|
||||
shader.LoadFragmentSlices(pGroups, "ObjectShader.glsl");
|
||||
|
||||
if (additionalSlices)
|
||||
for (const char* const* slice = additionalSlices; *slice != NULL; ++slice)
|
||||
shader.LoadSlices(pGroups, *slice);
|
||||
shader.LoadFragmentSlices(pGroups, *slice);
|
||||
|
||||
if (!shader.Init(name, uniformNames))
|
||||
{
|
||||
|
|
|
@ -165,7 +165,7 @@ public:
|
|||
virtual bool OnResolutionChanged(unsigned int iXRes, unsigned int iYRes); // reinit clipper for new resolution
|
||||
// Clipper
|
||||
bool UpdateClipper(); // set current clipper to render target
|
||||
void UpdateProjectionMatrix();
|
||||
const StdProjectionMatrix& GetProjectionMatrix() const { return ProjectionMatrix; }
|
||||
virtual bool PrepareMaterial(StdMeshMatManager& mat_manager, StdMeshMaterialLoader& loader, StdMeshMaterial& mat);
|
||||
// Surface
|
||||
virtual bool PrepareRendering(C4Surface * sfcToSurface); // check if/make rendering possible to given surface
|
||||
|
|
|
@ -77,6 +77,16 @@ void C4Shader::AddFragmentSlices(const char *szWhat, const char *szText, const c
|
|||
AddSlices(FragmentSlices, szWhat, szText, szSource, iSourceTime);
|
||||
}
|
||||
|
||||
bool C4Shader::LoadFragmentSlices(C4GroupSet *pGroups, const char *szFile)
|
||||
{
|
||||
return LoadSlices(FragmentSlices, pGroups, szFile);
|
||||
}
|
||||
|
||||
bool C4Shader::LoadVertexSlices(C4GroupSet *pGroups, const char *szFile)
|
||||
{
|
||||
return LoadSlices(VertexSlices, pGroups, szFile);
|
||||
}
|
||||
|
||||
void C4Shader::AddSlice(ShaderSliceList& slices, int iPos, const char *szText, const char *szSource, int iSourceTime)
|
||||
{
|
||||
ShaderSlice Slice;
|
||||
|
@ -240,7 +250,7 @@ int C4Shader::ParsePosition(const char *szWhat, const char **ppPos)
|
|||
return iPosition;
|
||||
}
|
||||
|
||||
bool C4Shader::LoadSlices(C4GroupSet *pGroups, const char *szFile)
|
||||
bool C4Shader::LoadSlices(ShaderSliceList& slices, C4GroupSet *pGroups, const char *szFile)
|
||||
{
|
||||
// Search for our shaders
|
||||
C4Group *pGroup = pGroups->FindEntry(szFile);
|
||||
|
@ -257,15 +267,10 @@ bool C4Shader::LoadSlices(C4GroupSet *pGroups, const char *szFile)
|
|||
iSourceTime = FileTime(Source.getData());
|
||||
// Load
|
||||
StdStrBuf What = FormatString("file %s", Config.AtRelativePath(Source.getData()));
|
||||
AddFragmentSlices(What.getData(), Shader.getData(), Source.getData(), iSourceTime);
|
||||
AddSlices(slices, What.getData(), Shader.getData(), Source.getData(), iSourceTime);
|
||||
return true;
|
||||
}
|
||||
|
||||
void C4Shader::AddVertexDefaults()
|
||||
{
|
||||
AddVertexSlice(C4Shader_Vertex_PositionPos, "gl_Position = ftransform();\n");
|
||||
}
|
||||
|
||||
#ifndef USE_CONSOLE
|
||||
GLenum C4Shader::AddTexCoord(const char *szName)
|
||||
{
|
||||
|
|
|
@ -137,10 +137,8 @@ public:
|
|||
void AddFragmentSlice(int iPos, const char *szText, const char *szSource = "", int iFileTime = 0);
|
||||
void AddVertexSlices(const char *szWhat, const char *szText, const char *szSource = "", int iFileTime = 0);
|
||||
void AddFragmentSlices(const char *szWhat, const char *szText, const char *szSource = "", int iFileTime = 0);
|
||||
bool LoadSlices(C4GroupSet *pGroupSet, const char *szFile);
|
||||
|
||||
// Add default vertex code (2D - no transformation)
|
||||
void AddVertexDefaults();
|
||||
bool LoadFragmentSlices(C4GroupSet *pGroupSet, const char *szFile);
|
||||
bool LoadVertexSlices(C4GroupSet *pGroupSet, const char *szFile);
|
||||
|
||||
#ifndef USE_CONSOLE
|
||||
// Allocate a texture coordinate, returning its ID to be used with glMultiTexCoord.
|
||||
|
@ -159,6 +157,7 @@ public:
|
|||
private:
|
||||
void AddSlice(ShaderSliceList& slices, int iPos, const char *szText, const char *szSource, int iFileTime);
|
||||
void AddSlices(ShaderSliceList& slices, const char *szWhat, const char *szText, const char *szSource, int iFileTime);
|
||||
bool LoadSlices(ShaderSliceList& slices, C4GroupSet *pGroupSet, const char *szFile);
|
||||
int ParsePosition(const char *szWhat, const char **ppPos);
|
||||
|
||||
StdStrBuf Build(const ShaderSliceList &Slices, bool fDebug = false);
|
||||
|
|
|
@ -554,8 +554,9 @@ const char *C4LandscapeRenderGL::UniformNames[C4LRU_Count+1];
|
|||
|
||||
bool C4LandscapeRenderGL::LoadShader(C4GroupSet *pGroups, C4Shader& shader, const char* name, int ssc)
|
||||
{
|
||||
// Create vertex shader (hard-coded)
|
||||
shader.AddVertexDefaults();
|
||||
// Create vertex shader
|
||||
shader.LoadVertexSlices(pGroups, "LandscapeVertexShader.glsl");
|
||||
|
||||
hLandscapeTexCoord = shader.AddTexCoord("landscapeCoord");
|
||||
if(ssc & C4SSC_LIGHT) hLightTexCoord = shader.AddTexCoord("lightCoord");
|
||||
|
||||
|
@ -564,8 +565,8 @@ bool C4LandscapeRenderGL::LoadShader(C4GroupSet *pGroups, C4Shader& shader, cons
|
|||
shader.AddFragmentSlice(-1, "#define OC_LANDSCAPE");
|
||||
if(ssc & C4SSC_LIGHT) shader.AddFragmentSlice(-1, "#define OC_DYNAMIC_LIGHT"); // sample light from light texture
|
||||
|
||||
shader.LoadSlices(pGroups, "CommonShader.glsl");
|
||||
shader.LoadSlices(pGroups, "LandscapeShader.glsl");
|
||||
shader.LoadFragmentSlices(pGroups, "CommonShader.glsl");
|
||||
shader.LoadFragmentSlices(pGroups, "LandscapeShader.glsl");
|
||||
|
||||
// Initialise!
|
||||
if (!shader.Init(name, UniformNames)) {
|
||||
|
@ -590,6 +591,7 @@ bool C4LandscapeRenderGL::LoadShaders(C4GroupSet *pGroups)
|
|||
|
||||
// Make uniform name map
|
||||
ZeroMem(UniformNames, sizeof(UniformNames));
|
||||
UniformNames[C4LRU_ProjectionMatrix] = "projectionMatrix";
|
||||
UniformNames[C4LRU_LandscapeTex] = "landscapeTex";
|
||||
UniformNames[C4LRU_ScalerTex] = "scalerTex";
|
||||
UniformNames[C4LRU_MaterialTex] = "materialTex";
|
||||
|
@ -905,6 +907,7 @@ void C4LandscapeRenderGL::Draw(const C4TargetFacet &cgo, const C4FoWRegion *Ligh
|
|||
ShaderCall.Start();
|
||||
|
||||
// Bind data
|
||||
ShaderCall.SetUniformMatrix4x4(C4LRU_ProjectionMatrix, pGL->GetProjectionMatrix());
|
||||
ShaderCall.SetUniform3fv(C4LRU_Gamma, 1, pGL->gammaOut);
|
||||
ShaderCall.SetUniform2f(C4LRU_Resolution, Surfaces[0]->Wdt, Surfaces[0]->Hgt);
|
||||
float centerX = float(cgo.TargetX)+float(cgo.Wdt)/2,
|
||||
|
|
|
@ -36,6 +36,8 @@ enum C4LR_Byte {
|
|||
// Don't forget to update GetUniformName when introducing new uniforms!
|
||||
enum C4LR_Uniforms
|
||||
{
|
||||
C4LRU_ProjectionMatrix,
|
||||
|
||||
C4LRU_LandscapeTex,
|
||||
C4LRU_ScalerTex,
|
||||
C4LRU_MaterialTex,
|
||||
|
|
|
@ -30,21 +30,20 @@ C4Shader *C4FoW::GetFramebufShader()
|
|||
// Not created yet?
|
||||
if (!FramebufShader.Initialised())
|
||||
{
|
||||
|
||||
// Create the frame buffer shader. The details are in C4FoWRegion, but
|
||||
// this is about how to utilise old frame buffer data in the lights texture.
|
||||
// Or put in other words: This shader is responsible for fading lights out.
|
||||
FramebufShader.AddVertexDefaults();
|
||||
FramebufShader.AddVertexSlice(-1, "uniform mat4 projectionMatrix;");
|
||||
FramebufShader.AddVertexSlice(0, "gl_Position = projectionMatrix * gl_Vertex;");
|
||||
FramebufShader.AddTexCoord("texCoord");
|
||||
FramebufShader.AddFragmentSlice(-1, "uniform sampler2D tex;");
|
||||
FramebufShader.AddFragmentSlice(0,
|
||||
"gl_FragColor = texture2D(tex, texCoord.st);");
|
||||
const char *szUniforms[] = { "tex", NULL };
|
||||
const char *szUniforms[] = { "tex", "projectionMatrix", NULL };
|
||||
if (!FramebufShader.Init("framebuf", szUniforms)) {
|
||||
FramebufShader.ClearSlices();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
return &FramebufShader;
|
||||
#else
|
||||
|
@ -52,6 +51,31 @@ C4Shader *C4FoW::GetFramebufShader()
|
|||
#endif
|
||||
}
|
||||
|
||||
C4Shader *C4FoW::GetRenderShader()
|
||||
{
|
||||
#ifndef USE_CONSOLE
|
||||
// Not created yet?
|
||||
if (!RenderShader.Initialised())
|
||||
{
|
||||
// Create the render shader. Fairly simple pass-through.
|
||||
RenderShader.AddVertexSlice(-1, "uniform mat4 projectionMatrix;");
|
||||
RenderShader.AddVertexSlice(0, "gl_FrontColor = gl_Color; gl_Position = projectionMatrix * gl_Vertex;");
|
||||
RenderShader.AddFragmentSlice(0,
|
||||
"gl_FragColor = gl_Color;");
|
||||
const char *szUniforms[] = { "projectionMatrix", NULL };
|
||||
if (!RenderShader.Init("fowRender", szUniforms)) {
|
||||
RenderShader.ClearSlices();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
return &RenderShader;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void C4FoW::Add(C4Object *pObj)
|
||||
{
|
||||
#ifndef USE_CONSOLE
|
||||
|
@ -119,11 +143,22 @@ void C4FoW::Update(C4Rect r, C4Player *pPlr)
|
|||
#endif
|
||||
}
|
||||
|
||||
void C4FoW::Render(C4FoWRegion *pRegion, const C4TargetFacet *pOnScreen, C4Player *pPlr)
|
||||
void C4FoW::Render(C4FoWRegion *pRegion, const C4TargetFacet *pOnScreen, C4Player *pPlr, const StdProjectionMatrix& projectionMatrix)
|
||||
{
|
||||
#ifndef USE_CONSOLE
|
||||
// Set up shader. If this one doesn't work, we're really in trouble.
|
||||
C4Shader *pShader = GetRenderShader();
|
||||
assert(pShader);
|
||||
if (!pShader) return;
|
||||
|
||||
C4ShaderCall Call(pShader);
|
||||
Call.Start();
|
||||
Call.SetUniformMatrix4x4(0, projectionMatrix);
|
||||
|
||||
for (C4FoWLight *pLight = pLights; pLight; pLight = pLight->getNext())
|
||||
if (pLight->IsVisibleForPlayer(pPlr))
|
||||
pLight->Render(pRegion, pOnScreen);
|
||||
|
||||
Call.Finish();
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -83,6 +83,8 @@ public:
|
|||
|
||||
// Shader to use for updating the frame buffer
|
||||
C4Shader *GetFramebufShader();
|
||||
// Shader to use for rendering the lights
|
||||
C4Shader *GetRenderShader();
|
||||
|
||||
void Clear();
|
||||
|
||||
|
@ -96,12 +98,13 @@ public:
|
|||
/** Triggers the recalculation of all light beams within the given rectangle because the landscape changed. */
|
||||
void Invalidate(C4Rect r);
|
||||
|
||||
void Render(class C4FoWRegion *pRegion, const C4TargetFacet *pOnScreen, C4Player *pPlr);
|
||||
void Render(class C4FoWRegion *pRegion, const C4TargetFacet *pOnScreen, C4Player *pPlr, const StdProjectionMatrix& projectionMatrix);
|
||||
|
||||
private:
|
||||
#ifndef USE_CONSOLE
|
||||
// Shader for updating the frame buffer
|
||||
C4Shader FramebufShader;
|
||||
C4Shader RenderShader;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "C4Include.h"
|
||||
#include "C4FoWRegion.h"
|
||||
#include "C4DrawGL.h"
|
||||
|
||||
C4FoWRegion::~C4FoWRegion()
|
||||
{
|
||||
|
@ -121,7 +122,7 @@ void C4FoWRegion::Render(const C4TargetFacet *pOnScreen)
|
|||
// On screen? No need to set up frame buffer - simply shortcut
|
||||
if (pOnScreen)
|
||||
{
|
||||
pFoW->Render(this, pOnScreen, pPlayer);
|
||||
pFoW->Render(this, pOnScreen, pPlayer, pGL->GetProjectionMatrix());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -143,10 +144,7 @@ void C4FoWRegion::Render(const C4TargetFacet *pOnScreen)
|
|||
|
||||
// Set up a clean context
|
||||
glViewport(0, 0, pSurface->Wdt, pSurface->Hgt);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
gluOrtho2D(0, pSurface->Wdt, pSurface->Hgt, 0);
|
||||
const StdProjectionMatrix projectionMatrix = StdProjectionMatrix::Orthographic(0.0, pSurface->Wdt, pSurface->Hgt, 0);
|
||||
|
||||
// Clear texture contents
|
||||
assert(pSurface->Hgt % 2 == 0);
|
||||
|
@ -163,7 +161,7 @@ void C4FoWRegion::Render(const C4TargetFacet *pOnScreen)
|
|||
|
||||
// Render FoW to frame buffer object
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
pFoW->Render(this, NULL, pPlayer);
|
||||
pFoW->Render(this, NULL, pPlayer, projectionMatrix);
|
||||
|
||||
// Copy over the old state
|
||||
if (OldRegion.Wdt > 0)
|
||||
|
@ -198,6 +196,7 @@ void C4FoWRegion::Render(const C4TargetFacet *pOnScreen)
|
|||
Call.Start();
|
||||
if (Call.AllocTexUnit(0))
|
||||
glBindTexture(GL_TEXTURE_2D, pBackSurface->textures[0].texName);
|
||||
Call.SetUniformMatrix4x4(1, projectionMatrix);
|
||||
glBlendFunc(GL_ONE_MINUS_CONSTANT_COLOR, GL_CONSTANT_COLOR);
|
||||
float normalBlend = 1.0f / 4.0f, // Normals change quickly
|
||||
brightBlend = 1.0f / 16.0f; // Intensity more slowly
|
||||
|
@ -214,8 +213,6 @@ void C4FoWRegion::Render(const C4TargetFacet *pOnScreen)
|
|||
|
||||
// Done!
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
pDraw->RestorePrimaryClipper();
|
||||
|
||||
OldRegion = Region;
|
||||
|
|
|
@ -414,6 +414,28 @@ StdProjectionMatrix StdProjectionMatrix::Rotate(float angle, float rx, float ry,
|
|||
return m;
|
||||
}
|
||||
|
||||
StdProjectionMatrix StdProjectionMatrix::Orthographic(float left, float right, float bottom, float top)
|
||||
{
|
||||
StdProjectionMatrix matrix;
|
||||
matrix(0,0) = 2.0f / (right - left);
|
||||
matrix(0,1) = 0.0f;
|
||||
matrix(0,2) = 0.0f;
|
||||
matrix(0,3) = -(right + left) / (right - left);
|
||||
matrix(1,0) = 0.0f;
|
||||
matrix(1,1) = 2.0f / (top - bottom);
|
||||
matrix(1,2) = 0.0f;
|
||||
matrix(1,3) = -(top + bottom) / (top - bottom);
|
||||
matrix(2,0) = 0.0f;
|
||||
matrix(2,1) = 0.0f;
|
||||
matrix(2,2) = -1.0f;
|
||||
matrix(2,3) = 0.0f;
|
||||
matrix(3,0) = 0.0f;
|
||||
matrix(3,1) = 0.0f;
|
||||
matrix(3,2) = 0.0f;
|
||||
matrix(3,3) = 1.0f;
|
||||
return matrix;
|
||||
}
|
||||
|
||||
StdMeshMatrix StdProjectionMatrix::Upper3x4(const StdProjectionMatrix& matrix)
|
||||
{
|
||||
StdMeshMatrix m;
|
||||
|
|
|
@ -126,6 +126,9 @@ public:
|
|||
static StdProjectionMatrix Translate(float dx, float dy, float dz);
|
||||
static StdProjectionMatrix Scale(float sx, float sy, float sz);
|
||||
static StdProjectionMatrix Rotate(float angle, float rx, float ry, float rz);
|
||||
|
||||
static StdProjectionMatrix Orthographic(float left, float right, float bottom, float top);
|
||||
|
||||
static StdMeshMatrix Upper3x4(const StdProjectionMatrix& matrix);
|
||||
|
||||
float& operator()(int i, int j) { return a[i][j]; }
|
||||
|
|
|
@ -71,8 +71,8 @@ public:
|
|||
if (ssc & C4SSC_BASE) shader.AddFragmentSlice(-1, "#define OC_HAVE_BASE");
|
||||
if (ssc & C4SSC_OVERLAY) shader.AddFragmentSlice(-1, "#define OC_HAVE_OVERLAY");
|
||||
|
||||
shader.LoadSlices(&::GraphicsResource.Files, "CommonShader.glsl");
|
||||
shader.LoadSlices(&::GraphicsResource.Files, "ObjectShader.glsl");
|
||||
shader.LoadFragmentSlices(&::GraphicsResource.Files, "CommonShader.glsl");
|
||||
shader.LoadFragmentSlices(&::GraphicsResource.Files, "ObjectShader.glsl");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue