OSDN Git Service

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