OSDN Git Service

[Draw][Qt][OpenGL] Implement selectable OpenGL render. Works excepts grid line.
[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 = false;
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         extfunc->glViewport(0, 0, p_wid->width(), p_wid->height());
190         extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
191 }       
192
193 void GLDraw_2_0::initFBO(void)
194 {
195
196         grids_shader_horizonal = new QOpenGLShaderProgram(p_wid);
197 #if defined(USE_SCREEN_ROTATE)   
198         if(grids_shader_horizonal != NULL) {
199                 grids_shader_horizonal->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/grids_vertex_shader.glsl");
200                 grids_shader_horizonal->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/grids_fragment_shader.glsl");
201                 grids_shader_horizonal->link();
202         }
203         grids_shader_vertical = new QOpenGLShaderProgram(p_wid);
204         if(grids_shader_vertical != NULL) {
205                 grids_shader_vertical->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/grids_vertex_shader.glsl");
206                 grids_shader_vertical->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/grids_fragment_shader.glsl");
207                 grids_shader_vertical->link();
208         }
209 #else
210         if(grids_shader_horizonal != NULL) {
211                 grids_shader_horizonal->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/grids_vertex_shader_fixed.glsl");
212                 grids_shader_horizonal->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/grids_fragment_shader.glsl");
213                 grids_shader_horizonal->link();
214         }
215         grids_shader_vertical = new QOpenGLShaderProgram(p_wid);
216         if(grids_shader_vertical != NULL) {
217                 grids_shader_vertical->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/grids_vertex_shader_fixed.glsl");
218                 grids_shader_vertical->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/grids_fragment_shader.glsl");
219                 grids_shader_vertical->link();
220         }
221 #endif
222 # if defined(ONE_BOARD_MICRO_COMPUTER)
223         bitmap_shader = new QOpenGLShaderProgram(p_wid);
224         if(bitmap_shader != NULL) {
225                 bitmap_shader->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/vertex_shader.glsl");
226                 bitmap_shader->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/normal_fragment_shader.glsl");
227                 bitmap_shader->link();
228         }
229 # endif
230 # if defined(MAX_BUTTONS)
231         for(i = 0; i < MAX_BUTTONS; i++) {
232                 button_shader[i] = new QOpenGLShaderProgram(p_wid);
233                 if(button_shader[i] != NULL) {
234                         button_shader[i]->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/vertex_shader.glsl");
235                         button_shader[i]->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/normal_fragment_shader.glsl");
236                         button_shader[i]->link();
237                 }
238         }
239 # endif
240         
241         glHorizGrids = (GLfloat *)malloc(sizeof(float) * (SCREEN_HEIGHT + 2) * 6);
242         if(glHorizGrids != NULL) {
243                 buffer_grid_horizonal = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
244                 vertex_grid_horizonal = new QOpenGLVertexArrayObject;
245                 
246                 screen_height = 1.0f;
247                 vert_lines = SCREEN_HEIGHT;
248                 if(vertex_grid_horizonal != NULL) {
249                         if(vertex_grid_horizonal->create()) {
250                                 buffer_grid_horizonal->create();
251                                 vertex_grid_horizonal->bind();
252                                 buffer_grid_horizonal->bind();
253                                 buffer_grid_horizonal->allocate((vert_lines + 1) * 6 * sizeof(GLfloat));
254                                 buffer_grid_horizonal->setUsagePattern(QOpenGLBuffer::StaticDraw);
255                                 buffer_grid_horizonal->release();
256                                 vertex_grid_horizonal->release();
257                 
258                         }
259                         doSetGridsHorizonal(SCREEN_HEIGHT, true);
260                 }
261         }
262         glVertGrids  = (GLfloat *)malloc(sizeof(float) * (SCREEN_WIDTH + 2) * 6);
263         if(glVertGrids != NULL) {
264                 buffer_grid_vertical = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
265                 vertex_grid_vertical = new QOpenGLVertexArrayObject;
266                 if(vertex_grid_vertical != NULL) {
267                         if(vertex_grid_vertical->create()) {
268                                 buffer_grid_vertical->bind();
269                                 vertex_grid_vertical->bind();
270                                 buffer_grid_vertical->allocate((SCREEN_WIDTH + 1) * 6 * sizeof(GLfloat));
271                                 buffer_grid_vertical->setUsagePattern(QOpenGLBuffer::StaticDraw);
272                                 vertex_grid_vertical->release();
273                                 buffer_grid_vertical->release();
274                                 doSetGridsVertical(SCREEN_WIDTH, true);
275                         }
276                 }
277         }
278 # if defined(MAX_BUTTONS)
279                 {
280                         vertexButtons = new QVector<VertexTexCoord_t>;
281                         int i;
282                         for(i = 0; i < MAX_BUTTONS; i++) {
283                                 buffer_button_vertex[i] = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
284                                 buffer_button_vertex[i]->create();
285                                 fButtonX[i] = -1.0 + (float)(buttons[i].x * 2) / (float)SCREEN_WIDTH;
286                                 fButtonY[i] = 1.0 - (float)(buttons[i].y * 2) / (float)SCREEN_HEIGHT;
287                                 fButtonWidth[i] = (float)(buttons[i].width * 2) / (float)SCREEN_WIDTH;
288                                 fButtonHeight[i] = (float)(buttons[i].height * 2) / (float)SCREEN_HEIGHT;
289                            
290                                 vertex_button[i] = new QOpenGLVertexArrayObject;
291                                 if(vertex_button[i] != NULL) {
292                                         if(vertex_button[i]->create()) {
293                                                 VertexTexCoord_t vt[4];
294                                                 vt[0].x =  fButtonX[i];
295                                                 vt[0].y =  fButtonY[i];
296                                                 vt[0].z =  -0.5f;
297                                                 vt[0].s = 0.0f;
298                                                 vt[0].t = 1.0f;
299                                            
300                                                 vt[1].x =  fButtonX[i] + fButtonWidth[i];
301                                                 vt[1].y =  fButtonY[i];
302                                                 vt[1].z =  -0.5f;
303                                                 vt[1].s = 1.0f;
304                                                 vt[1].t = 1.0f;
305                                            
306                                                 vt[2].x =  fButtonX[i] + fButtonWidth[i];
307                                                 vt[2].y =  fButtonY[i] - fButtonHeight[i];
308                                                 vt[2].z =  -0.5f;
309                                                 vt[2].s = 1.0f;
310                                                 vt[2].t = 0.0f;
311                                                 
312                                                 vt[3].x =  fButtonX[i];
313                                                 vt[3].y =  fButtonY[i] - fButtonHeight[i];
314                                                 vt[3].z =  -0.5f;
315                                                 vt[3].s = 0.0f;
316                                                 vt[3].t = 0.0f;
317
318                                                 vertexButtons->append(vt[0]);
319                                                 vertexButtons->append(vt[1]);
320                                                 vertexButtons->append(vt[2]);
321                                                 vertexButtons->append(vt[3]);
322                                                 vertex_button[i]->bind();
323                                                 buffer_button_vertex[i]->bind();
324                                                 buffer_button_vertex[i]->allocate(4 * sizeof(VertexTexCoord_t));
325                                                 
326                                                 buffer_button_vertex[i]->setUsagePattern(QOpenGLBuffer::StaticDraw);
327                                                 buffer_button_vertex[i]->release();
328                                                 vertex_button[i]->release();
329                                                 setNormalVAO(button_shader[i], vertex_button[i],
330                                                                          buffer_button_vertex[i],
331                                                                          vt, 4);
332                                         }
333                                 }
334                         }
335                 }
336 #endif
337 #if defined(ONE_BOARD_MICRO_COMPUTER)
338            buffer_bitmap_vertex = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
339            vertex_bitmap = new QOpenGLVertexArrayObject;
340            if(vertex_bitmap != NULL) {
341                    if(vertex_bitmap->create()) {
342                            {
343                                    QVector4D c;
344                                    c = QVector4D(1.0, 1.0, 1.0, 1.0);
345                                    bitmap_shader->setUniformValue("color", c);
346                            }
347                            vertexBitmap[0].x = -1.0f;
348                            vertexBitmap[0].y = -1.0f;
349                            vertexBitmap[0].z = -0.1f;
350                            vertexBitmap[0].s = 0.0f;
351                            vertexBitmap[0].t = 0.0f;
352                            
353                            vertexBitmap[1].x = +1.0f;
354                            vertexBitmap[1].y = -1.0f;
355                            vertexBitmap[1].z = -0.1f;
356                            vertexBitmap[1].s = 1.0f;
357                            vertexBitmap[1].t = 0.0f;
358                            
359                            vertexBitmap[2].x = +1.0f;
360                            vertexBitmap[2].y = +1.0f;
361                            vertexBitmap[2].z = -0.1f;
362                            vertexBitmap[2].s = 1.0f;
363                            vertexBitmap[2].t = 1.0f;
364                            
365                            vertexBitmap[3].x = -1.0f;
366                            vertexBitmap[3].y = +1.0f;
367                            vertexBitmap[3].z = -0.1f;
368                            vertexBitmap[3].s = 0.0f;
369                            vertexBitmap[3].t = 1.0f;
370                            
371                            buffer_bitmap_vertex->create();
372                            buffer_bitmap_vertex->setUsagePattern(QOpenGLBuffer::StaticDraw);
373                            int vertex_loc = bitmap_shader->attributeLocation("vertex");
374                            int texcoord_loc = bitmap_shader->attributeLocation("texcoord");
375                            
376                            vertex_bitmap->bind();
377                            buffer_bitmap_vertex->bind();
378                            buffer_bitmap_vertex->allocate(sizeof(vertexBitmap));
379                            buffer_bitmap_vertex->release();
380                            vertex_bitmap->release();
381                            setNormalVAO(bitmap_shader, vertex_bitmap,
382                                                         buffer_bitmap_vertex,
383                                                         vertexBitmap, 4);
384                    }
385            }
386 #endif
387         
388         bGL_PIXEL_UNPACK_BUFFER_BINDING = false;
389         // Init view
390         extfunc->glClearColor(0.0, 0.0, 0.0, 1.0);
391 }
392
393 void GLDraw_2_0::initLocalGLObjects(void)
394 {
395         main_shader = new QOpenGLShaderProgram(p_wid);
396         if(main_shader != NULL) {
397                 main_shader->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/vertex_shader.glsl");
398                 main_shader->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/chromakey_fragment_shader.glsl");
399                 main_shader->link();
400         }
401         buffer_screen_vertex = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
402         vertex_screen = new QOpenGLVertexArrayObject;
403         if(vertex_screen != NULL) {
404                 if(vertex_screen->create()) {
405                         {
406                                 QVector4D c;
407                                 c = QVector4D(1.0, 1.0, 1.0, 1.0);
408                                 main_shader->setUniformValue("color", c);
409                         }
410                         vertexFormat[0].x = -0.5f;
411                         vertexFormat[0].y = -0.5f;
412                         vertexFormat[0].z = -0.9f;
413                         vertexFormat[0].s = 0.0f;
414                         vertexFormat[0].t = 1.0f;
415                         
416                         vertexFormat[1].x = +0.5f;
417                         vertexFormat[1].y = -0.5f;
418                         vertexFormat[1].z = -0.9f;
419                         vertexFormat[1].s = 1.0f;
420                         vertexFormat[1].t = 1.0f;
421                         
422                         vertexFormat[2].x = +0.5f;
423                         vertexFormat[2].y = +0.5f;
424                         vertexFormat[2].z = -0.9f;
425                         vertexFormat[2].s = 1.0f;
426                         vertexFormat[2].t = 0.0f;
427                         
428                         vertexFormat[3].x = -0.5f;
429                         vertexFormat[3].y = +0.5f;
430                         vertexFormat[3].z = -0.9f;
431                         vertexFormat[3].s = 0.0f;
432                         vertexFormat[3].t = 0.0f;
433                         
434                         
435                         buffer_screen_vertex->create();
436                         buffer_screen_vertex->setUsagePattern(QOpenGLBuffer::DynamicDraw);
437                         
438                         vertex_screen->bind();
439                         buffer_screen_vertex->bind();
440                         buffer_screen_vertex->allocate(sizeof(VertexTexCoord_t) * 4);
441                         vertex_screen->release();
442                         buffer_screen_vertex->release();
443                         setNormalVAO(main_shader, vertex_screen,
444                                                  buffer_screen_vertex,
445                                                  vertexFormat, 4);
446                         //QMatrix4x4 mat;
447                         //mat.ortho(-1.0, 1.0, -1.0, +1.0, -1.0, 1.0);
448                         //mat.translate(0, 0, 0);
449                 }
450         }
451 }
452
453 void GLDraw_2_0::doSetGridsHorizonal(int lines, bool force)
454 {
455         int i;
456         GLfloat yf;
457         GLfloat delta;
458         
459         if((lines == vert_lines) && !force) return;
460         vert_lines = lines;
461         yf = -screen_height;
462         if(vert_lines <= 0) return;
463         if(vert_lines > SCREEN_HEIGHT) vert_lines = SCREEN_HEIGHT;
464         
465         delta = (2.0f * screen_height) / (float)vert_lines;
466         yf = yf - delta * 1.0f;
467         if(glHorizGrids != NULL) {
468                 for(i = 0; i < (vert_lines + 1) ; i++) {
469                         glHorizGrids[i * 6]     = -screen_width; // XBegin
470                         glHorizGrids[i * 6 + 3] = +screen_width; // XEnd
471                         glHorizGrids[i * 6 + 1] = yf; // YBegin
472                         glHorizGrids[i * 6 + 4] = yf; // YEnd
473                         glHorizGrids[i * 6 + 2] = -0.95f; // ZBegin
474                         glHorizGrids[i * 6 + 5] = -0.95f; // ZEnd
475                         yf = yf + delta;
476                 }
477         }
478         //AGAR_DebugLog(AGAR_LOG_DEBUG, "Set H-Lines: %d (%dx%d), %f, %d", vert_lines, p_wid->width(), p_wid->height()
479         //                        ,delta, vertex_grid_horizonal->isCreated()? 1 : 0);
480         if(vertex_grid_horizonal->isCreated()) {
481                 vertex_grid_horizonal->bind();
482                 buffer_grid_horizonal->bind();
483                 buffer_grid_horizonal->allocate((vert_lines + 1) * 6 * sizeof(GLfloat));
484                 buffer_grid_horizonal->write(0, glHorizGrids, (vert_lines + 1) * 6 * sizeof(GLfloat));
485                 
486                 grids_shader_horizonal->bind();
487                 int vertex_loc = grids_shader_horizonal->attributeLocation("vertex");
488                 grids_shader_horizonal->setAttributeBuffer(vertex_loc, GL_FLOAT, 0, 3);
489                 extfunc->glVertexAttribPointer(vertex_loc, 3, GL_FLOAT, GL_FALSE, 0, 0);
490                 grids_shader_horizonal->release();
491                 
492                 buffer_grid_horizonal->release();
493                 vertex_grid_horizonal->release();
494                 grids_shader_horizonal->enableAttributeArray(vertex_loc);
495         }
496 }
497
498 void GLDraw_2_0::doSetGridsVertical(int pixels, bool force)
499 {
500         int i;
501         GLfloat xf;
502         GLfloat delta;
503         
504         if((pixels == horiz_pixels) && !force) return;
505         horiz_pixels = pixels;
506         if(horiz_pixels <= 0) return;
507         if(horiz_pixels > SCREEN_WIDTH) horiz_pixels = SCREEN_WIDTH;
508         
509         xf = -screen_width;
510         delta = (2.0f * screen_width) / (float)horiz_pixels;
511         xf = xf - delta * 0.75f;
512         if(glVertGrids != NULL) {
513                 if(horiz_pixels > SCREEN_WIDTH) horiz_pixels = SCREEN_WIDTH;
514                 for(i = 0; i < (horiz_pixels + 1) ; i++) {
515                         glVertGrids[i * 6]     = xf; // XBegin
516                         glVertGrids[i * 6 + 3] = xf; // XEnd
517                         glVertGrids[i * 6 + 1] = -screen_height; // YBegin
518                         glVertGrids[i * 6 + 4] =  screen_height; // YEnd
519                         glVertGrids[i * 6 + 2] = -0.95f; // ZBegin
520                         glVertGrids[i * 6 + 5] = -0.95f; // ZEnd
521                         xf = xf + delta;
522                 }
523                 if(vertex_grid_vertical->isCreated()) {
524                         vertex_grid_vertical->bind();
525                         buffer_grid_vertical->bind();
526                         buffer_grid_vertical->allocate((horiz_pixels + 1) * 6 * sizeof(GLfloat));
527                         buffer_grid_vertical->write(0, glVertGrids, (horiz_pixels + 1)* 6 * sizeof(GLfloat));
528                         
529                         grids_shader_vertical->bind();
530                         int vertex_loc = grids_shader_vertical->attributeLocation("vertex");
531                         grids_shader_vertical->setAttributeBuffer(vertex_loc, GL_FLOAT, 0, 3);
532                         extfunc->glVertexAttribPointer(vertex_loc, 3, GL_FLOAT, GL_FALSE, 0, 0);
533                         grids_shader_vertical->release();
534                         
535                         buffer_grid_vertical->release();
536                         vertex_grid_vertical->release();
537                 }
538         }
539 }
540
541 void GLDraw_2_0::drawGridsMain(QOpenGLShaderProgram *prg,
542                                                                 QOpenGLVertexArrayObject *vp,
543                                                                 QOpenGLBuffer *bp,
544                                                                 int number,
545                                                                 GLfloat lineWidth,
546                                                                 QVector4D color)
547 {
548                 extfunc->glDisable(GL_TEXTURE_2D);
549                 extfunc->glDisable(GL_DEPTH_TEST);
550                 extfunc->glDisable(GL_BLEND);
551                 vp->bind();
552                 bp->bind();
553                 prg->bind();
554                 //extfunc->glViewport(0, 0, p_wid->width(), p_wid->height());
555                 //extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
556                 extfunc->glLineWidth(lineWidth);
557                 prg->setUniformValue("color", color);
558                 prg->enableAttributeArray("vertex");
559 # ifdef USE_SCREEN_ROTATE
560                 if(config.rotate_type) {
561                         prg->setUniformValue("rotate", GL_TRUE);
562                 } else {
563                         prg->setUniformValue("rotate", GL_FALSE);
564                 }
565 #endif     
566                 int vertex_loc = prg->attributeLocation("vertex");
567                 extfunc->glEnableVertexAttribArray(vertex_loc);
568                 extfunc->glEnableClientState(GL_VERTEX_ARRAY);
569                 extfunc->glDrawArrays(GL_LINES, 0, (number + 1) * 2);
570                 extfunc->glDisableClientState(GL_VERTEX_ARRAY);
571                 extfunc->glBindBuffer(GL_ARRAY_BUFFER, 0);
572                 bp->release();
573                 vp->release();
574                 prg->release();
575 }
576
577 void GLDraw_2_0::drawGridsHorizonal(void)
578 {
579         QVector4D c= QVector4D(0.0f, 0.0f, 0.0f, 1.0f);
580         drawGridsMain(grids_shader_horizonal,
581                                   vertex_grid_horizonal,
582                                   buffer_grid_horizonal,
583                                   vert_lines,
584                                   0.15f,
585                                   c);
586 }
587
588 void GLDraw_2_0::drawGridsVertical(void)
589 {
590         QVector4D c= QVector4D(0.0f, 0.0f, 0.0f, 1.0f);
591         drawGridsMain(grids_shader_vertical,
592                                   vertex_grid_vertical,
593                                   buffer_grid_vertical,
594                                   horiz_pixels,
595                                   0.5f,
596                                   c);
597 }
598
599
600 void GLDraw_2_0::drawGrids(void)
601 {
602         gl_grid_horiz = config.opengl_scanline_horiz;
603         gl_grid_vert  = config.opengl_scanline_vert;
604         if(gl_grid_horiz && (vert_lines > 0)) {
605                 this->drawGridsHorizonal();
606         }
607 #if defined(USE_VERTICAL_PIXEL_LINES)           
608         if(gl_grid_vert && (horiz_pixels > 0)) {
609                 this->drawGridsVertical();
610         }
611 #endif  
612 }
613
614 #if defined(MAX_BUTTONS)
615 void GLDraw_2_0::drawButtons()
616 {
617         int i;
618         //updateButtonTexture();
619         for(i = 0; i < MAX_BUTTONS; i++) {
620                 QVector4D c;
621                 c = QVector4D(1.0, 1.0, 1.0, 1.0);
622                 drawMain(button_shader[i], vertex_button[i],
623                                  buffer_button_vertex[i], uButtonTextureID[i],
624                                  c, false);
625         }
626 }
627 #endif
628
629
630 # ifdef ONE_BOARD_MICRO_COMPUTER
631 void GLDraw_2_0::drawBitmapTexture(void)
632 {
633         QVector4D c;
634         c = QVector4D(1.0, 1.0, 1.0, 1.0);
635         drawMain(bitmap_shader, vertex_bitmap,
636                          buffer_bitmap_vertex, uBitmapTextureID,
637                          c, false);
638 }
639 # endif
640
641 void GLDraw_2_0::drawScreenTexture(void)
642 {
643 #ifdef ONE_BOARD_MICRO_COMPUTER
644         if(uBitmapTextureID != 0) {
645                 extfunc->glEnable(GL_BLEND);
646                 extfunc->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
647         }
648 #else
649         extfunc->glDisable(GL_BLEND);
650 #endif
651         
652         QVector4D color;
653         smoosing = config.use_opengl_filters;
654         if(set_brightness) {
655                 color = QVector4D(fBrightR, fBrightG, fBrightB, 1.0);
656         } else {
657                 color = QVector4D(1.0, 1.0, 1.0, 1.0);
658         }                       
659         {
660                 drawMain(main_shader, vertex_screen,
661                                  buffer_screen_vertex, uVramTextureID, // v2.0
662                                  color, smoosing);
663         }               
664 #ifdef ONE_BOARD_MICRO_COMPUTER
665         extfunc->glDisable(GL_BLEND);
666 #endif  
667 }
668
669 void GLDraw_2_0::drawMain(QOpenGLShaderProgram *prg,
670                                                   QOpenGLVertexArrayObject *vp,
671                                                   QOpenGLBuffer *bp,
672                                                   GLuint texid,
673                                                   QVector4D color,
674                                                   bool f_smoosing,
675                                                   bool do_chromakey,
676                                                   QVector3D chromakey)
677                                                    
678 {
679         if(texid != 0) {
680                 extfunc->glEnable(GL_TEXTURE_2D);
681                 vp->bind();
682                 bp->bind();
683                 prg->bind();
684                 extfunc->glViewport(0, 0, p_wid->width(), p_wid->height());
685                 extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
686                 extfunc->glActiveTexture(GL_TEXTURE0);
687                 extfunc->glBindTexture(GL_TEXTURE_2D, texid);
688                 if(!f_smoosing) {
689                         extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
690                         extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
691                 } else {
692                         extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
693                         extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
694                 }
695                 prg->setUniformValue("a_texture", 0);
696                 prg->setUniformValue("color", color);
697                 prg->setUniformValue("tex_width",  (float)screen_texture_width); 
698                 prg->setUniformValue("tex_height", (float)screen_texture_height);
699 # ifdef USE_SCREEN_ROTATE
700                 if(config.rotate_type) {
701                         prg->setUniformValue("rotate", GL_TRUE);
702                 } else {
703                         prg->setUniformValue("rotate", GL_FALSE);
704                 }
705 #else           
706                 prg->setUniformValue("rotate", GL_FALSE);
707 #endif
708                 if(do_chromakey) {
709                         prg->setUniformValue("chromakey", chromakey);
710                         prg->setUniformValue("do_chromakey", GL_TRUE);
711                 } else {
712                         prg->setUniformValue("do_chromakey", GL_FALSE);
713                 }                       
714                 prg->enableAttributeArray("texcoord");
715                 prg->enableAttributeArray("vertex");
716                 int vertex_loc = prg->attributeLocation("vertex");
717                 int texcoord_loc = prg->attributeLocation("texcoord");
718                 extfunc->glEnableVertexAttribArray(vertex_loc);
719                 extfunc->glEnableVertexAttribArray(texcoord_loc);
720                 extfunc->glEnable(GL_VERTEX_ARRAY);
721
722                 extfunc->glDrawArrays(GL_POLYGON, 0, 4);
723                 bp->release();
724                 vp->release();
725                 
726                 prg->release();
727                 extfunc->glBindTexture(GL_TEXTURE_2D, 0);
728                 extfunc->glDisable(GL_TEXTURE_2D);
729         }
730 }
731
732
733 #if defined(ONE_BOARD_MICRO_COMPUTER)
734 void GLDraw_2_0::uploadBitmapTexture(QImage *p)
735 {
736         int i;
737         if(p == NULL) return;
738         if(!bitmap_uploaded) {
739                 if(uBitmapTextureID != 0) {
740                         this->deleteTexture(uBitmapTextureID);
741                 }
742                 uBitmapTextureID = this->bindTexture(*p);
743                 bitmap_uploaded = true;
744                 crt_flag = true;
745         }
746 }
747
748 void GLDraw_2_0::updateBitmap(QImage *p)
749 {
750         redraw_required = true;
751         bitmap_uploaded = false;
752         uploadBitmapTexture(p);
753 }
754 #endif
755
756 void GLDraw_2_0::uploadMainTexture(QImage *p, bool use_chromakey)
757 {
758         // set vertex
759         redraw_required = true;
760         imgptr = p;
761         if(p == NULL) return;
762         if(uVramTextureID == 0) {
763                 uVramTextureID = p_wid->bindTexture(*p);
764         }
765         {
766                 // Upload to main texture
767                 extfunc->glBindTexture(GL_TEXTURE_2D, uVramTextureID);
768                 extfunc->glTexSubImage2D(GL_TEXTURE_2D, 0,
769                                                          0, 0,
770                                                          p->width(), p->height(),
771                                                          GL_BGRA, GL_UNSIGNED_BYTE, p->constBits());
772                 extfunc->glBindTexture(GL_TEXTURE_2D, 0);
773         }
774         crt_flag = true;
775 }
776
777 void GLDraw_2_0::resizeGL(int width, int height)
778 {
779         int side = qMin(width, height);
780         double ww, hh;
781         int w, h;
782         extfunc->glViewport(0, 0, width, height);
783         extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
784         crt_flag = true;
785 #if !defined(ONE_BOARD_MICRO_COMPUTER) && !defined(MAX_BUTTONS)
786         doSetGridsHorizonal(vert_lines, true);
787 # if defined(USE_VERTICAL_PIXEL_LINES)          
788         doSetGridsVertical(horiz_pixels, true);
789 # endif         
790 #endif
791         if(vertex_screen->isCreated()) {
792                 {
793                         vertexFormat[0].x = -screen_width;
794                         vertexFormat[0].y = -screen_height;
795                         
796                         vertexFormat[1].x = +screen_width;
797                         vertexFormat[1].y = -screen_height;
798                         
799                         vertexFormat[2].x = +screen_width;
800                         vertexFormat[2].y = +screen_height;
801                         
802                         vertexFormat[3].x = -screen_width;
803                         vertexFormat[3].y = +screen_height;
804                 }
805                 setNormalVAO(main_shader, vertex_screen,
806                                          buffer_screen_vertex,
807                                          vertexFormat, 4);
808         }
809 #if defined(ONE_BOARD_MICRO_COMPUTER)   
810         if(vertex_bitmap->isCreated()) {
811 #if !defined(BITMAP_OFFSET_X)
812         #define BITMAP_OFFSET_X 0
813 #endif     
814 #if !defined(BITMAP_OFFSET_Y)
815         #define BITMAP_OFFSET_Y 0
816 #endif     
817                 vertexBitmap[0].x = -1.0f;
818                 vertexBitmap[0].y = -1.0f;
819            
820                 vertexBitmap[1].x = 1.0f - (float)BITMAP_OFFSET_X / (float)SCREEN_WIDTH;
821                 vertexBitmap[1].y = -1.0f;
822            
823                 vertexBitmap[2].x = 1.0f - (float)BITMAP_OFFSET_X / (float)SCREEN_WIDTH;
824                 vertexBitmap[2].y = 1.0f - (float)BITMAP_OFFSET_Y * 2.0 / (float)SCREEN_HEIGHT;
825            
826                 vertexBitmap[3].x = -1.0f;
827                 vertexBitmap[3].y = 1.0f - (float)BITMAP_OFFSET_Y * 2.0 / (float)SCREEN_HEIGHT;
828            
829                 setNormalVAO(bitmap_shader, vertex_bitmap,
830                                          buffer_bitmap_vertex,
831                                          vertexBitmap, 4);
832         }
833 #endif
834 #if defined(MAX_BUTTONS)
835         updateButtonTexture();
836 #endif
837 }
838
839 void GLDraw_2_0::paintGL(void)
840 {
841         int i;
842         if(!crt_flag && !redraw_required) return;
843         if(p_emu != NULL) {
844                 crt_flag = false;
845         }
846         redraw_required = false;
847         extfunc->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
848         extfunc->glEnable(GL_DEPTH_TEST);
849         extfunc->glDisable(GL_BLEND);
850 #ifdef ONE_BOARD_MICRO_COMPUTER
851         drawBitmapTexture();
852 #endif  
853 #if defined(MAX_BUTTONS)
854         drawButtons();
855 #endif  
856         /*
857          * VRAMの表示:テクスチャ貼った四角形
858          */
859         drawScreenTexture();
860         extfunc->glDisable(GL_BLEND);
861 #if !defined(ONE_BOARD_MICRO_COMPUTER) && !defined(MAX_BUTTONS)
862         drawGrids();
863 #endif  
864         extfunc->glFlush();
865 }
866
867 void GLDraw_2_0::do_set_screen_multiply(float mul)
868 {
869         screen_multiply = mul;
870         do_set_texture_size(imgptr, screen_texture_width, screen_texture_height);
871 }
872
873
874 void GLDraw_2_0::do_set_texture_size(QImage *p, int w, int h)
875 {
876         if(w <= 0) w = SCREEN_WIDTH;
877         if(h <= 0) h = SCREEN_HEIGHT;
878         float wfactor = 1.0f;
879         float hfactor = 1.0f;
880         float iw, ih;
881         if(p != NULL) {
882                 int ww = w;
883                 int hh = h;
884                 imgptr = p;
885                 iw = (float)p->width();
886                 ih = (float)p->height();
887                 //if(screen_multiply < 1.0f) {
888                 p_wid->makeCurrent();
889                 screen_texture_width = w;
890                 screen_texture_height = h;
891                 vertexFormat[0].s = 0.0f;
892                 vertexFormat[0].t = (float)hh / ih;
893                 vertexFormat[1].s = (float)ww / iw;
894                 vertexFormat[1].t = (float)hh / ih;
895                 vertexFormat[2].s = (float)ww / iw;
896                 vertexFormat[2].t = 0.0f;
897                 vertexFormat[3].s = 0.0f;
898                 vertexFormat[3].t = 0.0f;
899                 
900                 setNormalVAO(main_shader, vertex_screen,
901                                          buffer_screen_vertex,
902                                          vertexFormat, 4);
903                 p_wid->doneCurrent();
904         }               
905         this->doSetGridsHorizonal(h, true);
906         this->doSetGridsVertical(w, true);
907 }