mirror of https://github.com/PCSX2/pcsx2.git
gsdx-ogl:
* make a rough implementation of most of the opengl device interface. Only a savestate nothing to expect yet. * depend of libglew 1.6 (normally 1.7 but I manually defined the only missing function) git-svn-id: http://pcsx2.googlecode.com/svn/branches/gsdx-ogl@4971 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
da66ca7fd9
commit
6125baa578
|
@ -186,6 +186,9 @@ target_link_libraries(${Output} ${X11_LIBRARIES})
|
||||||
# link target with SDL
|
# link target with SDL
|
||||||
target_link_libraries(${Output} ${SDL_LIBRARY})
|
target_link_libraries(${Output} ${SDL_LIBRARY})
|
||||||
|
|
||||||
|
# link target with glew
|
||||||
|
target_link_libraries(${Output} ${GLEW_LIBRARY})
|
||||||
|
|
||||||
# User flags options
|
# User flags options
|
||||||
if(NOT USER_CMAKE_LD_FLAGS STREQUAL "")
|
if(NOT USER_CMAKE_LD_FLAGS STREQUAL "")
|
||||||
target_link_libraries(${Output} "${USER_CMAKE_LD_FLAGS}")
|
target_link_libraries(${Output} "${USER_CMAKE_LD_FLAGS}")
|
||||||
|
|
|
@ -54,21 +54,52 @@
|
||||||
|
|
||||||
|
|
||||||
GSDeviceOGL::GSDeviceOGL()
|
GSDeviceOGL::GSDeviceOGL()
|
||||||
|
: m_free_window(false)
|
||||||
|
, m_window(NULL)
|
||||||
|
, m_vb(0)
|
||||||
|
, m_pipeline(0)
|
||||||
|
, m_srv_changed(false)
|
||||||
|
, m_ss_changed(false)
|
||||||
{
|
{
|
||||||
/* TODO */
|
|
||||||
m_msaa = theApp.GetConfig("msaa", 0);
|
m_msaa = theApp.GetConfig("msaa", 0);
|
||||||
|
memset(&m_merge, 0, sizeof(m_merge));
|
||||||
|
memset(&m_interlace, 0, sizeof(m_interlace));
|
||||||
|
memset(&m_convert, 0, sizeof(m_convert));
|
||||||
|
memset(&m_date, 0, sizeof(m_date));
|
||||||
|
memset(&m_state, 0, sizeof(m_state));
|
||||||
}
|
}
|
||||||
|
|
||||||
GSDeviceOGL::~GSDeviceOGL() { /* TODO */ }
|
GSDeviceOGL::~GSDeviceOGL()
|
||||||
|
{
|
||||||
|
if(m_window != NULL && m_free_window)
|
||||||
|
{
|
||||||
|
SDL_DestroyWindow(m_window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GSTexture* GSDeviceOGL::CreateSurface(int type, int w, int h, bool msaa, int format)
|
GSTexture* GSDeviceOGL::CreateSurface(int type, int w, int h, bool msaa, int format)
|
||||||
{
|
{
|
||||||
// A wrapper to call GSTextureOGL, with the different kind of parameter
|
// A wrapper to call GSTextureOGL, with the different kind of parameter
|
||||||
|
GSTextureOGL* t = NULL;
|
||||||
|
t = new GSTextureOGL(type, w, h, msaa, format);
|
||||||
|
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
case GSTexture::RenderTarget:
|
||||||
|
ClearRenderTarget(t, 0);
|
||||||
|
break;
|
||||||
|
case GSTexture::DepthStencil:
|
||||||
|
ClearDepth(t, 0);
|
||||||
|
//FIXME might be need to clear the stencil too
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
GSTexture* GSDeviceOGL::FetchSurface(int type, int w, int h, bool msaa, int format)
|
GSTexture* GSDeviceOGL::FetchSurface(int type, int w, int h, bool msaa, int format)
|
||||||
{
|
{
|
||||||
// FIXME: keep DX code. Do not know how work msaa but not important for the moment
|
// FIXME: keep DX code. Do not know how work msaa but not important for the moment
|
||||||
|
// Current config give only 0 or 1
|
||||||
#if 0
|
#if 0
|
||||||
if(m_msaa < 2) {
|
if(m_msaa < 2) {
|
||||||
msaa = false;
|
msaa = false;
|
||||||
|
@ -81,39 +112,394 @@ GSTexture* GSDeviceOGL::FetchSurface(int type, int w, int h, bool msaa, int form
|
||||||
|
|
||||||
bool GSDeviceOGL::Create(GSWnd* wnd)
|
bool GSDeviceOGL::Create(GSWnd* wnd)
|
||||||
{
|
{
|
||||||
/* TODO */
|
if (m_window == NULL) {
|
||||||
|
#if SDL_VERSION_ATLEAST(1,3,0)
|
||||||
|
m_window = SDL_CreateWindowFrom(wnd->GetHandle());
|
||||||
|
#else
|
||||||
|
assert(0);
|
||||||
|
#endif
|
||||||
|
m_free_window = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __LINUX__
|
||||||
|
// In GSopen2, sdl failed to received any resize event. GSWnd::GetClientRect need to manually
|
||||||
|
// set the window size... So we send the m_window to the wnd object to allow some manipulation on it.
|
||||||
|
wnd->SetWindow(m_window);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ****************************************************************
|
||||||
|
// Various object
|
||||||
|
// ****************************************************************
|
||||||
|
glGenProgramPipelines(1, &m_pipeline);
|
||||||
|
glBindProgramPipeline(m_pipeline);
|
||||||
|
|
||||||
|
glGenFramebuffers(1, &m_fbo);
|
||||||
|
// ****************************************************************
|
||||||
|
// convert
|
||||||
|
// ****************************************************************
|
||||||
|
|
||||||
|
GSInputLayout il_convert[2] =
|
||||||
|
{
|
||||||
|
{0, 4, GL_FLOAT, sizeof(GSVertexPT1), (const GLvoid*)offsetof(struct GSVertexPT1, p) },
|
||||||
|
{1, 2, GL_FLOAT, sizeof(GSVertexPT1), (const GLvoid*)offsetof(struct GSVertexPT1, t) },
|
||||||
|
};
|
||||||
|
|
||||||
|
m_convert.il[0] = il_convert[0];
|
||||||
|
m_convert.il[1] = il_convert[1];
|
||||||
|
|
||||||
|
CompileShaderFromSource("convert.glsl", "vs_main", GL_VERTEX_SHADER, &m_convert.vs);
|
||||||
|
for(int i = 0; i < countof(m_convert.ps); i++)
|
||||||
|
CompileShaderFromSource("convert.glsl", format("ps_main%d", i), GL_FRAGMENT_SHADER, &m_convert.ps[i]);
|
||||||
|
|
||||||
|
// Note the following object are initialized to 0 so disabled.
|
||||||
|
// Note: maybe enable blend with a factor of 1
|
||||||
|
// m_convert.dss, m_convert.bs
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
memset(&dsd, 0, sizeof(dsd));
|
||||||
|
|
||||||
|
dsd.DepthEnable = false;
|
||||||
|
dsd.StencilEnable = false;
|
||||||
|
|
||||||
|
hr = m_dev->CreateDepthStencilState(&dsd, &m_convert.dss);
|
||||||
|
|
||||||
|
memset(&bsd, 0, sizeof(bsd));
|
||||||
|
|
||||||
|
bsd.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
|
||||||
|
|
||||||
|
hr = m_dev->CreateBlendState(&bsd, &m_convert.bs);
|
||||||
|
#endif
|
||||||
|
glGenSamplers(1, &m_convert.ln);
|
||||||
|
glSamplerParameteri(m_convert.ln, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glSamplerParameteri(m_convert.ln, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glSamplerParameteri(m_convert.ln, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||||
|
glSamplerParameteri(m_convert.ln, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
glSamplerParameteri(m_convert.ln, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
// FIXME which value for GL_TEXTURE_MIN_LOD
|
||||||
|
glSamplerParameteri(m_convert.ln, GL_TEXTURE_MAX_LOD, FLT_MAX);
|
||||||
|
// FIXME: seems there is 2 possibility in opengl
|
||||||
|
// DX: sd.ComparisonFunc = D3D11_COMPARISON_NEVER;
|
||||||
|
// glSamplerParameteri(m_convert.ln, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
||||||
|
glSamplerParameteri(m_convert.ln, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
||||||
|
glSamplerParameteri(m_convert.ln, GL_TEXTURE_COMPARE_FUNC, GL_NEVER);
|
||||||
|
|
||||||
|
|
||||||
|
glGenSamplers(1, &m_convert.pt);
|
||||||
|
glGenSamplers(1, &m_convert.pt);
|
||||||
|
glSamplerParameteri(m_convert.pt, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glSamplerParameteri(m_convert.pt, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glSamplerParameteri(m_convert.pt, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
||||||
|
glSamplerParameteri(m_convert.pt, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
glSamplerParameteri(m_convert.pt, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
// FIXME which value for GL_TEXTURE_MIN_LOD
|
||||||
|
glSamplerParameteri(m_convert.pt, GL_TEXTURE_MAX_LOD, FLT_MAX);
|
||||||
|
// FIXME: seems there is 2 possibility in opengl
|
||||||
|
// DX: sd.ComparisonFunc = D3D11_COMPARISON_NEVER;
|
||||||
|
// glSamplerParameteri(m_convert.pt, GL_TEXTURE_COMPARE_MODE, GL_NONE);
|
||||||
|
glSamplerParameteri(m_convert.pt, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
|
||||||
|
glSamplerParameteri(m_convert.pt, GL_TEXTURE_COMPARE_FUNC, GL_NEVER);
|
||||||
|
|
||||||
|
// ****************************************************************
|
||||||
|
// merge
|
||||||
|
// ****************************************************************
|
||||||
|
|
||||||
|
m_merge.cb->index = 1;
|
||||||
|
m_merge.cb->byte_size = sizeof(MergeConstantBuffer);
|
||||||
|
glGenBuffers(1, &m_merge.cb->buffer);
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, m_merge.cb->buffer);
|
||||||
|
glBufferData(GL_UNIFORM_BUFFER, m_merge.cb->byte_size, NULL, GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
|
for(int i = 0; i < countof(m_merge.ps); i++)
|
||||||
|
CompileShaderFromSource("merge.glsl", format("ps_main%d", i), GL_FRAGMENT_SHADER, &m_merge.ps[i]);
|
||||||
|
|
||||||
|
m_merge.bs->m_enable = true;
|
||||||
|
m_merge.bs->m_equation_RGB = GL_FUNC_ADD;
|
||||||
|
m_merge.bs->m_equation_ALPHA = GL_FUNC_ADD;
|
||||||
|
m_merge.bs->m_func_sRGB = GL_SRC_ALPHA;
|
||||||
|
m_merge.bs->m_func_dRGB = GL_ONE_MINUS_SRC_ALPHA;
|
||||||
|
m_merge.bs->m_func_sALPHA = GL_ONE;
|
||||||
|
m_merge.bs->m_func_dALPHA = GL_ZERO;
|
||||||
|
|
||||||
|
// ****************************************************************
|
||||||
|
// interlace
|
||||||
|
// ****************************************************************
|
||||||
|
m_interlace.cb->index = 2;
|
||||||
|
m_interlace.cb->byte_size = sizeof(InterlaceConstantBuffer);
|
||||||
|
glGenBuffers(1, &m_interlace.cb->buffer);
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, m_interlace.cb->buffer);
|
||||||
|
glBufferData(GL_UNIFORM_BUFFER, m_interlace.cb->byte_size, NULL, GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
|
for(int i = 0; i < countof(m_interlace.ps); i++)
|
||||||
|
CompileShaderFromSource("interlace.glsl", format("ps_main%d", i), GL_FRAGMENT_SHADER, &m_interlace.ps[i]);
|
||||||
|
|
||||||
|
// ****************************************************************
|
||||||
|
// rasterization configuration
|
||||||
|
// ****************************************************************
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
// FIXME enable it when multisample code will be here
|
||||||
|
// DX: rd.MultisampleEnable = true;
|
||||||
|
glDisable(GL_MULTISAMPLE);
|
||||||
|
// Hum I don't know for those options but let's hope there are not activated
|
||||||
|
#if 0
|
||||||
|
rd.FrontCounterClockwise = false;
|
||||||
|
rd.DepthBias = false;
|
||||||
|
rd.DepthBiasClamp = 0;
|
||||||
|
rd.SlopeScaledDepthBias = 0;
|
||||||
|
rd.DepthClipEnable = false; // ???
|
||||||
|
rd.AntialiasedLineEnable = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GSVector4i rect = wnd->GetClientRect();
|
||||||
|
Reset(rect.z, rect.w);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
HRESULT hr = E_FAIL;
|
||||||
|
|
||||||
|
DXGI_SWAP_CHAIN_DESC scd;
|
||||||
|
D3D11_BUFFER_DESC bd;
|
||||||
|
D3D11_SAMPLER_DESC sd;
|
||||||
|
D3D11_DEPTH_STENCIL_DESC dsd;
|
||||||
|
D3D11_RASTERIZER_DESC rd;
|
||||||
|
D3D11_BLEND_DESC bsd;
|
||||||
|
|
||||||
|
memset(&scd, 0, sizeof(scd));
|
||||||
|
|
||||||
|
scd.BufferCount = 2;
|
||||||
|
scd.BufferDesc.Width = 1;
|
||||||
|
scd.BufferDesc.Height = 1;
|
||||||
|
scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
//scd.BufferDesc.RefreshRate.Numerator = 60;
|
||||||
|
//scd.BufferDesc.RefreshRate.Denominator = 1;
|
||||||
|
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||||
|
scd.OutputWindow = (HWND)m_wnd->GetHandle();
|
||||||
|
scd.SampleDesc.Count = 1;
|
||||||
|
scd.SampleDesc.Quality = 0;
|
||||||
|
|
||||||
|
// Always start in Windowed mode. According to MS, DXGI just "prefers" this, and it's more or less
|
||||||
|
// required if we want to add support for dual displays later on. The fullscreen/exclusive flip
|
||||||
|
// will be issued after all other initializations are complete.
|
||||||
|
|
||||||
|
scd.Windowed = TRUE;
|
||||||
|
|
||||||
|
// NOTE : D3D11_CREATE_DEVICE_SINGLETHREADED
|
||||||
|
// This flag is safe as long as the DXGI's internal message pump is disabled or is on the
|
||||||
|
// same thread as the GS window (which the emulator makes sure of, if it utilizes a
|
||||||
|
// multithreaded GS). Setting the flag is a nice and easy 5% speedup on GS-intensive scenes.
|
||||||
|
|
||||||
|
uint32 flags = D3D11_CREATE_DEVICE_SINGLETHREADED;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
flags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
D3D_FEATURE_LEVEL level;
|
||||||
|
|
||||||
|
const D3D_FEATURE_LEVEL levels[] =
|
||||||
|
{
|
||||||
|
D3D_FEATURE_LEVEL_11_0,
|
||||||
|
D3D_FEATURE_LEVEL_10_1,
|
||||||
|
D3D_FEATURE_LEVEL_10_0,
|
||||||
|
};
|
||||||
|
|
||||||
|
hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, flags, levels, countof(levels), D3D11_SDK_VERSION, &scd, &m_swapchain, &m_dev, &level, &m_ctx);
|
||||||
|
// hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, flags, NULL, 0, D3D11_SDK_VERSION, &scd, &m_swapchain, &m_dev, &level, &m_ctx);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ****************************************************************
|
||||||
|
// The check of capability is done when context is created on openGL
|
||||||
|
// For the moment don't bother with extension, I just ask the most recent openGL version
|
||||||
|
// ****************************************************************
|
||||||
|
#if 0
|
||||||
|
if(FAILED(hr)) return false;
|
||||||
|
|
||||||
|
if(!SetFeatureLevel(level, true))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS options;
|
||||||
|
|
||||||
|
hr = m_dev->CheckFeatureSupport(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, &options, sizeof(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS));
|
||||||
|
|
||||||
|
// msaa
|
||||||
|
|
||||||
|
for(uint32 i = 2; i <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i++)
|
||||||
|
{
|
||||||
|
uint32 quality[2] = {0, 0};
|
||||||
|
|
||||||
|
if(SUCCEEDED(m_dev->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, i, &quality[0])) && quality[0] > 0
|
||||||
|
&& SUCCEEDED(m_dev->CheckMultisampleQualityLevels(DXGI_FORMAT_D32_FLOAT_S8X24_UINT, i, &quality[1])) && quality[1] > 0)
|
||||||
|
{
|
||||||
|
m_msaa_desc.Count = i;
|
||||||
|
m_msaa_desc.Quality = std::min<uint32>(quality[0] - 1, quality[1] - 1);
|
||||||
|
|
||||||
|
if(i >= m_msaa) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_msaa_desc.Count == 1)
|
||||||
|
{
|
||||||
|
m_msaa = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// TODO Later
|
||||||
|
// ****************************************************************
|
||||||
|
// fxaa
|
||||||
|
// ****************************************************************
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
memset(&bd, 0, sizeof(bd));
|
||||||
|
|
||||||
|
bd.ByteWidth = sizeof(FXAAConstantBuffer);
|
||||||
|
bd.Usage = D3D11_USAGE_DEFAULT;
|
||||||
|
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||||
|
|
||||||
|
hr = m_dev->CreateBuffer(&bd, NULL, &m_fxaa.cb);
|
||||||
|
|
||||||
|
hr = CompileShader(IDR_FXAA_FX, "ps_main", NULL, &m_fxaa.ps);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// TODO later
|
||||||
|
#if 0
|
||||||
|
CreateTextureFX();
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
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;
|
||||||
|
dsd.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
|
||||||
|
dsd.BackFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE;
|
||||||
|
dsd.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
|
||||||
|
dsd.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
|
||||||
|
|
||||||
|
m_dev->CreateDepthStencilState(&dsd, &m_date.dss);
|
||||||
|
|
||||||
|
D3D11_BLEND_DESC blend;
|
||||||
|
|
||||||
|
memset(&blend, 0, sizeof(blend));
|
||||||
|
|
||||||
|
m_dev->CreateBlendState(&blend, &m_date.bs);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GSDeviceOGL::Reset(int w, int h)
|
bool GSDeviceOGL::Reset(int w, int h)
|
||||||
{
|
{
|
||||||
// Hum map, m_backbuffer to a GSTexture
|
if(!GSDevice::Reset(w, h))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// Opengl allocate the backbuffer with the window. The render is done in the backbuffer when
|
||||||
|
// there isn't any FBO. Only a dummy texture is created to easily detect when the rendering is done
|
||||||
|
// in the backbuffer
|
||||||
|
m_backbuffer = new GSTextureOGL(0, w, h, false, 0);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if(m_swapchain)
|
||||||
|
{
|
||||||
|
DXGI_SWAP_CHAIN_DESC scd;
|
||||||
|
|
||||||
|
memset(&scd, 0, sizeof(scd));
|
||||||
|
|
||||||
|
m_swapchain->GetDesc(&scd);
|
||||||
|
m_swapchain->ResizeBuffers(scd.BufferCount, w, h, scd.BufferDesc.Format, 0);
|
||||||
|
|
||||||
|
CComPtr<ID3D11Texture2D> backbuffer;
|
||||||
|
|
||||||
|
if(FAILED(m_swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&backbuffer)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Swap buffer (back buffer, front buffer)
|
m_backbuffer = new GSTexture11(backbuffer);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSDeviceOGL::Flip()
|
||||||
|
{
|
||||||
// Warning it is not OGL dependent but application dependant (glx and so not portable)
|
// Warning it is not OGL dependent but application dependant (glx and so not portable)
|
||||||
void GSDeviceOGL::Flip() { /* TODO */ }
|
#if SDL_VERSION_ATLEAST(1,3,0)
|
||||||
|
SDL_GL_SwapWindow(m_window);
|
||||||
|
#else
|
||||||
|
SDL_GL_SwapBuffers();
|
||||||
|
#endif
|
||||||
|
|
||||||
// glDrawArrays
|
}
|
||||||
void GSDeviceOGL::DrawPrimitive() { /* TODO */ }
|
|
||||||
|
|
||||||
// Just a wrapper around glClear* functions
|
void GSDeviceOGL::DrawPrimitive()
|
||||||
void GSDeviceOGL::ClearRenderTarget(GSTexture* t, const GSVector4& c) { /* TODO */ }
|
{
|
||||||
void GSDeviceOGL::ClearRenderTarget(GSTexture* t, uint32 c) { /* TODO */ }
|
glDrawArrays(m_state.topology, m_vertices.start, m_vertices.count);
|
||||||
void GSDeviceOGL::ClearDepth(GSTexture* t, float c) { /* TODO */ }
|
}
|
||||||
void GSDeviceOGL::ClearStencil(GSTexture* t, uint8 c) { /* TODO */ }
|
|
||||||
|
|
||||||
// the 4 next functions are only used to set some default value for the format.
|
void GSDeviceOGL::ClearRenderTarget(GSTexture* t, const GSVector4& c)
|
||||||
// Need to find the default format...
|
{
|
||||||
// depth_stencil => GL_DEPTH32F_STENCIL8
|
GSTextureOGL* t_ogl = (GSTextureOGL*)t;
|
||||||
// others => (need 4* 8bits unsigned normalized integer) (GL_RGBA8 )
|
// FIXME I need to clarify this FBO attachment stuff
|
||||||
GSTexture* GSDeviceOGL::CreateRenderTarget(int w, int h, bool msaa, int format) { /* TODO */ }
|
// I would like to avoid FBO for a basic clean operation
|
||||||
GSTexture* GSDeviceOGL::CreateDepthStencil(int w, int h, bool msaa, int format) { /* TODO */ }
|
//glClearBufferfv(GL_COLOR, t_ogl->attachment(), c.v);
|
||||||
GSTexture* GSDeviceOGL::CreateTexture(int w, int h, int format) { /* TODO */ }
|
}
|
||||||
GSTexture* GSDeviceOGL::CreateOffscreen(int w, int h, int format) { /* TODO */ }
|
|
||||||
|
void GSDeviceOGL::ClearRenderTarget(GSTexture* t, uint32 c)
|
||||||
|
{
|
||||||
|
GSTextureOGL* t_ogl = (GSTextureOGL*)t;
|
||||||
|
GSVector4 color = GSVector4::rgba32(c) * (1.0f / 255);
|
||||||
|
// FIXME I need to clarify this FBO attachment stuff
|
||||||
|
// I would like to avoid FBO for a basic clean operation
|
||||||
|
//glClearBufferfv(GL_COLOR, t_ogl->attachment(), color.v);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSDeviceOGL::ClearDepth(GSTexture* t, float c)
|
||||||
|
{
|
||||||
|
glClearBufferfv(GL_DEPTH, 0, &c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSDeviceOGL::ClearStencil(GSTexture* t, uint8 c)
|
||||||
|
{
|
||||||
|
GLint color = c;
|
||||||
|
glClearBufferiv(GL_STENCIL, 0, &color);
|
||||||
|
}
|
||||||
|
|
||||||
|
GSTexture* GSDeviceOGL::CreateRenderTarget(int w, int h, bool msaa, int format)
|
||||||
|
{
|
||||||
|
return GSDevice::CreateRenderTarget(w, h, msaa, format ? format : GL_RGBA8);
|
||||||
|
}
|
||||||
|
|
||||||
|
GSTexture* GSDeviceOGL::CreateDepthStencil(int w, int h, bool msaa, int format)
|
||||||
|
{
|
||||||
|
return GSDevice::CreateDepthStencil(w, h, msaa, format ? format : GL_DEPTH32F_STENCIL8);
|
||||||
|
}
|
||||||
|
|
||||||
|
GSTexture* GSDeviceOGL::CreateTexture(int w, int h, int format)
|
||||||
|
{
|
||||||
|
return GSDevice::CreateTexture(w, h, format ? format : GL_RGBA8);
|
||||||
|
}
|
||||||
|
|
||||||
|
GSTexture* GSDeviceOGL::CreateOffscreen(int w, int h, int format)
|
||||||
|
{
|
||||||
|
return GSDevice::CreateOffscreen(w, h, format ? format : GL_RGBA8);
|
||||||
|
}
|
||||||
|
|
||||||
// blit a texture into an offscreen buffer
|
// blit a texture into an offscreen buffer
|
||||||
GSTexture* GSDeviceOGL::CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format)
|
GSTexture* GSDeviceOGL::CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format)
|
||||||
{
|
{
|
||||||
|
// I'm not sure about the object type for offscreen buffer
|
||||||
|
// TODO later;
|
||||||
|
assert(0);
|
||||||
|
|
||||||
// Need to find format equivalent. Then I think it will be straight forward
|
// Need to find format equivalent. Then I think it will be straight forward
|
||||||
|
|
||||||
// A four-component, 32-bit unsigned-normalized-integer format that supports 8 bits per channel including alpha.
|
// A four-component, 32-bit unsigned-normalized-integer format that supports 8 bits per channel including alpha.
|
||||||
|
@ -167,34 +553,49 @@ GSTexture* GSDeviceOGL::CopyOffscreen(GSTexture* src, const GSVector4& sr, int w
|
||||||
// From a sub-part to a full texture
|
// From a sub-part to a full texture
|
||||||
void GSDeviceOGL::CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r)
|
void GSDeviceOGL::CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
if(!st || !dt)
|
if(!st || !dt)
|
||||||
{
|
{
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D11_BOX box = {r.left, r.top, 0, r.right, r.bottom, 1};
|
assert(0);
|
||||||
|
// FIXME attach the texture to the FBO
|
||||||
|
GSTextureOGL* st_ogl = (GSTextureOGL*) st;
|
||||||
|
GSTextureOGL* dt_ogl = (GSTextureOGL*) dt;
|
||||||
|
dt_ogl->Attach(GL_COLOR_ATTACHMENT0);
|
||||||
|
st_ogl->Attach(GL_COLOR_ATTACHMENT1);
|
||||||
|
|
||||||
|
glReadBuffer(GL_COLOR_ATTACHMENT1);
|
||||||
|
// FIXME I'not sure how to select the destination
|
||||||
|
// const GLenum draw_buffer[1] = { GL_COLOR_ATTACHMENT0 };
|
||||||
|
// glDrawBuffers(draw_buffer);
|
||||||
|
dt_ogl->EnableUnit(0);
|
||||||
|
// FIXME need acess of target and it probably need to be same for both
|
||||||
|
//glCopyTexSubImage2D(dt_ogl.m_texture_target, 0, 0, 0, r.left, r.bottom, r.right-r.left, r.top-r.bottom);
|
||||||
|
// FIXME I'm not sure GL_TEXTURE_RECTANGLE is supported!!!
|
||||||
|
//glCopyTexSubImage2D(GL_TEXTURE_RECTANGLE, 0, 0, 0, r.left, r.bottom, r.right-r.left, r.top-r.bottom);
|
||||||
|
#if 0
|
||||||
|
D3D11_BOX box = {r.left, r.top, 0, r.right, r.bottom, 1};
|
||||||
m_ctx->CopySubresourceRegion(*(GSTexture11*)dt, 0, 0, 0, 0, *(GSTexture11*)st, 0, &box);
|
m_ctx->CopySubresourceRegion(*(GSTexture11*)dt, 0, 0, 0, 0, *(GSTexture11*)st, 0, &box);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Raster flow to resize a texture
|
|
||||||
// Note just call the StretchRect hardware accelerated
|
|
||||||
void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader, bool linear)
|
void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader, bool linear)
|
||||||
{
|
{
|
||||||
/* TODO */
|
StretchRect(st, sr, dt, dr, m_convert.ps[shader], NULL, linear);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, GLuint ps, GSUniformBufferOGL* ps_cb, bool linear)
|
void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, GLuint ps, GSUniformBufferOGL* ps_cb, bool linear)
|
||||||
{
|
{
|
||||||
// TODO
|
StretchRect(st, sr, dt, dr, ps, ps_cb, m_convert.bs, linear);
|
||||||
}
|
}
|
||||||
|
|
||||||
// probably no difficult to convert when all helpers function will be done
|
// probably no difficult to convert when all helpers function will be done
|
||||||
void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, GLuint ps, GSUniformBufferOGL ps_cb, GSBlendStateOGL* bs, bool linear)
|
void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, GLuint ps, GSUniformBufferOGL* ps_cb, GSBlendStateOGL* bs, bool linear)
|
||||||
{
|
{
|
||||||
|
//TODO later
|
||||||
|
assert(0);
|
||||||
#if 0
|
#if 0
|
||||||
if(!st || !dt)
|
if(!st || !dt)
|
||||||
{
|
{
|
||||||
|
@ -259,7 +660,6 @@ void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt,
|
||||||
|
|
||||||
void GSDeviceOGL::DoMerge(GSTexture* st[2], GSVector4* sr, GSTexture* dt, GSVector4* dr, bool slbg, bool mmod, const GSVector4& c)
|
void GSDeviceOGL::DoMerge(GSTexture* st[2], GSVector4* sr, GSTexture* dt, GSVector4* dr, bool slbg, bool mmod, const GSVector4& c)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
ClearRenderTarget(dt, c);
|
ClearRenderTarget(dt, c);
|
||||||
|
|
||||||
if(st[1] && !slbg)
|
if(st[1] && !slbg)
|
||||||
|
@ -269,16 +669,20 @@ void GSDeviceOGL::DoMerge(GSTexture* st[2], GSVector4* sr, GSTexture* dt, GSVect
|
||||||
|
|
||||||
if(st[0])
|
if(st[0])
|
||||||
{
|
{
|
||||||
|
if (m_state.cb != m_merge.cb->buffer) {
|
||||||
|
m_state.cb = m_merge.cb->buffer;
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, m_merge.cb->buffer);
|
||||||
|
}
|
||||||
|
glBufferSubData(GL_UNIFORM_BUFFER, 0, m_merge.cb->byte_size, &c.v);
|
||||||
|
#if 0
|
||||||
m_ctx->UpdateSubresource(m_merge.cb, 0, NULL, &c, 0, 0);
|
m_ctx->UpdateSubresource(m_merge.cb, 0, NULL, &c, 0, 0);
|
||||||
|
#endif
|
||||||
StretchRect(st[0], sr[0], dt, dr[0], m_merge.ps[mmod ? 1 : 0], m_merge.cb, m_merge.bs, true);
|
StretchRect(st[0], sr[0], dt, dr[0], m_merge.ps[mmod ? 1 : 0], m_merge.cb, m_merge.bs, true);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDeviceOGL::DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset)
|
void GSDeviceOGL::DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
GSVector4 s = GSVector4(dt->GetSize());
|
GSVector4 s = GSVector4(dt->GetSize());
|
||||||
|
|
||||||
GSVector4 sr(0, 0, 1, 1);
|
GSVector4 sr(0, 0, 1, 1);
|
||||||
|
@ -289,18 +693,25 @@ void GSDeviceOGL::DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool lin
|
||||||
cb.ZrH = GSVector2(0, 1.0f / s.y);
|
cb.ZrH = GSVector2(0, 1.0f / s.y);
|
||||||
cb.hH = s.y / 2;
|
cb.hH = s.y / 2;
|
||||||
|
|
||||||
|
if (m_state.cb != m_interlace.cb->buffer) {
|
||||||
|
m_state.cb = m_interlace.cb->buffer;
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, m_interlace.cb->buffer);
|
||||||
|
}
|
||||||
|
// FIXME I'm not sure it will be happy with InterlaceConstantBuffer type
|
||||||
|
glBufferSubData(GL_UNIFORM_BUFFER, 0, m_interlace.cb->byte_size, &cb);
|
||||||
|
#if 0
|
||||||
m_ctx->UpdateSubresource(m_interlace.cb, 0, NULL, &cb, 0, 0);
|
m_ctx->UpdateSubresource(m_interlace.cb, 0, NULL, &cb, 0, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
StretchRect(st, sr, dt, dr, m_interlace.ps[shader], m_interlace.cb, linear);
|
StretchRect(st, sr, dt, dr, m_interlace.ps[shader], m_interlace.cb, linear);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy a multisample texture to a non-texture multisample. On opengl you need 2 FBO with different level of
|
// copy a multisample texture to a non-texture multisample. On opengl you need 2 FBO with different level of
|
||||||
// sample and then do a blit. Headach expected to for the moment just drop MSAA...
|
// sample and then do a blit. Headach expected to for the moment just drop MSAA...
|
||||||
GSTexture* GSDeviceOGL::Resolve(GSTexture* t)
|
GSTexture* GSDeviceOGL::Resolve(GSTexture* t)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
ASSERT(t != NULL && t->IsMSAA());
|
ASSERT(t != NULL && t->IsMSAA());
|
||||||
|
#if 0
|
||||||
|
|
||||||
if(GSTexture* dst = CreateRenderTarget(t->GetWidth(), t->GetHeight(), false, t->GetFormat()))
|
if(GSTexture* dst = CreateRenderTarget(t->GetWidth(), t->GetHeight(), false, t->GetFormat()))
|
||||||
{
|
{
|
||||||
|
@ -323,151 +734,78 @@ void GSDeviceOGL::IASetVertexBuffer(const void* vertices, size_t stride, size_t
|
||||||
if(count * stride > m_vertices.limit * m_vertices.stride)
|
if(count * stride > m_vertices.limit * m_vertices.stride)
|
||||||
{
|
{
|
||||||
// Current GPU buffer is too small need to realocate a new one
|
// Current GPU buffer is too small need to realocate a new one
|
||||||
#if 0
|
if (m_vb) {
|
||||||
m_vb_old = m_vb;
|
glDeleteBuffers(1, &m_vb);
|
||||||
m_vb = NULL;
|
m_vb = 0;
|
||||||
|
}
|
||||||
|
|
||||||
m_vertices.start = 0;
|
m_vertices.start = 0;
|
||||||
m_vertices.count = 0;
|
m_vertices.count = 0;
|
||||||
m_vertices.limit = std::max<int>(count * 3 / 2, 11000);
|
m_vertices.limit = std::max<int>(count * 3 / 2, 11000);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_vb == NULL)
|
if(!m_vb)
|
||||||
{
|
{
|
||||||
// Allocate a GPU buffer: GL_DYNAMIC_DRAW vs GL_STREAM_DRAW !!!
|
glGenBuffers(1, &m_vb);
|
||||||
// glBufferData(GL_ARRAY_BUFFER, m_vertices.limit, NULL, GL_DYNAMIC_DRAW)
|
// FIXME: GL_DYNAMIC_DRAW vs GL_STREAM_DRAW !!!
|
||||||
#if 0
|
glBindBuffer(GL_ARRAY_BUFFER, m_vb);
|
||||||
D3D11_BUFFER_DESC bd;
|
glBufferData(GL_ARRAY_BUFFER, m_vertices.limit, NULL, GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
memset(&bd, 0, sizeof(bd));
|
|
||||||
|
|
||||||
bd.Usage = D3D11_USAGE_DYNAMIC;
|
|
||||||
bd.ByteWidth = m_vertices.limit * stride;
|
|
||||||
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
|
||||||
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
|
||||||
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
hr = m_dev->CreateBuffer(&bd, NULL, &m_vb);
|
|
||||||
|
|
||||||
if(FAILED(hr)) return;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// append data or go back to the beginning
|
// append data or go back to the beginning
|
||||||
// Hum why we don't always go back to the beginning !!!
|
// Hum why we don't always go back to the beginning !!!
|
||||||
#if 0
|
|
||||||
D3D11_MAP type = D3D11_MAP_WRITE_NO_OVERWRITE;
|
|
||||||
|
|
||||||
if(m_vertices.start + count > m_vertices.limit || stride != m_vertices.stride)
|
if(m_vertices.start + count > m_vertices.limit || stride != m_vertices.stride)
|
||||||
{
|
|
||||||
m_vertices.start = 0;
|
m_vertices.start = 0;
|
||||||
|
|
||||||
type = D3D11_MAP_WRITE_DISCARD;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Allocate the buffer
|
// Allocate the buffer
|
||||||
// glBufferSubData
|
// glBufferSubData
|
||||||
#if 0
|
glBufferSubData(GL_ARRAY_BUFFER, m_vertices.start * stride, count * stride, vertices);
|
||||||
D3D11_MAPPED_SUBRESOURCE m;
|
|
||||||
|
|
||||||
if(SUCCEEDED(m_ctx->Map(m_vb, 0, type, 0, &m)))
|
|
||||||
{
|
|
||||||
GSVector4i::storent((uint8*)m.pData + m_vertices.start * stride, vertices, count * stride);
|
|
||||||
|
|
||||||
m_ctx->Unmap(m_vb, 0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
m_vertices.count = count;
|
m_vertices.count = count;
|
||||||
m_vertices.stride = stride;
|
m_vertices.stride = stride;
|
||||||
|
|
||||||
// Useless ?
|
|
||||||
// binding of the buffer must be done anyway before glBufferSubData or glBufferData calls.
|
|
||||||
#if 0
|
|
||||||
IASetVertexBuffer(m_vb, stride);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Useless ?
|
void GSDeviceOGL::IASetInputLayout(GSInputLayout* layout, int layout_nbr)
|
||||||
#if 0
|
|
||||||
void GSDeviceOGL::IASetVertexBuffer(GLuint vb, size_t stride)
|
|
||||||
{
|
|
||||||
if(m_state.vb != vb || m_state.vb_stride != stride)
|
|
||||||
{
|
|
||||||
m_state.vb = vb;
|
|
||||||
m_state.vb_stride = stride;
|
|
||||||
|
|
||||||
uint32 stride2 = stride;
|
|
||||||
uint32 offset = 0;
|
|
||||||
|
|
||||||
m_ctx->IASetVertexBuffers(0, 1, &vb, &stride2, &offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Useless ?
|
|
||||||
#if 0
|
|
||||||
void GSDeviceOGL::IASetInputLayout(ID3D11InputLayout* layout)
|
|
||||||
{
|
{
|
||||||
if(m_state.layout != layout)
|
if(m_state.layout != layout)
|
||||||
{
|
{
|
||||||
m_state.layout = layout;
|
m_state.layout = layout;
|
||||||
|
|
||||||
m_ctx->IASetInputLayout(layout);
|
for (int i = 0; i < layout_nbr; i++)
|
||||||
|
glVertexAttribPointer(layout->index, layout->size, layout->type, GL_FALSE, layout->stride, layout->offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// Useless ?
|
|
||||||
#if 0
|
|
||||||
void GSDeviceOGL::IASetPrimitiveTopology(GLenum topology)
|
void GSDeviceOGL::IASetPrimitiveTopology(GLenum topology)
|
||||||
{
|
{
|
||||||
if(m_state.topology != topology)
|
if(m_state.topology != topology)
|
||||||
{
|
{
|
||||||
m_state.topology = topology;
|
m_state.topology = topology;
|
||||||
|
|
||||||
m_ctx->IASetPrimitiveTopology(topology);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void GSDeviceOGL::VSSetShader(GLuint vs, GSUniformBufferOGL* vs_cb)
|
void GSDeviceOGL::VSSetShader(GLuint vs, GSUniformBufferOGL* vs_cb)
|
||||||
{
|
{
|
||||||
// glUseProgramStage
|
|
||||||
#if 0
|
|
||||||
if(m_state.vs != vs)
|
if(m_state.vs != vs)
|
||||||
{
|
{
|
||||||
m_state.vs = vs;
|
m_state.vs = vs;
|
||||||
|
glUseProgramStages(m_pipeline, GL_VERTEX_SHADER_BIT, vs);
|
||||||
m_ctx->VSSetShader(vs, NULL, 0);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// glBindBufferBase
|
|
||||||
#if 0
|
|
||||||
if(m_state.vs_cb != vs_cb)
|
if(m_state.vs_cb != vs_cb)
|
||||||
{
|
{
|
||||||
m_state.vs_cb = vs_cb;
|
m_state.vs_cb = vs_cb;
|
||||||
|
glBindBufferBase(GL_UNIFORM_BUFFER, vs_cb->index, vs_cb->buffer);
|
||||||
m_ctx->VSSetConstantBuffers(0, 1, &vs_cb);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDeviceOGL::GSSetShader(GLuint gs)
|
void GSDeviceOGL::GSSetShader(GLuint gs)
|
||||||
{
|
{
|
||||||
// glUseProgramStage
|
|
||||||
#if 0
|
|
||||||
if(m_state.gs != gs)
|
if(m_state.gs != gs)
|
||||||
{
|
{
|
||||||
m_state.gs = gs;
|
m_state.gs = gs;
|
||||||
|
glUseProgramStages(m_pipeline, GL_GEOMETRY_SHADER_BIT, gs);
|
||||||
m_ctx->GSSetShader(gs, NULL, 0);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDeviceOGL::PSSetShaderResources(GSTexture* sr0, GSTexture* sr1)
|
void GSDeviceOGL::PSSetShaderResources(GSTexture* sr0, GSTexture* sr1)
|
||||||
|
@ -479,10 +817,9 @@ void GSDeviceOGL::PSSetShaderResources(GSTexture* sr0, GSTexture* sr1)
|
||||||
|
|
||||||
void GSDeviceOGL::PSSetShaderResource(int i, GSTexture* sr)
|
void GSDeviceOGL::PSSetShaderResource(int i, GSTexture* sr)
|
||||||
{
|
{
|
||||||
#if 0
|
GSTextureOGL* srv = NULL;
|
||||||
ID3D11ShaderResourceView* srv = NULL;
|
|
||||||
|
|
||||||
if(sr) srv = *(GSTexture11*)sr;
|
if(sr) srv = (GSTextureOGL*)sr;
|
||||||
|
|
||||||
if(m_state.ps_srv[i] != srv)
|
if(m_state.ps_srv[i] != srv)
|
||||||
{
|
{
|
||||||
|
@ -490,12 +827,10 @@ void GSDeviceOGL::PSSetShaderResource(int i, GSTexture* sr)
|
||||||
|
|
||||||
m_srv_changed = true;
|
m_srv_changed = true;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDeviceOGL::PSSetSamplerState(GLuint ss0, GLuint ss1, GLuint ss2)
|
void GSDeviceOGL::PSSetSamplerState(GLuint ss0, GLuint ss1, GLuint ss2)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
if(m_state.ps_ss[0] != ss0 || m_state.ps_ss[1] != ss1 || m_state.ps_ss[2] != ss2)
|
if(m_state.ps_ss[0] != ss0 || m_state.ps_ss[1] != ss1 || m_state.ps_ss[2] != ss2)
|
||||||
{
|
{
|
||||||
m_state.ps_ss[0] = ss0;
|
m_state.ps_ss[0] = ss0;
|
||||||
|
@ -504,21 +839,16 @@ void GSDeviceOGL::PSSetSamplerState(GLuint ss0, GLuint ss1, GLuint ss2)
|
||||||
|
|
||||||
m_ss_changed = true;
|
m_ss_changed = true;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDeviceOGL::PSSetShader(GLuint ps, GSUniformBufferOGL* ps_cb)
|
void GSDeviceOGL::PSSetShader(GLuint ps, GSUniformBufferOGL* ps_cb)
|
||||||
{
|
{
|
||||||
|
|
||||||
// glUseProgramStage
|
|
||||||
#if 0
|
|
||||||
if(m_state.ps != ps)
|
if(m_state.ps != ps)
|
||||||
{
|
{
|
||||||
m_state.ps = ps;
|
m_state.ps = ps;
|
||||||
|
glUseProgramStages(m_pipeline, GL_FRAGMENT_SHADER_BIT, ps);
|
||||||
m_ctx->PSSetShader(ps, NULL, 0);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// Sampler and texture must be set at the same time
|
// Sampler and texture must be set at the same time
|
||||||
// 1/ select the texture unit
|
// 1/ select the texture unit
|
||||||
|
@ -529,6 +859,12 @@ void GSDeviceOGL::PSSetShader(GLuint ps, GSUniformBufferOGL* ps_cb)
|
||||||
// glUniform1i(brickSamplerId , 1);
|
// glUniform1i(brickSamplerId , 1);
|
||||||
// 4/ set the sampler state
|
// 4/ set the sampler state
|
||||||
// glBindSampler(1 , sampler);
|
// glBindSampler(1 , sampler);
|
||||||
|
if (m_srv_changed || m_ss_changed) {
|
||||||
|
for (uint i=0 ; i < 3; i++) {
|
||||||
|
m_state.ps_srv[i]->EnableUnit(i);
|
||||||
|
glBindSampler(i, m_state.ps_ss[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
#if 0
|
#if 0
|
||||||
if (m_srv_changed)
|
if (m_srv_changed)
|
||||||
{
|
{
|
||||||
|
@ -545,29 +881,36 @@ void GSDeviceOGL::PSSetShader(GLuint ps, GSUniformBufferOGL* ps_cb)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// glBindBufferBase
|
|
||||||
#if 0
|
|
||||||
if(m_state.ps_cb != ps_cb)
|
if(m_state.ps_cb != ps_cb)
|
||||||
{
|
{
|
||||||
m_state.ps_cb = ps_cb;
|
m_state.ps_cb = ps_cb;
|
||||||
|
glBindBufferBase(GL_UNIFORM_BUFFER, ps_cb->index, ps_cb->buffer);
|
||||||
m_ctx->PSSetConstantBuffers(0, 1, &ps_cb);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDeviceOGL::OMSetDepthStencilState(GSDepthStencilOGL* dss, uint8 sref)
|
void GSDeviceOGL::OMSetDepthStencilState(GSDepthStencilOGL* dss, uint8 sref)
|
||||||
{
|
{
|
||||||
// Setup the stencil object. sref can be set by glStencilFunc (note remove it from the structure)
|
uint ref = sref;
|
||||||
#if 0
|
|
||||||
if(m_state.dss != dss || m_state.sref != sref)
|
if(m_state.dss != dss || m_state.sref != sref)
|
||||||
{
|
{
|
||||||
m_state.dss = dss;
|
m_state.dss = dss;
|
||||||
m_state.sref = sref;
|
m_state.sref = sref;
|
||||||
|
|
||||||
m_ctx->OMSetDepthStencilState(dss, sref);
|
if (dss->m_depth_enable) {
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glDepthFunc(dss->m_depth_func);
|
||||||
|
glDepthMask(dss->m_depth_mask);
|
||||||
|
} else
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
if (dss->m_stencil_enable) {
|
||||||
|
glEnable(GL_STENCIL_TEST);
|
||||||
|
glStencilFunc(dss->m_stencil_func, ref, dss->m_stencil_mask);
|
||||||
|
glStencilOp(dss->m_stencil_sfail_op, dss->m_stencil_spass_dfail_op, dss->m_stencil_spass_dpass_op);
|
||||||
|
} else
|
||||||
|
glDisable(GL_STENCIL_TEST);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDeviceOGL::OMSetBlendState(GSBlendStateOGL* bs, float bf)
|
void GSDeviceOGL::OMSetBlendState(GSBlendStateOGL* bs, float bf)
|
||||||
|
@ -575,23 +918,26 @@ void GSDeviceOGL::OMSetBlendState(GSBlendStateOGL* bs, float bf)
|
||||||
// DX:Blend factor D3D11_BLEND_BLEND_FACTOR | D3D11_BLEND_INV_BLEND_FACTOR
|
// DX:Blend factor D3D11_BLEND_BLEND_FACTOR | D3D11_BLEND_INV_BLEND_FACTOR
|
||||||
// OPENGL: GL_CONSTANT_COLOR | GL_ONE_MINUS_CONSTANT_COLOR
|
// OPENGL: GL_CONSTANT_COLOR | GL_ONE_MINUS_CONSTANT_COLOR
|
||||||
// Note factor must be set before by glBlendColor
|
// Note factor must be set before by glBlendColor
|
||||||
#if 0
|
|
||||||
if(m_state.bs != bs || m_state.bf != bf)
|
if(m_state.bs != bs || m_state.bf != bf)
|
||||||
{
|
{
|
||||||
m_state.bs = bs;
|
m_state.bs = bs;
|
||||||
m_state.bf = bf;
|
m_state.bf = bf;
|
||||||
|
|
||||||
float BlendFactor[] = {bf, bf, bf, 0};
|
// FIXME: double check when blend stuff is complete
|
||||||
|
if (bs->m_func_sRGB == GL_CONSTANT_COLOR || bs->m_func_sRGB == GL_ONE_MINUS_CONSTANT_COLOR
|
||||||
|
|| bs->m_func_dRGB == GL_CONSTANT_COLOR || bs->m_func_dRGB == GL_ONE_MINUS_CONSTANT_COLOR)
|
||||||
|
glBlendColor(bf, bf, bf, 0);
|
||||||
|
|
||||||
m_ctx->OMSetBlendState(bs, BlendFactor, 0xffffffff);
|
glBlendEquationSeparate(bs->m_equation_RGB, bs->m_equation_ALPHA);
|
||||||
|
glBlendFuncSeparate(bs->m_func_sRGB, bs->m_func_dRGB, bs->m_func_sALPHA, bs->m_func_dALPHA);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor)
|
void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVector4i* scissor)
|
||||||
{
|
{
|
||||||
// set the attachment inside the FBO
|
// attach render&depth to the FBO
|
||||||
|
// Hum, need to separate 2 case, Render target fbo and render target backbuffer
|
||||||
|
// Or maybe blit final result to the backbuffer
|
||||||
#if 0
|
#if 0
|
||||||
ID3D11RenderTargetView* rtv = NULL;
|
ID3D11RenderTargetView* rtv = NULL;
|
||||||
ID3D11DepthStencilView* dsv = NULL;
|
ID3D11DepthStencilView* dsv = NULL;
|
||||||
|
@ -607,37 +953,98 @@ void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVecto
|
||||||
m_ctx->OMSetRenderTargets(1, &rtv, dsv);
|
m_ctx->OMSetRenderTargets(1, &rtv, dsv);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
GSTextureOGL* rt_ogl = (GSTextureOGL*)rt;
|
||||||
|
GSTextureOGL* ds_ogl = (GSTextureOGL*)ds;
|
||||||
|
|
||||||
|
if (m_backbuffer == rt_ogl) {
|
||||||
|
if (m_state.fbo) {
|
||||||
|
m_state.fbo = 0;
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0); // render in the backbuffer
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(ds_ogl == NULL); // no depth-stencil without FBO
|
||||||
|
} else {
|
||||||
|
if (m_state.fbo != m_fbo) {
|
||||||
|
m_state.fbo = m_fbo;
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(rt_ogl != NULL); // a render target must exists
|
||||||
|
rt_ogl->Attach(GL_COLOR_ATTACHMENT0);
|
||||||
|
if (ds_ogl != NULL)
|
||||||
|
ds_ogl->Attach(GL_DEPTH_STENCIL_ATTACHMENT);
|
||||||
|
}
|
||||||
|
|
||||||
// Viewport -> glViewport
|
// Viewport -> glViewport
|
||||||
#if 0
|
|
||||||
if(m_state.viewport != rt->GetSize())
|
if(m_state.viewport != rt->GetSize())
|
||||||
{
|
{
|
||||||
m_state.viewport = rt->GetSize();
|
m_state.viewport = rt->GetSize();
|
||||||
|
glViewport(0, 0, rt->GetWidth(), rt->GetHeight());
|
||||||
D3D11_VIEWPORT vp;
|
|
||||||
|
|
||||||
memset(&vp, 0, sizeof(vp));
|
|
||||||
|
|
||||||
vp.TopLeftX = 0;
|
|
||||||
vp.TopLeftY = 0;
|
|
||||||
vp.Width = (float)rt->GetWidth();
|
|
||||||
vp.Height = (float)rt->GetHeight();
|
|
||||||
vp.MinDepth = 0.0f;
|
|
||||||
vp.MaxDepth = 1.0f;
|
|
||||||
|
|
||||||
m_ctx->RSSetViewports(1, &vp);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// Scissor -> glScissor (note must be enabled)
|
// Scissor -> glScissor (note must be enabled)
|
||||||
#if 0
|
|
||||||
GSVector4i r = scissor ? *scissor : GSVector4i(rt->GetSize()).zwxy();
|
GSVector4i r = scissor ? *scissor : GSVector4i(rt->GetSize()).zwxy();
|
||||||
|
|
||||||
if(!m_state.scissor.eq(r))
|
if(!m_state.scissor.eq(r))
|
||||||
{
|
{
|
||||||
m_state.scissor = r;
|
m_state.scissor = r;
|
||||||
|
// FIXME check position
|
||||||
|
glScissor(r.x, r.w, r.z-r.x, r.y-r.w);
|
||||||
|
#if 0
|
||||||
m_ctx->RSSetScissorRects(1, r);
|
m_ctx->RSSetScissorRects(1, r);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSDeviceOGL::CompileShaderFromSource(const std::string& glsl_file, const std::string& entry, GLenum type, GLuint* program)
|
||||||
|
{
|
||||||
|
// Could be useful to filter ubber shader
|
||||||
|
std::string shader_type;
|
||||||
|
switch (type) {
|
||||||
|
case GL_VERTEX_SHADER:
|
||||||
|
shader_type = "#define VERTEX_SHADER 1\n";
|
||||||
|
case GL_GEOMETRY_SHADER:
|
||||||
|
shader_type = "#define GEOMETRY_SHADER 1\n";
|
||||||
|
case GL_FRAGMENT_SHADER:
|
||||||
|
shader_type = "#define FRAGMENT_SHADER 1\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select the entry point
|
||||||
|
std::string entry_main = format("#define %s main\n", entry.c_str());
|
||||||
|
|
||||||
|
// Read the source file
|
||||||
|
std::string source;
|
||||||
|
std::string line;
|
||||||
|
// Each linux distributions have his rules for path so we give them the possibility to
|
||||||
|
// change it with compilation flags. -- Gregory
|
||||||
|
#ifdef PLUGIN_DIR_COMPILATION
|
||||||
|
#define xPLUGIN_DIR_str(s) PLUGIN_DIR_str(s)
|
||||||
|
#define PLUGIN_DIR_str(s) #s
|
||||||
|
const std::string shader_file = string(xPLUGIN_DIR_str(PLUGIN_DIR_COMPILATION)) + '/' + glsl_file;
|
||||||
|
#else
|
||||||
|
const std::string shader_file = string("plugins/") + glsl_file;
|
||||||
|
#endif
|
||||||
|
std::ifstream myfile(shader_file.c_str());
|
||||||
|
if (myfile.is_open()) {
|
||||||
|
while ( myfile.good() )
|
||||||
|
{
|
||||||
|
getline (myfile,line);
|
||||||
|
source += line;
|
||||||
|
source += '\n';
|
||||||
|
}
|
||||||
|
myfile.close();
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Error opening %s: ", shader_file.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a giant string with everythings
|
||||||
|
std::string full_source = shader_type + entry_main + source;
|
||||||
|
|
||||||
|
char* sources = (char*)malloc(full_source.size());
|
||||||
|
strncpy(sources, full_source.c_str(), full_source.size());
|
||||||
|
sources[full_source.size()] = '\0';
|
||||||
|
|
||||||
|
*program = glCreateShaderProgramv(type, 1, (const char**)&sources);
|
||||||
|
|
||||||
|
free(sources);
|
||||||
|
}
|
||||||
|
|
|
@ -21,9 +21,11 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
#include "GSDevice.h"
|
#include "GSDevice.h"
|
||||||
#include "GSTextureOGL.h"
|
#include "GSTextureOGL.h"
|
||||||
#include "GSdx.h"
|
#include "GSdx.h"
|
||||||
|
#include "../../3rdparty/SDL-1.3.0-5387/include/SDL.h"
|
||||||
|
|
||||||
struct GSBlendStateOGL {
|
struct GSBlendStateOGL {
|
||||||
// Note: You can also select the index of the draw buffer for which to set the blend setting
|
// Note: You can also select the index of the draw buffer for which to set the blend setting
|
||||||
|
@ -31,13 +33,16 @@ struct GSBlendStateOGL {
|
||||||
bool m_enable;
|
bool m_enable;
|
||||||
GLenum m_equation_RGB;
|
GLenum m_equation_RGB;
|
||||||
GLenum m_equation_ALPHA;
|
GLenum m_equation_ALPHA;
|
||||||
GLenum m_func_RGB;
|
GLenum m_func_sRGB;
|
||||||
GLenum m_func_ALPHA;
|
GLenum m_func_dRGB;
|
||||||
|
GLenum m_func_sALPHA;
|
||||||
|
GLenum m_func_dALPHA;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GSDepthStencilOGL {
|
struct GSDepthStencilOGL {
|
||||||
bool m_depth_enable;
|
bool m_depth_enable;
|
||||||
GLenum m_depth_func;
|
GLenum m_depth_func;
|
||||||
|
GLboolean m_depth_mask;
|
||||||
// Note front face and back can be split might. But it seems they have same parameter configuration
|
// Note front face and back can be split might. But it seems they have same parameter configuration
|
||||||
bool m_stencil_enable;
|
bool m_stencil_enable;
|
||||||
GLuint m_stencil_mask;
|
GLuint m_stencil_mask;
|
||||||
|
@ -49,16 +54,29 @@ struct GSDepthStencilOGL {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GSUniformBufferOGL {
|
struct GSUniformBufferOGL {
|
||||||
GLuint buffer;
|
GLuint buffer; // data object
|
||||||
|
GLuint index; // GLSL slot
|
||||||
|
uint byte_size; // size of the data
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GSInputLayout {
|
||||||
GLuint index;
|
GLuint index;
|
||||||
|
GLint size;
|
||||||
|
GLenum type;
|
||||||
|
GLsizei stride;
|
||||||
|
const GLvoid* offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GSDeviceOGL : public GSDevice
|
class GSDeviceOGL : public GSDevice
|
||||||
{
|
{
|
||||||
uint32 m_msaa;
|
uint32 m_msaa; // Level of Msaa
|
||||||
|
|
||||||
// Vertex buffer: glGenBuffers, glBindBuffer GL_ARRAY_BUFFER
|
bool m_free_window;
|
||||||
GLuint m_vb; // buffer object
|
SDL_Window* m_window; // pointer to the SDL window
|
||||||
|
|
||||||
|
GLuint m_vb; // vertex buffer object
|
||||||
|
GLuint m_pipeline; // pipeline to attach program shader
|
||||||
|
GLuint m_fbo; // frame buffer container
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
GLuint ps[2]; // program object
|
GLuint ps[2]; // program object
|
||||||
|
@ -71,21 +89,11 @@ class GSDeviceOGL : public GSDevice
|
||||||
GSUniformBufferOGL* cb; // uniform buffer object
|
GSUniformBufferOGL* cb; // uniform buffer object
|
||||||
} m_interlace;
|
} m_interlace;
|
||||||
|
|
||||||
//struct
|
struct {
|
||||||
//{
|
|
||||||
// CComPtr<ID3D11InputLayout> il;
|
|
||||||
// CComPtr<ID3D11VertexShader> vs; // program object
|
|
||||||
// CComPtr<ID3D11PixelShader> ps[8]; // program object
|
|
||||||
// CComPtr<ID3D11SamplerState> ln;
|
|
||||||
// CComPtr<ID3D11SamplerState> pt;
|
|
||||||
// CComPtr<ID3D11DepthStencilState> dss;
|
|
||||||
// CComPtr<ID3D11BlendState> bs; // no equivalent
|
|
||||||
//} m_convert;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
// Hum I think this one is useless. As far as I understand
|
// Hum I think this one is useless. As far as I understand
|
||||||
// it only get the index name of GLSL-equivalent input attribut
|
// it only get the index name of GLSL-equivalent input attribut
|
||||||
// ??? CComPtr<ID3D11InputLayout> il;
|
// ??? CComPtr<ID3D11InputLayout> il;
|
||||||
|
GSInputLayout il[2]; // description of the vertex array
|
||||||
GLuint vs; // program object
|
GLuint vs; // program object
|
||||||
GLuint ps[8]; // program object
|
GLuint ps[8]; // program object
|
||||||
GLuint ln; // sampler object
|
GLuint ln; // sampler object
|
||||||
|
@ -94,11 +102,6 @@ class GSDeviceOGL : public GSDevice
|
||||||
GSBlendStateOGL* bs;
|
GSBlendStateOGL* bs;
|
||||||
} m_convert;
|
} m_convert;
|
||||||
|
|
||||||
// struct
|
|
||||||
// {
|
|
||||||
// CComPtr<ID3D11DepthStencilState> dss;
|
|
||||||
// CComPtr<ID3D11BlendState> bs;
|
|
||||||
// } m_date;
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
GSDepthStencilOGL* dss;
|
GSDepthStencilOGL* dss;
|
||||||
|
@ -133,8 +136,10 @@ class GSDeviceOGL : public GSDevice
|
||||||
// Hum I think those things can be dropped on OGL. It probably need an others architecture (see glVertexAttribPointer)
|
// Hum I think those things can be dropped on OGL. It probably need an others architecture (see glVertexAttribPointer)
|
||||||
// size_t vb_stride;
|
// size_t vb_stride;
|
||||||
// ID3D11InputLayout* layout;
|
// ID3D11InputLayout* layout;
|
||||||
|
GSInputLayout* layout;
|
||||||
GLenum topology; // (ie GL_TRIANGLES...)
|
GLenum topology; // (ie GL_TRIANGLES...)
|
||||||
GLuint vs; // program
|
GLuint vs; // program
|
||||||
|
GLuint cb; // uniform current buffer
|
||||||
GSUniformBufferOGL* vs_cb; // uniform buffer
|
GSUniformBufferOGL* vs_cb; // uniform buffer
|
||||||
GLuint gs; // program
|
GLuint gs; // program
|
||||||
// FIXME texture binding. Maybe not equivalent for the state but the best I could find.
|
// FIXME texture binding. Maybe not equivalent for the state but the best I could find.
|
||||||
|
@ -152,6 +157,9 @@ class GSDeviceOGL : public GSDevice
|
||||||
// FIXME texture attachment in the FBO
|
// FIXME texture attachment in the FBO
|
||||||
// ID3D11RenderTargetView* rtv;
|
// ID3D11RenderTargetView* rtv;
|
||||||
// ID3D11DepthStencilView* dsv;
|
// ID3D11DepthStencilView* dsv;
|
||||||
|
GSTextureOGL* rtv;
|
||||||
|
GSTextureOGL* dsv;
|
||||||
|
GLuint fbo;
|
||||||
} m_state;
|
} m_state;
|
||||||
|
|
||||||
bool m_srv_changed;
|
bool m_srv_changed;
|
||||||
|
@ -219,11 +227,15 @@ class GSDeviceOGL : public GSDevice
|
||||||
|
|
||||||
void CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r);
|
void CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r);
|
||||||
void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader = 0, bool linear = true);
|
void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader = 0, bool linear = true);
|
||||||
void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, GLuint ps, GSUniformBufferOGL* ps_cb, bool linear);
|
void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, GLuint ps, GSUniformBufferOGL* ps_cb, bool linear = true);
|
||||||
void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, GLuint ps, GSUniformBufferOGL ps_cb, GSBlendStateOGL* bs, bool linear);
|
void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, GLuint ps, GSUniformBufferOGL* ps_cb, GSBlendStateOGL* bs, bool linear = true);
|
||||||
|
|
||||||
GSTexture* Resolve(GSTexture* t);
|
GSTexture* Resolve(GSTexture* t);
|
||||||
|
|
||||||
|
void CompileShaderFromSource(const std::string& glsl_file, const std::string& entry, GLenum type, GLuint* program);
|
||||||
|
|
||||||
|
void IASetPrimitiveTopology(GLenum topology);
|
||||||
|
void IASetInputLayout(GSInputLayout* layout, int layout_nbr);
|
||||||
void IASetVertexBuffer(const void* vertices, size_t stride, size_t count);
|
void IASetVertexBuffer(const void* vertices, size_t stride, size_t count);
|
||||||
|
|
||||||
void VSSetShader(GLuint vs, GSUniformBufferOGL* vs_cb);
|
void VSSetShader(GLuint vs, GSUniformBufferOGL* vs_cb);
|
||||||
|
|
|
@ -42,13 +42,12 @@ static void SysMessage(const char *fmt, ...)
|
||||||
|
|
||||||
bool RunLinuxDialog()
|
bool RunLinuxDialog()
|
||||||
{
|
{
|
||||||
// FIXME need to add msaa option configuration
|
|
||||||
GtkWidget *dialog;
|
GtkWidget *dialog;
|
||||||
GtkWidget *main_frame, *main_box;
|
GtkWidget *main_frame, *main_box;
|
||||||
GtkWidget *render_label, *render_combo_box;
|
GtkWidget *render_label, *render_combo_box;
|
||||||
GtkWidget *interlace_label, *interlace_combo_box;
|
GtkWidget *interlace_label, *interlace_combo_box;
|
||||||
GtkWidget *swthreads_label, *swthreads_text;
|
GtkWidget *swthreads_label, *swthreads_text;
|
||||||
GtkWidget *filter_check, *logz_check, *paltex_check, *fba_check, *aa_check, *win_check;
|
GtkWidget *filter_check, *logz_check, *paltex_check, *fba_check, *aa_check, *win_check, *msaa_check;
|
||||||
int return_value;
|
int return_value;
|
||||||
|
|
||||||
/* Create the widgets */
|
/* Create the widgets */
|
||||||
|
@ -134,6 +133,7 @@ bool RunLinuxDialog()
|
||||||
fba_check = gtk_check_button_new_with_label("Alpha correction (FBA)");
|
fba_check = gtk_check_button_new_with_label("Alpha correction (FBA)");
|
||||||
aa_check = gtk_check_button_new_with_label("Edge anti-aliasing");
|
aa_check = gtk_check_button_new_with_label("Edge anti-aliasing");
|
||||||
win_check = gtk_check_button_new_with_label("Disable Effects Processing");
|
win_check = gtk_check_button_new_with_label("Disable Effects Processing");
|
||||||
|
msaa_check = gtk_check_button_new_with_label("Enable MultiSample AA (not yet implemented)");
|
||||||
|
|
||||||
gtk_container_add(GTK_CONTAINER(main_box), filter_check);
|
gtk_container_add(GTK_CONTAINER(main_box), filter_check);
|
||||||
gtk_container_add(GTK_CONTAINER(main_box), logz_check);
|
gtk_container_add(GTK_CONTAINER(main_box), logz_check);
|
||||||
|
@ -141,6 +141,7 @@ bool RunLinuxDialog()
|
||||||
gtk_container_add(GTK_CONTAINER(main_box), fba_check);
|
gtk_container_add(GTK_CONTAINER(main_box), fba_check);
|
||||||
gtk_container_add(GTK_CONTAINER(main_box), aa_check);
|
gtk_container_add(GTK_CONTAINER(main_box), aa_check);
|
||||||
gtk_container_add(GTK_CONTAINER(main_box), win_check);
|
gtk_container_add(GTK_CONTAINER(main_box), win_check);
|
||||||
|
gtk_container_add(GTK_CONTAINER(main_box), msaa_check);
|
||||||
|
|
||||||
// Filter should be 3 states, not 2.
|
// Filter should be 3 states, not 2.
|
||||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(filter_check), theApp.GetConfig("filter", 1));
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(filter_check), theApp.GetConfig("filter", 1));
|
||||||
|
@ -149,6 +150,7 @@ bool RunLinuxDialog()
|
||||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fba_check), theApp.GetConfig("fba", 1));
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fba_check), theApp.GetConfig("fba", 1));
|
||||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(aa_check), theApp.GetConfig("aa1", 0));
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(aa_check), theApp.GetConfig("aa1", 0));
|
||||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(win_check), theApp.GetConfig("windowed", 1));
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(win_check), theApp.GetConfig("windowed", 1));
|
||||||
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(msaa_check), theApp.GetConfig("msaa", 0));
|
||||||
|
|
||||||
gtk_container_add (GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), main_frame);
|
gtk_container_add (GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), main_frame);
|
||||||
gtk_widget_show_all (dialog);
|
gtk_widget_show_all (dialog);
|
||||||
|
@ -188,6 +190,7 @@ bool RunLinuxDialog()
|
||||||
theApp.SetConfig("fba", (int)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fba_check)));
|
theApp.SetConfig("fba", (int)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fba_check)));
|
||||||
theApp.SetConfig("aa1", (int)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(aa_check)));
|
theApp.SetConfig("aa1", (int)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(aa_check)));
|
||||||
theApp.SetConfig("windowed", (int)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(win_check)));
|
theApp.SetConfig("windowed", (int)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(win_check)));
|
||||||
|
theApp.SetConfig("msaa", (int)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(msaa_check)));
|
||||||
|
|
||||||
gtk_widget_destroy (dialog);
|
gtk_widget_destroy (dialog);
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,8 @@
|
||||||
|
|
||||||
#include "GSTextureOGL.h"
|
#include "GSTextureOGL.h"
|
||||||
|
|
||||||
GSTextureOGL::GSTextureOGL(/* ID3D11Texture2D* texture */ )
|
GSTextureOGL::GSTextureOGL(int type, int w, int h, bool msaa, int format)
|
||||||
|
: m_texture_unit(0)
|
||||||
{
|
{
|
||||||
// *************************************************************
|
// *************************************************************
|
||||||
// Opengl world
|
// Opengl world
|
||||||
|
@ -63,6 +64,12 @@ GSTextureOGL::GSTextureOGL(/* ID3D11Texture2D* texture */ )
|
||||||
// : m_type
|
// : m_type
|
||||||
// : m_format
|
// : m_format
|
||||||
// : m_msaa
|
// : m_msaa
|
||||||
|
m_size.x = w;
|
||||||
|
m_size.y = h;
|
||||||
|
m_format = format;
|
||||||
|
m_type = type;
|
||||||
|
m_msaa = msaa;
|
||||||
|
|
||||||
// == Might be useful to save
|
// == Might be useful to save
|
||||||
// : m_texture_target (like GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE etc...)
|
// : m_texture_target (like GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE etc...)
|
||||||
// : m_texture_id (return by glGen*)
|
// : m_texture_id (return by glGen*)
|
||||||
|
@ -81,30 +88,68 @@ GSTextureOGL::GSTextureOGL(/* ID3D11Texture2D* texture */ )
|
||||||
// glGetTexImage: read pixels of a bound texture
|
// glGetTexImage: read pixels of a bound texture
|
||||||
// => To allow map/unmap. I think we can use a pixel buffer (target GL_PIXEL_UNPACK_BUFFER)
|
// => To allow map/unmap. I think we can use a pixel buffer (target GL_PIXEL_UNPACK_BUFFER)
|
||||||
// http://www.opengl.org/wiki/Pixel_Buffer_Objects
|
// http://www.opengl.org/wiki/Pixel_Buffer_Objects
|
||||||
// == Enable texture Unit
|
|
||||||
// EnableUnit();
|
|
||||||
// == Allocate space
|
|
||||||
// glRenderbufferStorageMultisample or glTexStorage2D
|
|
||||||
|
|
||||||
|
// Generate the buffer
|
||||||
|
switch (m_type) {
|
||||||
|
case GSTexture::RenderTarget:
|
||||||
|
// FIXME what is the real use case of this texture
|
||||||
|
// Maybe a texture will be better
|
||||||
|
glGenRenderbuffers(1, &m_texture_id);
|
||||||
|
m_texture_target = GL_RENDERBUFFER;
|
||||||
|
break;
|
||||||
|
case GSTexture::DepthStencil:
|
||||||
|
glGenRenderbuffers(1, &m_texture_id);
|
||||||
|
m_texture_target = GL_RENDERBUFFER;
|
||||||
|
break;
|
||||||
|
case GSTexture::Texture:
|
||||||
|
glGenTextures(1, &m_texture_id);
|
||||||
|
// FIXME, do we need rectangle (or better to use 2D texture)
|
||||||
|
//m_texture_target = GL_TEXTURE_2D;
|
||||||
|
m_texture_target = GL_TEXTURE_RECTANGLE;
|
||||||
|
// == For texture, the Unit must be selected
|
||||||
|
break;
|
||||||
|
case GSTexture::Offscreen:
|
||||||
|
//FIXME I not sure we need a pixel buffer object. It seems more a texture
|
||||||
|
// glGenBuffers(1, &m_texture_id);
|
||||||
|
// m_texture_target = GL_PIXEL_UNPACK_BUFFER;
|
||||||
|
assert(0);
|
||||||
|
// Note there is also a buffer texture!!!
|
||||||
|
// http://www.opengl.org/wiki/Buffer_Texture
|
||||||
|
// Note: in this case it must use in GLSL
|
||||||
|
// gvec texelFetch(gsampler sampler, ivec texCoord, int lod[, int sample]);
|
||||||
|
// corollary we can maybe use it for multisample stuff
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
uint msaa_level;
|
||||||
m_texture->GetDevice(&m_dev);
|
if (m_msaa) {
|
||||||
m_texture->GetDesc(&m_desc);
|
// FIXME which level of MSAA
|
||||||
|
msaa_level = 1;
|
||||||
|
} else {
|
||||||
|
msaa_level = 0;
|
||||||
|
}
|
||||||
|
|
||||||
m_dev->GetImmediateContext(&m_ctx);
|
// Allocate the buffer
|
||||||
|
switch (m_type) {
|
||||||
m_size.x = (int)m_desc.Width;
|
case GSTexture::RenderTarget:
|
||||||
m_size.y = (int)m_desc.Height;
|
case GSTexture::DepthStencil:
|
||||||
|
glBindRenderbuffer(m_texture_target, m_texture_id);
|
||||||
if(m_desc.BindFlags & D3D11_BIND_RENDER_TARGET) m_type = RenderTarget;
|
glRenderbufferStorageMultisample(m_texture_target, msaa_level, m_format, m_size.y, m_size.x);
|
||||||
else if(m_desc.BindFlags & D3D11_BIND_DEPTH_STENCIL) m_type = DepthStencil;
|
break;
|
||||||
else if(m_desc.BindFlags & D3D11_BIND_SHADER_RESOURCE) m_type = Texture;
|
case GSTexture::Texture:
|
||||||
else if(m_desc.Usage == D3D11_USAGE_STAGING) m_type = Offscreen;
|
// FIXME
|
||||||
|
// Howto allocate the texture unit !!!
|
||||||
m_format = (int)m_desc.Format;
|
// In worst case the HW renderer seems to use 3 texture unit
|
||||||
|
// For the moment SW renderer only use 1 so don't bother
|
||||||
m_msaa = m_desc.SampleDesc.Count > 1;
|
EnableUnit(0);
|
||||||
#endif
|
glTexStorage2D_glew17(m_texture_target, 0, m_format, m_size.y, m_size.x);
|
||||||
|
break;
|
||||||
|
case GSTexture::Offscreen:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GSTextureOGL::~GSTextureOGL()
|
GSTextureOGL::~GSTextureOGL()
|
||||||
|
@ -112,28 +157,36 @@ GSTextureOGL::~GSTextureOGL()
|
||||||
// glDeleteTextures or glDeleteRenderbuffers
|
// glDeleteTextures or glDeleteRenderbuffers
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSTextureOGL::EnableUnit()
|
void GSTextureOGL::Attach(GLenum attachment)
|
||||||
{
|
{
|
||||||
// == For texture, the Unit must be selected
|
if (m_type == GSTexture::DepthStencil)
|
||||||
// glActiveTexture
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, m_texture_target, m_texture_id);
|
||||||
// !!!!!!!!!! VERY BIG ISSUE, how to ensure that the different texture use different texture unit.
|
else
|
||||||
// I think we need to create a pool on GSdevice.
|
glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, m_texture_target, m_texture_id, 0);
|
||||||
// 1/ this->m_device_ogl
|
|
||||||
// 2/ int GSDeviceOGL::get_free_texture_unit() called from GSTextureOGL constructor
|
|
||||||
// 3/ void GSDeviceOGL::release_texture_unit(int) called from GSDeviceOGL destructor
|
|
||||||
// Another (better) idea, will be to create a global static pool
|
|
||||||
//
|
|
||||||
// == Bind the texture or buffer
|
|
||||||
// glBindRenderbuffer or glBindTexture
|
|
||||||
//
|
|
||||||
// !!!!!!!!!! Maybe attach to the FBO but where to manage the FBO!!!
|
|
||||||
// Create a separare public method for attachment ???
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
|
bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
|
||||||
{
|
{
|
||||||
// To update only a part of the texture you can use:
|
// To update only a part of the texture you can use:
|
||||||
// glTexSubImage2D — specify a two-dimensional texture subimage
|
// glTexSubImage2D — specify a two-dimensional texture subimage
|
||||||
|
switch (m_type) {
|
||||||
|
case GSTexture::Texture:
|
||||||
|
// glTexSubImage2D specifies a two-dimensional subtexture for the current texture unit, specified with glActiveTexture.
|
||||||
|
// If a non-zero named buffer object is bound to the GL_PIXEL_UNPACK_BUFFER target
|
||||||
|
//(see glBindBuffer) while a texture image is
|
||||||
|
// specified, data is treated as a byte offset into the buffer object's data store
|
||||||
|
// FIXME warning order of the y axis
|
||||||
|
// FIXME I'm not confident with GL_UNSIGNED_BYTE type
|
||||||
|
// FIXME add a state check
|
||||||
|
glBindTexture(m_texture_target, m_texture_id);
|
||||||
|
glTexSubImage2D(m_texture_target, 0, r.left, r.bottom, r.right-r.left, r.top-r.bottom, m_format, GL_UNSIGNED_BYTE, data);
|
||||||
|
break;
|
||||||
|
case GSTexture::RenderTarget:
|
||||||
|
case GSTexture::DepthStencil:
|
||||||
|
case GSTexture::Offscreen:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
#if 0
|
#if 0
|
||||||
if(m_dev && m_texture)
|
if(m_dev && m_texture)
|
||||||
{
|
{
|
||||||
|
@ -148,6 +201,25 @@ bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GSTextureOGL::EnableUnit(uint unit)
|
||||||
|
{
|
||||||
|
switch (m_type) {
|
||||||
|
case GSTexture::RenderTarget:
|
||||||
|
case GSTexture::DepthStencil:
|
||||||
|
case GSTexture::Offscreen:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
case GSTexture::Texture:
|
||||||
|
// FIXME
|
||||||
|
// Howto allocate the texture unit !!!
|
||||||
|
// In worst case the HW renderer seems to use 3 texture unit
|
||||||
|
// For the moment SW renderer only use 1 so don't bother
|
||||||
|
glActiveTexture(GL_TEXTURE0 + unit);
|
||||||
|
glBindTexture(m_texture_target, m_texture_id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool GSTextureOGL::Map(GSMap& m, const GSVector4i* r)
|
bool GSTextureOGL::Map(GSMap& m, const GSVector4i* r)
|
||||||
{
|
{
|
||||||
// The function allow to modify the texture from the CPU
|
// The function allow to modify the texture from the CPU
|
||||||
|
@ -156,6 +228,8 @@ bool GSTextureOGL::Map(GSMap& m, const GSVector4i* r)
|
||||||
// I think in opengl we need to copy back the data to the RAM: glReadPixels — read a block of pixels from the frame buffer
|
// I think in opengl we need to copy back the data to the RAM: glReadPixels — read a block of pixels from the frame buffer
|
||||||
//
|
//
|
||||||
// glMapBuffer — map a buffer object's data store
|
// glMapBuffer — map a buffer object's data store
|
||||||
|
// Can be used on GL_PIXEL_UNPACK_BUFFER or GL_TEXTURE_BUFFER
|
||||||
|
return false;
|
||||||
#if 0
|
#if 0
|
||||||
if(r != NULL)
|
if(r != NULL)
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,16 +28,17 @@ class GSTextureOGL : public GSTexture
|
||||||
private:
|
private:
|
||||||
GLenum m_texture_target; // texture target: 2D, rectangle etc...
|
GLenum m_texture_target; // texture target: 2D, rectangle etc...
|
||||||
GLuint m_texture_id; // the texture id
|
GLuint m_texture_id; // the texture id
|
||||||
int m_texture_unit; // the texture unit offset
|
uint m_texture_unit; // the texture unit offset
|
||||||
|
|
||||||
void EnableUnit();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit GSTextureOGL();
|
explicit GSTextureOGL(int type, int w, int h, bool msaa, int format);
|
||||||
virtual ~GSTextureOGL();
|
virtual ~GSTextureOGL();
|
||||||
|
|
||||||
bool Update(const GSVector4i& r, const void* data, int pitch);
|
bool Update(const GSVector4i& r, const void* data, int pitch);
|
||||||
bool Map(GSMap& m, const GSVector4i* r = NULL);
|
bool Map(GSMap& m, const GSVector4i* r = NULL);
|
||||||
void Unmap();
|
void Unmap();
|
||||||
bool Save(const string& fn, bool dds = false);
|
bool Save(const string& fn, bool dds = false);
|
||||||
|
|
||||||
|
void EnableUnit(uint unit);
|
||||||
|
void Attach(GLenum attachment);
|
||||||
};
|
};
|
||||||
|
|
|
@ -352,6 +352,8 @@ void GSWnd::Detach()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PFNGLTEXSTORAGE2DPROC glTexStorage2D_glew17 = NULL;
|
||||||
|
|
||||||
bool GSWnd::Create(const string& title, int w, int h)
|
bool GSWnd::Create(const string& title, int w, int h)
|
||||||
{
|
{
|
||||||
if(m_window != NULL) return false;
|
if(m_window != NULL) return false;
|
||||||
|
@ -405,6 +407,22 @@ bool GSWnd::Create(const string& title, int w, int h)
|
||||||
SDL_GetWindowWMInfo(m_window, &wminfo);
|
SDL_GetWindowWMInfo(m_window, &wminfo);
|
||||||
m_Xwindow = wminfo.info.x11.window;
|
m_Xwindow = wminfo.info.x11.window;
|
||||||
|
|
||||||
|
// OpenGL mode
|
||||||
|
// FIXME : be sure that the window is map
|
||||||
|
if ( theApp.GetConfig("renderer", 0) / 3 == 4 ) {
|
||||||
|
// FIXME......
|
||||||
|
// GLEW's problem is that it calls glGetString(GL_EXTENSIONS) which causes GL_INVALID_ENUM on GL 3.2 forward compatible context as soon as glewInit() is called. It also doesn't fetch the function pointers. The solution is for GLEW to use glGetStringi instead.
|
||||||
|
// The current version of GLEW is 1.7.0 but they still haven't corrected it. The only fix is to use glewExperimental for now :
|
||||||
|
glewExperimental=true;
|
||||||
|
const int glew_ok = glewInit();
|
||||||
|
if (glew_ok != GLEW_OK)
|
||||||
|
{
|
||||||
|
// FIXME:proper logging
|
||||||
|
fprintf(stderr, "Failed to init glew\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
glTexStorage2D_glew17 = (PFNGLTEXSTORAGE2DPROC)glXGetProcAddressARB((const GLubyte*)"glTexStorage2D");
|
||||||
|
}
|
||||||
|
|
||||||
return (m_window != NULL);
|
return (m_window != NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,142 @@
|
||||||
|
#if 0
|
||||||
|
struct VS_INPUT
|
||||||
|
{
|
||||||
|
float4 p : POSITION;
|
||||||
|
float2 t : TEXCOORD0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VS_OUTPUT
|
||||||
|
{
|
||||||
|
float4 p : SV_Position;
|
||||||
|
float2 t : TEXCOORD0;
|
||||||
|
};
|
||||||
|
|
||||||
|
Texture2D Texture;
|
||||||
|
SamplerState TextureSampler;
|
||||||
|
|
||||||
|
float4 sample_c(float2 uv)
|
||||||
|
{
|
||||||
|
return Texture.Sample(TextureSampler, uv);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PS_INPUT
|
||||||
|
{
|
||||||
|
float4 p : SV_Position;
|
||||||
|
float2 t : TEXCOORD0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PS_OUTPUT
|
||||||
|
{
|
||||||
|
float4 c : SV_Target0;
|
||||||
|
};
|
||||||
|
|
||||||
|
VS_OUTPUT vs_main(VS_INPUT input)
|
||||||
|
{
|
||||||
|
VS_OUTPUT output;
|
||||||
|
|
||||||
|
output.p = input.p;
|
||||||
|
output.t = input.t;
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
PS_OUTPUT ps_main0(PS_INPUT input)
|
||||||
|
{
|
||||||
|
PS_OUTPUT output;
|
||||||
|
|
||||||
|
output.c = sample_c(input.t);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
PS_OUTPUT ps_main7(PS_INPUT input)
|
||||||
|
{
|
||||||
|
PS_OUTPUT output;
|
||||||
|
|
||||||
|
float4 c = sample_c(input.t);
|
||||||
|
|
||||||
|
c.a = dot(c.rgb, float3(0.299, 0.587, 0.114));
|
||||||
|
|
||||||
|
output.c = c;
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
float4 ps_crt(PS_INPUT input, int i)
|
||||||
|
{
|
||||||
|
float4 mask[4] =
|
||||||
|
{
|
||||||
|
float4(1, 0, 0, 0),
|
||||||
|
float4(0, 1, 0, 0),
|
||||||
|
float4(0, 0, 1, 0),
|
||||||
|
float4(1, 1, 1, 0)
|
||||||
|
};
|
||||||
|
|
||||||
|
return sample_c(input.t) * saturate(mask[i] + 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint ps_main1(PS_INPUT input) : SV_Target0
|
||||||
|
{
|
||||||
|
float4 c = sample_c(input.t);
|
||||||
|
|
||||||
|
c.a *= 256.0f / 127; // hm, 0.5 won't give us 1.0 if we just multiply with 2
|
||||||
|
|
||||||
|
uint4 i = c * float4(0x001f, 0x03e0, 0x7c00, 0x8000);
|
||||||
|
|
||||||
|
return (i.x & 0x001f) | (i.y & 0x03e0) | (i.z & 0x7c00) | (i.w & 0x8000);
|
||||||
|
}
|
||||||
|
|
||||||
|
PS_OUTPUT ps_main2(PS_INPUT input)
|
||||||
|
{
|
||||||
|
PS_OUTPUT output;
|
||||||
|
|
||||||
|
clip(sample_c(input.t).a - 128.0f / 255); // >= 0x80 pass
|
||||||
|
|
||||||
|
output.c = 0;
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
PS_OUTPUT ps_main3(PS_INPUT input)
|
||||||
|
{
|
||||||
|
PS_OUTPUT output;
|
||||||
|
|
||||||
|
clip(127.95f / 255 - sample_c(input.t).a); // < 0x80 pass (== 0x80 should not pass)
|
||||||
|
|
||||||
|
output.c = 0;
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
PS_OUTPUT ps_main4(PS_INPUT input)
|
||||||
|
{
|
||||||
|
PS_OUTPUT output;
|
||||||
|
|
||||||
|
output.c = fmod(sample_c(input.t) * 255 + 0.5f, 256) / 255;
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
PS_OUTPUT ps_main5(PS_INPUT input) // triangular
|
||||||
|
{
|
||||||
|
PS_OUTPUT output;
|
||||||
|
|
||||||
|
uint4 p = (uint4)input.p;
|
||||||
|
|
||||||
|
// output.c = ps_crt(input, ((p.x + (p.y & 1) * 3) >> 1) % 3);
|
||||||
|
output.c = ps_crt(input, ((p.x + ((p.y >> 1) & 1) * 3) >> 1) % 3);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
PS_OUTPUT ps_main6(PS_INPUT input) // diagonal
|
||||||
|
{
|
||||||
|
PS_OUTPUT output;
|
||||||
|
|
||||||
|
uint4 p = (uint4)input.p;
|
||||||
|
|
||||||
|
output.c = ps_crt(input, (p.x + (p.y % 3)) % 3);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,46 @@
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
Texture2D Texture;
|
||||||
|
SamplerState Sampler;
|
||||||
|
|
||||||
|
cbuffer cb0
|
||||||
|
{
|
||||||
|
float2 ZrH;
|
||||||
|
float hH;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PS_INPUT
|
||||||
|
{
|
||||||
|
float4 p : SV_Position;
|
||||||
|
float2 t : TEXCOORD0;
|
||||||
|
};
|
||||||
|
|
||||||
|
float4 ps_main0(PS_INPUT input) : SV_Target0
|
||||||
|
{
|
||||||
|
clip(frac(input.t.y * hH) - 0.5);
|
||||||
|
|
||||||
|
return Texture.Sample(Sampler, input.t);
|
||||||
|
}
|
||||||
|
|
||||||
|
float4 ps_main1(PS_INPUT input) : SV_Target0
|
||||||
|
{
|
||||||
|
clip(0.5 - frac(input.t.y * hH));
|
||||||
|
|
||||||
|
return Texture.Sample(Sampler, input.t);
|
||||||
|
}
|
||||||
|
|
||||||
|
float4 ps_main2(PS_INPUT input) : SV_Target0
|
||||||
|
{
|
||||||
|
float4 c0 = Texture.Sample(Sampler, input.t - ZrH);
|
||||||
|
float4 c1 = Texture.Sample(Sampler, input.t);
|
||||||
|
float4 c2 = Texture.Sample(Sampler, input.t + ZrH);
|
||||||
|
|
||||||
|
return (c0 + c1 * 2 + c2) / 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
float4 ps_main3(PS_INPUT input) : SV_Target0
|
||||||
|
{
|
||||||
|
return Texture.Sample(Sampler, input.t);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,31 @@
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
Texture2D Texture;
|
||||||
|
SamplerState Sampler;
|
||||||
|
|
||||||
|
cbuffer cb0
|
||||||
|
{
|
||||||
|
float4 BGColor;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PS_INPUT
|
||||||
|
{
|
||||||
|
float4 p : SV_Position;
|
||||||
|
float2 t : TEXCOORD0;
|
||||||
|
};
|
||||||
|
|
||||||
|
float4 ps_main0(PS_INPUT input) : SV_Target0
|
||||||
|
{
|
||||||
|
float4 c = Texture.Sample(Sampler, input.t);
|
||||||
|
c.a = min(c.a * 2, 1);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
float4 ps_main1(PS_INPUT input) : SV_Target0
|
||||||
|
{
|
||||||
|
float4 c = Texture.Sample(Sampler, input.t);
|
||||||
|
c.a = BGColor.a;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -113,8 +113,14 @@ using namespace stdext;
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
|
#include <GL/glx.h>
|
||||||
#include <GL/glext.h>
|
#include <GL/glext.h>
|
||||||
|
|
||||||
|
// Need to have glew 1.7 but Debian/Ubuntu is only 1.6
|
||||||
|
// We will see later for the upgrade
|
||||||
|
typedef void (GLAPIENTRY * PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
|
||||||
|
extern PFNGLTEXSTORAGE2DPROC glTexStorage2D_glew17;
|
||||||
|
|
||||||
//using namespace __gnu_cxx;
|
//using namespace __gnu_cxx;
|
||||||
|
|
||||||
#define DIRECTORY_SEPARATOR '/'
|
#define DIRECTORY_SEPARATOR '/'
|
||||||
|
|
Loading…
Reference in New Issue