1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
//============================================================
//
// target.cpp - Render target abstraction for BGFX layer
//
//============================================================
#include "emucore.h"
#include "target.h"
bgfx_target::bgfx_target(std::string name, bgfx::TextureFormat::Enum format, uint16_t width, uint16_t height, uint32_t style, bool double_buffer, bool filter, uint16_t scale, uint32_t screen)
: m_name(name)
, m_format(format)
, m_targets(nullptr)
, m_textures(nullptr)
, m_width(width)
, m_height(height)
, m_double_buffer(double_buffer)
, m_style(style)
, m_filter(filter)
, m_scale(scale)
, m_screen(screen)
, m_current_page(0)
, m_initialized(false)
, m_page_count(double_buffer ? 2 : 1)
{
if (m_width > 0 && m_height > 0)
{
m_width *= m_scale;
m_height *= m_scale;
uint32_t wrap_mode = BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP;
uint32_t filter_mode = filter ? (BGFX_TEXTURE_MIN_ANISOTROPIC | BGFX_TEXTURE_MAG_ANISOTROPIC) : (BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT | BGFX_TEXTURE_MIP_POINT);
m_textures = new bgfx::TextureHandle[m_page_count];
m_targets = new bgfx::FrameBufferHandle[m_page_count];
for (int page = 0; page < m_page_count; page++)
{
m_textures[page] = bgfx::createTexture2D(m_width, m_height, false, 1, format, wrap_mode | filter_mode | BGFX_TEXTURE_RT);
assert(m_textures[page].idx != 0xffff);
m_targets[page] = bgfx::createFrameBuffer(1, &m_textures[page], false);
assert(m_targets[page].idx != 0xffff);
}
m_initialized = true;
}
}
bgfx_target::bgfx_target(void *handle, uint16_t width, uint16_t height)
: m_name("backbuffer")
, m_format(bgfx::TextureFormat::Unknown)
, m_targets(nullptr)
, m_textures(nullptr)
, m_width(width)
, m_height(height)
, m_double_buffer(false)
, m_style(TARGET_STYLE_CUSTOM)
, m_filter(false)
, m_scale(0)
, m_screen(-1)
, m_current_page(0)
, m_initialized(true)
, m_page_count(0)
{
m_targets = new bgfx::FrameBufferHandle[1];
m_targets[0] = bgfx::createFrameBuffer(handle, width, height);
// No backing texture
}
bgfx_target::~bgfx_target()
{
if (!m_initialized)
{
return;
}
if (m_page_count > 0)
{
for (int page = 0; page < m_page_count; page++)
{
bgfx::destroyFrameBuffer(m_targets[page]);
bgfx::destroyTexture(m_textures[page]);
}
delete [] m_textures;
delete [] m_targets;
}
else
{
bgfx::destroyFrameBuffer(m_targets[0]);
delete [] m_targets;
}
}
void bgfx_target::page_flip()
{
if (!m_initialized) return;
if (m_double_buffer)
{
m_current_page = 1 - m_current_page;
}
}
bgfx::FrameBufferHandle bgfx_target::target()
{
if (!m_initialized) return BGFX_INVALID_HANDLE;
return m_targets[m_current_page];
}
bgfx::TextureHandle bgfx_target::texture() const
{
if (!m_initialized) return BGFX_INVALID_HANDLE;
if (m_double_buffer)
{
return m_textures[1 - m_current_page];
}
else
{
return m_textures[m_current_page];
}
}
|