OSDN Git Service

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