OSDN Git Service

34015ef2a4608ae30952e89430a97a878bf2b2bc
[csp-qt/common_source_project-fm7.git] / source / src / qt / gui / gl4_5 / qt_glutil_gl4_5.cpp
1 /*
2  * qt_glutil_gl3_0.cpp
3  * (c) 2016 K.Ohta <whatisthis.sowhat@gmail.com>
4  * License: GPLv2.
5  * Renderer with OpenGL v3.0 (extend from renderer with OpenGL v2.0).
6  * History:
7  * Jan 22, 2016 : Initial.
8  */
9
10 #include "osd_types.h"
11 #include "qt_gldraw.h"
12 #include "qt_glpack.h"
13 #include "qt_glutil_gl4_5.h"
14 #include "csp_logger.h"
15 #include "menu_flags.h"
16
17 #include <QOpenGLFunctions>
18 #include <QOpenGLTexture>
19 #include <QImage>
20 #include <QImageReader>
21 #include <QMatrix4x4>
22 #include <QOpenGLPixelTransferOptions>
23 #include <QOpenGLVertexArrayObject>
24 #include <QOpenGLShaderProgram>
25 #include <QOpenGLBuffer>
26
27 #include <QOpenGLContext>
28 #include <QOpenGLFramebufferObject>
29 #include <QOpenGLFramebufferObjectFormat>
30 #include <QOpenGLPixelTransferOptions>
31
32 #include <QMatrix4x2>
33 #include <QMatrix4x4>
34
35 #include <QVector>
36 #include <QVector2D>
37 #include <QVector3D>
38 #include <QVector4D>
39 #include <QMutex>
40
41 #include <QOpenGLFunctions_4_5_Core>
42
43 //extern USING_FLAGS *using_flags;
44
45 GLDraw_4_5::GLDraw_4_5(GLDrawClass *parent, USING_FLAGS *p, CSP_Logger *logger, EMU *emu) : GLDraw_Tmpl(parent, p, logger, emu)
46 {
47         uTmpTextureID = 0;
48         
49         grids_shader = NULL;
50         
51         main_pass = NULL;
52         std_pass = NULL;
53         ntsc_pass1 = NULL;
54         ntsc_pass2 = NULL;
55         led_pass = NULL;
56         for(int i = 0; i < 32; i++) {
57                 led_pass_vao[i] = NULL;
58                 led_pass_vbuffer[i] = NULL;
59                 osd_pass_vao[i] = NULL;
60                 osd_pass_vbuffer[i] = NULL;
61         }
62         grids_horizonal_buffer = NULL;
63         grids_horizonal_vertex = NULL;
64         
65         grids_vertical_buffer = NULL;
66         grids_vertical_vertex = NULL;
67         ringing_phase = 0.0f;
68 #if defined(__LITTLE_ENDIAN__)
69         swap_byteorder = true;
70 #else
71         swap_byteorder = false;
72 #endif
73         pixel_width = 0;
74         pixel_height = 0;
75         main_texture_buffer = 0;
76         map_base_address = NULL;
77         main_mutex = new QMutex();
78         main_texture_ready = false;
79 }
80
81 GLDraw_4_5::~GLDraw_4_5()
82 {
83
84         if(main_pass  != NULL) delete main_pass;
85         if(std_pass   != NULL) delete std_pass;
86         if(ntsc_pass1 != NULL) delete ntsc_pass1;
87         if(ntsc_pass2 != NULL) delete ntsc_pass2;
88         if(led_pass   != NULL) delete led_pass;
89         for(int i = 0; i < 32; i++) {
90                 if(led_pass_vao[i] != NULL) delete led_pass_vao[i];     
91                 if(led_pass_vbuffer[i] != NULL) delete led_pass_vbuffer[i];
92                 if(osd_pass_vao[i] != NULL) delete osd_pass_vao[i];     
93                 if(osd_pass_vbuffer[i] != NULL) delete osd_pass_vbuffer[i];
94         }
95         
96         if(grids_horizonal_buffer != NULL) {
97                 if(grids_horizonal_buffer->isCreated()) grids_horizonal_buffer->destroy();
98         }
99         if(grids_horizonal_vertex != NULL) {
100                 if(grids_horizonal_vertex->isCreated()) grids_horizonal_vertex->destroy();
101         }
102         if(grids_vertical_buffer != NULL) {
103                 if(grids_vertical_buffer->isCreated()) grids_vertical_buffer->destroy();
104         }
105         if(grids_horizonal_vertex != NULL) {
106                 if(grids_vertical_vertex->isCreated()) grids_vertical_vertex->destroy();
107         }
108 }
109
110 QOpenGLTexture *GLDraw_4_5::createMainTexture(QImage *img)
111 {
112         QOpenGLTexture *tx;
113         QImage *ip = NULL;
114         int w;
115         int h;
116         if(img == NULL) {
117                 w = using_flags->get_real_screen_width();
118                 h = using_flags->get_real_screen_height();
119         } else {
120                 w = img->width();
121                 h = img->height();
122         }
123         QImage im(w, h, QImage::Format_RGBA8888);
124         if(img == NULL) {
125                 ip = &im;
126         } else {
127                 ip = img;
128         }
129         //tx->setFormat(QOpenGLTexture::RGBA8_UNorm);
130         
131         if(main_texture_buffer != 0) {
132                 main_mutex->lock();
133                 main_texture_ready = false;
134                 this->unmap_vram_texture();
135                 map_base_address = NULL;
136                 extfunc->glDeleteBuffers(1, &main_texture_buffer);
137                 main_texture_buffer = 0;
138
139                 extfunc->glClientWaitSync(sync_fence, GL_SYNC_FLUSH_COMMANDS_BIT, 0);
140                 extfunc->glDeleteSync(sync_fence);
141                 sync_fence = extfunc->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE,  0);
142                 main_mutex->unlock();
143         }
144         {
145                 main_mutex->lock();
146                 extfunc->glGenBuffers(1, &main_texture_buffer);
147                 extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, main_texture_buffer);
148                 //extfunc->glBufferData(GL_PIXEL_UNPACK_BUFFER, w * h * sizeof(uint32_t), ip->constBits(), GL_DYNAMIC_COPY);
149                 //extfunc->glBufferStorage(GL_PIXEL_UNPACK_BUFFER, w * h * sizeof(uint32_t), ip->constBits(),  GL_DYNAMIC_STORAGE_BIT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
150                 extfunc->glBufferStorage(GL_PIXEL_UNPACK_BUFFER, w * h * sizeof(uint32_t), ip->constBits(),  GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
151                 tx = new QOpenGLTexture(QOpenGLTexture::Target2D);
152                 tx->setFormat(QOpenGLTexture::RGBA8_UNorm);
153                 tx->setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Nearest);
154                 tx->setWrapMode(QOpenGLTexture::ClampToEdge);
155                 tx->setData(*ip, QOpenGLTexture::DontGenerateMipMaps);
156                 tx->bind();
157                 tx->release();
158                 extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
159                 
160                 extfunc->glClientWaitSync(sync_fence, GL_SYNC_FLUSH_COMMANDS_BIT, 0);
161                 extfunc->glDeleteSync(sync_fence);
162                 sync_fence = extfunc->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE,  0);
163                 
164                 if(map_vram_texture()) {
165                         main_texture_ready = true;
166                 }                       
167                 pixel_width = w;
168                 pixel_height = h;
169                 main_mutex->unlock();
170                 
171         }
172
173         return tx;
174 }
175
176 void GLDraw_4_5::initBitmapVertex(void)
177 {
178         if(using_flags->is_use_one_board_computer()) {
179                 vertexBitmap[0].x = -1.0f;
180                 vertexBitmap[0].y = -1.0f;
181                 vertexBitmap[0].z = 0.5f;
182                 vertexBitmap[0].s = 0.0f;
183                 vertexBitmap[0].t = 1.0f;
184                 
185                 vertexBitmap[1].x = +1.0f;
186                 vertexBitmap[1].y = -1.0f;
187                 vertexBitmap[1].z = 0.5f;
188                 vertexBitmap[1].s = 1.0f;
189                 vertexBitmap[1].t = 1.0f;
190                 
191                 vertexBitmap[2].x = +1.0f;
192                 vertexBitmap[2].y = +1.0f;
193                 vertexBitmap[2].z = 0.5f;
194                 vertexBitmap[2].s = 1.0f;
195                 vertexBitmap[2].t = 0.0f;
196                 
197                 vertexBitmap[3].x = -1.0f;
198                 vertexBitmap[3].y = +1.0f;
199                 vertexBitmap[3].z = 0.5f;
200                 vertexBitmap[3].s = 0.0f;
201                 vertexBitmap[3].t = 0.0f;
202                 
203         }
204 }
205
206 void GLDraw_4_5::initFBO(void)
207 {
208         glHorizGrids = (GLfloat *)malloc(sizeof(float) * (using_flags->get_real_screen_height() + 2) * 6);
209
210         if(glHorizGrids != NULL) {
211                 doSetGridsHorizonal(using_flags->get_real_screen_height(), true);
212         }
213         glVertGrids  = (GLfloat *)malloc(sizeof(float) * (using_flags->get_real_screen_width() + 2) * 6);
214         if(glVertGrids != NULL) {
215                 doSetGridsVertical(using_flags->get_real_screen_width(), true);
216         }
217         if(using_flags->get_max_button() > 0) {
218                 initButtons();
219         }
220         // Init view
221         extfunc->glClearColor(0.0, 0.0, 0.0, 1.0);
222
223         sync_fence = extfunc->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE,  0);
224 }
225
226 void GLDraw_4_5::setNormalVAO(QOpenGLShaderProgram *prg,
227                                                            QOpenGLVertexArrayObject *vp,
228                                                            QOpenGLBuffer *bp,
229                                                            VertexTexCoord_t *tp,
230                                                            int size)
231 {
232         int vertex_loc = prg->attributeLocation("vertex");
233         int texcoord_loc = prg->attributeLocation("texcoord");
234
235         vp->bind();
236         bp->bind();
237
238         if(tp == NULL) {
239         } else {
240                 bp->write(0, tp, sizeof(VertexTexCoord_t) * size);
241         }
242         prg->setAttributeBuffer(vertex_loc, GL_FLOAT, 0, 3, sizeof(VertexTexCoord_t));
243         prg->setAttributeBuffer(texcoord_loc, GL_FLOAT, 3 * sizeof(GLfloat), 2, sizeof(VertexTexCoord_t));
244         prg->setUniformValue("a_texture", 0);
245                            
246         extfunc->glVertexAttribPointer(vertex_loc, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTexCoord_t), 0); 
247         extfunc->glVertexAttribPointer(texcoord_loc, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTexCoord_t), 
248                                                                (char *)NULL + 3 * sizeof(GLfloat)); 
249         bp->release();
250         vp->release();
251         prg->enableAttributeArray(vertex_loc);
252         prg->enableAttributeArray(texcoord_loc);
253 }
254
255 void GLDraw_4_5::initGLObjects()
256 {
257         extfunc = new QOpenGLFunctions_4_5_Core();
258         extfunc->initializeOpenGLFunctions();
259         extfunc->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texture_max_size);
260 }       
261
262 void GLDraw_4_5::initPackedGLObject(GLScreenPack **p,
263                                                                         int _width, int _height,
264                                                                         const QString vertex_shader, const QString fragment_shader,
265                                                                         const QString _name, bool req_float, bool req_highp)
266 {
267         QString s;
268         GLScreenPack *pp;
269         if(p != NULL) {
270                 pp = new GLScreenPack(_width, _height, _name,  p_wid, req_float, req_highp);
271                 *p = pp;
272                 if(pp != NULL) {
273                         pp->initialize(_width, _height, vertex_shader, fragment_shader);
274                         s = pp->getShaderLog();
275                         if(s.size() > 0) {
276                                 csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GL_SHADER, "In shader of %s ", _name.toLocal8Bit().constData());
277                                 csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GL_SHADER, "Vertex: %s ",  vertex_shader.toLocal8Bit().constData());
278                                 csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GL_SHADER, "Fragment: %s ", fragment_shader.toLocal8Bit().constData());
279                                 csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GL_SHADER, "%s", s.toLocal8Bit().constData());
280                         }
281                         s = pp->getGLLog();
282                         if(s.size() > 0) {
283                                 csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GL_SHADER, "In shader of %s ", _name.toLocal8Bit().constData());
284                                 csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GL_SHADER, "Vertex: %s ",  vertex_shader.toLocal8Bit().constData());
285                                 csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GL_SHADER, "Fragment: %s ", fragment_shader.toLocal8Bit().constData());
286                                 csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GL_SHADER, "%s", s.toLocal8Bit().constData());
287                         }
288                         pp->clearGLLog();
289                 }
290         }
291         QOpenGLContext *context = QOpenGLContext::currentContext();
292         gl_major_version = context->format().version().first;
293         gl_minor_version = context->format().version().second;
294
295 }
296                                         
297
298
299 bool GLDraw_4_5::initGridShaders(const QString vertex_fixed, const QString vertex_rotate, const QString fragment)
300 {
301         QOpenGLContext *context = QOpenGLContext::currentContext();
302         QPair<int, int> _version = QOpenGLVersionProfile(context->format()).version();
303         QString versionext = QString::fromUtf8("");
304         if(((_version.first == 4) && (_version.second >= 3)) || (_version.first >= 5)) {
305                 versionext = QString::fromUtf8("#version 430 core \n"); // OK?
306         } else if((_version.first == 4)) {
307                 versionext = QString::fromUtf8("#version 400 core \n");
308         } else { // Require GLVersion >= 3.2
309                 versionext = QString::fromUtf8("#version 150 \n");
310         }
311         bool f = false;
312         
313         grids_shader = new QOpenGLShaderProgram(p_wid);
314         if(grids_shader == NULL) return false;
315         
316         QFile vertex_src(vertex_rotate);
317         if (vertex_src.open(QIODevice::ReadOnly | QIODevice::Text)) {
318                 QString srcs = versionext;
319                 srcs = srcs + QString::fromUtf8(vertex_src.readAll());
320                 f  = grids_shader->addShaderFromSourceCode(QOpenGLShader::Vertex, srcs);
321                 vertex_src.close();
322         } else {
323                 return false;
324         }
325         
326         QFile fragment_src(fragment);
327         if ((fragment_src.open(QIODevice::ReadOnly | QIODevice::Text)) && (f)){
328                 QString _src;
329                 QString _ext = QString::fromUtf8("");;
330                 _ext = versionext;
331                 _src = QString::fromUtf8(fragment_src.readAll());
332                 f &= grids_shader->addShaderFromSourceCode(QOpenGLShader::Fragment, _ext + _src);
333                 fragment_src.close();
334         } else {
335                 return false;
336         }
337
338         f &= grids_shader->link();
339         return f;
340 }
341
342 bool GLDraw_4_5::initGridVertexObject(QOpenGLBuffer **vbo, QOpenGLVertexArrayObject **vao, int alloc_size)
343 {
344         QOpenGLBuffer *bp = NULL;
345         QOpenGLVertexArrayObject *ap = NULL;
346         *vao = NULL;
347         *vbo = NULL;
348         *vbo  = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
349         bp = *vbo;
350         if(bp != NULL) {
351                 if(bp->create()) {
352                         bp->bind();
353                         bp->allocate(alloc_size * sizeof(GLfloat) * 3 * 2);
354                         bp->release();
355                 } else {
356                         delete *vbo;
357                         return false;
358                 }
359         } else {
360                 return false;
361         }
362         
363         *vao = new QOpenGLVertexArrayObject;
364         ap = *vao;
365         if(ap == NULL) {
366                 bp->destroy();
367                 delete *vbo;
368                 return false;
369         }
370         if(!ap->create()) {
371                 delete *vao;
372                 bp->destroy();
373                 delete *vbo;
374                 return false;
375         }
376         return true;
377 }
378
379
380 void GLDraw_4_5::initLocalGLObjects(void)
381 {
382
383         int _width = using_flags->get_screen_width();
384         int _height = using_flags->get_screen_height();
385         
386         if(((int)(_width * 3.5)) <= texture_max_size) {
387                 _width = (int)(_width * 3.5);
388                 low_resolution_screen = true;
389         } else {
390                 _width = _width * 2;
391         }
392         p_wid->makeCurrent();
393         
394         vertexFormat[0].x = -1.0f;
395         vertexFormat[0].y = -1.0f;
396         vertexFormat[0].z = -0.9f;
397         vertexFormat[0].s = 0.0f;
398         vertexFormat[0].t = 1.0f;
399         
400         vertexFormat[1].x = +1.0f;
401         vertexFormat[1].y = -1.0f;
402         vertexFormat[1].z = -0.9f;
403         vertexFormat[1].s = 1.0f;
404         vertexFormat[1].t = 1.0f;
405         
406         vertexFormat[2].x = +1.0f;
407         vertexFormat[2].y = +1.0f;
408         vertexFormat[2].z = -0.9f;
409         vertexFormat[2].s = 1.0f;
410         vertexFormat[2].t = 0.0f;
411         
412         vertexFormat[3].x = -1.0f;
413         vertexFormat[3].y = +1.0f;
414         vertexFormat[3].z = -0.9f;
415         vertexFormat[3].s = 0.0f;
416         vertexFormat[3].t = 0.0f;
417
418         if(using_flags->is_use_one_board_computer() || (using_flags->get_max_button() > 0)) {
419                 initPackedGLObject(&main_pass,
420                                                    using_flags->get_screen_width() * 2, using_flags->get_screen_height() * 2,
421                                                    ":/gl4_5/vertex_shader.glsl" , ":/gl4_5/chromakey_fragment_shader2.glsl",
422                                                    "Main Shader", true);
423         } else {
424                 initPackedGLObject(&main_pass,
425                                                    using_flags->get_screen_width() * 2, using_flags->get_screen_height() * 2,
426                                                    ":/gl4_5/vertex_shader.glsl" , ":/gl4_5/fragment_shader.glsl",
427                                                    "Main Shader", true);
428         }               
429         if(main_pass != NULL) {
430                 setNormalVAO(main_pass->getShader(), main_pass->getVAO(),
431                                          main_pass->getVertexBuffer(),
432                                          vertexFormat, 4);
433         }
434 #if 0
435         initPackedGLObject(&std_pass,
436                                            using_flags->get_screen_width(), using_flags->get_screen_height(),
437                                            ":/gl4_5/vertex_shader.glsl" , ":/gl4_5/chromakey_fragment_shader.glsl",
438                                            "Standard Shader", true);
439 #endif
440         initPackedGLObject(&led_pass,
441                                            10, 10,
442                                            ":/gl4_5/led_vertex_shader.glsl" , ":/gl4_5/led_fragment_shader.glsl",
443                                            "LED Shader", true);
444         for(int i = 0; i < 32; i++) {
445                 led_pass_vao[i] = new QOpenGLVertexArrayObject;
446                 led_pass_vbuffer[i] = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
447                 if(led_pass_vao[i]->create()) {
448                         if(led_pass_vbuffer[i]->create()) {
449                                 led_pass_vbuffer[i]->setUsagePattern(QOpenGLBuffer::DynamicDraw);
450                                 led_pass_vao[i]->bind();
451                                 led_pass_vbuffer[i]->bind();
452                                 led_pass_vbuffer[i]->allocate(sizeof(VertexTexCoord_t) * 4);
453                                 led_pass_vbuffer[i]->release();
454                                 led_pass_vao[i]->release();
455                                 set_led_vertex(i);
456                         }
457                 }
458         }
459         initPackedGLObject(&osd_pass,
460                                            48.0, 48.0,
461                                            ":/gl4_5/vertex_shader.glsl" , ":/gl4_5/icon_fragment_shader.glsl",
462                                            "OSD Shader", true);
463         for(int i = 0; i < 32; i++) {
464                 osd_pass_vao[i] = new QOpenGLVertexArrayObject;
465                 osd_pass_vbuffer[i] = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
466                 if(osd_pass_vao[i]->create()) {
467                         if(osd_pass_vbuffer[i]->create()) {
468                                 osd_pass_vbuffer[i]->setUsagePattern(QOpenGLBuffer::DynamicDraw);
469                                 osd_pass_vao[i]->bind();
470                                 osd_pass_vbuffer[i]->bind();
471                                 osd_pass_vbuffer[i]->allocate(sizeof(VertexTexCoord_t) * 4);
472                                 osd_pass_vbuffer[i]->release();
473                                 osd_pass_vao[i]->release();
474                                 set_osd_vertex(i);
475                         }
476                 }
477         }
478 #if 1
479
480         initPackedGLObject(&ntsc_pass1,
481 //                                         using_flags->get_screen_width() * 2, using_flags->get_screen_height() * 2,
482                                            _width, _height,
483                                            ":/gl4_5/vertex_shader.glsl" , ":/gl4_5/ntsc_pass1.glsl",
484                                            "NTSC Shader Pass1", true, true);
485         initPackedGLObject(&ntsc_pass2,
486                                            using_flags->get_screen_width() * 2, using_flags->get_screen_height() * 2,
487 //                                         _width , _height,
488                                            ":/gl4_5/vertex_shader.glsl" , ":/gl4_5/ntsc_pass2.glsl",
489                                            "NTSC Shader Pass2", true, true);
490         if(!(((gl_major_version >= 3) && (gl_minor_version >= 1)) || (gl_major_version >= 4))){
491                 int ii;
492                 QOpenGLShaderProgram *shader = ntsc_pass2->getShader();
493                 shader->bind();
494                 ii = shader->uniformLocation("luma_filter");
495                 if(ii >= 0) {
496                         shader->setUniformValueArray(ii, luma_filter, 24 + 1, 1);
497                 }
498                 ii = shader->uniformLocation("chroma_filter");
499                 if(ii >= 0) {
500                         shader->setUniformValueArray(ii, chroma_filter, 24 + 1, 1);
501                 }
502                 shader->release();
503         }
504
505 #endif   
506         if(using_flags->is_use_one_board_computer()) {
507                 initBitmapVertex();
508                 initPackedGLObject(&bitmap_block,
509                                                    _width * 2, _height * 2,
510                                                    ":/gl4_5/vertex_shader.glsl", ":/gl4_5/normal_fragment_shader.glsl",
511                                                    "Background Bitmap Shader", true);
512                 if(bitmap_block != NULL) {
513                         setNormalVAO(bitmap_block->getShader(), bitmap_block->getVAO(),
514                                                  bitmap_block->getVertexBuffer(),
515                                                  vertexBitmap, 4);
516                 }
517         }
518
519         initGridShaders(":/gl4_5/grids_vertex_shader_fixed.glsl", ":/gl4_5/grids_vertex_shader.glsl", ":/gl4_5/grids_fragment_shader.glsl");
520         
521         initGridVertexObject(&grids_horizonal_buffer, &grids_horizonal_vertex, using_flags->get_real_screen_height() + 3);
522         doSetGridsHorizonal(using_flags->get_real_screen_height(), true);
523         
524         initGridVertexObject(&grids_vertical_buffer, &grids_vertical_vertex, using_flags->get_real_screen_width() + 3);
525         doSetGridsVertical(using_flags->get_real_screen_width(), true);
526
527         do_set_texture_size(NULL, -1, -1);
528         p_wid->doneCurrent();
529 }
530
531 void GLDraw_4_5::updateGridsVAO(QOpenGLBuffer *bp,
532                                                                 QOpenGLVertexArrayObject *vp,
533                                                                 GLfloat *tp,
534                                                                 int number)
535
536 {
537         bool checkf = false;
538         if((bp != NULL) && (vp != NULL)) {
539                 if(bp->isCreated()) {
540                         if(bp->size() < (int)((number + 1) * sizeof(GLfloat) * 3 * 2)) {
541                                 bp->destroy();
542                                 bp->create();
543                                 checkf = true;
544                         }
545                 } else {
546                         bp->create();
547                         checkf = true;
548                 }
549                 vp->bind();
550                 bp->bind();
551                 if(checkf) {
552                         bp->allocate((number + 1) * sizeof(GLfloat) * 3 * 2);
553                 }
554                 if(tp != NULL) {
555                         bp->write(0, tp, number * sizeof(GLfloat) * 3 * 2);
556                 }
557                 bp->release();
558                 vp->release();
559         }
560 }
561
562 void GLDraw_4_5::drawGrids(void)
563 {
564         gl_grid_horiz = p_config->opengl_scanline_horiz;
565         gl_grid_vert  = p_config->opengl_scanline_vert;
566         if(gl_grid_horiz && (vert_lines > 0)) {
567                 drawGridsHorizonal();
568         } // Will fix.
569         if(using_flags->is_use_vertical_pixel_lines()) {
570                 if(gl_grid_vert && (horiz_pixels > 0)) {
571                         drawGridsVertical();
572                 }
573         }
574 }
575
576 void GLDraw_4_5::drawGridsMain(QOpenGLShaderProgram *prg,
577                                                                  QOpenGLBuffer *bp,
578                                                                  QOpenGLVertexArrayObject *vp,
579                                                                  int number,
580                                                                  GLfloat lineWidth,
581                                                                  QVector4D color)
582 {
583         if(number <= 0) return;
584         extfunc->glDisable(GL_DEPTH_TEST);
585         extfunc->glDisable(GL_BLEND);
586
587         if((bp == NULL) || (vp == NULL) || (prg == NULL)) return;
588         if((!bp->isCreated()) || (!vp->isCreated()) || (!prg->isLinked())) return;
589         {
590                 bp->bind();
591                 vp->bind();
592                 prg->bind();
593                 QMatrix2x2 rot;
594                 switch(p_config->rotate_type) {
595                         case 0:
596                                 rot = QMatrix2x2(rot0);
597                                 break;
598                         case 1:
599                                 rot = QMatrix2x2(rot90);
600                                 break;
601                         case 2:
602                                 rot = QMatrix2x2(rot180);
603                                 break;
604                         case 3:
605                                 rot = QMatrix2x2(rot270);
606                                 break;
607                         default:
608                                 rot = QMatrix2x2(rot0);
609                                 break;
610                 }
611                 prg->setUniformValue("rotate_mat", rot);
612                 prg->setUniformValue("color", color);
613                 prg->enableAttributeArray("vertex");
614                 int vertex_loc = prg->attributeLocation("vertex");
615                 
616                 extfunc->glViewport(0, 0, p_wid->width(), p_wid->height());
617                 extfunc->glVertexAttribPointer(vertex_loc, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3, 0); 
618                 extfunc->glEnableVertexAttribArray(vertex_loc);
619                 
620                 extfunc->glLineWidth(lineWidth);
621                 extfunc->glDrawArrays(GL_LINES, 0, (number + 1) * 2);
622                 prg->release();
623                 vp->release();
624                 bp->release();
625         }
626 }
627
628 void GLDraw_4_5::doSetGridsVertical(int pixels, bool force)
629 {
630         GLDraw_Tmpl::doSetGridsVertical(pixels, force);
631         updateGridsVAO(grids_vertical_buffer,
632                                    grids_vertical_vertex,
633                                    glVertGrids,
634                                    pixels);
635         
636 }
637 void GLDraw_4_5::doSetGridsHorizonal(int lines, bool force)
638 {
639         if((lines == vert_lines) && !force) return;
640         GLDraw_Tmpl::doSetGridsHorizonal(lines, force);
641
642         updateGridsVAO(grids_horizonal_buffer,
643                                    grids_horizonal_vertex,
644                                    glHorizGrids,
645                                    lines);
646 }
647
648 void GLDraw_4_5::drawGridsHorizonal(void)
649 {
650         QVector4D c= QVector4D(0.0f, 0.0f, 0.0f, 1.0f);
651         drawGridsMain(grids_shader,
652                                         grids_horizonal_buffer,
653                                         grids_horizonal_vertex,
654                                         vert_lines,
655                                         0.15f,
656                                         c);
657 }
658
659 void GLDraw_4_5::drawGridsVertical(void)
660 {
661         QVector4D c= QVector4D(0.0f, 0.0f, 0.0f, 1.0f);
662         drawGridsMain(grids_shader,
663                                         grids_vertical_buffer,
664                                         grids_vertical_vertex,
665                                         horiz_pixels,
666                                         0.5f,
667                                         c);
668 }
669
670 void GLDraw_4_5::renderToTmpFrameBuffer_nPass(GLuint src_texture,
671                                                                                           GLuint src_w,
672                                                                                           GLuint src_h,
673                                                                                           GLScreenPack *renderObject,
674                                                                                           GLuint dst_w,
675                                                                                           GLuint dst_h,
676                                                                                           bool use_chromakey)
677 {
678         {
679                 QOpenGLShaderProgram *shader = renderObject->getShader();
680                 int ii;
681                 // NTSC_PASSx
682
683                 extfunc->glClearColor(0.0, 0.0, 0.0, 1.0);
684                 extfunc->glClearDepthf(1.0f);
685                 extfunc->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
686                 {
687                         if((src_texture != 0) && (shader != NULL)) {
688                                 QMatrix4x4 ortho;
689                                 //ortho.ortho(0.0f, (float)dst_w, 0.0f, (float)dst_h, -1.0, 1.0);
690                                 ortho.ortho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
691
692
693                                 renderObject->bind();
694                                 extfunc->glViewport(0, 0, dst_w, dst_h);
695                                 //extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
696                                 extfunc->glActiveTexture(GL_TEXTURE0);
697                                 extfunc->glBindTexture(GL_TEXTURE_2D, src_texture);
698                                 extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
699                                 extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
700                                 //extfunc->glColor4f(1.0, 1.0, 1.0, 1.0);
701                                 shader->setUniformValue("a_texture", 0);
702                                 shader->setUniformValue("v_ortho", ortho);
703                                 //shader->setUniformValue("a_texture", src_texture);
704                                 {
705                                         ii = shader->uniformLocation("source_size");
706                                         if(ii >= 0) {
707                                                 QVector4D source_size = QVector4D((float)src_w, (float)src_h, 0, 0);
708                                                 shader->setUniformValue(ii, source_size);
709                                         }
710                                         ii = shader->uniformLocation("target_size");
711                                         if(ii >= 0) {
712                                                 QVector4D target_size = QVector4D((float)dst_w, (float)dst_h, 0, 0);
713                                                 shader->setUniformValue(ii, target_size);
714                                         }
715                                         ii = shader->uniformLocation("phase");
716                                         if(ii >= 0) {
717                                                 ringing_phase = ringing_phase + 0.093;
718                                                 if(ringing_phase > 1.0) ringing_phase = ringing_phase - 1.0;
719                                                 shader->setUniformValue(ii,  ringing_phase);
720                                         }
721                                         QMatrix2x2 rot;
722                                         /*
723                                          * Note : Not rotate within renderer.
724                                          */
725                                         /*
726                                         switch(p_config->rotate_type) {
727                                         case 0:
728                                                 rot = QMatrix2x2(rot0);
729                                                 break;
730                                         case 1:
731                                                 rot = QMatrix2x2(rot90);
732                                                 break;
733                                         case 2:
734                                                 rot = QMatrix2x2(rot180);
735                                                 break;
736                                         case 3:
737                                                 rot = QMatrix2x2(rot270);
738                                                 break;
739                                         default:
740                                                 rot = QMatrix2x2(rot0);
741                                                 break;
742                                         }
743                                         */
744                                         rot = QMatrix2x2(rot0);
745                                         shader->setUniformValue("rotate_mat", rot);
746                                         //if(!(((gl_major_version >= 3) && (gl_minor_version >= 1)) || (gl_major_version >= 4))){
747                                                 //ii = shader->uniformLocation("luma_filter");
748                                                 //if(ii >= 0) {
749                                                 //      shader->setUniformValueArray(ii, luma_filter, 24 + 1, 1);
750                                                 //}
751                                                 //ii = shader->uniformLocation("chroma_filter");
752                                                 //if(ii >= 0) {
753                                                 //      shader->setUniformValueArray(ii, chroma_filter, 24 + 1, 1);
754                                                 //}
755                                         //}
756                                 }
757                                 {
758                                         QVector4D c(fBrightR, fBrightG, fBrightB, 1.0);
759                                         QVector3D chromakey(0.0, 0.0, 0.0);
760                 
761                                         ii = shader->uniformLocation("color");
762                                         if(ii >= 0) {
763                                                 shader->setUniformValue(ii, c);
764                                         }
765                                         ii = shader->uniformLocation("do_chromakey");
766                                         if(ii >= 0) {
767                                                 if(use_chromakey) {
768                                                         int ij;
769                                                         ij = shader->uniformLocation("chromakey");
770                                                         if(ij >= 0) {
771                                                                 shader->setUniformValue(ij, chromakey);
772                                                         }
773                                                         shader->setUniformValue(ii, GL_TRUE);
774                                                 } else {
775                                                         shader->setUniformValue(ii, GL_FALSE);
776                                                 }
777                                         }
778                                 }
779
780                                 shader->enableAttributeArray("texcoord");
781                                 shader->enableAttributeArray("vertex");
782                                 
783                                 int vertex_loc = shader->attributeLocation("vertex");
784                                 int texcoord_loc = shader->attributeLocation("texcoord");
785                                 shader->setAttributeBuffer(vertex_loc, GL_FLOAT, 0, 3, sizeof(VertexTexCoord_t));
786                                 shader->setAttributeBuffer(texcoord_loc, GL_FLOAT, 3 * sizeof(GLfloat), 2, sizeof(VertexTexCoord_t));
787                                 extfunc->glEnableVertexAttribArray(vertex_loc);
788                                 extfunc->glEnableVertexAttribArray(texcoord_loc);
789
790                                 extfunc->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
791                                 
792                                 //extfunc->glViewport(0, 0, dst_w, dst_h);
793                                 //extfunc->glOrtho(0.0f, (float)dst_w, 0.0f, (float)dst_h, -1.0, 1.0);
794                                 renderObject->release();
795                                 extfunc->glBindTexture(GL_TEXTURE_2D, 0);
796                         }
797                 }
798         }
799 }
800
801 void GLDraw_4_5::uploadMainTexture(QImage *p, bool use_chromakey, bool was_mapped)
802 {
803         // set vertex
804         redraw_required = true;
805         //if(p == NULL) return;
806         //redraw_required = true;
807         imgptr = p;
808         if(uVramTextureID == NULL) {
809                 uVramTextureID = createMainTexture(p);
810         } else  {
811                 // Upload to main texture
812                 if(p != NULL) {
813 #if 1
814                         if(map_base_address == NULL) {
815                                 extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, main_texture_buffer);
816                                 uint32_t* pp = (uint32_t *)(extfunc->glMapNamedBufferRange(main_texture_buffer, 0, pixel_width * pixel_height * sizeof(scrntype_t),  GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT));
817                                 //uint32_t *pp = (uint32_t *)(extfunc->glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY));
818                                 if(pp != NULL) {
819                                         int hh = (pixel_height < p->height()) ? pixel_height : p->height();
820                                         for(int y = 0; y < hh; y++) {
821                                                 memcpy(&(pp[y * pixel_width]), p->scanLine(y), p->width() * sizeof(uint32_t));
822                                         }
823                                 }
824                                 extfunc->glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
825                                 //extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
826
827                                 //extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, main_texture_buffer);
828                                 extfunc->glBindTexture(GL_TEXTURE_2D, uVramTextureID->textureId());
829                                 //extfunc->glActiveTexture(GL_TEXTURE0);
830                                 extfunc->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, p->width(), p->height(), GL_RGBA, GL_UNSIGNED_BYTE, 0);
831                                 extfunc->glBindTexture(GL_TEXTURE_2D, 0);
832                                 extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
833                         
834                         } else {
835                                 main_mutex->lock();
836                                 extfunc->glFlushMappedBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, pixel_width *pixel_height * sizeof(scrntype_t));
837                                 extfunc->glWaitSync(sync_fence, GL_SYNC_FLUSH_COMMANDS_BIT, 0);
838                                 extfunc->glDeleteSync(sync_fence);
839                                 sync_fence = extfunc->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE,  0);
840
841                                 extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, main_texture_buffer);
842                                 extfunc->glBindTexture(GL_TEXTURE_2D, uVramTextureID->textureId());
843                                 //extfunc->glActiveTexture(GL_TEXTURE0);
844                                 extfunc->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pixel_width, pixel_height, GL_RGBA, GL_UNSIGNED_BYTE, 0);
845                                 extfunc->glBindTexture(GL_TEXTURE_2D, 0);
846                                 extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
847                            
848                                 //extfunc->glClientWaitSync(sync_fence, GL_SYNC_FLUSH_COMMANDS_BIT, 0);
849                                 //extfunc->glDeleteSync(sync_fence);
850                                 //sync_fence = extfunc->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE,  0);
851                                 main_mutex->unlock();
852                         }
853 #else
854                         uVramTextureID->setData(*p, QOpenGLTexture::DontGenerateMipMaps);
855 #endif
856                 } else {
857                         // This sequence is *outside* of normal rendering phase, maybe using compute shader.
858                         extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, main_texture_buffer);
859                         extfunc->glBindTexture(GL_TEXTURE_2D, uVramTextureID->textureId());
860                         //extfunc->glActiveTexture(GL_TEXTURE0);
861                         extfunc->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pixel_width, pixel_height, GL_RGBA, GL_UNSIGNED_BYTE, 0);
862                         extfunc->glBindTexture(GL_TEXTURE_2D, 0);
863                         extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
864                 }
865         }
866 #if 1
867         if(using_flags->is_support_tv_render() && (p_config->rendering_type == CONFIG_RENDER_TYPE_TV)) {
868                 renderToTmpFrameBuffer_nPass(uVramTextureID->textureId(),
869                                                                          screen_texture_width,
870                                                                          screen_texture_height,
871                                                                          ntsc_pass1,
872                                                                          ntsc_pass1->getViewportWidth(),
873                                                                          ntsc_pass1->getViewportHeight());
874                 
875                 renderToTmpFrameBuffer_nPass(ntsc_pass1->getTexture(),
876                                                                          ntsc_pass1->getViewportWidth(),
877                                                                          ntsc_pass1->getViewportHeight(),
878                                                                          ntsc_pass2,
879                                                                          ntsc_pass2->getViewportWidth(),
880                                                                          ntsc_pass2->getViewportHeight());
881                 uTmpTextureID = ntsc_pass2->getTexture();
882         } else
883 #endif
884         {
885                 uTmpTextureID = uVramTextureID->textureId();
886         }
887         crt_flag = true;
888 }
889
890 void GLDraw_4_5::drawScreenTexture(void)
891 {
892         if(using_flags->is_use_one_board_computer()) {
893                 extfunc->glEnable(GL_BLEND);
894                 extfunc->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
895         } else {
896                 extfunc->glDisable(GL_BLEND);
897         }
898
899         QVector4D color;
900         smoosing = p_config->use_opengl_filters;
901         if(set_brightness) {
902                 color = QVector4D(fBrightR, fBrightG, fBrightB, 1.0);
903         } else {
904                 color = QVector4D(1.0, 1.0, 1.0, 1.0);
905         }
906         if(using_flags->is_use_one_board_computer()) {
907                 drawMain(main_pass,
908                                  uTmpTextureID, // v2.0
909                                  color, smoosing,
910                                  true, QVector3D(0.0, 0.0, 0.0));       
911                 extfunc->glDisable(GL_BLEND);
912         } else {
913                 drawMain(main_pass,
914                                  uTmpTextureID, // v2.0
915                                  color, smoosing);      
916         }
917 }
918
919 void GLDraw_4_5::drawMain(QOpenGLShaderProgram *prg,
920                                                   QOpenGLVertexArrayObject *vp,
921                                                   QOpenGLBuffer *bp,
922                                                   GLuint texid,
923                                                   QVector4D color,
924                                                   bool f_smoosing,
925                                                   bool do_chromakey,
926                                                   QVector3D chromakey)
927 {
928         int ii;
929
930    if(texid != 0) {
931                 vp->bind();
932                 bp->bind();
933                 prg->bind();
934                 extfunc->glViewport(0, 0, p_wid->width(), p_wid->height());
935                 QMatrix4x4 ortho;
936                 ortho.ortho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
937
938                 extfunc->glActiveTexture(GL_TEXTURE0);
939                 extfunc->glBindTexture(GL_TEXTURE_2D, texid);
940                 //extfunc->glBindTexture(GL_PIXEL_UNPACK_BUFFER, texid);
941
942                 extfunc->glClearColor(1.0, 1.0, 1.0, 1.0);
943                 if(!f_smoosing) {
944                         extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
945                         extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
946                 } else {
947                         extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
948                         extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
949                 }
950                 prg->setUniformValue("a_texture", 0);
951                 prg->setUniformValue("v_ortho", ortho);
952                 
953                 ii = prg->uniformLocation("color");
954                 if(ii >= 0) {
955                         prg->setUniformValue(ii,  color);
956                 }
957                 
958                 ii = prg->uniformLocation("tex_width");
959                 if(ii >= 0) {
960                         prg->setUniformValue(ii,  (float)screen_texture_width);
961                 }
962                 
963                 ii = prg->uniformLocation("tex_height");
964                 if(ii >= 0) {
965                         prg->setUniformValue(ii,  (float)screen_texture_height);
966                 }
967                 QMatrix2x2 rot;
968                 switch(p_config->rotate_type) {
969                         case 0:
970                                 rot = QMatrix2x2(rot0);
971                                 break;
972                         case 1:
973                                 rot = QMatrix2x2(rot90);
974                                 break;
975                         case 2:
976                                 rot = QMatrix2x2(rot180);
977                                 break;
978                         case 3:
979                                 rot = QMatrix2x2(rot270);
980                                 break;
981                         default:
982                                 rot = QMatrix2x2(rot0);
983                                 break;
984                 }
985                 prg->setUniformValue("rotate_mat", rot);
986                 //} else {
987                 //prg->setUniformValue("rotate", GL_FALSE);
988                 //}
989
990                 if(do_chromakey) {
991                         ii = prg->uniformLocation("chromakey");
992                         if(ii >= 0) {
993                                 prg->setUniformValue(ii, chromakey);
994                         }
995                         ii = prg->uniformLocation("do_chromakey");
996                         if(ii >= 0) {
997                                 prg->setUniformValue(ii, GL_TRUE);
998                         }
999                 } else {
1000                         ii = prg->uniformLocation("do_chromakey");
1001                         if(ii >= 0) {
1002                                 prg->setUniformValue(ii, GL_FALSE);
1003                         }
1004                 }
1005                 
1006                 prg->enableAttributeArray("texcoord");
1007                 prg->enableAttributeArray("vertex");
1008                 int vertex_loc = prg->attributeLocation("vertex");
1009                 int texcoord_loc = prg->attributeLocation("texcoord");
1010                 
1011                 //prg->enableAttributeArray(vertex_loc);
1012                 prg->setAttributeBuffer(vertex_loc, GL_FLOAT, 0, 3, sizeof(VertexTexCoord_t));
1013                 prg->setAttributeBuffer(texcoord_loc, GL_FLOAT, 3 * sizeof(GLfloat), 2, sizeof(VertexTexCoord_t));
1014                 extfunc->glEnableVertexAttribArray(vertex_loc);
1015                 extfunc->glEnableVertexAttribArray(texcoord_loc);
1016                 
1017                 extfunc->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1018                 bp->release();
1019                 vp->release();
1020                 
1021                 prg->release();
1022                 extfunc->glBindTexture(GL_TEXTURE_2D, 0);
1023                 //extfunc->glBindTexture(GL_TEXTURE_2D, 0);
1024    }
1025         else {
1026                 vp->bind();
1027                 bp->bind();
1028                 prg->bind();
1029                 extfunc->glViewport(0, 0, p_wid->width(), p_wid->height());
1030                 QMatrix4x4 ortho;
1031                 ortho.ortho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
1032                 //extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
1033                 ii = prg->uniformLocation("color");
1034                 if(ii >= 0) {
1035                         prg->setUniformValue(ii,  color);
1036                 }
1037                 QMatrix2x2 rot;
1038                 switch(p_config->rotate_type) {
1039                         case 0:
1040                                 rot = QMatrix2x2(rot0);
1041                                 break;
1042                         case 1:
1043                                 rot = QMatrix2x2(rot90);
1044                                 break;
1045                         case 2:
1046                                 rot = QMatrix2x2(rot180);
1047                                 break;
1048                         case 3:
1049                                 rot = QMatrix2x2(rot270);
1050                                 break;
1051                         default:
1052                                 rot = QMatrix2x2(rot0);
1053                                 break;
1054                 }
1055                 prg->setUniformValue("rotate_mat", rot);
1056                 prg->setUniformValue("v_ortho", ortho);
1057
1058                 if(do_chromakey) {
1059                         ii = prg->uniformLocation("chromakey");
1060                         if(ii >= 0) {
1061                                 prg->setUniformValue(ii, chromakey);
1062                         }
1063                         ii = prg->uniformLocation("do_chromakey");
1064                         if(ii >= 0) {
1065                                 prg->setUniformValue(ii, GL_TRUE);
1066                         }
1067                 } else {
1068                         ii = prg->uniformLocation("do_chromakey");
1069                         if(ii >= 0) {
1070                                 prg->setUniformValue(ii, GL_FALSE);
1071                         }
1072                 }
1073                 
1074                 prg->enableAttributeArray("vertex");
1075                 int vertex_loc = prg->attributeLocation("vertex");
1076                 extfunc->glEnableVertexAttribArray(vertex_loc);
1077                 extfunc->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1078                 bp->release();
1079                 vp->release();
1080                 prg->release();
1081                 extfunc->glBindTexture(GL_TEXTURE_2D, 0);
1082         }
1083         
1084    extfunc->glClientWaitSync(sync_fence, GL_SYNC_FLUSH_COMMANDS_BIT, 0);
1085    extfunc->glDeleteSync(sync_fence);
1086    sync_fence = extfunc->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE,  0);
1087 }
1088
1089 void GLDraw_4_5::drawMain(GLScreenPack *obj,
1090                                                   GLuint texid,
1091                                                   QVector4D color,
1092                                                   bool f_smoosing,
1093                                                   bool do_chromakey,
1094                                                   QVector3D chromakey)
1095                                                    
1096 {
1097         QOpenGLShaderProgram *prg = obj->getShader();
1098         QOpenGLVertexArrayObject *vp = obj->getVAO();
1099         QOpenGLBuffer *bp = obj->getVertexBuffer();
1100
1101         drawMain(prg, vp, bp, texid, color, f_smoosing, do_chromakey, chromakey);
1102 }
1103
1104 void GLDraw_4_5::drawButtonsMain(int num, bool f_smoosing)
1105 {
1106         GLuint texid = uButtonTextureID[num]->textureId();
1107         QOpenGLBuffer *bp = buffer_button_vertex[num];
1108         QOpenGLShaderProgram  *prg = button_shader;
1109         QOpenGLVertexArrayObject *vp = vertex_button[num];
1110         QVector4D color;
1111         int ii;
1112         
1113         color = QVector4D(1.0, 1.0, 1.0, 1.0);
1114         if((bp != NULL) && (vp != NULL) && (prg != NULL)) {
1115                 if((bp->isCreated()) && (vp->isCreated()) && (prg->isLinked())) {
1116                         bp->bind();
1117                         vp->bind();
1118                         prg->bind();
1119                         QMatrix4x4 ortho;
1120                         ortho.ortho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
1121                         extfunc->glViewport(0, 0, p_wid->width(), p_wid->height());
1122
1123                         extfunc->glActiveTexture(GL_TEXTURE0);
1124                         extfunc->glBindTexture(GL_TEXTURE_2D, texid);
1125                         if(!f_smoosing) {
1126                                 extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1127                                 extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
1128                         } else {
1129                                 extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1130                                 extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1131                         }
1132                         prg->setUniformValue("a_texture", 0);
1133                         prg->setUniformValue("v_ortho", ortho);
1134                         
1135                         ii = prg->uniformLocation("color");
1136                         if(ii >= 0) {
1137                                 prg->setUniformValue(ii,  color);
1138                         }
1139                         ii = prg->uniformLocation("do_chromakey");
1140                         if(ii >= 0) {
1141                                 prg->setUniformValue(ii, GL_FALSE);
1142                         }
1143                         QMatrix2x2 rot;
1144                         switch(p_config->rotate_type) {
1145                         case 0:
1146                                 rot = QMatrix2x2(rot0);
1147                                 break;
1148                         case 1:
1149                                 rot = QMatrix2x2(rot90);
1150                                 break;
1151                         case 2:
1152                                 rot = QMatrix2x2(rot180);
1153                                 break;
1154                         case 3:
1155                                 rot = QMatrix2x2(rot270);
1156                                 break;
1157                         default:
1158                                 rot = QMatrix2x2(rot0);
1159                                 break;
1160                         }
1161                         prg->setUniformValue("rotate_mat", rot);
1162                         
1163                         int vertex_loc = prg->attributeLocation("vertex");
1164                         int texcoord_loc = prg->attributeLocation("texcoord");
1165                         prg->setAttributeBuffer(vertex_loc, GL_FLOAT, 0, 3, sizeof(VertexTexCoord_t));
1166                         prg->setAttributeBuffer(texcoord_loc, GL_FLOAT, 3 * sizeof(GLfloat), 2, sizeof(VertexTexCoord_t));
1167                         prg->enableAttributeArray(vertex_loc);
1168                         prg->enableAttributeArray(texcoord_loc);
1169                         //extfunc->glEnableVertexAttribArray(vertex_loc);
1170                         //extfunc->glEnableVertexAttribArray(texcoord_loc);
1171                         extfunc->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1172                         bp->release();
1173                         vp->release();
1174                         prg->release();
1175                         extfunc->glBindTexture(GL_TEXTURE_2D, 0);
1176                         return;
1177                         }
1178                 }
1179
1180 }
1181
1182 void GLDraw_4_5::drawButtons(void)
1183 {
1184         for(int i = 0; i < using_flags->get_max_button(); i++) {
1185                 drawButtonsMain(i, false);
1186         }
1187 }
1188
1189 void GLDraw_4_5::drawBitmapTexture(void)
1190 {
1191         QVector4D color = QVector4D(1.0f, 1.0f, 1.0f, 1.0f);
1192         smoosing = p_config->use_opengl_filters;
1193
1194         if(using_flags->is_use_one_board_computer() && (uBitmapTextureID != NULL)) {
1195                 //extfunc->glDisable(GL_BLEND);
1196                 drawMain(bitmap_block,
1197                                  uBitmapTextureID->textureId(),
1198                                  color, smoosing);
1199         }
1200 }
1201
1202 void GLDraw_4_5::drawLedMain(GLScreenPack *obj, int num, QVector4D color)
1203 {
1204         QOpenGLShaderProgram *prg = obj->getShader();
1205         QOpenGLVertexArrayObject *vp = led_pass_vao[num];
1206         QOpenGLBuffer *bp = led_pass_vbuffer[num];
1207         int ii;
1208                 
1209         {
1210                 extfunc->glEnable(GL_BLEND);
1211                 extfunc->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1212                 vp->bind();
1213                 bp->bind();
1214                 prg->bind();
1215                 extfunc->glViewport(0, 0, p_wid->width(), p_wid->height());
1216                 //extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
1217                 ii = prg->uniformLocation("color");
1218                 if(ii >= 0) {
1219                         prg->setUniformValue(ii,  color);
1220                 }
1221                 
1222                 prg->enableAttributeArray("vertex");
1223                 int vertex_loc = prg->attributeLocation("vertex");
1224                 prg->setAttributeBuffer(vertex_loc, GL_FLOAT, 0, 3, sizeof(VertexTexCoord_t));
1225                 extfunc->glVertexAttribPointer(vertex_loc, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTexCoord_t), 0); 
1226
1227                 extfunc->glEnableVertexAttribArray(vertex_loc);
1228                 extfunc->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
1229                 bp->release();
1230                 vp->release();
1231                 
1232                 prg->release();
1233                 extfunc->glDisable(GL_BLEND);
1234         }
1235
1236 }
1237
1238
1239 void GLDraw_4_5::drawOsdLeds()
1240 {
1241         QVector4D color_on;
1242         QVector4D color_off;
1243         uint32_t bit = 0x00000001;
1244         if(osd_onoff) {
1245                 color_on = QVector4D(0.95, 0.0, 0.05, 1.0);
1246                 color_off = QVector4D(0.05,0.05, 0.05, 0.10);
1247         } else {
1248                 color_on = QVector4D(0.00,0.00, 0.00, 0.0);
1249                 color_off = QVector4D(0.00,0.00, 0.00, 0.0);
1250         }
1251         if(osd_onoff) {
1252                 //if(osd_led_status_bak != osd_led_status) {
1253                         for(int i = 0; i < osd_led_bit_width; i++) {
1254                                 if((bit & osd_led_status) == (bit & osd_led_status_bak)) {
1255                                         bit <<= 1;
1256                                         continue;
1257                                 }
1258                                 drawLedMain(led_pass, i,
1259                                                         ((osd_led_status & bit) != 0) ? color_on : color_off);
1260                                 bit <<= 1;
1261                         }
1262                         osd_led_status_bak = osd_led_status;
1263                 //}
1264         }
1265 }
1266
1267 void GLDraw_4_5::drawOsdIcons()
1268 {
1269         QVector4D color_on;
1270         QVector4D color_off;
1271         uint32_t bit = 0x00000001;
1272         if(osd_onoff) {
1273                 color_on = QVector4D(1.0,  1.0, 1.0, 0.8);
1274                 color_off = QVector4D(1.0, 1.0, 1.0, 0.00);
1275         } else {
1276                 color_on = QVector4D(0.00,0.00, 0.00, 0.0);
1277                 color_off = QVector4D(0.00,0.00, 0.00, 0.0);
1278         }
1279         if(osd_onoff) {
1280                 int major, minor;
1281                 //if(osd_led_status_bak != osd_led_status) {
1282                         for(int i = 0; i < osd_led_bit_width; i++) {
1283                                 if((bit & osd_led_status) == (bit & osd_led_status_bak)) {
1284                                         if((bit & osd_led_status) == 0) { 
1285                                                 bit <<= 1;
1286                                                 continue;
1287                                         }
1288                                 }
1289                                 if((i >= 2) && (i < 10)) { // FD
1290                                         major = 2;
1291                                         minor = i - 2;
1292                                 } else if((i >= 10) && (i < 12)) { // QD
1293                                         major = 3;
1294                                         minor = i - 10;
1295                                 } else if((i >= 12) && (i < 14)) { // CMT(R)
1296                                         major = 4;
1297                                         minor = i - 12;
1298                                 } else if((i >= 14) && (i < 16)) { // CMT(W)
1299                                         major = 5;
1300                                         minor = i - 14;
1301                                 } else {
1302                                         major = 0;
1303                                         minor = 0;
1304                                 }
1305                                 if(major != 0) {
1306                                         drawMain(osd_pass->getShader(), osd_pass_vao[i], osd_pass_vbuffer[i],
1307                                                          icon_texid[major][minor]->textureId(),
1308                                                          ((osd_led_status & bit) != 0) ? color_on : color_off,
1309                                                          false, false, QVector3D(0.0, 0.0, 0.0));
1310                                 }
1311                                 bit <<= 1;
1312                         }
1313                         osd_led_status_bak = osd_led_status;
1314                 //}
1315         }
1316 }
1317
1318 void GLDraw_4_5::paintGL(void)
1319 {
1320         //p_wid->makeCurrent();
1321         
1322 //      if(crt_flag || redraw_required) { //return;
1323                 if(emu_launched) {
1324                         crt_flag = false;
1325                 }
1326                 redraw_required = false;
1327                 extfunc->glViewport(0, 0, p_wid->width(), p_wid->height());
1328                 //extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
1329
1330                 extfunc->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1331                 extfunc->glDisable(GL_DEPTH_TEST);
1332                 extfunc->glDisable(GL_BLEND);
1333                 if(using_flags->is_use_one_board_computer() || using_flags->is_use_bitmap()) {
1334                         extfunc->glEnable(GL_BLEND);
1335                         drawBitmapTexture();
1336                 }
1337                 if(using_flags->get_max_button() > 0) {
1338                         extfunc->glEnable(GL_BLEND);
1339                         drawButtons();
1340                 }
1341                 drawScreenTexture();
1342                 extfunc->glEnable(GL_BLEND);
1343                 extfunc->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1344                 extfunc->glDisable(GL_DEPTH_TEST);
1345                 //drawOsdLeds();
1346                 if(p_config->use_osd_virtual_media) drawOsdIcons();
1347                 extfunc->glDisable(GL_BLEND);
1348                 if(!using_flags->is_use_one_board_computer() && (using_flags->get_max_button() <= 0)) {
1349                         drawGrids();
1350                 }
1351                 extfunc->glFlush();
1352 }
1353
1354 void GLDraw_4_5::setBrightness(GLfloat r, GLfloat g, GLfloat b)
1355 {
1356         fBrightR = r;
1357         fBrightG = g;
1358         fBrightB = b;
1359
1360         if(imgptr != NULL) {
1361                 p_wid->makeCurrent();
1362                 if(uVramTextureID == NULL) {
1363                         uVramTextureID = createMainTexture(imgptr);
1364                 }
1365 //              if(using_flags->is_use_one_board_computer() || (using_flags->get_max_button() > 0)) {
1366 //                      uploadMainTexture(imgptr, true);
1367 //              } else {
1368 //                      uploadMainTexture(imgptr, false);
1369 //              }
1370                 p_wid->doneCurrent();
1371         }
1372         crt_flag = true;
1373 }
1374
1375 void GLDraw_4_5::set_texture_vertex(float wmul, float hmul)
1376 {
1377         float wfactor = 1.0f;
1378         float hfactor = 1.0f;
1379
1380         vertexTmpTexture[0].x = -1.0f;
1381         vertexTmpTexture[0].y = -1.0f;
1382         vertexTmpTexture[0].z = -0.1f;
1383         vertexTmpTexture[0].s = 0.0f;
1384         vertexTmpTexture[0].t = 0.0f;
1385         
1386         vertexTmpTexture[1].x = wfactor;
1387         vertexTmpTexture[1].y = -1.0f;
1388         vertexTmpTexture[1].z = -0.1f;
1389         vertexTmpTexture[1].s = wmul;
1390         vertexTmpTexture[1].t = 0.0f;
1391         
1392         vertexTmpTexture[2].x = wfactor;
1393         vertexTmpTexture[2].y = hfactor;
1394         vertexTmpTexture[2].z = -0.1f;
1395         vertexTmpTexture[2].s = wmul;
1396         vertexTmpTexture[2].t = hmul;
1397         
1398         vertexTmpTexture[3].x = -1.0f;
1399         vertexTmpTexture[3].y = hfactor;
1400         vertexTmpTexture[3].z = -0.1f;
1401         vertexTmpTexture[3].s = 0.0f;
1402         vertexTmpTexture[3].t = hmul;
1403 }
1404
1405
1406 void GLDraw_4_5::set_osd_vertex(int xbit)
1407 {
1408         float xbase, ybase, zbase;
1409         VertexTexCoord_t vertex[4];
1410         int major, minor, nl;
1411         int i = xbit;
1412         if((xbit < 0) || (xbit >= 32)) return;
1413         if((i >= 2) && (i < 10)) { // FD
1414                 major = 0;
1415                 minor = i - 2;
1416                 nl = using_flags->get_max_drive();
1417         } else if((i >= 10) && (i < 12)) { // QD
1418                 major = 2;
1419                 minor = i - 10;
1420                 nl = using_flags->get_max_qd();
1421         } else if((i >= 12) && (i < 14)) { // CMT(R)
1422                 major = 1;
1423                 minor = i - 12;
1424                 nl = using_flags->get_max_tape();
1425         } else if((i >= 14) && (i < 16)) { // CMT(W)
1426                 major = 1;
1427                 minor = i - 14;
1428                 nl = using_flags->get_max_tape();
1429         } else if(i >= 16) {
1430                 major = 4 + (i / 8) - 2;
1431                 minor = i % 8;
1432                 nl = 8;
1433         } else {
1434                 major = 6;
1435                 minor = i;
1436                 nl = 2;
1437         }
1438         xbase =  1.0f - (1.0f * 48.0f / 640.0f) * (float)(nl - minor) - (4.0f / 640.0f);;
1439         ybase = -1.0f + (1.0f * 48.0f / 400.0f) * (float)(major + 1) + (4.0f / 400.0f);
1440         zbase = -0.998f;
1441         vertex[0].x = xbase;
1442         vertex[0].y = ybase;
1443         vertex[0].z = zbase;
1444         vertex[0].s = 0.0f;
1445         vertex[0].t = 0.0f;
1446         
1447         vertex[1].x = xbase + (48.0f / 640.0f);
1448         vertex[1].y = ybase;
1449         vertex[1].z = zbase;
1450         vertex[1].s = 1.0f;
1451         vertex[1].t = 0.0f;
1452         
1453         vertex[2].x = xbase + (48.0f / 640.0f);
1454         vertex[2].y = ybase - (48.0f / 400.0f);
1455         vertex[2].z = zbase;
1456         vertex[2].s = 1.0f;
1457         vertex[2].t = 1.0f;
1458         
1459         vertex[3].x = xbase;
1460         vertex[3].y = ybase - (48.0f / 400.0f);
1461         vertex[3].z = zbase;
1462         vertex[3].s = 0.0f;
1463         vertex[3].t = 1.0f;
1464         
1465         setNormalVAO(osd_pass->getShader(), osd_pass_vao[xbit],
1466                                  osd_pass_vbuffer[xbit],
1467                                  vertex, 4);
1468 }
1469
1470 void GLDraw_4_5::set_led_vertex(int xbit)
1471 {
1472         float xbase, ybase, zbase;
1473         VertexTexCoord_t vertex[4];
1474
1475         if((xbit < 0) || (xbit >=32)) return;
1476         xbase = 0.0f + (1.0f / 32.0f) * 31.0f - ((1.0f * (float)xbit) / 32.0f) + (1.0f / 128.0f);
1477         ybase = -1.0f + (2.0f / 64.0f) * 1.5f;
1478         zbase = -0.999f;
1479         vertex[0].x = xbase;
1480         vertex[0].y = ybase;
1481         vertex[0].z = zbase;
1482         vertex[0].s = 0.0f;
1483         vertex[0].t = 0.0f;
1484         
1485         vertex[1].x = xbase + (1.0f / 64.0f);
1486         vertex[1].y = ybase;
1487         vertex[1].z = zbase;
1488         vertex[1].s = 1.0f;
1489         vertex[1].t = 0.0f;
1490         
1491         vertex[2].x = xbase + (1.0f / 64.0f);
1492         vertex[2].y = ybase - (1.0f / 64.0f);
1493         vertex[2].z = zbase;
1494         vertex[2].s = 1.0f;
1495         vertex[2].t = 1.0f;
1496         
1497         vertex[3].x = xbase;
1498         vertex[3].y = ybase - (1.0f / 64.0f);
1499         vertex[3].z = zbase;
1500         vertex[3].s = 0.0f;
1501         vertex[3].t = 1.0f;
1502         
1503         setNormalVAO(led_pass->getShader(), led_pass_vao[xbit],
1504                                  led_pass_vbuffer[xbit],
1505                                  vertex, 4);
1506 }
1507
1508 void GLDraw_4_5::do_set_screen_multiply(float mul)
1509 {
1510         screen_multiply = mul;
1511         do_set_texture_size(imgptr, screen_texture_width, screen_texture_height);
1512 }
1513
1514 void GLDraw_4_5::do_set_texture_size(QImage *p, int w, int h)
1515 {
1516         if(w <= 0) w = using_flags->get_real_screen_width();
1517         if(h <= 0) h = using_flags->get_real_screen_height();
1518         imgptr = p;
1519         float iw, ih;
1520         if(p != NULL) {
1521                 iw = (float)p->width();
1522                 ih = (float)p->height();
1523         } else {
1524                 iw = (float)using_flags->get_real_screen_width();
1525                 ih = (float)using_flags->get_real_screen_height();
1526         }
1527         //printf("%dx%d -> %fx%f\n", w, h, iw, ih);
1528         if(p_wid != NULL) {
1529                 screen_texture_width = w;
1530                 screen_texture_height = h;
1531
1532                 p_wid->makeCurrent();
1533                 {
1534                         //set_texture_vertex(p, p_wid->width(), p_wid->height(), w, h);
1535                         set_texture_vertex((float)w / iw, (float)h / ih);
1536                         setNormalVAO(ntsc_pass1->getShader(), ntsc_pass1->getVAO(),
1537                                                  ntsc_pass1->getVertexBuffer(),
1538                                                  vertexTmpTexture, 4);
1539
1540                         set_texture_vertex(1.0f, 1.0f);
1541                         setNormalVAO(ntsc_pass2->getShader(), ntsc_pass2->getVAO(),
1542                                                  ntsc_pass2->getVertexBuffer(),
1543                                                  vertexTmpTexture, 4);
1544                         
1545                 }
1546                 if(((int)iw != pixel_width) || ((int)ih != pixel_height)) {
1547                         QImage im((int)screen_texture_width, (int)screen_texture_height, QImage::Format_RGBA8888);
1548                         if(p == NULL) {
1549                                 p = &im;
1550                         }
1551                         if(uVramTextureID != NULL) {
1552                                 p_wid->makeCurrent();
1553                                 uVramTextureID->destroy();
1554                                 delete uVramTextureID;
1555                                 uVramTextureID = createMainTexture(p);
1556                                 p_wid->doneCurrent();
1557                         } else {
1558                                 p_wid->makeCurrent();
1559                                 uVramTextureID = createMainTexture(p);
1560                                 p_wid->doneCurrent();
1561                         }
1562                 }
1563                 vertexFormat[0].x = -1.0f;
1564                 vertexFormat[0].y = -1.0f;
1565                 vertexFormat[0].z = -0.9f;
1566                 vertexFormat[1].x =  1.0f;
1567                 vertexFormat[1].y = -1.0f;
1568                 vertexFormat[1].z = -0.9f;
1569                 vertexFormat[2].x =  1.0f;
1570                 vertexFormat[2].y =  1.0f;
1571                 vertexFormat[2].z = -0.9f;
1572                 vertexFormat[3].x = -1.0f;
1573                 vertexFormat[3].y =  1.0f;
1574                 vertexFormat[3].z = -0.9f;
1575
1576                 vertexFormat[0].s = 0.0f;
1577                 //vertexFormat[0].t = (float)h / ih;
1578                 //vertexFormat[1].s = (float)w / iw;
1579                 //vertexFormat[1].t = (float)h / ih;
1580                 //vertexFormat[2].s = (float)w / iw;
1581                 vertexFormat[0].t = 1.0f;
1582                 vertexFormat[1].s = 1.0f;
1583                 vertexFormat[1].t = 1.0f;
1584                 vertexFormat[2].s = 1.0f;
1585                 vertexFormat[2].t = 0.0f;
1586                 vertexFormat[3].s = 0.0f;
1587                 vertexFormat[3].t = 0.0f;
1588                 
1589                 setNormalVAO(main_pass->getShader(), main_pass->getVAO(),
1590                                          main_pass->getVertexBuffer(),
1591                                          vertexFormat, 4);
1592                 
1593                 if(w > using_flags->get_real_screen_width()) {
1594                         w = using_flags->get_real_screen_width();
1595                 }                       
1596                 if(h > using_flags->get_real_screen_height()) {
1597                         h = using_flags->get_real_screen_height();
1598                 }
1599                 this->doSetGridsHorizonal(h, false);
1600                 this->doSetGridsVertical(w, false);
1601                 p_wid->doneCurrent();
1602         }
1603 }
1604 void GLDraw_4_5::do_set_horiz_lines(int lines)
1605 {
1606         if(lines > using_flags->get_real_screen_height()) {
1607                 lines = using_flags->get_real_screen_height();
1608         }                       
1609         this->doSetGridsHorizonal(lines, false);
1610 }
1611
1612 void GLDraw_4_5::resizeGL_Screen(void)
1613 {
1614         if(main_pass != NULL) {
1615                 setNormalVAO(main_pass->getShader(), main_pass->getVAO(),
1616                                          main_pass->getVertexBuffer(),
1617                                          vertexFormat, 4);
1618         }
1619 }       
1620
1621 void GLDraw_4_5::resizeGL(int width, int height)
1622 {
1623         //int side = qMin(width, height);
1624         extfunc->glViewport(0, 0, width, height);
1625         //extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
1626         crt_flag = true;
1627         if(!using_flags->is_use_one_board_computer() && (using_flags->get_max_button() <= 0)) {
1628                 doSetGridsHorizonal(vert_lines, true);
1629                 if(using_flags->is_use_vertical_pixel_lines()) {
1630                         doSetGridsVertical(horiz_pixels, true);
1631                 }
1632         }
1633         resizeGL_SetVertexs();
1634         resizeGL_Screen();
1635         if(using_flags->is_use_one_board_computer()) {
1636                 setNormalVAO(bitmap_block->getShader(), bitmap_block->getVAO(),
1637                                          bitmap_block->getVertexBuffer(),
1638                                          vertexBitmap, 4);
1639         }       
1640         if(using_flags->get_max_button() > 0) {
1641                 updateButtonTexture();
1642         }
1643 }
1644
1645 void GLDraw_4_5::initButtons(void)
1646 {
1647         button_desc_t *vm_buttons_d = using_flags->get_vm_buttons();
1648         QOpenGLContext *context = QOpenGLContext::currentContext();
1649         QPair<int, int> _version = QOpenGLVersionProfile(context->format()).version();
1650         QString versionext = QString::fromUtf8("");
1651         if(((_version.first == 4) && (_version.second >= 3)) || (_version.first >= 5)) {
1652                 versionext = QString::fromUtf8("#version 430 core \n"); // OK?
1653         } else if((_version.first == 4)) {
1654                 versionext = QString::fromUtf8("#version 400 core \n");
1655         } else { // Require GLVersion >= 3.2
1656                 versionext = QString::fromUtf8("#version 150 \n");
1657         }
1658         
1659         if(vm_buttons_d != NULL) {
1660                 button_shader = new QOpenGLShaderProgram(p_wid);
1661                 if(button_shader != NULL) {
1662                         bool f = false;
1663                         QFile vertex_src(QString::fromUtf8(":/gl4_5/vertex_shader.glsl"));
1664                         if (vertex_src.open(QIODevice::ReadOnly | QIODevice::Text)) {
1665                                 QString srcs = versionext;
1666                                 srcs = srcs + QString::fromUtf8(vertex_src.readAll());
1667                                 f  = button_shader->addShaderFromSourceCode(QOpenGLShader::Vertex, srcs);
1668                                 vertex_src.close();
1669                         } else {
1670                                 return;
1671                         }
1672                         QFile fragment_src(QString::fromUtf8(":/gl4_5/normal_fragment_shader.glsl"));
1673                         if (fragment_src.open(QIODevice::ReadOnly | QIODevice::Text)) {
1674                                 QString srcs = versionext;
1675                                 srcs = srcs + QString::fromUtf8(fragment_src.readAll());
1676                                 f &= button_shader->addShaderFromSourceCode(QOpenGLShader::Fragment, srcs);
1677                                 fragment_src.close();
1678                         } else {
1679                                 return;
1680                         }
1681                         if(!f) return;
1682                         button_shader->link();
1683                 }
1684
1685                 int ip = using_flags->get_max_button();
1686                 if(ip > 0) {
1687                         for(int num = 0; num < ip; num++) {
1688                                 QString tmps;
1689                                 tmps = QString::asprintf(":/button%02d.png", num);
1690                                 QImageReader *reader = new QImageReader(tmps);
1691                                 QImage *result = new QImage(reader->read());
1692                                 QImage pic;
1693                                 if(result != NULL) {
1694                                         if(!result->isNull()) {
1695                                                 pic = result->convertToFormat(QImage::Format_ARGB32);
1696                                         } else {
1697                                                 pic = QImage(10, 10, QImage::Format_RGBA8888);
1698                                                 pic.fill(QColor(0,0,0,0));
1699                                         }
1700                                         delete result;
1701                                 }else {
1702                                         pic = QImage(10, 10, QImage::Format_RGBA8888);
1703                                         pic.fill(QColor(0,0,0,0));
1704                                 }
1705                                 ButtonImages.push_back(pic);
1706                         }
1707                 }
1708                 vertexButtons = new QVector<VertexTexCoord_t>;
1709                 for(int i = 0; i < using_flags->get_max_button(); i++) {
1710                         buffer_button_vertex[i] = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
1711                         buffer_button_vertex[i]->create();
1712                         fButtonX[i] = -1.0 + (float)(vm_buttons_d[i].x * 2) / (float)using_flags->get_screen_width();
1713                         fButtonY[i] = 1.0 - (float)(vm_buttons_d[i].y * 2) / (float)using_flags->get_screen_height();
1714                         fButtonWidth[i] = (float)(vm_buttons_d[i].width * 2) / (float)using_flags->get_screen_width();
1715                         fButtonHeight[i] = (float)(vm_buttons_d[i].height * 2) / (float)using_flags->get_screen_height();
1716                         
1717                         vertex_button[i] = new QOpenGLVertexArrayObject;
1718                         if(vertex_button[i] != NULL) {
1719                                 if(vertex_button[i]->create()) {
1720                                         VertexTexCoord_t vt[4];
1721                                         
1722                                         vt[0].x =  fButtonX[i];
1723                                         vt[0].y =  fButtonY[i];
1724                                         vt[0].z =  -0.5f;
1725                                         vt[0].s = 0.0f;
1726                                         vt[0].t = 0.0f;
1727                                         
1728                                         vt[1].x =  fButtonX[i] + fButtonWidth[i];
1729                                         vt[1].y =  fButtonY[i];
1730                                         vt[1].z =  -0.5f;
1731                                         vt[1].s = 1.0f;
1732                                         vt[1].t = 0.0f;
1733                                         
1734                                         vt[2].x =  fButtonX[i] + fButtonWidth[i];
1735                                         vt[2].y =  fButtonY[i] - fButtonHeight[i];
1736                                         vt[2].z =  -0.5f;
1737                                         vt[2].s = 1.0f;
1738                                         vt[2].t = 1.0f;
1739                                         
1740                                         vt[3].x =  fButtonX[i];
1741                                         vt[3].y =  fButtonY[i] - fButtonHeight[i];
1742                                         vt[3].z =  -0.5f;
1743                                         vt[3].s = 0.0f;
1744                                         vt[3].t = 1.0f;
1745                                         
1746                                         vertexButtons->append(vt[0]);
1747                                         vertexButtons->append(vt[1]);
1748                                         vertexButtons->append(vt[2]);
1749                                         vertexButtons->append(vt[3]);
1750                                         vertex_button[i]->bind();
1751                                         buffer_button_vertex[i]->bind();
1752                                         buffer_button_vertex[i]->allocate(4 * sizeof(VertexTexCoord_t));
1753                                         
1754                                         buffer_button_vertex[i]->setUsagePattern(QOpenGLBuffer::StaticDraw);
1755                                         buffer_button_vertex[i]->release();
1756                                         vertex_button[i]->release();
1757                                         setNormalVAO(button_shader, vertex_button[i],
1758                                                                  buffer_button_vertex[i],
1759                                                                  vt, 4);
1760                                 }
1761                         }
1762                 }
1763         }
1764 }
1765
1766 void GLDraw_4_5::do_set_display_osd(bool onoff)
1767 {
1768         osd_onoff = onoff;
1769 }
1770
1771 void GLDraw_4_5::do_display_osd_leds(int lednum, bool onoff)
1772 {
1773         if(lednum == -1) {
1774                 osd_led_status = (onoff) ? 0xffffffff : 0x00000000;
1775         } else if((lednum >= 0) && (lednum < 32)) {
1776                 uint32_t nn;
1777                 nn = 0x00000001 << lednum;
1778                 if(onoff) {
1779                         osd_led_status |= nn;
1780                 } else {
1781                         osd_led_status &= ~nn;
1782                 }
1783         }
1784 }
1785
1786 void GLDraw_4_5::uploadIconTexture(QPixmap *p, int icon_type, int localnum)
1787 {
1788         if((icon_type >  7) || (icon_type < 0)) return;
1789         if((localnum  >= 9) || (localnum  <  0)) return;
1790         if(p == NULL) return;
1791         p_wid->makeCurrent();
1792         QImage image = p->toImage();
1793
1794         if(icon_texid[icon_type][localnum] != NULL) delete icon_texid[icon_type][localnum];
1795         {
1796                 icon_texid[icon_type][localnum] = new QOpenGLTexture(image);
1797         }
1798         p_wid->doneCurrent();
1799
1800 }
1801
1802
1803 void GLDraw_4_5::updateBitmap(QImage *p)
1804 {
1805         if(!using_flags->is_use_one_board_computer()) return;
1806         redraw_required = true;
1807         bitmap_uploaded = false;
1808         uploadBitmapTexture(p);
1809 }
1810
1811 void GLDraw_4_5::uploadBitmapTexture(QImage *p)
1812 {
1813         if(!using_flags->is_use_one_board_computer()) return;
1814         if(p == NULL) return;
1815         if(!bitmap_uploaded) {
1816                 p_wid->makeCurrent();
1817                 if(uBitmapTextureID != NULL) {
1818                         delete uBitmapTextureID;
1819                 }
1820                 uBitmapTextureID = new QOpenGLTexture(*p);
1821                 p_wid->doneCurrent();
1822                 bitmap_uploaded = true;
1823                 crt_flag = true;
1824         }
1825 }
1826
1827 void GLDraw_4_5::updateButtonTexture(void)
1828 {
1829         int i;
1830         button_desc_t *vm_buttons_d = using_flags->get_vm_buttons();
1831         if(button_updated) return;
1832         if(vm_buttons_d != NULL) {
1833                 for(i = 0; i < using_flags->get_max_button(); i++) {
1834                         QImage img = ButtonImages.at(i);
1835                         if(uButtonTextureID[i] != NULL) {
1836                                 delete uButtonTextureID[i];
1837                         }
1838                         uButtonTextureID[i] = new QOpenGLTexture(img);
1839                 }
1840         }
1841         button_updated = true;
1842 }
1843
1844 void GLDraw_4_5::get_screen_geometry(int *w, int *h)
1845 {
1846         if(w != NULL) *w = pixel_width; 
1847         if(h != NULL) *h = pixel_height;
1848 }
1849
1850 scrntype_t *GLDraw_4_5::get_screen_buffer(int y)
1851 {
1852         if((y < 0) || (y >= pixel_height)) return NULL;
1853         if((map_base_address == NULL) || !(main_texture_ready)) {
1854                 return NULL;
1855         } else {
1856                 main_mutex->lock();
1857                 extfunc->glClientWaitSync(sync_fence, GL_SYNC_FLUSH_COMMANDS_BIT, 0);
1858                 extfunc->glDeleteSync(sync_fence);
1859                 sync_fence = extfunc->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE,  0);
1860                 
1861                 scrntype_t *p = (scrntype_t *)map_base_address;
1862                 p = p + (pixel_width * y);
1863                 //printf("%08x\n", (uintptr_t)p);   
1864                 main_mutex->unlock();
1865                 return p;
1866         }
1867 }
1868 // Note: Mapping vram from draw_thread does'nt work well.
1869 // This feature might be disable. 20180728 K.Ohta.
1870 bool GLDraw_4_5::is_ready_to_map_vram_texture(void)
1871 {
1872         if(main_texture_buffer == 0) {
1873                 return false;
1874         }
1875         if(gl_major_version < 4) {
1876                 return false;
1877         }
1878         if(gl_minor_version < 4) {
1879                 return false;
1880         }
1881         return true;
1882 }
1883
1884 bool GLDraw_4_5::map_vram_texture(void)
1885 {
1886         if(main_texture_buffer == 0) {
1887                 return false;
1888         }
1889 //      if(!(main_texture_ready)) {
1890 //              return false;
1891 //      }
1892
1893         if(gl_major_version < 4) {
1894                 return false;
1895         }
1896         if(gl_minor_version < 4) {
1897                 return false;
1898         }
1899 #if 0
1900         return false;
1901 #else
1902
1903         extfunc->glClientWaitSync(sync_fence, GL_SYNC_FLUSH_COMMANDS_BIT, 0);
1904         extfunc->glDeleteSync(sync_fence);
1905         sync_fence = extfunc->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE,  0);
1906         
1907         //extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, main_texture_buffer);
1908         map_base_address = (scrntype_t *)(extfunc->glMapNamedBufferRange(main_texture_buffer, 0, pixel_width * pixel_height * sizeof(scrntype_t),  GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT));
1909         csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_SCREEN, "MAPPED SCREEN TO PHYSICAL ADDRESS:%0llx\n", (uintptr_t)map_base_address);
1910         //extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
1911         if(map_base_address == NULL) return false;
1912         return true;
1913 #endif
1914 }
1915
1916 bool GLDraw_4_5::unmap_vram_texture(void)
1917 {
1918         if((map_base_address == NULL) || (main_texture_buffer == 0)) return false;
1919
1920         extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, main_texture_buffer);
1921         extfunc->glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
1922         extfunc->glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
1923                         
1924         return true;
1925 }