openMSX
video
SDLGLOutputSurface.cc
Go to the documentation of this file.
1
#
include
"SDLGLOutputSurface.hh"
2
#
include
"GLContext.hh"
3
#
include
"OutputSurface.hh"
4
#
include
"PNG.hh"
5
#
include
"build-info.hh"
6
#
include
"Math.hh"
7
#
include
"MemBuffer.hh"
8
#
include
"vla.hh"
9
#
include
<
SDL
.
h
>
10
11
using
namespace
gl;
12
13
namespace
openmsx
{
14
15
SDLGLOutputSurface
::
SDLGLOutputSurface
(
FrameBuffer
frameBuffer_
)
16
:
fbTex
(
Null
())
17
,
frameBuffer
(
frameBuffer_
)
18
{
19
}
20
21
void
SDLGLOutputSurface
::
init
(
OutputSurface
&
output
)
22
{
23
// This is logically a part of the constructor, but the constructor
24
// of the child class needs to run before this code (to create a
25
// openGL context). So we split the constructor in two parts, the
26
// child class is responsible for calling this second part.
27
28
SDLAllocFormatPtr
format
(
SDL_AllocFormat
(
29
(
frameBuffer
==
FB_16BPP
) ?
SDL_PIXELFORMAT_RGB24
:
30
OPENMSX_BIGENDIAN
?
SDL_PIXELFORMAT_RGBA8888
:
31
SDL_PIXELFORMAT_ARGB8888
));
32
output
.
setSDLFormat
(*
format
);
33
34
if
(
frameBuffer
==
FB_NONE
) {
35
output
.
setBufferPtr
(
nullptr
, 0);
// direct access not allowed
36
}
else
{
37
// TODO 64 byte aligned (see RawFrame)
38
unsigned
width
=
output
.
getWidth
();
39
unsigned
height
=
output
.
getHeight
();
40
unsigned
texW
=
Math
::
ceil2
(
width
);
41
unsigned
texH
=
Math
::
ceil2
(
height
);
42
fbBuf
.
resize
(
format
->
BytesPerPixel
*
texW
*
texH
);
43
unsigned
pitch
=
width
*
format
->
BytesPerPixel
;
44
output
.
setBufferPtr
(
fbBuf
.
data
(),
pitch
);
45
46
texCoordX
=
float
(
width
) /
texW
;
47
texCoordY
=
float
(
height
) /
texH
;
48
49
fbTex
.
allocate
();
50
fbTex
.
setInterpolation
(
false
);
51
if
(
frameBuffer
==
FB_16BPP
) {
52
// TODO: Why use RGB texture instead of RGBA?
53
glTexImage2D
(
GL_TEXTURE_2D
, 0,
GL_RGB
,
texW
,
texH
, 0,
54
GL_RGB
,
GL_UNSIGNED_SHORT_5_6_5
,
fbBuf
.
data
());
55
}
else
{
56
glTexImage2D
(
GL_TEXTURE_2D
, 0,
GL_RGBA8
,
texW
,
texH
, 0,
57
GL_BGRA
,
GL_UNSIGNED_BYTE
,
fbBuf
.
data
());
58
}
59
}
60
}
61
62
void
SDLGLOutputSurface
::
flushFrameBuffer
(
unsigned
width
,
unsigned
height
)
63
{
64
assert((
frameBuffer
==
FB_16BPP
) || (
frameBuffer
==
FB_32BPP
));
65
66
fbTex
.
bind
();
67
if
(
frameBuffer
==
FB_16BPP
) {
68
glTexSubImage2D
(
GL_TEXTURE_2D
, 0, 0, 0,
width
,
height
,
69
GL_RGB
,
GL_UNSIGNED_SHORT_5_6_5
,
fbBuf
.
data
());
70
}
else
{
71
glTexSubImage2D
(
GL_TEXTURE_2D
, 0, 0, 0,
width
,
height
,
72
GL_BGRA
,
GL_UNSIGNED_BYTE
,
fbBuf
.
data
());
73
}
74
75
vec2
pos
[4] = {
76
vec2
(0,
height
),
77
vec2
(
width
,
height
),
78
vec2
(
width
, 0 ),
79
vec2
(0, 0 ),
80
};
81
vec2
tex
[4] = {
82
vec2
(0.0f,
texCoordY
),
83
vec2
(
texCoordX
,
texCoordY
),
84
vec2
(
texCoordX
, 0.0f ),
85
vec2
(0.0f, 0.0f ),
86
};
87
gl
::
context
->
progTex
.
activate
();
88
glUniform4f
(
gl
::
context
->
unifTexColor
, 1.0f, 1.0f, 1.0f, 1.0f);
89
glUniformMatrix4fv
(
gl
::
context
->
unifTexMvp
, 1,
GL_FALSE
,
90
&
gl
::
context
->
pixelMvp
[0][0]);
91
glVertexAttribPointer
(0, 2,
GL_FLOAT
,
GL_FALSE
, 0,
pos
);
92
glVertexAttribPointer
(1, 2,
GL_FLOAT
,
GL_FALSE
, 0,
tex
);
93
glEnableVertexAttribArray
(0);
94
glEnableVertexAttribArray
(1);
95
glDrawArrays
(
GL_TRIANGLE_FAN
, 0, 4);
96
glDisableVertexAttribArray
(1);
97
glDisableVertexAttribArray
(0);
98
}
99
100
void
SDLGLOutputSurface
::
clearScreen
()
101
{
102
glClearColor
(0.0f, 0.0f, 0.0f, 1.0f);
103
glClear
(
GL_COLOR_BUFFER_BIT
);
104
}
105
106
void
SDLGLOutputSurface
::
saveScreenshot
(
107
const
std
::
string
&
filename
,
const
OutputSurface
&
output
)
const
108
{
109
gl
::
ivec2
offset
=
output
.
getViewOffset
();
110
gl
::
ivec2
size
=
output
.
getViewSize
();
111
112
VLA
(
const
void
*,
rowPointers
,
size
[1]);
113
MemBuffer
<
uint8_t
>
buffer
(
size
[0] *
size
[1] * 3);
114
for
(
int
i
= 0;
i
<
size
[1]; ++
i
) {
115
rowPointers
[
size
[1] - 1 -
i
] = &
buffer
[
size
[0] * 3 *
i
];
116
}
117
glReadPixels
(
offset
[0],
offset
[1],
size
[0],
size
[1],
GL_RGB
,
GL_UNSIGNED_BYTE
,
buffer
.
data
());
118
PNG
::
save
(
size
[0],
size
[1],
rowPointers
,
filename
);
119
}
120
121
}
// namespace openmsx
openmsx::EnumSetting::getEnum
bool getEnum() const noexcept
Definition:
EnumSetting.hh:96
VLA
#define VLA(TYPE, NAME, LENGTH)
Definition:
vla.hh:10
Generated on Sun Oct 20 2019 21:22:15 for openMSX by
1.8.13