mirror of https://github.com/PCSX2/pcsx2.git
gsdx-ogl: LINUX-ONLY
* add the forgotten hardware renderer object. Oh my gosh! Opengl is 20% faster than Dx!!! git-svn-id: http://pcsx2.googlecode.com/svn/branches/gsdx-ogl@5000 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
e4c70ad229
commit
9272be182e
|
@ -103,6 +103,23 @@ GSDeviceOGL::~GSDeviceOGL()
|
|||
// Clean various opengl allocation
|
||||
glDeleteProgramPipelines(1, &m_pipeline);
|
||||
glDeleteFramebuffers(1, &m_fbo);
|
||||
|
||||
// Delete HW FX
|
||||
delete m_vs_cb;
|
||||
delete m_ps_cb;
|
||||
glDeleteSamplers(1, &m_rt_ss);
|
||||
delete m_vb;
|
||||
|
||||
for (auto it : m_vs) glDeleteProgram(it.second);
|
||||
for (auto it : m_gs) glDeleteProgram(it.second);
|
||||
for (auto it : m_ps) glDeleteProgram(it.second);
|
||||
for (auto it : m_ps_ss) glDeleteSamplers(1, &it.second);
|
||||
m_vs.clear();
|
||||
m_gs.clear();
|
||||
m_ps.clear();
|
||||
m_ps_ss.clear();
|
||||
m_om_dss.clear();
|
||||
m_om_bs.clear();
|
||||
}
|
||||
|
||||
GSTexture* GSDeviceOGL::CreateSurface(int type, int w, int h, bool msaa, int format)
|
||||
|
@ -291,6 +308,50 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
|
|||
rd.AntialiasedLineEnable = false;
|
||||
#endif
|
||||
|
||||
// TODO Later
|
||||
// ****************************************************************
|
||||
// fxaa (bonus)
|
||||
// ****************************************************************
|
||||
// FIXME need to define FXAA_GLSL_130 for the shader
|
||||
// FIXME need to manually set the index...
|
||||
// FIXME need dofxaa interface too
|
||||
// m_fxaa.cb = new GSUniformBufferOGL(3, sizeof(FXAAConstantBuffer));
|
||||
//CompileShaderFromSource("fxaa.fx", format("ps_main", i), GL_FRAGMENT_SHADER, &m_fxaa.ps);
|
||||
|
||||
// ****************************************************************
|
||||
// date
|
||||
// ****************************************************************
|
||||
|
||||
m_date.dss = new GSDepthStencilOGL();
|
||||
m_date.dss->m_stencil_enable = true;
|
||||
m_date.dss->m_stencil_func = GL_ALWAYS;
|
||||
m_date.dss->m_stencil_spass_dpass_op = GL_REPLACE;
|
||||
//memset(&dsd, 0, sizeof(dsd));
|
||||
|
||||
//dsd.DepthEnable = false;
|
||||
//dsd.StencilEnable = true;
|
||||
//dsd.StencilReadMask = 1;
|
||||
//dsd.StencilWriteMask = 1;
|
||||
|
||||
//dsd.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
|
||||
//dsd.FrontFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE;
|
||||
//dsd.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
|
||||
//dsd.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
|
||||
|
||||
//m_dev->CreateDepthStencilState(&dsd, &m_date.dss);
|
||||
|
||||
// FIXME are the blend state really empty
|
||||
m_date.bs = new GSBlendStateOGL();
|
||||
//D3D11_BLEND_DESC blend;
|
||||
|
||||
//memset(&blend, 0, sizeof(blend));
|
||||
|
||||
//m_dev->CreateBlendState(&blend, &m_date.bs);
|
||||
|
||||
// ****************************************************************
|
||||
// HW renderer shader
|
||||
// ****************************************************************
|
||||
CreateTextureFX();
|
||||
|
||||
// ****************************************************************
|
||||
// Finish window setup and backbuffer
|
||||
|
@ -392,50 +453,7 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
|
|||
}
|
||||
#endif
|
||||
|
||||
// TODO Later
|
||||
// ****************************************************************
|
||||
// fxaa (bonus)
|
||||
// ****************************************************************
|
||||
// FIXME need to define FXAA_GLSL_130 for the shader
|
||||
// FIXME need to manually set the index...
|
||||
// FIXME need dofxaa interface too
|
||||
// m_fxaa.cb = new GSUniformBufferOGL(3, sizeof(FXAAConstantBuffer));
|
||||
//CompileShaderFromSource("fxaa.fx", format("ps_main", i), GL_FRAGMENT_SHADER, &m_fxaa.ps);
|
||||
|
||||
// ****************************************************************
|
||||
// date
|
||||
// ****************************************************************
|
||||
|
||||
m_date.dss = new GSDepthStencilOGL();
|
||||
m_date.dss->m_stencil_enable = true;
|
||||
m_date.dss->m_stencil_func = GL_ALWAYS;
|
||||
m_date.dss->m_stencil_spass_dpass_op = GL_REPLACE;
|
||||
//memset(&dsd, 0, sizeof(dsd));
|
||||
|
||||
//dsd.DepthEnable = false;
|
||||
//dsd.StencilEnable = true;
|
||||
//dsd.StencilReadMask = 1;
|
||||
//dsd.StencilWriteMask = 1;
|
||||
|
||||
//dsd.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
|
||||
//dsd.FrontFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE;
|
||||
//dsd.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
|
||||
//dsd.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
|
||||
|
||||
//m_dev->CreateDepthStencilState(&dsd, &m_date.dss);
|
||||
|
||||
// FIXME are the blend state really empty
|
||||
m_date.bs = new GSBlendStateOGL();
|
||||
//D3D11_BLEND_DESC blend;
|
||||
|
||||
//memset(&blend, 0, sizeof(blend));
|
||||
|
||||
//m_dev->CreateBlendState(&blend, &m_date.bs);
|
||||
|
||||
// ****************************************************************
|
||||
// HW renderer shader
|
||||
// ****************************************************************
|
||||
CreateTextureFX();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSDeviceOGL::Reset(int w, int h)
|
||||
|
@ -472,6 +490,9 @@ void GSDeviceOGL::ClearRenderTarget(GSTexture* t, const GSVector4& c)
|
|||
OMSetFBO(0);
|
||||
//glClearBufferfv(GL_COLOR, GL_LEFT, c.v);
|
||||
glClearBufferfv(GL_COLOR, 0, c.v);
|
||||
// code for the old interface
|
||||
// glClearColor(c.x, c.y, c.z, c.w);
|
||||
// glClear(GL_COLOR_BUFFER_BIT);
|
||||
} else {
|
||||
// FIXME I need to clarify this FBO attachment stuff
|
||||
// I would like to avoid FBO for a basic clean operation
|
||||
|
|
|
@ -0,0 +1,353 @@
|
|||
/*
|
||||
* Copyright (C) 2011-2011 Gregory hainaut
|
||||
* Copyright (C) 2007-2009 Gabest
|
||||
*
|
||||
* 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 2, 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 GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "GSDeviceOGL.h"
|
||||
#include "GSTables.h"
|
||||
|
||||
void GSDeviceOGL::CreateTextureFX()
|
||||
{
|
||||
m_vs_cb = new GSUniformBufferOGL(4, sizeof(VSConstantBuffer));
|
||||
m_ps_cb = new GSUniformBufferOGL(5, sizeof(PSConstantBuffer));
|
||||
|
||||
glGenSamplers(1, &m_rt_ss);
|
||||
// FIXME, seem to have no difference between sampler !!!
|
||||
m_palette_ss = m_rt_ss;
|
||||
|
||||
glSamplerParameteri(m_rt_ss, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glSamplerParameteri(m_rt_ss, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glSamplerParameteri(m_rt_ss, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
glSamplerParameteri(m_rt_ss, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glSamplerParameteri(m_rt_ss, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
// FIXME which value for GL_TEXTURE_MIN_LOD
|
||||
glSamplerParameteri(m_rt_ss, GL_TEXTURE_MAX_LOD, FLT_MAX);
|
||||
// FIXME: seems there is 2 possibility in opengl
|
||||
// DX: sd.ComparisonFunc = D3D11_COMPARISON_NEVER;
|
||||
// glSamplerParameteri(m_rt_ss, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
||||
glSamplerParameteri(m_rt_ss, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
||||
glSamplerParameteri(m_rt_ss, GL_TEXTURE_COMPARE_FUNC, GL_NEVER);
|
||||
// FIXME: need ogl extension sd.MaxAnisotropy = 16;
|
||||
|
||||
//{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
//{"TEXCOORD", 1, DXGI_FORMAT_R32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
//float2 t : TEXCOORD0;
|
||||
//float q : TEXCOORD1;
|
||||
//
|
||||
//{"POSITION", 0, DXGI_FORMAT_R16G16_UINT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
//{"POSITION", 1, DXGI_FORMAT_R32_UINT, 0, 20, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
//uint2 p : POSITION0;
|
||||
//uint z : POSITION1;
|
||||
//
|
||||
//{"COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
//{"COLOR", 1, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0},
|
||||
//float4 c : COLOR0;
|
||||
//float4 f : COLOR1;
|
||||
|
||||
GSInputLayout vert_format[6] =
|
||||
{
|
||||
// FIXME
|
||||
{0 , 2 , GL_FLOAT , GL_FALSE , sizeof(GSVertexHW11) , (const GLvoid*)(0) } ,
|
||||
{1 , 4 , GL_UNSIGNED_BYTE , GL_TRUE , sizeof(GSVertexHW11) , (const GLvoid*)(8) } ,
|
||||
{2 , 1 , GL_FLOAT , GL_FALSE , sizeof(GSVertexHW11) , (const GLvoid*)(12) } ,
|
||||
{3 , 2 , GL_UNSIGNED_SHORT , GL_FALSE , sizeof(GSVertexHW11) , (const GLvoid*)(16) } ,
|
||||
{4 , 1 , GL_UNSIGNED_INT , GL_FALSE , sizeof(GSVertexHW11) , (const GLvoid*)(20) } ,
|
||||
// note: there is a 32 bits pad
|
||||
{5 , 4 , GL_UNSIGNED_BYTE , GL_TRUE , sizeof(GSVertexHW11) , (const GLvoid*)(28) } ,
|
||||
};
|
||||
m_vb = new GSVertexBufferState(sizeof(GSVertexHW11), vert_format, countof(vert_format));
|
||||
}
|
||||
|
||||
void GSDeviceOGL::SetupIA(const void* vertices, int count, GLenum prim)
|
||||
{
|
||||
IASetVertexState(m_vb);
|
||||
IASetVertexBuffer(vertices, count);
|
||||
IASetPrimitiveTopology(prim);
|
||||
}
|
||||
|
||||
void GSDeviceOGL::SetupVS(VSSelector sel, const VSConstantBuffer* cb)
|
||||
{
|
||||
// *************************************************************
|
||||
// Static
|
||||
// *************************************************************
|
||||
auto i = m_vs.find(sel);
|
||||
|
||||
if(i == m_vs.end())
|
||||
{
|
||||
std::string macro = format("#define VS_BPPZ %d\n", sel.bppz)
|
||||
+ format("#define VS_TME %d\n", sel.tme)
|
||||
+ format("#define VS_FST %d\n", sel.fst)
|
||||
+ format("#define VS_RTCOPY %d\n", sel.rtcopy);
|
||||
|
||||
GLuint vs;
|
||||
CompileShaderFromSource("tfx.glsl", "vs_main", GL_VERTEX_SHADER, &vs, macro);
|
||||
|
||||
m_vs[sel] = vs;
|
||||
i = m_vs.find(sel);
|
||||
}
|
||||
|
||||
// *************************************************************
|
||||
// Dynamic
|
||||
// *************************************************************
|
||||
if(m_vs_cb_cache.Update(cb))
|
||||
{
|
||||
SetUniformBuffer(m_vs_cb);
|
||||
m_vs_cb->upload(&cb);
|
||||
}
|
||||
|
||||
VSSetShader(i->second);
|
||||
}
|
||||
|
||||
void GSDeviceOGL::SetupGS(GSSelector sel)
|
||||
{
|
||||
// *************************************************************
|
||||
// Static
|
||||
// *************************************************************
|
||||
GLuint gs = 0;
|
||||
if(sel.prim > 0 && (sel.iip == 0 || sel.prim == 3)) {
|
||||
auto i = m_gs.find(sel);
|
||||
|
||||
if(i == m_gs.end()) {
|
||||
std::string macro = format("#define GS_IIP %d\n", sel.iip)
|
||||
+ format("#define GS_PRIM %d\n", sel.prim);
|
||||
|
||||
CompileShaderFromSource("tfx.glsl", "gs_main", GL_GEOMETRY_SHADER, &gs, macro);
|
||||
|
||||
m_gs[sel] = gs;
|
||||
} else {
|
||||
gs = i->second;
|
||||
}
|
||||
}
|
||||
// *************************************************************
|
||||
// Dynamic
|
||||
// *************************************************************
|
||||
GSSetShader(gs);
|
||||
}
|
||||
|
||||
void GSDeviceOGL::SetupPS(PSSelector sel, const PSConstantBuffer* cb, PSSamplerSelector ssel)
|
||||
{
|
||||
// *************************************************************
|
||||
// Static
|
||||
// *************************************************************
|
||||
GLuint ps;
|
||||
auto i = m_ps.find(sel);
|
||||
|
||||
if (i == m_ps.end())
|
||||
{
|
||||
std::string macro = format("#define PS_FST %d\n", sel.fst)
|
||||
+ format("#define PS_WMS %d\n", sel.wms)
|
||||
+ format("#define PS_WMT %d\n", sel.wmt)
|
||||
+ format("#define PS_FMT %d\n", sel.fmt)
|
||||
+ format("#define PS_AEM %d\n", sel.aem)
|
||||
+ format("#define PS_TFX %d\n", sel.tfx)
|
||||
+ format("#define PS_TCC %d\n", sel.tcc)
|
||||
+ format("#define PS_ATST %d\n", sel.atst)
|
||||
+ format("#define PS_FOG %d\n", sel.fog)
|
||||
+ format("#define PS_CLR1 %d\n", sel.clr1)
|
||||
+ format("#define PS_FBA %d\n", sel.fba)
|
||||
+ format("#define PS_AOUT %d\n", sel.aout)
|
||||
+ format("#define PS_LTF %d\n", sel.ltf)
|
||||
+ format("#define PS_COLCLIP %d\n", sel.colclip)
|
||||
+ format("#define PS_DATE %d\n", sel.date);
|
||||
|
||||
CompileShaderFromSource("tfx.glsl", "ps_main", GL_FRAGMENT_SHADER, &ps, macro);
|
||||
|
||||
m_ps[sel] = ps;
|
||||
i = m_ps.find(sel);
|
||||
} else {
|
||||
ps = i->second;
|
||||
}
|
||||
|
||||
// *************************************************************
|
||||
// Dynamic
|
||||
// *************************************************************
|
||||
if(m_ps_cb_cache.Update(cb))
|
||||
{
|
||||
SetUniformBuffer(m_ps_cb);
|
||||
m_ps_cb->upload(&cb);
|
||||
}
|
||||
|
||||
GLuint ss0, ss1;
|
||||
ss0 = ss1 = 0;
|
||||
if(sel.tfx != 4)
|
||||
{
|
||||
if(!(sel.fmt < 3 && sel.wms < 3 && sel.wmt < 3))
|
||||
{
|
||||
ssel.ltf = 0;
|
||||
}
|
||||
|
||||
auto i = m_ps_ss.find(ssel);
|
||||
|
||||
if(i != m_ps_ss.end())
|
||||
{
|
||||
ss0 = i->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
// *************************************************************
|
||||
// Static
|
||||
// *************************************************************
|
||||
glGenSamplers(1, &ss0);
|
||||
if (ssel.ltf) {
|
||||
glSamplerParameteri(ss0, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glSamplerParameteri(ss0, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
} else {
|
||||
glSamplerParameteri(ss0, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glSamplerParameteri(ss0, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
}
|
||||
|
||||
// FIXME ensure U -> S, V -> T and W->R
|
||||
if (ssel.tau)
|
||||
glSamplerParameteri(ss0, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
else
|
||||
glSamplerParameteri(ss0, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
|
||||
if (ssel.tav)
|
||||
glSamplerParameteri(ss0, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
else
|
||||
glSamplerParameteri(ss0, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glSamplerParameteri(ss0, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||
|
||||
// FIXME which value for GL_TEXTURE_MIN_LOD
|
||||
glSamplerParameteri(m_rt_ss, GL_TEXTURE_MAX_LOD, FLT_MAX);
|
||||
// FIXME: seems there is 2 possibility in opengl
|
||||
// DX: sd.ComparisonFunc = D3D11_COMPARISON_NEVER;
|
||||
// glSamplerParameteri(m_rt_ss, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
||||
glSamplerParameteri(m_rt_ss, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
||||
glSamplerParameteri(m_rt_ss, GL_TEXTURE_COMPARE_FUNC, GL_NEVER);
|
||||
// FIXME: need ogl extension sd.MaxAnisotropy = 16;
|
||||
|
||||
m_ps_ss[ssel] = ss0;
|
||||
}
|
||||
|
||||
if(sel.fmt >= 3)
|
||||
{
|
||||
ss1 = m_palette_ss;
|
||||
}
|
||||
}
|
||||
|
||||
PSSetSamplerState(ss0, ss1, sel.date ? m_rt_ss : 0);
|
||||
|
||||
PSSetShader(ps);
|
||||
}
|
||||
|
||||
void GSDeviceOGL::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint8 afix)
|
||||
{
|
||||
auto i = m_om_dss.find(dssel);
|
||||
|
||||
// *************************************************************
|
||||
// Static
|
||||
// *************************************************************
|
||||
if (i == m_om_dss.end())
|
||||
{
|
||||
GSDepthStencilOGL* dss = new GSDepthStencilOGL();
|
||||
|
||||
if (dssel.date)
|
||||
{
|
||||
dss->m_stencil_enable = true;
|
||||
dss->m_stencil_func = GL_EQUAL;
|
||||
dss->m_stencil_spass_dpass_op = GL_KEEP;
|
||||
}
|
||||
|
||||
if(dssel.ztst != ZTST_ALWAYS || dssel.zwe)
|
||||
{
|
||||
static const GLenum ztst[] =
|
||||
{
|
||||
GL_NEVER,
|
||||
GL_ALWAYS,
|
||||
GL_GEQUAL,
|
||||
GL_GREATER
|
||||
};
|
||||
dss->m_depth_enable = true;
|
||||
dss->m_depth_mask = dssel.zwe ? GL_TRUE : GL_FALSE;
|
||||
dss->m_depth_func = ztst[dssel.ztst];
|
||||
}
|
||||
|
||||
m_om_dss[dssel] = dss;
|
||||
i = m_om_dss.find(dssel);
|
||||
}
|
||||
|
||||
// *************************************************************
|
||||
// Dynamic
|
||||
// *************************************************************
|
||||
OMSetDepthStencilState(i->second, 1);
|
||||
|
||||
// *************************************************************
|
||||
// Static
|
||||
// *************************************************************
|
||||
auto j = m_om_bs.find(bsel);
|
||||
|
||||
if(j == m_om_bs.end())
|
||||
{
|
||||
GSBlendStateOGL* bs = new GSBlendStateOGL();
|
||||
|
||||
bs->m_enable = bsel.abe;
|
||||
|
||||
if(bsel.abe)
|
||||
{
|
||||
int i = ((bsel.a * 3 + bsel.b) * 3 + bsel.c) * 3 + bsel.d;
|
||||
bs->m_equation_RGB = m_blendMapD3D9[i].op;
|
||||
bs->m_func_sRGB = m_blendMapD3D9[i].src;
|
||||
bs->m_func_dRGB = m_blendMapD3D9[i].dst;
|
||||
|
||||
// Not very good but I don't wanna write another 81 row table
|
||||
if(bsel.negative)
|
||||
{
|
||||
if(bs->m_equation_RGB == GL_FUNC_ADD)
|
||||
bs->m_equation_RGB = GL_FUNC_REVERSE_SUBTRACT;
|
||||
else if(bs->m_equation_RGB == GL_FUNC_REVERSE_SUBTRACT)
|
||||
bs->m_equation_RGB = GL_FUNC_ADD;
|
||||
else
|
||||
; // god knows, best just not to mess with it for now
|
||||
}
|
||||
|
||||
if(m_blendMapD3D9[i].bogus == 1)
|
||||
{
|
||||
if (bsel.a == 0)
|
||||
bs->m_func_sRGB = GL_ONE;
|
||||
else
|
||||
bs->m_func_dRGB = GL_ONE;
|
||||
|
||||
const string afixstr = format("%d >> 7", afix);
|
||||
const char *col[3] = {"Cs", "Cd", "0"};
|
||||
const char *alpha[3] = {"As", "Ad", afixstr.c_str()};
|
||||
|
||||
// FIXME, need to investigate OGL capabilities. Maybe for OGL5 ;)
|
||||
fprintf(stderr, "Impossible blend for D3D: (%s - %s) * %s + %s\n", col[bsel.a], col[bsel.b], alpha[bsel.c], col[bsel.d]);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
bs->m_r_msk = bsel.wr;
|
||||
bs->m_g_msk = bsel.wg;
|
||||
bs->m_b_msk = bsel.wb;
|
||||
bs->m_a_msk = bsel.wa;
|
||||
|
||||
m_om_bs[bsel] = bs;
|
||||
j = m_om_bs.find(bsel);
|
||||
}
|
||||
|
||||
// *************************************************************
|
||||
// Dynamic
|
||||
// *************************************************************
|
||||
OMSetBlendState(j->second, (float)(int)afix / 0x80);
|
||||
}
|
Loading…
Reference in New Issue