OSDN Git Service

[UI][Qt] Not liking config, using_flags directly.
[csp-qt/common_source_project-fm7.git] / source / src / qt / gui / 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 <QOpenGLFramebufferObject>
14 #include <QColor>
15
16 #include "qt_gldraw.h"
17 #include "agar_logger.h"
18 #include "qt_glutil_gl2_0.h"
19 #include "menu_flags.h"
20
21 //extern USING_FLAGS *using_flags;
22
23
24 GLDraw_2_0::GLDraw_2_0(GLDrawClass *parent, USING_FLAGS *p, EMU *emu) : QObject(parent)
25 {
26         p_wid = parent;
27         p_emu = emu;
28         using_flags = p;
29         
30         gl_grid_horiz = false;
31         gl_grid_vert = false;
32         glVertGrids = NULL;
33         glHorizGrids = NULL;
34
35         vert_lines = using_flags->get_screen_height();
36         horiz_pixels = using_flags->get_screen_width();
37         set_brightness = false;
38         crt_flag = false;
39         smoosing = false;
40         uVramTextureID = 0;
41
42         imgptr = NULL;
43         screen_multiply = 1.0f;
44         screen_texture_width = using_flags->get_screen_width();
45         screen_texture_width_old = using_flags->get_screen_width();
46         screen_texture_height = using_flags->get_screen_height();
47         screen_texture_height_old = using_flags->get_screen_height();
48         p_emu = emu;
49         extfunc = NULL;
50         redraw_required = false;
51
52         uBitmapTextureID = 0;
53         bitmap_uploaded = false;
54         int i;
55         // Will fix: Must fix setup of vm_buttons[].
56         button_desc_t *vm_buttons_d = using_flags->get_vm_buttons();
57         if(vm_buttons_d != NULL) {
58                 for(i = 0; i < using_flags->get_max_button(); i++) {
59 # if defined(_USE_GLAPI_QT5_4)   
60                         uButtonTextureID[i] = new QOpenGLTexture(QOpenGLTexture::Target2D);
61 # else     
62                         uButtonTextureID[i] = 0;
63 # endif
64                         fButtonX[i] = -1.0 + (float)(vm_buttons_d[i].x * 2) / (float)using_flags->get_screen_width();
65                         fButtonY[i] = 1.0 - (float)(vm_buttons_d[i].y * 2) / (float)using_flags->get_screen_height();
66                         fButtonWidth[i] = (float)(vm_buttons_d[i].width * 2) / (float)using_flags->get_screen_width();
67                         fButtonHeight[i] = (float)(vm_buttons_d[i].height * 2) / (float)using_flags->get_screen_height();
68                 } // end of will fix.
69         }
70         button_updated = false;
71         button_drawn = false;
72
73         fBrightR = 1.0; // 輝度の初期化
74         fBrightG = 1.0;
75         fBrightB = 1.0;
76         set_brightness = false;
77         crt_flag = false;
78         smoosing = false;
79         
80         gl_grid_horiz = false;
81         gl_grid_vert = false;
82
83         vert_lines = using_flags->get_screen_height();
84         horiz_pixels = using_flags->get_screen_width();
85         screen_width = 1.0;
86         screen_height = 1.0;
87
88         offscreen_frame_buffer = NULL;
89         offscreen_frame_buffer_format = NULL;
90         rec_count = 0;
91         rec_width  = using_flags->get_screen_width();
92         rec_height = using_flags->get_screen_height();
93
94 }
95
96 GLDraw_2_0::~GLDraw_2_0()
97 {
98         if(buffer_screen_vertex->isCreated()) buffer_screen_vertex->destroy();
99         if(vertex_screen->isCreated()) vertex_screen->destroy();
100         if(glVertGrids != NULL) free(glVertGrids);
101         if(glHorizGrids != NULL) free(glHorizGrids);
102         if(using_flags->is_use_one_board_computer()) {
103                 if(uBitmapTextureID != 0) {
104                         p_wid->deleteTexture(uBitmapTextureID);
105                 }
106         }
107         if(using_flags->get_max_button() > 0) {
108                 int i;
109                 for(i = 0; i < using_flags->get_max_button() > 0; i++) {
110                         if(uButtonTextureID[i] != 0) p_wid->deleteTexture(uButtonTextureID[i]);
111                 }
112                 for(i = 0; i < using_flags->get_max_button(); i++) {
113                         if(vertex_button[i]->isCreated()) vertex_button[i]->destroy();
114                 }
115         }
116
117         if(using_flags->is_use_one_board_computer()) {
118                 if(vertex_bitmap->isCreated()) vertex_bitmap->destroy();
119         }
120         if(extfunc != NULL) delete extfunc;
121 }
122
123 void GLDraw_2_0::initializeGL(void)
124 {
125 }
126
127 void GLDraw_2_0::setNormalVAO(QOpenGLShaderProgram *prg,
128                                                            QOpenGLVertexArrayObject *vp,
129                                                            QOpenGLBuffer *bp,
130                                                            VertexTexCoord_t *tp,
131                                                            int size)
132 {
133         int vertex_loc = prg->attributeLocation("vertex");
134         int texcoord_loc = prg->attributeLocation("texcoord");
135
136         if(bp == NULL) return;
137         if(prg == NULL) return;
138         if(!bp->isCreated()) return;
139
140         bp->bind();
141         bp->write(0, tp, sizeof(VertexTexCoord_t) * size);
142         prg->setAttributeBuffer(vertex_loc, GL_FLOAT, 0, 3, sizeof(VertexTexCoord_t));
143         prg->setAttributeBuffer(texcoord_loc, GL_FLOAT, 3 * sizeof(GLfloat), 2, sizeof(VertexTexCoord_t));
144         bp->release();
145
146         prg->setUniformValue("a_texture", 0);
147                            
148 }
149
150 void GLDraw_2_0::setChangeBrightness(bool flag)
151 {
152         set_brightness = flag;
153 }
154
155 void GLDraw_2_0::setBrightness(GLfloat r, GLfloat g, GLfloat b)
156 {
157         fBrightR = r;
158         fBrightG = g;
159         fBrightB = b;
160 }
161
162 void GLDraw_2_0::setImgPtr(QImage *p)
163 {
164         imgptr = p;
165 }
166
167 void GLDraw_2_0::setSmoosing(bool flag)
168 {
169         smoosing = flag;
170         crt_flag = true;
171 }
172
173 void GLDraw_2_0::setVirtualVramSize(int width, int height)
174 {
175         vert_lines = height;
176         horiz_pixels = width;
177         crt_flag = true;
178 }
179
180 void GLDraw_2_0::setEmuPtr(EMU *p)
181 {
182         p_emu = p;
183 }
184
185 void GLDraw_2_0::setDrawGLGridVert(bool flag)
186 {
187         gl_grid_vert = flag;
188         crt_flag = true;
189 }
190
191 void GLDraw_2_0::setDrawGLGridHoriz(bool flag)
192 {
193         gl_grid_vert = flag;
194         crt_flag = true;
195 }
196
197 void GLDraw_2_0::initGLObjects()
198 {
199         extfunc = new QOpenGLFunctions_2_0;
200         extfunc->initializeOpenGLFunctions();
201         extfunc->glViewport(0, 0, p_wid->width(), p_wid->height());
202         extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
203 }       
204
205 void GLDraw_2_0::initFBO(void)
206 {
207         if(using_flags->is_use_one_board_computer()) {
208                 bitmap_shader = new QOpenGLShaderProgram(p_wid);
209                 if(bitmap_shader != NULL) {
210                         bitmap_shader->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/vertex_shader.glsl");
211                         bitmap_shader->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/normal_fragment_shader.glsl");
212                         bitmap_shader->link();
213                 }
214         }
215         if(using_flags->get_max_button() > 0) {
216                 button_shader = new QOpenGLShaderProgram(p_wid);
217                 if(button_shader != NULL) {
218                         button_shader->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/vertex_shader.glsl");
219                         button_shader->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/normal_fragment_shader.glsl");
220                         button_shader->link();
221                 }
222         }
223         glHorizGrids = (GLfloat *)malloc(sizeof(float) * (using_flags->get_screen_height() + 2) * 6);
224         if(glHorizGrids != NULL) {
225                 doSetGridsHorizonal(using_flags->get_screen_height(), true);
226         }
227         glVertGrids  = (GLfloat *)malloc(sizeof(float) * (using_flags->get_screen_width() + 2) * 6);
228         if(glVertGrids != NULL) {
229                 doSetGridsVertical(using_flags->get_screen_width(), true);
230         }
231         // Will fix around vm_buttons[].
232         button_desc_t *vm_buttons_d = using_flags->get_vm_buttons();
233         if(vm_buttons_d != NULL) {
234                 if(using_flags->get_max_button() > 0) {
235                         vertexButtons = new QVector<VertexTexCoord_t>;
236                         int i;
237                         
238                         for(i = 0; i < using_flags->get_max_button(); i++) {
239                                 buffer_button_vertex[i] = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
240                                 buffer_button_vertex[i]->create();
241                                 fButtonX[i] = -1.0 + (float)(vm_buttons_d[i].x * 2) / (float)using_flags->get_screen_width();
242                                 fButtonY[i] = 1.0 - (float)(vm_buttons_d[i].y * 2) / (float)using_flags->get_screen_height();
243                                 fButtonWidth[i] = (float)(vm_buttons_d[i].width * 2) / (float)using_flags->get_screen_width();
244                                 fButtonHeight[i] = (float)(vm_buttons_d[i].height * 2) / (float)using_flags->get_screen_height();
245                            
246                                 vertex_button[i] = new QOpenGLVertexArrayObject;
247                                 if(vertex_button[i] != NULL) {
248                                         if(vertex_button[i]->create()) {
249                                                 VertexTexCoord_t vt[4];
250
251                                                 vt[0].x =  fButtonX[i];
252                                                 vt[0].y =  fButtonY[i];
253                                                 vt[0].z =  -0.5f;
254                                                 vt[0].s = 0.0f;
255                                                 vt[0].t = 1.0f;
256                                                 
257                                                 vt[1].x =  fButtonX[i] + fButtonWidth[i];
258                                                 vt[1].y =  fButtonY[i];
259                                                 vt[1].z =  -0.5f;
260                                                 vt[1].s = 1.0f;
261                                                 vt[1].t = 1.0f;
262                                                 
263                                                 vt[2].x =  fButtonX[i] + fButtonWidth[i];
264                                                 vt[2].y =  fButtonY[i] - fButtonHeight[i];
265                                                 vt[2].z =  -0.5f;
266                                                 vt[2].s = 1.0f;
267                                                 vt[2].t = 0.0f;
268                                                 
269                                                 vt[3].x =  fButtonX[i];
270                                                 vt[3].y =  fButtonY[i] - fButtonHeight[i];
271                                                 vt[3].z =  -0.5f;
272                                                 vt[3].s = 0.0f;
273                                                 vt[3].t = 0.0f;
274                                 
275                                                 vertexButtons->append(vt[0]);
276                                                 vertexButtons->append(vt[1]);
277                                                 vertexButtons->append(vt[2]);
278                                                 vertexButtons->append(vt[3]);
279                                                 vertex_button[i]->bind();
280                                                 buffer_button_vertex[i]->bind();
281                                                 buffer_button_vertex[i]->allocate(4 * sizeof(VertexTexCoord_t));
282                                                 
283                                                 buffer_button_vertex[i]->setUsagePattern(QOpenGLBuffer::StaticDraw);
284                                                 buffer_button_vertex[i]->release();
285                                                 vertex_button[i]->release();
286                                                 setNormalVAO(button_shader, vertex_button[i],
287                                                                          buffer_button_vertex[i],
288                                                                          vt, 4);
289                                         }
290                                 }
291                         }
292                 }
293         }
294         if(using_flags->is_use_one_board_computer()) {
295            buffer_bitmap_vertex = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
296            vertex_bitmap = new QOpenGLVertexArrayObject;
297            vertexBitmap[0].x = -1.0f;
298            vertexBitmap[0].y = -1.0f;
299            vertexBitmap[0].z = -0.1f;
300            vertexBitmap[0].s = 0.0f;
301            vertexBitmap[0].t = 0.0f;
302            
303            vertexBitmap[1].x = +1.0f;
304            vertexBitmap[1].y = -1.0f;
305            vertexBitmap[1].z = -0.1f;
306            vertexBitmap[1].s = 1.0f;
307            vertexBitmap[1].t = 0.0f;
308            
309            vertexBitmap[2].x = +1.0f;
310            vertexBitmap[2].y = +1.0f;
311            vertexBitmap[2].z = -0.1f;
312            vertexBitmap[2].s = 1.0f;
313            vertexBitmap[2].t = 1.0f;
314            
315            vertexBitmap[3].x = -1.0f;
316            vertexBitmap[3].y = +1.0f;
317            vertexBitmap[3].z = -0.1f;
318            vertexBitmap[3].s = 0.0f;
319            vertexBitmap[3].t = 1.0f;
320            
321            if(vertex_bitmap != NULL) {
322                    if(vertex_bitmap->create()) {
323                            buffer_bitmap_vertex->create();
324                            buffer_bitmap_vertex->setUsagePattern(QOpenGLBuffer::StaticDraw);
325                            
326                            {
327                                    QVector4D c;
328                                    c = QVector4D(1.0, 1.0, 1.0, 1.0);
329                                    bitmap_shader->setUniformValue("color", c);
330                            }
331                            vertex_bitmap->bind();
332                            buffer_bitmap_vertex->bind();
333                            buffer_bitmap_vertex->allocate(sizeof(vertexBitmap));
334                            buffer_bitmap_vertex->release();
335                            vertex_bitmap->release();
336                            setNormalVAO(bitmap_shader, vertex_bitmap,
337                                                         buffer_bitmap_vertex,
338                                                         vertexBitmap, 4);
339                    }
340            }
341         }
342         // Init view
343         extfunc->glClearColor(0.0, 0.0, 0.0, 1.0);
344 }
345
346 void GLDraw_2_0::initLocalGLObjects(void)
347 {
348         main_shader = new QOpenGLShaderProgram(p_wid);
349         if(main_shader != NULL) {
350                 main_shader->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/vertex_shader.glsl");
351                 main_shader->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/chromakey_fragment_shader.glsl");
352                 main_shader->link();
353         }
354         buffer_screen_vertex = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
355         vertex_screen = new QOpenGLVertexArrayObject;
356         
357         vertexFormat[0].x = -0.5f;
358         vertexFormat[0].y = -0.5f;
359         vertexFormat[0].z = -0.9f;
360         vertexFormat[0].s = 0.0f;
361         vertexFormat[0].t = 1.0f;
362                         
363         vertexFormat[1].x = +0.5f;
364         vertexFormat[1].y = -0.5f;
365         vertexFormat[1].z = -0.9f;
366         vertexFormat[1].s = 1.0f;
367         vertexFormat[1].t = 1.0f;
368                         
369         vertexFormat[2].x = +0.5f;
370         vertexFormat[2].y = +0.5f;
371         vertexFormat[2].z = -0.9f;
372         vertexFormat[2].s = 1.0f;
373         vertexFormat[2].t = 0.0f;
374         
375         vertexFormat[3].x = -0.5f;
376         vertexFormat[3].y = +0.5f;
377         vertexFormat[3].z = -0.9f;
378         vertexFormat[3].s = 0.0f;
379         vertexFormat[3].t = 0.0f;
380         if(buffer_screen_vertex != NULL) {
381                 if(buffer_screen_vertex->create()) {
382                         {
383                                 QVector4D c;
384                                 c = QVector4D(1.0, 1.0, 1.0, 1.0);
385                                 main_shader->setUniformValue("color", c);
386                         }
387                         
388                         buffer_screen_vertex->create();
389                         buffer_screen_vertex->setUsagePattern(QOpenGLBuffer::DynamicDraw);
390                         
391                         if(vertex_screen != NULL) vertex_screen->bind();
392                         buffer_screen_vertex->bind();
393                         buffer_screen_vertex->allocate(sizeof(VertexTexCoord_t) * 4);
394                         if(vertex_screen != NULL) vertex_screen->release();
395                         buffer_screen_vertex->release();
396                         setNormalVAO(main_shader, vertex_screen,
397                                                  buffer_screen_vertex,
398                                                  vertexFormat, 4);
399                 }
400         }
401 }
402
403 void GLDraw_2_0::doSetGridsHorizonal(int lines, bool force)
404 {
405         int i;
406         GLfloat yf;
407         GLfloat delta;
408         
409         if((lines == vert_lines) && !force) return;
410         vert_lines = lines;
411         yf = -screen_height;
412         if(vert_lines <= 0) return;
413         if(vert_lines > using_flags->get_screen_height()) vert_lines = using_flags->get_screen_height();
414         
415         delta = (2.0f * screen_height) / (float)vert_lines;
416         yf = yf - delta * 1.0f;
417         if(glHorizGrids != NULL) {
418                 for(i = 0; i < (vert_lines + 1) ; i++) {
419                         glHorizGrids[i * 6]     = -screen_width; // XBegin
420                         glHorizGrids[i * 6 + 3] = +screen_width; // XEnd
421                         glHorizGrids[i * 6 + 1] = yf; // YBegin
422                         glHorizGrids[i * 6 + 4] = yf; // YEnd
423                         glHorizGrids[i * 6 + 2] = -0.95f; // ZBegin
424                         glHorizGrids[i * 6 + 5] = -0.95f; // ZEnd
425                         yf = yf + delta;
426                 }
427         }
428 }
429
430 void GLDraw_2_0::doSetGridsVertical(int pixels, bool force)
431 {
432         int i;
433         GLfloat xf;
434         GLfloat delta;
435         
436         if((pixels == horiz_pixels) && !force) return;
437         horiz_pixels = pixels;
438         if(horiz_pixels <= 0) return;
439         if(horiz_pixels > using_flags->get_screen_width()) horiz_pixels = using_flags->get_screen_width();
440         
441         xf = -screen_width;
442         delta = (2.0f * screen_width) / (float)horiz_pixels;
443         xf = xf - delta * 0.75f;
444         if(glVertGrids != NULL) {
445                 if(horiz_pixels > using_flags->get_screen_width()) horiz_pixels = using_flags->get_screen_width();
446                 for(i = 0; i < (horiz_pixels + 1) ; i++) {
447                         glVertGrids[i * 6]     = xf; // XBegin
448                         glVertGrids[i * 6 + 3] = xf; // XEnd
449                         glVertGrids[i * 6 + 1] = -screen_height; // YBegin
450                         glVertGrids[i * 6 + 4] =  screen_height; // YEnd
451                         glVertGrids[i * 6 + 2] = -0.95f; // ZBegin
452                         glVertGrids[i * 6 + 5] = -0.95f; // ZEnd
453                         xf = xf + delta;
454                 }
455         }
456 }
457 void GLDraw_2_0::drawGridsMain(GLfloat *tp,
458                                                            int number,
459                                                            GLfloat lineWidth,
460                                                            QVector4D color)
461 {
462         if(number <= 0) return;
463         extfunc->glDisable(GL_TEXTURE_2D);
464         extfunc->glDisable(GL_DEPTH_TEST);
465         extfunc->glDisable(GL_BLEND);
466         { 
467                 if(tp != NULL) {
468                         int i;
469                         int p = 0;
470                         extfunc->glColor4f(color.x(), color.y(), color.z(), color.w());
471                         extfunc->glLineWidth(lineWidth);
472                         extfunc->glBegin(GL_LINES);
473                         for(i = 0; i < (number + 1); i++) {
474                                 extfunc->glVertex3f(tp[p + 0], tp[p + 1], tp[p + 2]);
475                                 extfunc->glVertex3f(tp[p + 3], tp[p + 4], tp[p + 5]);
476                                 p += 6;
477                         }
478                         extfunc->glEnd();
479                 }
480         }
481 }
482
483 void GLDraw_2_0::drawGridsHorizonal(void)
484 {
485         QVector4D c= QVector4D(0.0f, 0.0f, 0.0f, 1.0f);
486         drawGridsMain(glHorizGrids,
487                                   vert_lines,
488                                   0.15f,
489                                   c);
490 }
491
492 void GLDraw_2_0::drawGridsVertical(void)
493 {
494         QVector4D c= QVector4D(0.0f, 0.0f, 0.0f, 1.0f);
495         drawGridsMain(glVertGrids,
496                                   horiz_pixels,
497                                   0.5f,
498                                   c);
499 }
500
501
502 void GLDraw_2_0::drawGrids(void)
503 {
504         gl_grid_horiz = using_flags->get_config_ptr()->opengl_scanline_horiz;
505         gl_grid_vert  = using_flags->get_config_ptr()->opengl_scanline_vert;
506         if(gl_grid_horiz && (vert_lines > 0)) {
507                 drawGridsHorizonal();
508         } // Will fix.
509         if(using_flags->is_use_vertical_pixel_lines()) {
510                 if(gl_grid_vert && (horiz_pixels > 0)) {
511                         drawGridsVertical();
512                 }
513         }
514 }
515
516 void GLDraw_2_0::updateButtonTexture(void)
517 {
518         int i;
519         QImage *img;
520         QPainter *painter;
521         QColor col;
522         QRect rect;
523         QPen *pen;
524         QFont font = QFont(QString::fromUtf8("Sans"));
525         if(button_updated) return;
526         col.setRgb(0, 0, 0, 255);
527         pen = new QPen(col);
528         button_desc_t *vm_buttons_d = using_flags->get_vm_buttons();
529         if(vm_buttons_d != NULL) {
530                 for(i = 0; i < using_flags->get_max_button(); i++) {
531                         img = new QImage(vm_buttons_d[i].width * 4, vm_buttons_d[i].height * 4, QImage::Format_RGB32);
532                         painter = new QPainter(img);
533                         painter->setRenderHint(QPainter::Antialiasing, true);
534                         col.setRgb(255, 255, 255, 255);
535                         if(strlen(vm_buttons_d[i].caption) <= 3) {
536                                 font.setPixelSize((vm_buttons_d[i].width * 4) / 2); 
537                         } else {
538                                 font.setPixelSize((vm_buttons_d[i].width * 4) / 4); 
539                         }
540                         painter->fillRect(0, 0, vm_buttons_d[i].width * 4, vm_buttons_d[i].height * 4, col);
541                         painter->setFont(font);
542                         //painter->setPen(pen);
543                         rect.setWidth(vm_buttons_d[i].width * 4);
544                         rect.setHeight(vm_buttons_d[i].height * 4);
545                         rect.setX(0);
546                         rect.setY(0);
547                         painter->drawText(rect, Qt::AlignCenter, QString::fromUtf8(vm_buttons_d[i].caption));
548                         if(uButtonTextureID[i] != 0) {
549                                 p_wid->deleteTexture(uButtonTextureID[i]);
550                         }
551                         uButtonTextureID[i] = p_wid->bindTexture(*img);
552                         delete painter;
553                         delete img;
554                 }
555         }
556         delete pen;
557         button_updated = true;
558 }
559
560 void GLDraw_2_0::drawButtons()
561 {
562         int i;
563         //updateButtonTexture();
564         for(i = 0; i < using_flags->get_max_button(); i++) {
565                 QVector4D c;
566                 VertexTexCoord_t vt[4];
567                 vt[0].x =  fButtonX[i];
568                 vt[0].y =  fButtonY[i];
569                 vt[0].z =  -0.5f;
570                 vt[0].s = 0.0f;
571                 vt[0].t = 1.0f;
572                 
573                 vt[1].x =  fButtonX[i] + fButtonWidth[i];
574                 vt[1].y =  fButtonY[i];
575                 vt[1].z =  -0.5f;
576                 vt[1].s = 1.0f;
577                 vt[1].t = 1.0f;
578                 
579                 vt[2].x =  fButtonX[i] + fButtonWidth[i];
580                 vt[2].y =  fButtonY[i] - fButtonHeight[i];
581                 vt[2].z =  -0.5f;
582                 vt[2].s = 1.0f;
583                 vt[2].t = 0.0f;
584                 
585                 vt[3].x =  fButtonX[i];
586                 vt[3].y =  fButtonY[i] - fButtonHeight[i];
587                 vt[3].z =  -0.5f;
588                 vt[3].s = 0.0f;
589                 vt[3].t = 0.0f;
590                 c = QVector4D(1.0, 1.0, 1.0, 1.0);
591                 drawMain(button_shader, vertex_button[i],
592                                  buffer_button_vertex[i],
593                                  vt,
594                                  uButtonTextureID[i],
595                                  c, false);
596         }
597 }
598
599
600 void GLDraw_2_0::drawBitmapTexture(void)
601 {
602         if(using_flags->is_use_one_board_computer()) {
603                 QVector4D c;
604                 c = QVector4D(1.0, 1.0, 1.0, 1.0);
605                 drawMain(bitmap_shader, vertex_bitmap,
606                                  buffer_bitmap_vertex,
607                                  vertexBitmap,
608                                  uBitmapTextureID,
609                                  c, false);
610         }
611 }
612
613 void GLDraw_2_0::drawScreenTexture(void)
614 {
615         if(using_flags->is_use_one_board_computer()) {
616                 if(uBitmapTextureID != 0) {
617                         extfunc->glEnable(GL_BLEND);
618                         extfunc->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
619                 }
620         } else {
621                 extfunc->glDisable(GL_BLEND);
622         }
623         
624         QVector4D color;
625         smoosing = using_flags->get_config_ptr()->use_opengl_filters;
626         if(set_brightness) {
627                 color = QVector4D(fBrightR, fBrightG, fBrightB, 1.0);
628         } else {
629                 color = QVector4D(1.0, 1.0, 1.0, 1.0);
630         }                       
631         if(using_flags->is_use_one_board_computer()) {
632                 QVector3D cc = QVector3D(0.0, 0.0, 0.0);
633                 drawMain(main_shader, vertex_screen,
634                                  buffer_screen_vertex,
635                                  vertexFormat,
636                                  uVramTextureID, // v2.0
637                                  color, smoosing,
638                                  true, cc);
639                 extfunc->glDisable(GL_BLEND);
640         } else{
641                 drawMain(main_shader, vertex_screen,
642                                  buffer_screen_vertex,
643                                  vertexFormat,
644                                  uVramTextureID, // v2.0
645                                  color, smoosing);
646         }               
647 }
648
649 void GLDraw_2_0::drawMain(QOpenGLShaderProgram *prg,
650                                                   QOpenGLVertexArrayObject *vp,
651                                                   QOpenGLBuffer *bp,
652                                                   VertexTexCoord_t *vertex_data,
653                                                   GLuint texid,
654                                                   QVector4D color,
655                                                   bool f_smoosing,
656                                                   bool do_chromakey,
657                                                   QVector3D chromakey)
658                                                    
659 {
660         if(texid != 0) {
661                 extfunc->glEnable(GL_TEXTURE_2D);
662
663                 //extfunc->glViewport(0, 0, p_wid->width(), p_wid->height());
664                 extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
665                 extfunc->glBindTexture(GL_TEXTURE_2D, texid);
666
667                 if(!f_smoosing) {
668                         extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
669                         extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
670                 } else {
671                         extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
672                         extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
673                 }
674
675                 if((bp != NULL) && (vp != NULL) && (prg != NULL)) {
676                         if((bp->isCreated()) && (vp->isCreated()) && (prg->isLinked())) {
677                                 bp->bind();
678                                 vp->bind();
679                                 prg->bind();
680                                 prg->setUniformValue("a_texture", 0);
681                                 prg->setUniformValue("color", color);
682                                 prg->setUniformValue("tex_width",  (float)screen_texture_width); 
683                                 prg->setUniformValue("tex_height", (float)screen_texture_height);
684                                 if(using_flags->is_use_screen_rotate()) {
685                                         if(using_flags->get_config_ptr()->rotate_type) {
686                                                 prg->setUniformValue("rotate", GL_TRUE);
687                                         } else {
688                                                 prg->setUniformValue("rotate", GL_FALSE);
689                                         }
690                                 } else {
691                                         prg->setUniformValue("rotate", GL_FALSE);
692                                 }
693                                 if(do_chromakey) {
694                                         prg->setUniformValue("chromakey", chromakey);
695                                         prg->setUniformValue("do_chromakey", GL_TRUE);
696                                 } else {
697                                         prg->setUniformValue("do_chromakey", GL_FALSE);
698                                 }                       
699                                 int vertex_loc = prg->attributeLocation("vertex");
700                                 int texcoord_loc = prg->attributeLocation("texcoord");
701                                 prg->setAttributeBuffer(vertex_loc, GL_FLOAT, 0, 3, sizeof(VertexTexCoord_t));
702                                 prg->setAttributeBuffer(texcoord_loc, GL_FLOAT, 3 * sizeof(GLfloat), 2, sizeof(VertexTexCoord_t));
703                                 prg->enableAttributeArray(vertex_loc);
704                                 prg->enableAttributeArray(texcoord_loc);
705                                 
706                                 extfunc->glEnableClientState(GL_VERTEX_ARRAY);
707                                 extfunc->glEnableClientState(GL_TEXTURE_COORD_ARRAY);
708                                 extfunc->glColor3f(1.0f, 1.0f, 1.0f);
709                                 
710                                 extfunc->glVertexPointer(3, GL_FLOAT, sizeof(VertexTexCoord_t), (void *)0);
711                                 extfunc->glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTexCoord_t), (void *)(0 + 3 * sizeof(GLfloat)));
712                                 extfunc->glDrawArrays(GL_POLYGON, 0, 4);
713                                 extfunc->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
714                                 extfunc->glDisableClientState(GL_VERTEX_ARRAY);
715                                 
716                                 bp->release();
717                                 vp->release();
718                                 prg->release();
719                                 extfunc->glBindTexture(GL_TEXTURE_2D, 0);
720                                 extfunc->glDisable(GL_TEXTURE_2D);
721                                 return;
722                         }
723                 }
724                 
725                 { // Fallback
726                         int i;
727                         extfunc->glBegin(GL_POLYGON);
728                         for(i = 0; i < 4; i++) {
729                                 extfunc->glTexCoord2f(vertex_data[i].s, vertex_data[i].t);
730                                 extfunc->glVertex3f(vertex_data[i].x, vertex_data[i].y, vertex_data[i].z);
731                         }
732                         extfunc->glEnd();
733                         extfunc->glBindTexture(GL_TEXTURE_2D, 0);
734                         extfunc->glDisable(GL_TEXTURE_2D);
735                 }
736         }
737 }
738
739 void GLDraw_2_0::uploadBitmapTexture(QImage *p)
740 {
741         int i;
742         if(!using_flags->is_use_one_board_computer()) return;
743         if(p == NULL) return;
744         if(!bitmap_uploaded) {
745                 if(uBitmapTextureID != 0) {
746                         p_wid->deleteTexture(uBitmapTextureID);
747                 }
748                 uBitmapTextureID = p_wid->bindTexture(*p);
749                 bitmap_uploaded = true;
750                 crt_flag = true;
751         }
752 }
753
754 void GLDraw_2_0::updateBitmap(QImage *p)
755 {
756         if(!using_flags->is_use_one_board_computer()) return;
757         redraw_required = true;
758         bitmap_uploaded = false;
759         uploadBitmapTexture(p);
760 }
761
762 void GLDraw_2_0::uploadMainTexture(QImage *p, bool use_chromakey)
763 {
764         // set vertex
765         redraw_required = true;
766         imgptr = p;
767         if(p == NULL) return;
768         {
769                 if(use_chromakey) {
770                         bool checkf = false;
771                         if(vertex_screen == NULL) {
772                                 checkf = true;
773                         } else {
774                                 if(!vertex_screen->isCreated()) checkf = true;
775                         }
776                         if(buffer_screen_vertex == NULL) {
777                                 checkf = true;
778                         } else {
779                                 if(!buffer_screen_vertex->isCreated()) checkf = true;
780                         }
781                         if(main_shader == NULL) {
782                                 checkf = true;
783                         } else {
784                                 if(!main_shader->isLinked()) checkf = true;
785                         }
786                         if(checkf) {
787                                 QColor mask = QColor(0, 0, 0, 255);
788                                 QImage pp = p->QImage::createMaskFromColor(mask.rgba(), Qt::MaskOutColor);
789                                 if(uVramTextureID == 0) {
790                                         uVramTextureID = p_wid->bindTexture(pp);
791                                 }
792                                 extfunc->glBindTexture(GL_TEXTURE_2D, uVramTextureID);
793                                 extfunc->glTexSubImage2D(GL_TEXTURE_2D, 0,
794                                                                                  0, 0,
795                                                                                  pp.width(), pp.height(),
796                                                                                  GL_BGRA, GL_UNSIGNED_BYTE, pp.constBits());
797                                 extfunc->glBindTexture(GL_TEXTURE_2D, 0);
798                                 crt_flag = true;
799                                 return;
800                         }
801                 }
802                 // Upload to main texture
803                 if(uVramTextureID == 0) {
804                         uVramTextureID = p_wid->bindTexture(*p);
805                 }
806                 extfunc->glBindTexture(GL_TEXTURE_2D, uVramTextureID);
807                 extfunc->glTexSubImage2D(GL_TEXTURE_2D, 0,
808                                                                  0, 0,
809                                                                  p->width(), p->height(),
810                                                                  GL_BGRA, GL_UNSIGNED_BYTE, p->constBits());
811                 extfunc->glBindTexture(GL_TEXTURE_2D, 0);
812         }
813         crt_flag = true;
814 }
815
816 void GLDraw_2_0::resizeGL(int width, int height)
817 {
818         int side = qMin(width, height);
819         double ww, hh;
820         int w, h;
821         extfunc->glViewport(0, 0, width, height);
822         extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
823         crt_flag = true;
824         if(!using_flags->is_use_one_board_computer() && (using_flags->get_max_button() <= 0)) {
825                 doSetGridsHorizonal(vert_lines, true);
826                 if(using_flags->is_use_vertical_pixel_lines()) {
827                         doSetGridsVertical(horiz_pixels, true);
828                 }
829         }
830         vertexFormat[0].x = -screen_width;
831         vertexFormat[0].y = -screen_height;
832         
833         vertexFormat[1].x = +screen_width;
834         vertexFormat[1].y = -screen_height;
835         
836         vertexFormat[2].x = +screen_width;
837         vertexFormat[2].y = +screen_height;
838         
839         vertexFormat[3].x = -screen_width;
840         vertexFormat[3].y = +screen_height;
841         
842         if(buffer_screen_vertex->isCreated()) {
843                 setNormalVAO(main_shader, vertex_screen,
844                                          buffer_screen_vertex,
845                                          vertexFormat, 4);
846         }
847         if(using_flags->is_use_one_board_computer()) {
848                 if(vertex_bitmap->isCreated()) {
849 #if !defined(BITMAP_OFFSET_X)
850                 #define BITMAP_OFFSET_X 0
851 #endif     
852 #if !defined(BITMAP_OFFSET_Y)
853                 #define BITMAP_OFFSET_Y 0
854 #endif     
855                         vertexBitmap[0].x = -1.0f;
856                         vertexBitmap[0].y = -1.0f;
857                         
858                         vertexBitmap[1].x = 1.0f - (float)BITMAP_OFFSET_X / (float)using_flags->get_screen_width();
859                         vertexBitmap[1].y = -1.0f;
860                         
861                         vertexBitmap[2].x = 1.0f - (float)BITMAP_OFFSET_X / (float)using_flags->get_screen_width();
862                         vertexBitmap[2].y = 1.0f - (float)BITMAP_OFFSET_Y * 2.0 / (float)using_flags->get_screen_height();
863                         
864                         vertexBitmap[3].x = -1.0f;
865                         vertexBitmap[3].y = 1.0f - (float)BITMAP_OFFSET_Y * 2.0 / (float)using_flags->get_screen_height();
866                         
867                         setNormalVAO(bitmap_shader, vertex_bitmap,
868                                                  buffer_bitmap_vertex,
869                                                  vertexBitmap, 4);
870                 }
871         }
872         if(using_flags->get_max_button() > 0) {
873                 updateButtonTexture();
874         }
875 }
876
877 void GLDraw_2_0::paintGL(void)
878 {
879         int i;
880         if(crt_flag || redraw_required) { //return;
881                 if(p_emu != NULL) {
882                         crt_flag = false;
883                 }
884                 redraw_required = false;
885                 extfunc->glViewport(0, 0, p_wid->width(), p_wid->height());
886                 extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
887                 
888                 extfunc->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
889                 extfunc->glEnable(GL_DEPTH_TEST);
890                 extfunc->glDisable(GL_BLEND);
891                 if(using_flags->is_use_one_board_computer()) drawBitmapTexture();
892                 drawButtons();
893                 /*
894                  * VRAMの表示:テクスチャ貼った四角形
895                  */
896                 drawScreenTexture();
897                 extfunc->glDisable(GL_BLEND);
898                 if(!using_flags->is_use_one_board_computer() && (using_flags->get_max_button() <= 0)) {
899                         drawGrids();
900                 }
901                 extfunc->glFlush();
902         }
903 }
904
905 void GLDraw_2_0::paintGL_OffScreen(int count, int w, int h)
906 {
907         rec_count += count;
908         rec_width  = w;
909         rec_height = h;
910 }
911
912 void GLDraw_2_0::do_set_screen_multiply(float mul)
913 {
914         screen_multiply = mul;
915         do_set_texture_size(imgptr, screen_texture_width, screen_texture_height);
916 }
917
918
919 void GLDraw_2_0::do_set_texture_size(QImage *p, int w, int h)
920 {
921         if(w <= 0) w = using_flags->get_screen_width();
922         if(h <= 0) h = using_flags->get_screen_height();
923         float wfactor = 1.0f;
924         float hfactor = 1.0f;
925         float iw, ih;
926         if(p != NULL) {
927                 int ww = w;
928                 int hh = h;
929                 imgptr = p;
930                 iw = (float)p->width();
931                 ih = (float)p->height();
932                 //if(screen_multiply < 1.0f) {
933                 p_wid->makeCurrent();
934                 screen_texture_width = w;
935                 screen_texture_height = h;
936                 vertexFormat[0].s = 0.0f;
937                 vertexFormat[0].t = (float)hh / ih;
938                 vertexFormat[1].s = (float)ww / iw;
939                 vertexFormat[1].t = (float)hh / ih;
940                 vertexFormat[2].s = (float)ww / iw;
941                 vertexFormat[2].t = 0.0f;
942                 vertexFormat[3].s = 0.0f;
943                 vertexFormat[3].t = 0.0f;
944                 
945                 setNormalVAO(main_shader, vertex_screen,
946                                          buffer_screen_vertex,
947                                          vertexFormat, 4);
948                 p_wid->doneCurrent();
949         }               
950         this->doSetGridsHorizonal(h, true);
951         this->doSetGridsVertical(w, true);
952 }