OSDN Git Service

3b3dd8e384822519ac3ba84fc6c350b2ef1aef36
[csp-qt/common_source_project-fm7.git] / source / src / qt / gui / gl2 / qt_glutil_gl2_0.cpp
1 /*
2  * qt_glutil_gl2_0.cpp
3  * (c) 2016 K.Ohta <whatisthis.sowhat@gmail.com>
4  * License: GPLv2.
5  * Renderer with OpenGL v2.0 .
6  * History:
7  * Jan 21, 2016 : Initial.
8  */
9
10 //#include "emu.h"
11
12 #include <QOpenGLFramebufferObject>
13 #include <QColor>
14 #include <QImageReader>
15 #include <QRect>
16 #include <QOpenGLFunctions_2_0>
17
18 #include "osd_types.h"
19 #include "qt_gldraw.h"
20 #include "qt_glutil_gl2_0.h"
21 #include "menu_flags.h"
22
23 GLDraw_2_0::GLDraw_2_0(GLDrawClass *parent, USING_FLAGS *p, CSP_Logger *logger, EMU *emu) : GLDraw_Tmpl(parent, p, logger, emu)
24 {
25         extfunc_2 = NULL;
26         
27 }
28
29 GLDraw_2_0::~GLDraw_2_0()
30 {
31         if(buffer_screen_vertex->isCreated()) buffer_screen_vertex->destroy();
32         if(vertex_screen->isCreated()) vertex_screen->destroy();
33         if(glVertGrids != NULL) free(glVertGrids);
34         if(glHorizGrids != NULL) free(glHorizGrids);
35         if(using_flags->is_use_one_board_computer()) {
36                 if(uBitmapTextureID != NULL) {
37                         delete uBitmapTextureID;
38                 }
39         }
40         if(using_flags->get_max_button() > 0) {
41                 int i;
42                 for(i = 0; i < using_flags->get_max_button(); i++) {
43                         if(uButtonTextureID[i] != NULL) delete uButtonTextureID[i];
44                 }
45                 for(i = 0; i < using_flags->get_max_button(); i++) {
46                         if(vertex_button[i]->isCreated()) vertex_button[i]->destroy();
47                 }
48         }
49
50         if(using_flags->is_use_one_board_computer()) {
51                 if(vertex_bitmap->isCreated()) vertex_bitmap->destroy();
52         }
53         if(uVramTextureID != NULL) {
54                 delete uVramTextureID;
55         }
56         if(extfunc_2 != NULL) delete extfunc_2;
57 }
58
59 void GLDraw_2_0::initializeGL(void)
60 {
61 }
62
63 void GLDraw_2_0::do_set_display_osd(bool onoff)
64 {
65         osd_onoff = onoff;
66 }
67
68 void GLDraw_2_0::set_osd_vertex(int xbit)
69 {
70         float xbase, ybase, zbase;
71         int major, minor, nl;
72         int i = xbit;
73         if((xbit < 0) || (xbit >= 32)) return;
74         if((i >= 2) && (i < 10)) { // FD
75                 major = 0;
76                 minor = i - 2;
77                 nl = using_flags->get_max_drive();
78         } else if((i >= 10) && (i < 12)) { // QD
79                 major = 2;
80                 minor = i - 10;
81                 nl = using_flags->get_max_qd();
82         } else if((i >= 12) && (i < 14)) { // CMT(R)
83                 major = 1;
84                 minor = i - 12;
85                 nl = using_flags->get_max_tape();
86         } else if((i >= 14) && (i < 16)) { // CMT(W)
87                 major = 1;
88                 minor = i - 14;
89                 nl = using_flags->get_max_tape();
90         } else if(i >= 16) {
91                 major = 4 + (i / 8) - 2;
92                 minor = i % 8;
93                 nl = 8;
94         } else {
95                 major = 6;
96                 minor = i;
97                 nl = 2;
98         }
99         xbase =  1.0f - (1.0f * 48.0f / 640.0f) * (float)(nl - minor) - (4.0f / 640.0f);;
100         ybase = -1.0f + (1.0f * 48.0f / 400.0f) * (float)(major + 1) + (4.0f / 400.0f);
101         zbase = -0.998f;
102         vertexOSD[i][0].x = xbase;
103         vertexOSD[i][0].y = ybase;
104         vertexOSD[i][0].z = zbase;
105         vertexOSD[i][0].s = 0.0f;
106         vertexOSD[i][0].t = 0.0f;
107         
108         vertexOSD[i][1].x = xbase + (48.0f / 640.0f);
109         vertexOSD[i][1].y = ybase;
110         vertexOSD[i][1].z = zbase;
111         vertexOSD[i][1].s = 1.0f;
112         vertexOSD[i][1].t = 0.0f;
113         
114         vertexOSD[i][2].x = xbase + (48.0f / 640.0f);
115         vertexOSD[i][2].y = ybase - (48.0f / 400.0f);
116         vertexOSD[i][2].z = zbase;
117         vertexOSD[i][2].s = 1.0f;
118         vertexOSD[i][2].t = 1.0f;
119         
120         vertexOSD[i][3].x = xbase;
121         vertexOSD[i][3].y = ybase - (48.0f / 400.0f);
122         vertexOSD[i][3].z = zbase;
123         vertexOSD[i][3].s = 0.0f;
124         vertexOSD[i][3].t = 1.0f;
125         
126         setNormalVAO(osd_shader, vertex_osd[xbit],
127                                  buffer_osd[xbit],
128                                  &(vertexOSD[i][0]), 4);
129 }
130
131
132 void GLDraw_2_0::do_display_osd_leds(int lednum, bool onoff)
133 {
134         if(lednum == -1) {
135                 osd_led_status = (onoff) ? 0xffffffff : 0x00000000;
136         } else if((lednum >= 0) && (lednum < 32)) {
137                 uint32_t nn;
138                 nn = 0x00000001 << lednum;
139                 if(onoff) {
140                         osd_led_status |= nn;
141                 } else {
142                         osd_led_status &= ~nn;
143                 }
144         }
145 }
146
147 void GLDraw_2_0::drawOsdLeds()
148 {
149         QVector4D color_on;
150         QVector4D color_off;
151         VertexTexCoord_t vertex[4];
152         float xbase, ybase, zbase;
153         if(osd_onoff) {
154                 color_on = QVector4D(0.95, 0.0, 0.05, 1.0);
155                 color_off = QVector4D(0.05,0.05, 0.05, 0.10);
156         } else {
157                 color_on = QVector4D(0.00,0.00, 0.00, 0.0);
158                 color_off = QVector4D(0.00,0.00, 0.00, 0.0);
159         }
160         xbase = 0.0f + (1.0f / 32.0f) * 31.0f + (1.0f / 128.0f);
161         ybase = -1.0f + (2.0f / 64.0f) * 1.5f;
162         zbase = -0.999f;
163         
164         extfunc_2->glEnable(GL_BLEND);
165         extfunc_2->glDisable(GL_TEXTURE_2D);
166         extfunc_2->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
167         extfunc_2->glDisable(GL_DEPTH_TEST);
168         extfunc_2->glViewport(0, 0, p_wid->width(), p_wid->height());
169         extfunc_2->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
170         if(osd_led_status != osd_led_status_bak) {
171                 if(osd_onoff) {
172                         uint32_t _bit = 0x00000001;
173                         for(int ii = 0; ii < osd_led_bit_width; ii++) {
174                                 if((_bit & osd_led_status) == (_bit & osd_led_status_bak)) {
175                                         xbase = xbase - (1.0f / 32.0f);
176                                         _bit <<= 1;
177                                         continue;
178                                 }
179                                 vertex[0].x = xbase;
180                                 vertex[0].y = ybase;
181                                 vertex[0].z = zbase;
182                                 
183                                 vertex[1].x = xbase + (1.0f / 64.0f);
184                                 vertex[1].y = ybase;
185                                 vertex[1].z = zbase;
186                                 
187                                 vertex[2].x = xbase + (1.0f / 64.0f);
188                                 vertex[2].y = ybase - (1.0f / 64.0f);
189                                 vertex[2].z = zbase;
190                         
191                                 vertex[3].x = xbase;
192                                 vertex[3].y = ybase - (1.0f / 64.0f);
193                                 vertex[3].z = zbase;
194                                 if(_bit & osd_led_status) {
195                                         extfunc_2->glColor4f(color_on.x(), color_on.y(), color_on.z(), color_on.w());
196                                 } else {
197                                         extfunc_2->glColor4f(color_off.x(), color_off.y(), color_off.z(), color_off.w());
198                                 }                       
199                                 extfunc_2->glBegin(GL_POLYGON);
200                                 for(int j = 0; j < 4; j++) {
201                                         extfunc_2->glVertex3f(vertex[j].x, vertex[j].y, vertex[j].z);
202                                 }
203                                 extfunc_2->glEnd();
204                                 xbase = xbase - (1.0f / 32.0f);
205                                 _bit <<= 1;
206                         }
207                         osd_led_status_bak = osd_led_status;
208                 }
209         }
210 }
211
212
213 void GLDraw_2_0::drawOsdIcons()
214 {
215         QVector4D color_on;
216         QVector4D color_off;
217         int major, minor;
218         if(osd_onoff) {
219                 color_on = QVector4D(1.0, 1.0, 1.0, 0.8);
220                 color_off = QVector4D(1.0, 1.0, 1.0, 0.00);
221         } else {
222                 color_on = QVector4D(0.00,0.00, 0.00, 0.0);
223                 color_off = QVector4D(0.00,0.00, 0.00, 0.0);
224         }
225         extfunc_2->glEnable(GL_BLEND);
226         extfunc_2->glEnable(GL_TEXTURE_2D);
227         extfunc_2->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
228         extfunc_2->glDisable(GL_DEPTH_TEST);
229         extfunc_2->glViewport(0, 0, p_wid->width(), p_wid->height());
230         extfunc_2->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
231         if(osd_onoff) {
232                 uint32_t _bit = 0x00000001;
233                 bool checkf;
234                 for(int ii = 0; ii < osd_led_bit_width; ii++) {
235                         checkf = ((_bit & osd_led_status) != 0); 
236                         if(checkf == ((_bit & osd_led_status_bak) != 0)) {
237                                 if(!checkf) {
238                                         _bit <<= 1;
239                                         continue;
240                                 }
241                         }
242                         if((ii >= 2) && (ii < 10)) { // FD
243                                 major = 2;
244                                 minor = ii - 2;
245                         } else if((ii >= 10) && (ii < 12)) { // QD
246                                 major = 3;
247                                 minor = ii - 10;
248                         } else if((ii >= 12) && (ii < 14)) { // CMT(R)
249                                 major = 4;
250                                 minor = ii - 12;
251                         } else if((ii >= 14) && (ii < 16)) { // CMT(W)
252                                 major = 5;
253                                 minor = ii - 14;
254                         } else if(ii >= 16) {
255                                 major = 4 + (ii / 8) - 2;
256                                 minor = ii % 8;
257                         } else {
258                                 major = 0;
259                                 minor = 0;
260                         }
261                         // ToDo: CD,LD and HDD.
262                         if(checkf) {
263                                 drawMain(osd_shader, vertex_osd[ii],
264                                                  buffer_osd[ii],
265                                                  vertexOSD[ii],
266                                                  icon_texid[major][minor]->textureId(),
267                                                  color_on, false);
268                         } else {
269                                 drawMain(osd_shader, vertex_osd[ii],
270                                                  buffer_osd[ii],
271                                                  vertexOSD[ii],
272                                                  icon_texid[major][minor]->textureId(),
273                                                  color_off, false);
274                         }                       
275                         _bit <<= 1;
276                 }
277                 osd_led_status_bak = osd_led_status;
278         }
279 }
280
281 void GLDraw_2_0::setNormalVAO(QOpenGLShaderProgram *prg,
282                                                            QOpenGLVertexArrayObject *vp,
283                                                            QOpenGLBuffer *bp,
284                                                            VertexTexCoord_t *tp,
285                                                            int size)
286 {
287         int vertex_loc = prg->attributeLocation("vertex");
288         int texcoord_loc = prg->attributeLocation("texcoord");
289
290         if(bp == NULL) return;
291         if(prg == NULL) return;
292         if(!bp->isCreated()) return;
293
294         bp->bind();
295         bp->write(0, tp, sizeof(VertexTexCoord_t) * size);
296         prg->setAttributeBuffer(vertex_loc, GL_FLOAT, 0, 3, sizeof(VertexTexCoord_t));
297         prg->setAttributeBuffer(texcoord_loc, GL_FLOAT, 3 * sizeof(GLfloat), 2, sizeof(VertexTexCoord_t));
298         bp->release();
299
300         prg->setUniformValue("a_texture", 0);
301                            
302 }
303
304 void GLDraw_2_0::setChangeBrightness(bool flag)
305 {
306         set_brightness = flag;
307 }
308
309 void GLDraw_2_0::setBrightness(GLfloat r, GLfloat g, GLfloat b)
310 {
311         fBrightR = r;
312         fBrightG = g;
313         fBrightB = b;
314 }
315
316 void GLDraw_2_0::setImgPtr(QImage *p)
317 {
318         imgptr = p;
319 }
320
321 void GLDraw_2_0::setSmoosing(bool flag)
322 {
323         smoosing = flag;
324         crt_flag = true;
325 }
326
327 void GLDraw_2_0::setVirtualVramSize(int width, int height)
328 {
329         vert_lines = height;
330         horiz_pixels = width;
331         crt_flag = true;
332 }
333
334 void GLDraw_2_0::set_emu_launched(void)
335 {
336         emu_launched = true;
337 }
338
339 void GLDraw_2_0::setDrawGLGridVert(bool flag)
340 {
341         gl_grid_vert = flag;
342         crt_flag = true;
343 }
344
345 void GLDraw_2_0::setDrawGLGridHoriz(bool flag)
346 {
347         gl_grid_vert = flag;
348         crt_flag = true;
349 }
350
351 void GLDraw_2_0::initGLObjects()
352 {
353         extfunc_2 = new QOpenGLFunctions_2_0;
354         extfunc_2->initializeOpenGLFunctions();
355         extfunc_2->glViewport(0, 0, p_wid->width(), p_wid->height());
356         extfunc_2->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
357         extfunc_2->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texture_max_size);
358 }       
359
360 void GLDraw_2_0::initButtons(void)
361 {
362         button_desc_t *vm_buttons_d = using_flags->get_vm_buttons();
363         
364         if(vm_buttons_d != NULL) {
365                 button_shader = new QOpenGLShaderProgram(p_wid);
366                 if(button_shader != NULL) {
367                         button_shader->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/gl2/vertex_shader.glsl");
368                         button_shader->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/gl2/normal_fragment_shader.glsl");
369                         button_shader->link();
370                 }
371
372                 int ip = using_flags->get_max_button();
373                 if(ip > 0) {
374                         for(int num = 0; num < ip; num++) {
375                                 QString tmps;
376                                 tmps = QString::asprintf(":/button%02d.png", num);
377                                 QImageReader *reader = new QImageReader(tmps);
378                                 QImage *result = new QImage(reader->read());
379                                 QImage pic;
380                                 if(result != NULL) {
381                                         if(!result->isNull()) {
382                                                 pic = result->convertToFormat(QImage::Format_ARGB32);
383                                         } else {
384                                                 pic = QImage(10, 10, QImage::Format_RGBA8888);
385                                                 pic.fill(QColor(0,0,0,0));
386                                         }
387                                         delete result;
388                                 }else {
389                                         pic = QImage(10, 10, QImage::Format_RGBA8888);
390                                         pic.fill(QColor(0,0,0,0));
391                                 }
392                                 ButtonImages.push_back(pic);
393                         }
394                 }
395                 vertexButtons = new QVector<VertexTexCoord_t>;
396                 for(int i = 0; i < using_flags->get_max_button(); i++) {
397                         buffer_button_vertex[i] = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
398                         buffer_button_vertex[i]->create();
399                         fButtonX[i] = -1.0 + (float)(vm_buttons_d[i].x * 2) / (float)using_flags->get_screen_width();
400                         fButtonY[i] = 1.0 - (float)(vm_buttons_d[i].y * 2) / (float)using_flags->get_screen_height();
401                         fButtonWidth[i] = (float)(vm_buttons_d[i].width * 2) / (float)using_flags->get_screen_width();
402                         fButtonHeight[i] = (float)(vm_buttons_d[i].height * 2) / (float)using_flags->get_screen_height();
403                         
404                         vertex_button[i] = new QOpenGLVertexArrayObject;
405                         if(vertex_button[i] != NULL) {
406                                 if(vertex_button[i]->create()) {
407                                         VertexTexCoord_t vt[4];
408                                         
409                                         vt[0].x =  fButtonX[i];
410                                         vt[0].y =  fButtonY[i];
411                                         vt[0].z =  -0.5f;
412                                         vt[0].s = 0.0f;
413                                         vt[0].t = 0.0f;
414                                         
415                                         vt[1].x =  fButtonX[i] + fButtonWidth[i];
416                                         vt[1].y =  fButtonY[i];
417                                         vt[1].z =  -0.5f;
418                                         vt[1].s = 1.0f;
419                                         vt[1].t = 0.0f;
420                                         
421                                         vt[2].x =  fButtonX[i] + fButtonWidth[i];
422                                         vt[2].y =  fButtonY[i] - fButtonHeight[i];
423                                         vt[2].z =  -0.5f;
424                                         vt[2].s = 1.0f;
425                                         vt[2].t = 1.0f;
426                                         
427                                         vt[3].x =  fButtonX[i];
428                                         vt[3].y =  fButtonY[i] - fButtonHeight[i];
429                                         vt[3].z =  -0.5f;
430                                         vt[3].s = 0.0f;
431                                         vt[3].t = 1.0f;
432                                         
433                                         vertexButtons->append(vt[0]);
434                                         vertexButtons->append(vt[1]);
435                                         vertexButtons->append(vt[2]);
436                                         vertexButtons->append(vt[3]);
437                                         vertex_button[i]->bind();
438                                         buffer_button_vertex[i]->bind();
439                                         buffer_button_vertex[i]->allocate(4 * sizeof(VertexTexCoord_t));
440                                         
441                                         buffer_button_vertex[i]->setUsagePattern(QOpenGLBuffer::StaticDraw);
442                                         buffer_button_vertex[i]->release();
443                                         vertex_button[i]->release();
444                                         setNormalVAO(button_shader, vertex_button[i],
445                                                                  buffer_button_vertex[i],
446                                                                  vt, 4);
447                                 }
448                         }
449                 }
450         }
451 }
452
453 void GLDraw_2_0::initBitmapVertex(void)
454 {
455         if(using_flags->is_use_one_board_computer()) {
456                 vertexBitmap[0].x = -1.0f;
457                 vertexBitmap[0].y = -1.0f;
458                 vertexBitmap[0].z = -0.1f;
459                 vertexBitmap[0].s = 0.0f;
460                 vertexBitmap[0].t = 1.0f;
461                 
462                 vertexBitmap[1].x = +1.0f;
463                 vertexBitmap[1].y = -1.0f;
464                 vertexBitmap[1].z = -0.1f;
465                 vertexBitmap[1].s = 1.0f;
466                 vertexBitmap[1].t = 1.0f;
467                 
468                 vertexBitmap[2].x = +1.0f;
469                 vertexBitmap[2].y = +1.0f;
470                 vertexBitmap[2].z = -0.1f;
471                 vertexBitmap[2].s = 1.0f;
472                 vertexBitmap[2].t = 0.0f;
473                 
474                 vertexBitmap[3].x = -1.0f;
475                 vertexBitmap[3].y = +1.0f;
476                 vertexBitmap[3].z = -0.1f;
477                 vertexBitmap[3].s = 0.0f;
478                 vertexBitmap[3].t = 0.0f;
479                 
480         }
481 }
482
483 void GLDraw_2_0::initBitmapVAO(void)
484 {
485         if(using_flags->is_use_one_board_computer()) {
486                 bitmap_shader = new QOpenGLShaderProgram(p_wid);
487                 if(bitmap_shader != NULL) {
488                         bitmap_shader->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/gl2/vertex_shader.glsl");
489                         bitmap_shader->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/gl2/normal_fragment_shader.glsl");
490                         bitmap_shader->link();
491                 }
492                 buffer_bitmap_vertex = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
493                 vertex_bitmap = new QOpenGLVertexArrayObject;
494                 if(vertex_bitmap != NULL) {
495                         if(vertex_bitmap->create()) {
496                                 buffer_bitmap_vertex->create();
497                                 buffer_bitmap_vertex->setUsagePattern(QOpenGLBuffer::StaticDraw);
498                                 
499                                 {
500                                         QVector4D c;
501                                         c = QVector4D(1.0, 1.0, 1.0, 1.0);
502                                         bitmap_shader->setUniformValue("color", c);
503                                 }
504                                 vertex_bitmap->bind();
505                                 buffer_bitmap_vertex->bind();
506                                 buffer_bitmap_vertex->allocate(sizeof(vertexBitmap));
507                                 buffer_bitmap_vertex->release();
508                                 vertex_bitmap->release();
509                                 setNormalVAO(bitmap_shader, vertex_bitmap,
510                                                          buffer_bitmap_vertex,
511                                                          vertexBitmap, 4);
512                         }
513                 }
514         }       
515 }
516
517 void GLDraw_2_0::initFBO(void)
518 {
519         // Will fix around vm_buttons[].
520         initBitmapVertex();
521         if(using_flags->get_max_button() > 0) {
522                 initButtons();
523         }
524         glHorizGrids = (GLfloat *)malloc(sizeof(float) * (using_flags->get_real_screen_height() + 2) * 6);
525         if(glHorizGrids != NULL) {
526                 doSetGridsHorizonal(using_flags->get_real_screen_height(), true);
527         }
528         glVertGrids  = (GLfloat *)malloc(sizeof(float) * (using_flags->get_real_screen_width() + 2) * 6);
529         if(glVertGrids != NULL) {
530                 doSetGridsVertical(using_flags->get_real_screen_width(), true);
531         }
532         // Init view
533         extfunc_2->glClearColor(0.0, 0.0, 0.0, 1.0);
534 }
535
536 void GLDraw_2_0::initLocalGLObjects(void)
537 {
538         main_shader = new QOpenGLShaderProgram(p_wid);
539         if(main_shader != NULL) {
540                 main_shader->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/gl2/vertex_shader.glsl");
541                 main_shader->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/gl2/chromakey_fragment_shader2.glsl");
542                 main_shader->link();
543         }
544         buffer_screen_vertex = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
545         vertex_screen = new QOpenGLVertexArrayObject;
546         
547         vertexFormat[0].x = -0.5f;
548         vertexFormat[0].y = -0.5f;
549         vertexFormat[0].z = -0.9f;
550         vertexFormat[0].s = 0.0f;
551         vertexFormat[0].t = 1.0f;
552                         
553         vertexFormat[1].x = +0.5f;
554         vertexFormat[1].y = -0.5f;
555         vertexFormat[1].z = -0.9f;
556         vertexFormat[1].s = 1.0f;
557         vertexFormat[1].t = 1.0f;
558                         
559         vertexFormat[2].x = +0.5f;
560         vertexFormat[2].y = +0.5f;
561         vertexFormat[2].z = -0.9f;
562         vertexFormat[2].s = 1.0f;
563         vertexFormat[2].t = 0.0f;
564         
565         vertexFormat[3].x = -0.5f;
566         vertexFormat[3].y = +0.5f;
567         vertexFormat[3].z = -0.9f;
568         vertexFormat[3].s = 0.0f;
569         vertexFormat[3].t = 0.0f;
570         if(buffer_screen_vertex != NULL) {
571                 if(buffer_screen_vertex->create()) {
572                         {
573                                 QVector4D c;
574                                 c = QVector4D(1.0, 1.0, 1.0, 1.0);
575                                 main_shader->setUniformValue("color", c);
576                         }
577                         
578                         //buffer_screen_vertex->create();
579                         buffer_screen_vertex->setUsagePattern(QOpenGLBuffer::DynamicDraw);
580                         vertex_screen->create();
581                         
582                         if(vertex_screen != NULL) vertex_screen->bind();
583                         buffer_screen_vertex->bind();
584                         buffer_screen_vertex->allocate(sizeof(VertexTexCoord_t) * 4);
585                         if(vertex_screen != NULL) vertex_screen->release();
586                         buffer_screen_vertex->release();
587                         setNormalVAO(main_shader, vertex_screen,
588                                                  buffer_screen_vertex,
589                                                  vertexFormat, 4);
590                 }
591         }
592         initBitmapVAO();
593         initOsdObjects();
594 }
595
596 void GLDraw_2_0::initOsdObjects(void)
597 {
598         osd_shader = new QOpenGLShaderProgram(p_wid);
599         if(osd_shader != NULL) {
600                 osd_shader->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/gl2/vertex_shader.glsl");
601                 osd_shader->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/gl2/icon_fragment_shader.glsl");
602                 osd_shader->link();
603         }
604         for(int i = 0; i < 32; i++) {
605                 buffer_osd[i] = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
606                 vertex_osd[i] = new QOpenGLVertexArrayObject;
607                 
608                 if(buffer_osd[i] != NULL) {
609                         if(buffer_osd[i]->create()) {
610                                 {
611                                         QVector4D c;
612                                         c = QVector4D(1.0, 1.0, 1.0, 1.0);
613                                         osd_shader->setUniformValue("color", c);
614                                 }
615                                 
616                                 //buffer_screen_vertex->create();
617                                 buffer_osd[i]->setUsagePattern(QOpenGLBuffer::StaticDraw);
618                                 vertex_osd[i]->create();
619                                 
620                                 if(vertex_osd[i] != NULL) vertex_osd[i]->bind();
621                                 buffer_osd[i]->bind();
622                                 buffer_osd[i]->allocate(sizeof(VertexTexCoord_t) * 4);
623                                 if(vertex_osd[i] != NULL) vertex_osd[i]->release();
624                                 buffer_osd[i]->release();
625                                 set_osd_vertex(i);
626                         }
627                 }
628         }
629 }
630
631 void GLDraw_2_0::drawGridsMain(GLfloat *tp,
632                                                            int number,
633                                                            GLfloat lineWidth,
634                                                            QVector4D color)
635 {
636         if(number <= 0) return;
637         extfunc_2->glDisable(GL_TEXTURE_2D);
638         extfunc_2->glDisable(GL_DEPTH_TEST);
639         extfunc_2->glDisable(GL_BLEND);
640         { 
641                 if(tp != NULL) {
642                         int i;
643                         int p = 0;
644                         QMatrix2x2 rot;
645                         extfunc_2->glColor4f(color.x(), color.y(), color.z(), color.w());
646                         extfunc_2->glLineWidth(lineWidth);
647                         extfunc_2->glBegin(GL_LINES);
648                         if((p_config->rotate_type == 1) || (p_config->rotate_type == 3)) {
649                                 for(i = 0; i < (number + 1); i++) {
650                                         extfunc_2->glVertex3f(tp[p + 1], tp[p + 0], tp[p + 2]);
651                                         extfunc_2->glVertex3f(tp[p + 4], tp[p + 3], tp[p + 5]);
652                                         p += 6;
653                                 }
654                         } else {
655                                 for(i = 0; i < (number + 1); i++) {
656                                         extfunc_2->glVertex3f(tp[p + 0], tp[p + 1], tp[p + 2]);
657                                         extfunc_2->glVertex3f(tp[p + 3], tp[p + 4], tp[p + 5]);
658                                         p += 6;
659                                 }
660                         }
661                         extfunc_2->glEnd();
662                 }
663         }
664 }
665
666 void GLDraw_2_0::drawGridsHorizonal(void)
667 {
668         QVector4D c= QVector4D(0.0f, 0.0f, 0.0f, 1.0f);
669         drawGridsMain(glHorizGrids,
670                                   vert_lines,
671                                   0.15f,
672                                   c);
673 }
674
675 void GLDraw_2_0::drawGridsVertical(void)
676 {
677         QVector4D c= QVector4D(0.0f, 0.0f, 0.0f, 1.0f);
678         drawGridsMain(glVertGrids,
679                                   horiz_pixels,
680                                   0.5f,
681                                   c);
682 }
683
684
685 void GLDraw_2_0::drawGrids(void)
686 {
687         gl_grid_horiz = p_config->opengl_scanline_horiz;
688         gl_grid_vert  = p_config->opengl_scanline_vert;
689         if(gl_grid_horiz && (vert_lines > 0)) {
690                 drawGridsHorizonal();
691         } // Will fix.
692         if(using_flags->is_use_vertical_pixel_lines()) {
693                 if(gl_grid_vert && (horiz_pixels > 0)) {
694                         drawGridsVertical();
695                 }
696         }
697 }
698
699 void GLDraw_2_0::updateButtonTexture(void)
700 {
701         int i;
702         button_desc_t *vm_buttons_d = using_flags->get_vm_buttons();
703         if(button_updated) return;
704         if(vm_buttons_d != NULL) {
705                 for(i = 0; i < using_flags->get_max_button(); i++) {
706                         QImage img = ButtonImages.at(i);
707                         if(uButtonTextureID[i] != NULL) {
708                                 delete uButtonTextureID[i];
709                         }
710                         uButtonTextureID[i] = new QOpenGLTexture(img);
711                 }
712         }
713         button_updated = true;
714 }
715
716 void GLDraw_2_0::drawButtons()
717 {
718         int i;
719         updateButtonTexture();
720         for(i = 0; i < using_flags->get_max_button(); i++) {
721                 QVector4D c;
722                 VertexTexCoord_t vt[4];
723                 vt[0].x =  fButtonX[i];
724                 vt[0].y =  fButtonY[i];
725                 vt[0].z =  -0.5f;
726                 vt[0].s = 0.0f;
727                 vt[0].t = 1.0f;
728                 
729                 vt[1].x =  fButtonX[i] + fButtonWidth[i];
730                 vt[1].y =  fButtonY[i];
731                 vt[1].z =  -0.5f;
732                 vt[1].s = 1.0f;
733                 vt[1].t = 1.0f;
734                 
735                 vt[2].x =  fButtonX[i] + fButtonWidth[i];
736                 vt[2].y =  fButtonY[i] - fButtonHeight[i];
737                 vt[2].z =  -0.5f;
738                 vt[2].s = 1.0f;
739                 vt[2].t = 0.0f;
740                 
741                 vt[3].x =  fButtonX[i];
742                 vt[3].y =  fButtonY[i] - fButtonHeight[i];
743                 vt[3].z =  -0.5f;
744                 vt[3].s = 0.0f;
745                 vt[3].t = 0.0f;
746                 c = QVector4D(1.0, 1.0, 1.0, 1.0);
747                 if(uButtonTextureID[i] == NULL) continue;
748                 drawMain(button_shader, vertex_button[i],
749                                  buffer_button_vertex[i],
750                                  vt,
751                                  uButtonTextureID[i]->textureId(),
752                                  c, false);
753         }
754 }
755
756
757 void GLDraw_2_0::drawBitmapTexture(void)
758 {
759         if(using_flags->is_use_one_board_computer()) {
760                 QVector4D c;
761                 c = QVector4D(1.0, 1.0, 1.0, 1.0);
762                 if(uBitmapTextureID == NULL) return;
763                 drawMain(bitmap_shader, vertex_bitmap,
764                                  buffer_bitmap_vertex,
765                                  vertexBitmap,
766                                  uBitmapTextureID->textureId(),
767                                  c, false);
768         }
769 }
770
771 void GLDraw_2_0::drawScreenTexture(void)
772 {
773         if(using_flags->is_use_one_board_computer()) {
774                 if(uBitmapTextureID != NULL) {
775                         extfunc_2->glEnable(GL_BLEND);
776                         extfunc_2->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
777                 }
778         } else {
779                 extfunc_2->glDisable(GL_BLEND);
780         }
781         if(uVramTextureID == NULL) return;
782         QVector4D color;
783         smoosing = p_config->use_opengl_filters;
784         if(set_brightness) {
785                 color = QVector4D(fBrightR, fBrightG, fBrightB, 1.0);
786         } else {
787                 color = QVector4D(1.0, 1.0, 1.0, 1.0);
788         }                       
789         if(using_flags->is_use_one_board_computer()) {
790                 QVector3D cc = QVector3D(0.0, 0.0, 0.0);
791                 drawMain(main_shader, vertex_screen,
792                                  buffer_screen_vertex,
793                                  vertexFormat,
794                                  uVramTextureID->textureId(), // v2.0
795                                  color, smoosing,
796                                  true, cc);
797                 extfunc_2->glDisable(GL_BLEND);
798         } else{
799                 drawMain(main_shader, vertex_screen,
800                                  buffer_screen_vertex,
801                                  vertexFormat,
802                                  uVramTextureID->textureId(), // v2.0
803                                  color, smoosing);
804         }               
805 }
806
807 void GLDraw_2_0::drawMain(QOpenGLShaderProgram *prg,
808                                                   QOpenGLVertexArrayObject *vp,
809                                                   QOpenGLBuffer *bp,
810                                                   VertexTexCoord_t *vertex_data,
811                                                   GLuint texid,
812                                                   QVector4D color,
813                                                   bool f_smoosing,
814                                                   bool do_chromakey,
815                                                   QVector3D chromakey)
816                                                    
817 {
818         if(texid != 0) {
819                 QImage *p = imgptr;
820                 extfunc_2->glEnable(GL_TEXTURE_2D);
821
822                 extfunc_2->glViewport(0, 0, p_wid->width(), p_wid->height());
823                 extfunc_2->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
824                 extfunc_2->glBindTexture(GL_TEXTURE_2D, texid);
825
826                 if(!f_smoosing) {
827                         extfunc_2->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
828                         extfunc_2->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
829                 } else {
830                         extfunc_2->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
831                         extfunc_2->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
832                 }
833
834                 if((bp != NULL) && (vp != NULL) && (prg != NULL)) {
835                         if((bp->isCreated()) && (vp->isCreated()) && (prg->isLinked())) {
836                                 bp->bind();
837                                 vp->bind();
838                                 prg->bind();
839                                 prg->setUniformValue("a_texture", 0);
840                                 prg->setUniformValue("color", color);
841                                 //prg->setUniformValue("tex_width",  (float)screen_texture_width); 
842                                 //prg->setUniformValue("tex_height", (float)screen_texture_height);
843                                 if(p != NULL) {
844                                         prg->setUniformValue("tex_width",  (float)p->width()); 
845                                         prg->setUniformValue("tex_height", (float)p->height());
846                                 }
847                                 QMatrix2x2 rot;
848                                 switch(p_config->rotate_type) {
849                                 case 0:
850                                         rot = QMatrix2x2(rot0);
851                                         break;
852                                 case 1:
853                                         rot = QMatrix2x2(rot90);
854                                         break;
855                                 case 2:
856                                         rot = QMatrix2x2(rot180);
857                                         break;
858                                 case 3:
859                                         rot = QMatrix2x2(rot270);
860                                         break;
861                                 default:
862                                         rot = QMatrix2x2(rot0);
863                                         break;
864                                 }
865                                 prg->setUniformValue("rotate_mat", rot);
866                                 if(do_chromakey) {
867                                         prg->setUniformValue("chromakey", chromakey);
868                                         prg->setUniformValue("do_chromakey", GL_TRUE);
869                                 } else {
870                                         prg->setUniformValue("do_chromakey", GL_FALSE);
871                                 }                       
872                                 int vertex_loc = prg->attributeLocation("vertex");
873                                 int texcoord_loc = prg->attributeLocation("texcoord");
874                                 prg->setAttributeBuffer(vertex_loc, GL_FLOAT, 0, 3, sizeof(VertexTexCoord_t));
875                                 prg->setAttributeBuffer(texcoord_loc, GL_FLOAT, 3 * sizeof(GLfloat), 2, sizeof(VertexTexCoord_t));
876                                 prg->enableAttributeArray(vertex_loc);
877                                 prg->enableAttributeArray(texcoord_loc);
878                                 
879                                 extfunc_2->glDisable(GL_DEPTH_TEST);
880                                 extfunc_2->glEnableClientState(GL_VERTEX_ARRAY);
881                                 extfunc_2->glEnableClientState(GL_TEXTURE_COORD_ARRAY);
882                                 extfunc_2->glColor3f(1.0f, 1.0f, 1.0f);
883                                 
884                                 extfunc_2->glVertexPointer(3, GL_FLOAT, sizeof(VertexTexCoord_t), (void *)0);
885                                 extfunc_2->glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTexCoord_t), (void *)(0 + 3 * sizeof(GLfloat)));
886                                 extfunc_2->glDrawArrays(GL_POLYGON, 0, 4);
887                                 extfunc_2->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
888                                 extfunc_2->glDisableClientState(GL_VERTEX_ARRAY);
889                                 
890                                 bp->release();
891                                 vp->release();
892                                 prg->release();
893                                 extfunc_2->glBindTexture(GL_TEXTURE_2D, 0);
894                                 extfunc_2->glDisable(GL_TEXTURE_2D);
895                                 return;
896                         }
897                 }
898                 
899                 { // Fallback
900                         int i;
901                         extfunc_2->glDisable(GL_DEPTH_TEST);
902                         extfunc_2->glBegin(GL_POLYGON);
903                         for(i = 0; i < 4; i++) {
904                                 extfunc_2->glTexCoord2f(vertex_data[i].s, vertex_data[i].t);
905                                 extfunc_2->glVertex3f(vertex_data[i].x, vertex_data[i].y, vertex_data[i].z);
906                         }
907                         extfunc_2->glEnd();
908                         extfunc_2->glBindTexture(GL_TEXTURE_2D, 0);
909                         extfunc_2->glDisable(GL_TEXTURE_2D);
910                 }
911         }
912 }
913
914 void GLDraw_2_0::uploadBitmapTexture(QImage *p)
915 {
916         if(!using_flags->is_use_one_board_computer()) return;
917         if(p == NULL) return;
918         if(!bitmap_uploaded) {
919                 p_wid->makeCurrent();
920                 if(uBitmapTextureID != NULL) {
921                         delete uBitmapTextureID;
922                 }
923                 uBitmapTextureID = new QOpenGLTexture(*p);
924                 p_wid->doneCurrent();
925                 bitmap_uploaded = true;
926                 crt_flag = true;
927         }
928 }
929
930 void GLDraw_2_0::uploadIconTexture(QPixmap *p, int icon_type, int localnum)
931 {
932         if((icon_type >  8) || (icon_type < 0)) return;
933         if((localnum  >= 9) || (localnum  <  0)) return;
934         if(p == NULL) return;
935         p_wid->makeCurrent();
936         QImage image = p->toImage();
937
938         if(icon_texid[icon_type][localnum] != NULL) delete icon_texid[icon_type][localnum];
939         {
940                 icon_texid[icon_type][localnum] = new QOpenGLTexture(image);
941         }
942         p_wid->doneCurrent();
943
944 }
945
946 void GLDraw_2_0::updateBitmap(QImage *p)
947 {
948         if(!using_flags->is_use_one_board_computer()) return;
949         redraw_required = true;
950         bitmap_uploaded = false;
951         uploadBitmapTexture(p);
952 }
953
954 void GLDraw_2_0::uploadMainTexture(QImage *p, bool use_chromakey, bool was_mapped)
955 {
956         // set vertex
957         redraw_required = true;
958         imgptr = p;
959         if(p == NULL) return;
960         {
961                 // Upload to main texture
962                 if(uVramTextureID == NULL) {
963                         uVramTextureID = new QOpenGLTexture(*p);
964                 }
965                 extfunc_2->glBindTexture(GL_TEXTURE_2D, uVramTextureID->textureId());
966                 extfunc_2->glTexSubImage2D(GL_TEXTURE_2D, 0,
967                                                                  0, 0,
968                                                                  p->width(), p->height(),
969                                                                  GL_RGBA, GL_UNSIGNED_BYTE, p->constBits());
970                 extfunc_2->glBindTexture(GL_TEXTURE_2D, 0);
971         }
972         crt_flag = true;
973 }
974
975 void GLDraw_2_0::resizeGL_Screen(void)
976 {
977         if(buffer_screen_vertex->isCreated()) {
978                 setNormalVAO(main_shader, vertex_screen,
979                                          buffer_screen_vertex,
980                                          vertexFormat, 4);
981         }
982 }       
983
984 void GLDraw_2_0::resizeGL_SetVertexs(void)
985 {
986         vertexFormat[0].x = -screen_width;
987         vertexFormat[0].y = -screen_height;
988         vertexFormat[1].x = +screen_width;
989         vertexFormat[1].y = -screen_height;
990         vertexFormat[2].x = +screen_width;
991         vertexFormat[2].y = +screen_height;
992         vertexFormat[3].x = -screen_width;
993         vertexFormat[3].y = +screen_height;
994         
995         if(using_flags->is_use_one_board_computer()) {
996 #if !defined(BITMAP_OFFSET_X)
997                 #define BITMAP_OFFSET_X 0
998 #endif     
999 #if !defined(BITMAP_OFFSET_Y)
1000                 #define BITMAP_OFFSET_Y 0
1001 #endif     
1002                         vertexBitmap[0].x = -1.0f;
1003                         vertexBitmap[0].y = -1.0f;
1004                         
1005                         vertexBitmap[1].x = 1.0f - (float)BITMAP_OFFSET_X / (float)using_flags->get_screen_width();
1006                         vertexBitmap[1].y = -1.0f;
1007                         
1008                         vertexBitmap[2].x = 1.0f - (float)BITMAP_OFFSET_X / (float)using_flags->get_screen_width();
1009                         vertexBitmap[2].y = 1.0f - (float)BITMAP_OFFSET_Y * 2.0 / (float)using_flags->get_screen_height();
1010                         
1011                         vertexBitmap[3].x = -1.0f;
1012                         vertexBitmap[3].y = 1.0f - (float)BITMAP_OFFSET_Y * 2.0 / (float)using_flags->get_screen_height();
1013                         
1014         }
1015 }
1016
1017 void GLDraw_2_0::resizeGL(int width, int height)
1018 {
1019         //int side = qMin(width, height);
1020         p_wid->makeCurrent();
1021         extfunc_2->glViewport(0, 0, width, height);
1022         extfunc_2->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
1023         crt_flag = true;
1024         if(!using_flags->is_use_one_board_computer() && (using_flags->get_max_button() <= 0)) {
1025                 doSetGridsHorizonal(vert_lines, true);
1026                 if(using_flags->is_use_vertical_pixel_lines()) {
1027                         doSetGridsVertical(horiz_pixels, true);
1028                 }
1029         }
1030         resizeGL_SetVertexs();
1031         resizeGL_Screen();
1032         if(using_flags->is_use_one_board_computer()) {
1033                 if(vertex_bitmap != NULL) {
1034                         if(vertex_bitmap->isCreated()) {
1035                                 setNormalVAO(bitmap_shader, vertex_bitmap,
1036                                                          buffer_bitmap_vertex,
1037                                                          vertexBitmap, 4);
1038                         }
1039                 }
1040         }
1041
1042         if(using_flags->get_max_button() > 0) {
1043                 updateButtonTexture();
1044         }
1045         p_wid->doneCurrent();
1046 }
1047
1048 void GLDraw_2_0::paintGL(void)
1049 {
1050         //p_wid->makeCurrent();
1051         //if(crt_flag || redraw_required) { //return;
1052                 if(emu_launched) {
1053                         crt_flag = false;
1054                 }
1055                 redraw_required = false;
1056                 extfunc_2->glViewport(0, 0, p_wid->width(), p_wid->height());
1057                 extfunc_2->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
1058                 
1059                 extfunc_2->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1060                 //extfunc_2->glDisable(GL_DEPTH_TEST);
1061                 extfunc_2->glEnable(GL_DEPTH_TEST);
1062                 extfunc_2->glDisable(GL_BLEND);
1063                 if(using_flags->is_use_one_board_computer() || using_flags->is_use_bitmap()) {
1064                         drawBitmapTexture();
1065                 }
1066                 if((using_flags->get_max_button() > 0)) {
1067                         drawButtons();
1068                 }
1069                 /*
1070                  * VRAMの表示:テクスチャ貼った四角形
1071                  */
1072                 drawScreenTexture();
1073                 extfunc_2->glDisable(GL_BLEND);
1074                 if(!using_flags->is_use_one_board_computer() && (using_flags->get_max_button() <= 0)) {
1075                         drawGrids();
1076                 }
1077                 if(p_config->use_osd_virtual_media) drawOsdIcons();
1078                 extfunc_2->glFlush();
1079 }
1080
1081 void GLDraw_2_0::paintGL_OffScreen(int count, int w, int h)
1082 {
1083         rec_count += count;
1084         rec_width  = w;
1085         rec_height = h;
1086 }
1087
1088 void GLDraw_2_0::do_set_screen_multiply(float mul)
1089 {
1090         screen_multiply = mul;
1091         do_set_texture_size(imgptr, screen_texture_width, screen_texture_height);
1092         //do_set_texture_size(imgptr, -1, -1);
1093 }
1094
1095
1096 void GLDraw_2_0::do_set_texture_size(QImage *p, int w, int h)
1097 {
1098         if(w <= 0) w = using_flags->get_real_screen_width();
1099         if(h <= 0) h = using_flags->get_real_screen_height();
1100         float iw;
1101         float ih;
1102         imgptr = p;
1103         if(p != NULL) {
1104                 iw = (float)p->width();
1105                 ih = (float)p->height();
1106         } else {
1107                 iw = (float)using_flags->get_real_screen_width();
1108                 ih = (float)using_flags->get_real_screen_height();
1109         }
1110         screen_texture_width = w;
1111         screen_texture_height = h;
1112
1113         if(p_wid != NULL) {
1114                 p_wid->makeCurrent();
1115                 vertexFormat[0].s = 0.0f;
1116                 vertexFormat[0].t = (float)h / ih;
1117                 vertexFormat[1].s = (float)w / iw;
1118                 vertexFormat[1].t = (float)h / ih;
1119                 vertexFormat[2].s = (float)w / iw;
1120                 vertexFormat[2].t = 0.0f;
1121                 vertexFormat[3].s = 0.0f;
1122                 vertexFormat[3].t = 0.0f;
1123                 setNormalVAO(main_shader, vertex_screen,
1124                                          buffer_screen_vertex,
1125                                          vertexFormat, 4);
1126                 p_wid->doneCurrent();
1127         }               
1128         if(w > using_flags->get_real_screen_width()) {
1129                 w = using_flags->get_real_screen_width();
1130         }                       
1131         if(h > using_flags->get_real_screen_height()) {
1132                 h = using_flags->get_real_screen_height();
1133         }
1134         this->doSetGridsVertical(w, false);
1135         this->doSetGridsHorizonal(h, false);
1136
1137 }
1138
1139 void GLDraw_2_0::do_set_horiz_lines(int lines)
1140 {
1141         if(lines > using_flags->get_real_screen_height()) {
1142                 lines = using_flags->get_real_screen_height();
1143         }
1144         this->doSetGridsHorizonal(lines, false);
1145 }
1146
1147 void GLDraw_2_0::do_set_led_width(int bitwidth)
1148 {
1149         if((bitwidth >= 0) && (bitwidth < 32)) osd_led_bit_width = bitwidth;
1150         printf("%d\n", bitwidth);
1151 }