Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Ludmány Balázs
/
thin-client
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
3aeb58bf
authored
Jul 26, 2016
by
Ludmány Balázs
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Reuse buffers
parent
48d85ad7
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
232 additions
and
146 deletions
+232
-146
ThinClient.pro
+1
-1
ThinClient.pro.user
+1
-1
copy_shader.fsh
+2
-1
copy_shader.vsh
+7
-7
dispatcher.cpp
+14
-22
dispatcher.h
+1
-3
draw_shader.fsh
+4
-3
draw_shader.vsh
+10
-9
jpegdecoder.cpp
+3
-2
jpegdecoder.h
+5
-11
main.qml
+4
-3
qvnc.cpp
+7
-4
qvnc.h
+1
-1
uploader.cpp
+0
-0
uploader.h
+118
-26
vncrenderer.cpp
+46
-43
vncrenderer.h
+8
-9
No files found.
ThinClient.pro
View file @
3aeb58bf
TEMPLATE
=
app
QT
+=
qml
quick
CONFIG
+=
c
++
1
1
CONFIG
+=
c
++
1
4
SOURCES
+=
main
.
cpp
\
jpegdecoder
.
cpp
\
...
...
ThinClient.pro.user
View file @
3aeb58bf
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 3.5.1, 2016-07-2
0T14:21:50
. -->
<!-- Written by QtCreator 3.5.1, 2016-07-2
6T16:47:48
. -->
<qtcreator>
<data>
<variable>
EnvironmentId
</variable>
...
...
copy_shader.fsh
View file @
3aeb58bf
uniform sampler2D texture;
varying
high
p vec2 vartexcoord;
varying
medium
p vec2 vartexcoord;
void main(void)
{
gl_FragColor = vec4(texture2D(texture, vartexcoord).rgb, 1.0);
//gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
copy_shader.vsh
View file @
3aeb58bf
uniform highp mat4 ortho;
attribute highp vec2 position;
attribute highp vec2 texcoord;
varying highp vec2 vartexcoord;
uniform mediump mat4 ortho;
uniform mediump mat4 texortho;
attribute mediump vec2 position;
attribute mediump vec2 texcoord;
varying mediump vec2 vartexcoord;
void main(void)
{
gl_Position = vec4(position, 1.0, 1.0);
highp vec4 temp = ortho * vec4(texcoord, 0.0, 1.0);
vartexcoord = temp.xy * vec2(0.5, 0.5) + vec2(0.5, 0.5);
gl_Position = vec4((position.x - 1024.0) / 1024.0, (position.y - 1024.0) / 1024.0, 0.0, 1.0);
vartexcoord = vec2(0.0, 1.0) - vec2(texcoord.x / 1280.0, texcoord.y / 720.0);
}
dispatcher.cpp
View file @
3aeb58bf
...
...
@@ -12,7 +12,7 @@ rfbBool Dispatcher::MallocFrameBuffer(rfbClient *client)
return
TRUE
;
}
void
Dispatcher
::
GotCopyRect
(
rfbClient
*
client
,
int
src_x
,
int
src_y
,
int
w
,
int
h
,
int
dest_x
,
int
dest_y
)
void
Dispatcher
::
GotCopyRect
(
rfbClient
*
client
,
const
int
src_x
,
const
int
src_y
,
const
int
w
,
const
int
h
,
const
int
dest_x
,
const
int
dest_y
)
{
Dispatcher
*
dispatcher
=
(
Dispatcher
*
)
rfbClientGetClientData
(
client
,
0
);
dispatcher
->
uploader
()
->
gotCopy
(
src_x
,
src_y
,
w
,
h
,
dest_x
,
dest_y
);
...
...
@@ -31,13 +31,15 @@ void Dispatcher::GotBitmap(rfbClient *client, const uint8_t *buffer, int x, int
{
Dispatcher
*
dispatcher
=
(
Dispatcher
*
)
rfbClientGetClientData
(
client
,
0
);
// We have to make a deep copy because libvnc might free the buffer as soon as this function returns
dispatcher
->
uploader
()
->
gotBitmap
(
QByteArray
((
const
char
*
)
buffer
,
w
*
h
*
(
dispatcher
->
bitsPerPixel
()
/
8
)),
x
,
y
,
w
,
h
,
GL_RGBA
,
GL_UNSIGNED_BYTE
);
QImage
image
(
buffer
,
w
,
h
,
QImage
::
Format_RGBX8888
);
dispatcher
->
uploader
()
->
gotBitmap
(
image
.
convertToFormat
(
QImage
::
Format_RGB888
),
x
,
y
,
w
,
h
);
}
rfbBool
Dispatcher
::
GotJpeg
(
rfbClient
*
client
,
const
uint8_t
*
buffer
,
int
length
,
int
x
,
int
y
,
int
w
,
int
h
)
{
Dispatcher
*
dispatcher
=
static_cast
<
Dispatcher
*>
(
rfbClientGetClientData
(
client
,
0
));
Jpeg
*
jpeg
=
new
Jpeg
((
unsigned
char
*
)
buffer
,
length
,
dispatcher
->
uploader
()
->
gotJpeg
(
x
,
y
,
w
,
h
));
dispatcher
->
uploader
()
->
gotJpeg
();
Jpeg
*
jpeg
=
new
Jpeg
({(
unsigned
char
*
)
buffer
,
length
,
x
,
y
,
w
,
h
});
dispatcher
->
queue
()
->
enqueue
(
jpeg
);
return
TRUE
;
}
...
...
@@ -70,13 +72,6 @@ int Dispatcher::bitsPerPixel()
return
m_client
->
format
.
bitsPerPixel
;
}
QVector3D
Dispatcher
::
colorMax
()
const
{
if
(
m_client
==
NULL
)
return
QVector3D
();
return
QVector3D
(
m_client
->
format
.
redMax
,
m_client
->
format
.
greenMax
,
m_client
->
format
.
blueMax
);
}
ConcurrentQueue
<
Jpeg
*
,
256u
>
*
Dispatcher
::
queue
()
{
return
&
m_queue
;
...
...
@@ -107,8 +102,8 @@ void Dispatcher::open(const QString host, const int port, const int width, const
// Set the format requested by the user
m_client
->
width
=
width
;
m_client
->
height
=
height
;
m_client
->
appData
.
compressLevel
=
0
;
m_client
->
appData
.
qualityLevel
=
0
;
//
m_client->appData.compressLevel = 0;
//
m_client->appData.qualityLevel = 0;
#ifdef __BIG_ENDIAN__
m_client
->
format
.
bigEndian
=
TRUE
;
#else
...
...
@@ -124,7 +119,6 @@ void Dispatcher::open(const QString host, const int port, const int width, const
emit
error
();
return
;
}
emit
colorMaxChanged
(
colorMax
());
// Stick to the format sent by the server if we can render it easily, set a new one otherwise
//
...
...
@@ -156,25 +150,23 @@ void Dispatcher::refresh()
if
(
m_client
==
NULL
)
return
;
m_uploader
->
cleanup
();
int
message
=
0
;
if
(
!
HandleRFBServerMessage
(
m_client
))
{
terminate
();
emit
error
();
return
;
}
// Wait until we get something
while
(
message
==
0
)
{
message
=
WaitForMessage
(
m_client
,
1000
0
);
message
=
WaitForMessage
(
m_client
,
1000
);
if
(
message
<
0
)
{
terminate
();
emit
error
();
return
;
}
}
if
(
!
HandleRFBServerMessage
(
m_client
))
{
terminate
();
emit
error
();
return
;
}
}
void
Dispatcher
::
terminate
()
...
...
dispatcher.h
View file @
3aeb58bf
...
...
@@ -25,7 +25,7 @@ public:
// libvnc hooks
static
rfbBool
MallocFrameBuffer
(
rfbClient
*
client
);
static
void
GotCopyRect
(
rfbClient
*
client
,
int
src_x
,
int
src_y
,
int
w
,
int
h
,
int
dest_x
,
int
dest_y
);
static
void
GotCopyRect
(
rfbClient
*
client
,
const
int
src_x
,
const
int
src_y
,
const
int
w
,
const
int
h
,
const
int
dest_x
,
const
int
dest_y
);
static
void
GotFillRect
(
rfbClient
*
client
,
int
x
,
int
y
,
int
w
,
int
h
,
uint32_t
colour
);
static
void
GotBitmap
(
rfbClient
*
client
,
const
uint8_t
*
buffer
,
int
x
,
int
y
,
int
w
,
int
h
);
static
rfbBool
GotJpeg
(
rfbClient
*
client
,
const
uint8_t
*
buffer
,
int
length
,
int
x
,
int
y
,
int
w
,
int
h
);
...
...
@@ -36,7 +36,6 @@ public:
// parameters of the VNC connection
int
bitsPerPixel
();
QVector3D
colorMax
()
const
;
// getters
ConcurrentQueue
<
Jpeg
*
,
256u
>*
queue
();
...
...
@@ -52,7 +51,6 @@ signals:
void
gotBitmap
(
const
QImage
&
image
,
const
quint32
x
,
const
quint32
y
,
const
quint32
width
,
const
quint32
height
);
void
finishedUpdate
();
void
resizeFramebuffer
(
const
QSize
&
size
);
void
colorMaxChanged
(
const
QVector3D
&
colorMax
);
void
error
();
public
slots
:
// manage VNC connection
...
...
draw_shader.fsh
View file @
3aeb58bf
uniform sampler2D texture;
varying
low
p vec2 vartexcoord;
varying lowp vec
3
varcolor;
varying
medium
p vec2 vartexcoord;
varying lowp vec
4
varcolor;
void main(void)
{
gl_FragColor = vec4(texture2D(texture, vartexcoord).rgb + varcolor, 1.0);
gl_FragColor = vec4(texture2D(texture, vartexcoord).rgb, 1.0) + varcolor;
// gl_FragColor = vec4(vartexcoord, 0.0, 1.0);
}
draw_shader.vsh
View file @
3aeb58bf
uniform lowp mat4 ortho;
uniform lowp vec3 colormax;
attribute lowp vec2 position;
attribute lowp vec3 color;
attribute lowp vec2 texcoord;
varying lowp vec3 varcolor;
varying lowp vec2 vartexcoord;
uniform mediump mat4 ortho;
attribute mediump vec2 position;
attribute lowp vec4 color;
attribute mediump vec2 texcoord;
varying lowp vec4 varcolor;
varying mediump vec2 vartexcoord;
void main(void)
{
gl_Position = ortho * vec4(position, 0.0, 1.0);
varcolor = color
/ colormax
;
vartexcoord =
texcoord
;
varcolor = color
.gggg
;
vartexcoord =
vec2(texcoord.x / 2048.0, texcoord.y / 2048.0)
;
}
jpegdecoder.cpp
View file @
3aeb58bf
...
...
@@ -22,7 +22,7 @@ void JpegDecoder::operate()
}
jpeg_create_decompress
(
&
cinfo
);
cinfo
.
do_fancy_upsampling
=
TRUE
;
cinfo
.
dct_method
=
JDCT_
IFAS
T
;
cinfo
.
dct_method
=
JDCT_
FLOA
T
;
jpeg_mem_src
(
&
cinfo
,
jpeg
->
data
,
jpeg
->
length
);
(
void
)
jpeg_read_header
(
&
cinfo
,
TRUE
);
...
...
@@ -38,7 +38,8 @@ void JpegDecoder::operate()
jpeg_read_scanlines
(
&
cinfo
,
rows
+
cinfo
.
output_scanline
,
1
);
}
(
void
)
jpeg_finish_decompress
(
&
cinfo
);
emit
finished
(
samples
,
cinfo
.
output_width
,
cinfo
.
output_height
,
jpeg
->
index
);
emit
finished
(
samples
,
jpeg
->
x
,
jpeg
->
y
,
jpeg
->
width
,
jpeg
->
height
);
delete
[]
jpeg
->
data
;
delete
jpeg
;
delete
rows
;
jpeg_destroy_decompress
(
&
cinfo
);
...
...
jpegdecoder.h
View file @
3aeb58bf
...
...
@@ -14,18 +14,12 @@
struct
Jpeg
{
Jpeg
(
uint8_t
*
d
,
const
int
l
,
const
int
i
)
:
data
(
d
),
length
(
l
),
index
(
i
)
{
}
~
Jpeg
()
{
delete
[]
data
;
}
uint8_t
*
data
;
int
length
;
int
index
;
int
x
;
int
y
;
int
width
;
int
height
;
};
/*!
...
...
@@ -40,7 +34,7 @@ public:
JpegDecoder
(
ConcurrentQueue
<
Jpeg
*
,
256u
>
*
queue
,
QObject
*
parent
=
0
);
ConcurrentQueue
<
Jpeg
*
,
256u
>
*
m_queue
;
signals
:
void
finished
(
const
unsigned
char
*
image
,
const
int
width
,
const
int
height
,
const
int
index
);
void
finished
(
const
unsigned
char
*
image
,
const
quint32
x
,
const
quint32
y
,
const
quint32
width
,
const
quint32
height
);
public
slots
:
void
operate
();
};
...
...
main.qml
View file @
3aeb58bf
...
...
@@ -4,7 +4,8 @@ import thinclient 1.3
ApplicationWindow
{
visible
:
true
visibility
:
"Maximized"
width
:
vnc
.
width
height
:
tab
.
height
+
vnc
.
height
id
:
window
header
:
TabBar
{
...
...
@@ -27,7 +28,7 @@ ApplicationWindow {
id
:
vnc
host
:
"vm.ik.bme.hu"
port
:
10495
width
:
window
.
width
height
:
window
.
height
-
tab
.
height
width
:
1280
height
:
720
}
}
qvnc.cpp
View file @
3aeb58bf
...
...
@@ -25,6 +25,7 @@ QVnc::QVnc(QQuickItem *parent) :
connect
(
this
,
&
QVnc
::
open_connection
,
m_dispatcher
,
&
Dispatcher
::
open
);
connect
(
this
,
&
QVnc
::
terminate_connection
,
m_dispatcher
,
&
Dispatcher
::
terminate
);
connect
(
m_dispatcher
,
&
Dispatcher
::
error
,
this
,
&
QVnc
::
dispatch_error
);
connect
(
m_uploader
,
&
Uploader
::
uploadFinished
,
m_dispatcher
,
&
Dispatcher
::
refresh
);
int
i
=
1
;
foreach
(
JpegDecoder
*
d
,
m_decoders
)
{
...
...
@@ -85,17 +86,19 @@ void QVnc::dispatch_error()
void
QVnc
::
winChanged
(
QQuickWindow
*
window
)
{
if
(
window
!=
NULL
)
if
(
window
!=
NULL
)
{
connect
(
window
,
&
QQuickWindow
::
openglContextCreated
,
m_uploader
,
&
Uploader
::
createContext
,
Qt
::
BlockingQueuedConnection
);
connect
(
window
,
&
QQuickWindow
::
frameSwapped
,
m_uploader
,
&
Uploader
::
frameSwapped
);
}
}
QQuickFramebufferObject
::
Renderer
*
QVnc
::
createRenderer
()
const
{
VncRenderer
*
renderer
=
new
VncRenderer
(
window
(),
m_uploader
->
vertices
(),
m_uploader
->
textures
());
connect
(
m_dispatcher
,
&
Dispatcher
::
colorMaxChanged
,
renderer
,
&
VncRenderer
::
setColorMax
);
connect
(
renderer
,
&
VncRenderer
::
finishedRendering
,
m_dispatcher
,
&
Dispatcher
::
refresh
);
m_uploader
->
indices
(),
m_uploader
->
texture
(),
m_uploader
->
drawCount
()
);
connect
(
renderer
,
&
VncRenderer
::
FBOTextureChanged
,
m_uploader
,
&
Uploader
::
changeFBOTexture
);
return
renderer
;
}
...
...
qvnc.h
View file @
3aeb58bf
#ifndef VNC_H
#define VNC_H
#define DECODER_COUNT
16
#define DECODER_COUNT
8
#include <QQuickWindow>
#include <QObject>
...
...
uploader.cpp
View file @
3aeb58bf
This diff is collapsed.
Click to expand it.
uploader.h
View file @
3aeb58bf
/*
* Design decisions:
* - There is no way to access texture memory directly, copying is required.
* See: https://www.raspberrypi.org/forums/viewtopic.php?f=67&t=25959
* - libvnc hooks free the memory buffer after they return (except for gotJpeg)
* Solutions:
* 1) copy images to separate textures
* Pro: simple
* Con: multiple textures (slow)
* 2) make deep copies of the images and move them to a single texture when decoding finished
* Pro: optimal texture atlas
* Con: deep copy
* 3) first-fit allocation
*/
#ifndef UPLOADER_H
#define UPLOADER_H
#define TEXTURE_WIDTH 2048
#define TEXTURE_HEIGHT 2048
#define COPY_BUFFER 1024
#define VERTEX_BUFFER 1024
#include <utility>
#include <QObject>
#include <QQuickWindow>
#include <QDebug>
...
...
@@ -9,24 +31,53 @@
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QOpenGLBuffer>
#include <QOpenGLTexture>
#include <QOpenGLPixelTransferOptions>
#include <QOpenGLShaderProgram>
#include <QOpenGLFramebufferObject>
#include <QThreadPool>
#include <QtAlgorithms>
#include <QSharedPointer>
#include <QtMath>
class
Bitmap
{
public
:
QByteArray
data
;
int
x
;
int
y
;
int
width
;
int
height
;
struct
Indices
{
// 4 corner/rectangle and the first and last one duplicated except for the first and last rectangle
unsigned
short
i
[(
VERTEX_BUFFER
/
4
)
*
6
-
2
];
constexpr
Indices
()
:
i
()
{
i
[
0
]
=
0
;
auto
index
=
1
;
for
(
auto
value
=
1
;
value
<
VERTEX_BUFFER
;
value
++
)
{
i
[
index
++
]
=
value
;
if
(
value
%
4
==
0
||
value
%
4
==
3
)
i
[
index
++
]
=
value
;
}
}
};
constexpr
Indices
ind
;
struct
Vertex
{
GLushort
x
;
GLushort
y
;
GLubyte
red
;
GLubyte
green
;
GLubyte
blue
;
GLubyte
alpha
;
GLushort
texX
;
GLushort
texY
;
};
struct
Copy
{
GLushort
x
;
GLushort
y
;
GLushort
texX
;
GLushort
texY
;
};
/*!
* \brief The Uploader class
*
* A framebuffer is bound to the
*/
class
Uploader
:
public
QObject
{
Q_OBJECT
...
...
@@ -34,42 +85,83 @@ public:
Uploader
(
QObject
*
parent
=
Q_NULLPTR
);
~
Uploader
();
QOpenGLBuffer
vertices
()
const
;
QSharedPointer
<
QVector
<
GLuint
>>
textures
()
const
;
QOpenGLBuffer
**
vertices
()
const
;
QOpenGLBuffer
indices
()
const
;
GLuint
**
texture
()
const
;
unsigned
int
*
drawCount
()
const
;
// VNC events
void
gotCopy
(
const
int
src_x
,
const
int
src_y
,
const
int
width
,
const
int
height
,
const
int
dest_x
,
const
int
dest_y
);
void
gotFill
(
const
int
x
,
const
int
y
,
const
int
width
,
const
int
height
,
const
float
red
,
const
float
green
,
const
float
blue
);
int
gotJpeg
(
const
quint32
x
,
const
quint32
y
,
const
quint32
width
,
const
quint32
height
);
void
gotBitmap
(
const
QByteArray
&
bitmap
,
const
quint32
x
,
const
quint32
y
,
const
quint32
width
,
const
quint32
height
,
const
GLenum
format
,
const
GLenum
type
);
void
gotFill
(
const
GLushort
x
,
const
GLushort
y
,
const
GLushort
width
,
const
GLushort
height
,
const
GLubyte
red
,
const
GLubyte
green
,
const
GLubyte
blue
);
void
gotCopy
(
const
GLushort
src_x
,
const
GLushort
src_y
,
const
GLushort
width
,
const
GLushort
height
,
const
GLushort
dest_x
,
const
GLushort
dest_y
);
void
gotBitmap
(
const
QImage
&
image
,
const
GLushort
x
,
const
GLushort
y
,
const
GLushort
width
,
const
GLushort
height
);
void
gotJpeg
();
void
finishedUpdate
();
private
:
QOffscreenSurface
m_surface
;
QOpenGLContext
m_context
;
QOpenGLFunctions
*
m_functions
;
QOpenGLBuffer
m_vertices
;
unsigned
int
m_allocated
;
QSharedPointer
<
QVector
<
GLuint
>>
m_textures
;
QOpenGLBuffer
m_indices
;
QOpenGLBuffer
**
m_uploadVertices
;
QOpenGLBuffer
**
m_renderVertices
;
Vertex
*
m_vertexPointer
;
size_t
m_vertexIndex
;
GLuint
m_FBOId
;
GLuint
m_texId
[
2
];
GLuint
**
m_uploadTexture
;
GLuint
**
m_renderTexture
;
unsigned
int
*
m_drawCount
;
QOpenGLShaderProgram
m_program
;
GLuint
m_FBOTexture
;
QVector
<
float
>
m_data
;
QVector
<
Bitmap
*>
m_bitmaps
;
int
m_jpegs
;
// Got a FinishedUpdate event from libvnc
bool
m_finished
;
// Framebuffer swapped
bool
m_swapped
;
void
swapBuffers
();
unsigned
short
m_atlasX
;
unsigned
short
m_atlasY
;
unsigned
short
m_atlasRowHeight
;
unsigned
short
m_atlasLastWidth
;
QOpenGLBuffer
m_copyBuffer
;
Copy
*
m_copyPointer
;
size_t
m_copyIndex
;
bool
refreshAtlas
(
const
int
width
,
const
int
height
);
// Called when:
// - got a Finished update event from libvnc
// - and every jpeg was uploaded
// - and the rendering thread swapped buffers
void
startRendering
();
// Called when:
// - got a Finished update event from libvnc
// - and the rendering thread swapped buffers
void
copyRectangles
();
signals
:
// Emit from startRendering only!
void
uploadFinished
();
public
slots
:
void
changeFBOTexture
(
const
unsigned
int
FBOTexture
,
const
QMatrix4x4
&
ortho
);
void
createContext
(
QOpenGLContext
*
context
);
void
cleanup
();
void
finishedJpeg
(
const
unsigned
char
*
image
,
const
quint32
width
,
const
quint32
height
,
int
index
);
void
finishedJpeg
(
const
unsigned
char
*
image
,
const
GLushort
x
,
const
GLushort
y
,
const
GLushort
width
,
const
GLushort
height
);
void
frameSwapped
();
};
#endif // UPLOADER_H
vncrenderer.cpp
View file @
3aeb58bf
#include "vncrenderer.h"
#include <cstring>
#include "uploader.h"
VncRenderer
::
VncRenderer
(
QQuickWindow
*
window
,
QOpenGLBuffer
vertices
,
QSharedPointer
<
QVector
<
GLuint
>>
textures
,
QOpenGLBuffer
**
vertices
,
QOpenGLBuffer
indices
,
GLuint
**
texture
,
unsigned
int
*
drawCount
,
QObject
*
parent
)
:
QObject
(
parent
),
m_window
(
window
),
m_vertices
(
vertices
),
m_
textures
(
textures
),
m_rendered
(
false
)
QObject
(
parent
),
m_window
(
window
),
m_vertices
(
vertices
),
m_
indices
(
indices
),
m_texture
(
texture
),
m_drawCount
(
drawCount
),
m_rendered
(
false
)
{
connect
(
m_window
,
&
QQuickWindow
::
frameSwapped
,
this
,
&
VncRenderer
::
frameSwapped
);
m_program
.
addShaderFromSourceFile
(
QOpenGLShader
::
Vertex
,
"draw_shader.vsh"
);
m_program
.
addShaderFromSourceFile
(
QOpenGLShader
::
Fragment
,
"draw_shader.fsh"
);
m_program
.
bind
();
m_program
.
setUniformValue
(
"texture"
,
0
);
QMatrix4x4
ortho
;
ortho
.
ortho
(
QRect
(
QPoint
(
0
,
0
),
QSize
(
2048
,
2048
)));
m_program
.
setUniformValue
(
"texortho"
,
ortho
);
m_program
.
release
();
m_functions
=
QOpenGLContext
::
currentContext
()
->
functions
();
...
...
@@ -21,36 +26,50 @@ VncRenderer::VncRenderer(QQuickWindow *window,
void
VncRenderer
::
render
()
{
/*static QTime frameTime;
qDebug() << qRound(1000.0 / frameTime.elapsed()) <<
m_textures->length()
;
qDebug() << qRound(1000.0 / frameTime.elapsed()) <<
*m_drawCount
;
frameTime.restart();*/
m_program
.
bind
();
m_vertices
.
bind
();
if
(
*
m_drawCount
>
0
)
{
m_program
.
bind
();
// m_functions->glActiveTexture(GL_TEXTURE0);
(
*
m_vertices
)
->
bind
();
m_indices
.
bind
();
m_functions
->
glVertexAttribPointer
(
m_program
.
attributeLocation
(
"position"
),
2
,
GL_UNSIGNED_SHORT
,
GL_FALSE
,
sizeof
(
Vertex
),
(
void
*
)
0
);
m_functions
->
glVertexAttribPointer
(
m_program
.
attributeLocation
(
"color"
),
4
,
GL_UNSIGNED_BYTE
,
GL_TRUE
,
sizeof
(
Vertex
),
(
void
*
)
(
2
*
sizeof
(
GLushort
)));
m_functions
->
glVertexAttribPointer
(
m_program
.
attributeLocation
(
"texcoord"
),
2
,
GL_UNSIGNED_SHORT
,
GL_FALSE
,
sizeof
(
Vertex
),
(
void
*
)
(
2
*
sizeof
(
GLushort
)
+
4
*
sizeof
(
GLubyte
)));
m_program
.
enableAttributeArray
(
"position"
);
m_program
.
enableAttributeArray
(
"color"
);
m_program
.
enableAttributeArray
(
"texcoord"
);
m_functions
->
glBindTexture
(
GL_TEXTURE_2D
,
**
m_texture
);
m_functions
->
glTexParameteri
(
GL_TEXTURE_2D
,
GL_TEXTURE_MIN_FILTER
,
GL_NEAREST
);
m_functions
->
glTexParameteri
(
GL_TEXTURE_2D
,
GL_TEXTURE_MAG_FILTER
,
GL_NEAREST
);
m_functions
->
glTexParameteri
(
GL_TEXTURE_2D
,
GL_TEXTURE_WRAP_S
,
GL_CLAMP_TO_EDGE
);
m_functions
->
glTexParameteri
(
GL_TEXTURE_2D
,
GL_TEXTURE_WRAP_T
,
GL_CLAMP_TO_EDGE
);
m_program
.
setAttributeBuffer
(
"position"
,
GL_FLOAT
,
0
*
sizeof
(
float
),
2
,
7
*
sizeof
(
float
));
m_program
.
setAttributeBuffer
(
"color"
,
GL_FLOAT
,
2
*
sizeof
(
float
),
3
,
7
*
sizeof
(
float
));
m_program
.
setAttributeBuffer
(
"texcoord"
,
GL_FLOAT
,
5
*
sizeof
(
float
),
2
,
7
*
sizeof
(
float
));
m_program
.
enableAttributeArray
(
"position"
);
m_program
.
enableAttributeArray
(
"color"
);
m_program
.
enableAttributeArray
(
"texcoord"
);
m_functions
->
glDrawElements
(
GL_TRIANGLE_STRIP
,
*
m_drawCount
,
GL_UNSIGNED_SHORT
,
(
void
*
)
0
);
*
m_drawCount
=
0
;
for
(
int
i
=
0
;
i
<
m_textures
->
length
();
i
++
)
{
m_functions
->
glBindTexture
(
GL_TEXTURE_2D
,
m_textures
->
at
(
i
));
if
(
m_textures
->
at
(
i
)
!=
0
)
{
m_functions
->
glTexParameteri
(
GL_TEXTURE_2D
,
GL_TEXTURE_MIN_FILTER
,
GL_NEAREST
);
m_functions
->
glTexParameteri
(
GL_TEXTURE_2D
,
GL_TEXTURE_MAG_FILTER
,
GL_NEAREST
);
m_functions
->
glTexParameteri
(
GL_TEXTURE_2D
,
GL_TEXTURE_WRAP_S
,
GL_CLAMP_TO_EDGE
);
m_functions
->
glTexParameteri
(
GL_TEXTURE_2D
,
GL_TEXTURE_WRAP_T
,
GL_CLAMP_TO_EDGE
);
}
m_functions
->
glDrawArrays
(
GL_TRIANGLE_STRIP
,
i
*
4
,
4
);
m_window
->
resetOpenGLState
();
}
m_window
->
resetOpenGLState
();
m_rendered
=
true
;
}
QOpenGLFramebufferObject
*
VncRenderer
::
createFramebufferObject
(
const
QSize
&
size
)
{
qDebug
()
<<
size
;
QMatrix4x4
ortho
;
ortho
.
ortho
(
QRect
(
QPoint
(
0
,
size
.
height
()),
QSize
(
size
.
width
(),
-
1
*
size
.
height
())));
m_program
.
bind
();
...
...
@@ -62,8 +81,8 @@ QOpenGLFramebufferObject *VncRenderer::createFramebufferObject(const QSize &size
#ifdef GL_RGBA8
format
.
setInternalTextureFormat
(
GL_RGBA8
);
#else
#ifdef
GL_
RGBA8_OES
format
.
setInternalTextureFormat
(
GL_
RGBA8_OES
);
#ifdef RGBA8_OES
format
.
setInternalTextureFormat
(
RGBA8_OES
);
#else
format
.
setInternalTextureFormat
(
GL_RGBA
);
#endif
...
...
@@ -73,19 +92,3 @@ QOpenGLFramebufferObject *VncRenderer::createFramebufferObject(const QSize &size
emit
FBOTextureChanged
(
framebufferObject
->
texture
(),
ortho
);
return
framebufferObject
;
}
void
VncRenderer
::
setColorMax
(
const
QVector3D
&
colorMax
)
{
if
(
m_program
.
bind
())
{
m_program
.
setUniformValue
(
"colormax"
,
colorMax
);
m_program
.
release
();
}
}
void
VncRenderer
::
frameSwapped
()
{
if
(
m_rendered
)
{
m_rendered
=
false
;
emit
finishedRendering
();
}
}
vncrenderer.h
View file @
3aeb58bf
...
...
@@ -9,7 +9,6 @@
#include <QMatrix4x4>
#include <QOpenGLShaderProgram>
#include <QOpenGLBuffer>
#include <QSharedPointer>
#include <QTime>
class
VncRenderer
:
public
QObject
,
public
QQuickFramebufferObject
::
Renderer
...
...
@@ -17,24 +16,24 @@ class VncRenderer : public QObject, public QQuickFramebufferObject::Renderer
Q_OBJECT
public
:
VncRenderer
(
QQuickWindow
*
window
,
QOpenGLBuffer
vertices
,
QSharedPointer
<
QVector
<
GLuint
>>
textures
,
QOpenGLBuffer
**
vertices
,
QOpenGLBuffer
indices
,
GLuint
**
textures
,
unsigned
int
*
drawCount
,
QObject
*
parent
=
0
);
protected
:
void
render
()
override
;
QOpenGLFramebufferObject
*
createFramebufferObject
(
const
QSize
&
size
)
override
;
private
:
QQuickWindow
*
m_window
;
QOpenGLBuffer
m_vertices
;
QSharedPointer
<
QVector
<
GLuint
>>
m_textures
;
QOpenGLBuffer
**
m_vertices
;
QOpenGLBuffer
m_indices
;
GLuint
**
m_texture
;
unsigned
int
*
m_drawCount
;
QVector3D
m_colorMax
;
QOpenGLShaderProgram
m_program
;
QOpenGLFunctions
*
m_functions
;
bool
m_rendered
;
public
slots
:
void
setColorMax
(
const
QVector3D
&
colorMax
);
private
slots
:
void
frameSwapped
();
signals
:
void
FBOTextureChanged
(
const
unsigned
int
FBOTexture
,
const
QMatrix4x4
&
ortho
);
void
finishedRendering
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment