3 * (c) 2016 K.Ohta <whatisthis.sowhat@gmail.com>
5 * Renderer with OpenGL v3.0 (extend from renderer with OpenGL v2.0).
7 * Jan 22, 2016 : Initial.
10 #include "qt_gldraw.h"
11 #include "qt_glpack.h"
12 #include "qt_glutil_gl3_0.h"
13 #include "csp_logger.h"
14 #include "menu_flags.h"
15 #include <QOpenGLTexture>
16 #include <QOpenGLFunctions_3_0>
18 //extern USING_FLAGS *using_flags;
21 const float luma_filter[24 + 1] = {
48 const float chroma_filter[24 + 1] = {
78 const float luma_filter[24 + 1] = {
105 const float chroma_filter[24 + 1] = {
132 // END "ntsc-decode-filter-3phase.inc" //
135 const float luma_filter[24 + 1] = {
163 const float chroma_filter[24 + 1] = {
190 // END "ntsc-decode-filter-3phase.inc" //
194 GLDraw_3_0::GLDraw_3_0(GLDrawClass *parent, USING_FLAGS *p, CSP_Logger *logger, EMU *emu) : GLDraw_2_0(parent, p, logger, emu)
205 for(int i = 0; i < 32; i++) {
206 led_pass_vao[i] = NULL;
207 led_pass_vbuffer[i] = NULL;
208 osd_pass_vao[i] = NULL;
209 osd_pass_vbuffer[i] = NULL;
211 grids_horizonal_buffer = NULL;
212 grids_horizonal_vertex = NULL;
214 grids_vertical_buffer = NULL;
215 grids_vertical_vertex = NULL;
216 ringing_phase = 0.0f;
220 GLDraw_3_0::~GLDraw_3_0()
223 if(main_pass != NULL) delete main_pass;
224 if(std_pass != NULL) delete std_pass;
225 if(ntsc_pass1 != NULL) delete ntsc_pass1;
226 if(ntsc_pass2 != NULL) delete ntsc_pass2;
227 if(led_pass != NULL) delete led_pass;
228 for(int i = 0; i < 32; i++) {
229 if(led_pass_vao[i] != NULL) delete led_pass_vao[i];
230 if(led_pass_vbuffer[i] != NULL) delete led_pass_vbuffer[i];
231 if(osd_pass_vao[i] != NULL) delete osd_pass_vao[i];
232 if(osd_pass_vbuffer[i] != NULL) delete osd_pass_vbuffer[i];
235 if(grids_horizonal_buffer != NULL) {
236 if(grids_horizonal_buffer->isCreated()) grids_horizonal_buffer->destroy();
238 if(grids_horizonal_vertex != NULL) {
239 if(grids_horizonal_vertex->isCreated()) grids_horizonal_vertex->destroy();
241 if(grids_vertical_buffer != NULL) {
242 if(grids_vertical_buffer->isCreated()) grids_vertical_buffer->destroy();
244 if(grids_horizonal_vertex != NULL) {
245 if(grids_vertical_vertex->isCreated()) grids_vertical_vertex->destroy();
250 void GLDraw_3_0::initFBO(void)
252 glHorizGrids = (GLfloat *)malloc(sizeof(float) * (using_flags->get_real_screen_height() + 2) * 6);
253 if(glHorizGrids != NULL) {
254 doSetGridsHorizonal(using_flags->get_real_screen_height(), true);
256 glVertGrids = (GLfloat *)malloc(sizeof(float) * (using_flags->get_real_screen_width() + 2) * 6);
257 if(glVertGrids != NULL) {
258 doSetGridsVertical(using_flags->get_real_screen_width(), true);
260 if(using_flags->get_max_button() > 0) {
264 extfunc->glClearColor(0.0, 0.0, 0.0, 1.0);
267 void GLDraw_3_0::setNormalVAO(QOpenGLShaderProgram *prg,
268 QOpenGLVertexArrayObject *vp,
270 VertexTexCoord_t *tp,
273 int vertex_loc = prg->attributeLocation("vertex");
274 int texcoord_loc = prg->attributeLocation("texcoord");
281 bp->write(0, tp, sizeof(VertexTexCoord_t) * size);
283 prg->setAttributeBuffer(vertex_loc, GL_FLOAT, 0, 3, sizeof(VertexTexCoord_t));
284 prg->setAttributeBuffer(texcoord_loc, GL_FLOAT, 3 * sizeof(GLfloat), 2, sizeof(VertexTexCoord_t));
285 prg->setUniformValue("a_texture", 0);
287 extfunc->glVertexAttribPointer(vertex_loc, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTexCoord_t), 0);
288 extfunc->glVertexAttribPointer(texcoord_loc, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTexCoord_t),
289 (char *)NULL + 3 * sizeof(GLfloat));
292 prg->enableAttributeArray(vertex_loc);
293 prg->enableAttributeArray(texcoord_loc);
296 void GLDraw_3_0::initGLObjects()
298 extfunc = new QOpenGLFunctions_3_0;
299 extfunc->initializeOpenGLFunctions();
300 extfunc->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texture_max_size);
303 void GLDraw_3_0::initPackedGLObject(GLScreenPack **p,
304 int _width, int _height,
305 const QString vertex_shader, const QString fragment_shader,
311 pp = new GLScreenPack(_width, _height, _name, p_wid);
314 pp->initialize(_width, _height, vertex_shader, fragment_shader);
315 s = pp->getShaderLog();
317 csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GL_SHADER, "In shader of %s ", _name.toLocal8Bit().constData());
318 csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GL_SHADER, "Vertex: %s ", vertex_shader.toLocal8Bit().constData());
319 csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GL_SHADER, "Fragment: %s ", fragment_shader.toLocal8Bit().constData());
320 csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GL_SHADER, "%s", s.toLocal8Bit().constData());
324 csp_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_GL_SHADER, "%s", s.toLocal8Bit().constData());
333 bool GLDraw_3_0::initGridShaders(const QString vertex_fixed, const QString vertex_rotate, const QString fragment)
336 grids_shader = new QOpenGLShaderProgram(p_wid);
337 if(grids_shader != NULL) {
338 if(using_flags->is_use_screen_rotate()) {
339 f = grids_shader->addShaderFromSourceFile(QOpenGLShader::Vertex, vertex_rotate);
341 f = grids_shader->addShaderFromSourceFile(QOpenGLShader::Vertex, vertex_fixed);
343 f &= grids_shader->addShaderFromSourceFile(QOpenGLShader::Fragment, fragment);
344 f &= grids_shader->link();
349 bool GLDraw_3_0::initGridVertexObject(QOpenGLBuffer **vbo, QOpenGLVertexArrayObject **vao, int alloc_size)
351 QOpenGLBuffer *bp = NULL;
352 QOpenGLVertexArrayObject *ap = NULL;
355 *vbo = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
360 bp->allocate(alloc_size * sizeof(GLfloat) * 3 * 2);
370 *vao = new QOpenGLVertexArrayObject;
387 void GLDraw_3_0::initLocalGLObjects(void)
390 int _width = using_flags->get_screen_width();
391 int _height = using_flags->get_screen_height();
393 if((_width * 4) <= texture_max_size) {
395 low_resolution_screen = true;
399 p_wid->makeCurrent();
401 vertexFormat[0].x = -1.0f;
402 vertexFormat[0].y = -1.0f;
403 vertexFormat[0].z = -0.9f;
404 vertexFormat[0].s = 0.0f;
405 vertexFormat[0].t = 1.0f;
407 vertexFormat[1].x = +1.0f;
408 vertexFormat[1].y = -1.0f;
409 vertexFormat[1].z = -0.9f;
410 vertexFormat[1].s = 1.0f;
411 vertexFormat[1].t = 1.0f;
413 vertexFormat[2].x = +1.0f;
414 vertexFormat[2].y = +1.0f;
415 vertexFormat[2].z = -0.9f;
416 vertexFormat[2].s = 1.0f;
417 vertexFormat[2].t = 0.0f;
419 vertexFormat[3].x = -1.0f;
420 vertexFormat[3].y = +1.0f;
421 vertexFormat[3].z = -0.9f;
422 vertexFormat[3].s = 0.0f;
423 vertexFormat[3].t = 0.0f;
425 if(using_flags->is_use_one_board_computer() || (using_flags->get_max_button() > 0)) {
426 initPackedGLObject(&main_pass,
427 using_flags->get_screen_width() * 2, using_flags->get_screen_height() * 2,
428 ":/gl3/vertex_shader.glsl" , ":/gl3/chromakey_fragment_shader2.glsl",
431 initPackedGLObject(&main_pass,
432 using_flags->get_screen_width() * 2, using_flags->get_screen_height() * 2,
433 ":/gl3/vertex_shader.glsl" , ":/gl3/fragment_shader.glsl",
436 if(main_pass != NULL) {
437 setNormalVAO(main_pass->getShader(), main_pass->getVAO(),
438 main_pass->getVertexBuffer(),
441 initPackedGLObject(&std_pass,
442 using_flags->get_screen_width(), using_flags->get_screen_height(),
443 ":/gl3/vertex_shader.glsl" , ":/gl3/chromakey_fragment_shader.glsl",
445 initPackedGLObject(&led_pass,
447 ":/gl3/led_vertex_shader.glsl" , ":/gl3/led_fragment_shader.glsl",
449 for(int i = 0; i < 32; i++) {
450 led_pass_vao[i] = new QOpenGLVertexArrayObject;
451 led_pass_vbuffer[i] = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
452 if(led_pass_vao[i]->create()) {
453 if(led_pass_vbuffer[i]->create()) {
454 led_pass_vbuffer[i]->setUsagePattern(QOpenGLBuffer::DynamicDraw);
455 led_pass_vao[i]->bind();
456 led_pass_vbuffer[i]->bind();
457 led_pass_vbuffer[i]->allocate(sizeof(VertexTexCoord_t) * 4);
458 led_pass_vbuffer[i]->release();
459 led_pass_vao[i]->release();
464 initPackedGLObject(&osd_pass,
466 ":/gl3/vertex_shader.glsl" , ":/gl3/icon_fragment_shader.glsl",
468 for(int i = 0; i < 32; i++) {
469 osd_pass_vao[i] = new QOpenGLVertexArrayObject;
470 osd_pass_vbuffer[i] = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
471 if(osd_pass_vao[i]->create()) {
472 if(osd_pass_vbuffer[i]->create()) {
473 osd_pass_vbuffer[i]->setUsagePattern(QOpenGLBuffer::DynamicDraw);
474 osd_pass_vao[i]->bind();
475 osd_pass_vbuffer[i]->bind();
476 osd_pass_vbuffer[i]->allocate(sizeof(VertexTexCoord_t) * 4);
477 osd_pass_vbuffer[i]->release();
478 osd_pass_vao[i]->release();
484 initPackedGLObject(&ntsc_pass1,
486 ":/gl3/vertex_shader.glsl" , ":/gl3/ntsc_pass1.glsl",
487 "NTSC Shader Pass1");
488 initPackedGLObject(&ntsc_pass2,
490 ":/gl3/vertex_shader.glsl" , ":/gl3/ntsc_pass2.glsl",
491 "NTSC Shader Pass2");
494 QOpenGLShaderProgram *shader = ntsc_pass2->getShader();
496 ii = shader->uniformLocation("luma_filter");
498 shader->setUniformValueArray(ii, luma_filter, 24 + 1, 1);
500 ii = shader->uniformLocation("chroma_filter");
502 shader->setUniformValueArray(ii, chroma_filter, 24 + 1, 1);
507 if(using_flags->is_use_one_board_computer()) {
509 initPackedGLObject(&bitmap_block,
510 _width * 2, _height * 2,
511 ":/gl3/vertex_shader.glsl", ":/gl3/normal_fragment_shader.glsl",
512 "Background Bitmap Shader");
513 if(bitmap_block != NULL) {
514 setNormalVAO(bitmap_block->getShader(), bitmap_block->getVAO(),
515 bitmap_block->getVertexBuffer(),
519 initGridShaders(":/gl3/grids_vertex_shader_fixed.glsl", ":/gl3/grids_vertex_shader.glsl", ":/gl3/grids_fragment_shader.glsl");
521 initGridVertexObject(&grids_horizonal_buffer, &grids_horizonal_vertex, using_flags->get_real_screen_height() + 3);
522 doSetGridsHorizonal(using_flags->get_real_screen_height(), true);
524 initGridVertexObject(&grids_vertical_buffer, &grids_vertical_vertex, using_flags->get_real_screen_width() + 3);
525 doSetGridsVertical(using_flags->get_real_screen_width(), true);
527 do_set_texture_size(NULL, -1, -1);
528 p_wid->doneCurrent();
531 void GLDraw_3_0::updateGridsVAO(QOpenGLBuffer *bp,
532 QOpenGLVertexArrayObject *vp,
538 if((bp != NULL) && (vp != NULL)) {
539 if(bp->isCreated()) {
540 if(bp->size() < (int)((number + 1) * sizeof(GLfloat) * 3 * 2)) {
552 bp->allocate((number + 1) * sizeof(GLfloat) * 3 * 2);
555 bp->write(0, tp, (number + 1) * sizeof(GLfloat) * 3 * 2);
561 void GLDraw_3_0::drawGridsMain_3(QOpenGLShaderProgram *prg,
563 QOpenGLVertexArrayObject *vp,
568 if(number <= 0) return;
569 extfunc->glDisable(GL_TEXTURE_2D);
570 extfunc->glDisable(GL_DEPTH_TEST);
571 extfunc->glDisable(GL_BLEND);
573 if((bp == NULL) || (vp == NULL) || (prg == NULL)) return;
574 if((!bp->isCreated()) || (!vp->isCreated()) || (!prg->isLinked())) return;
580 //bp->read(8, &ff, sizeof(GLfloat) * 2);
581 //printf("%d %f %f\n", number, ff[0], ff[1]);
583 prg->setUniformValue("color", color);
584 prg->enableAttributeArray("vertex");
585 int vertex_loc = prg->attributeLocation("vertex");
587 extfunc->glViewport(0, 0, p_wid->width(), p_wid->height());
588 extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
589 //extfunc->glEnable(GL_BLEND);
590 //extfunc->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
591 //extfunc->glBlendFunc(GL_SRC_ALPHA, GL_ONE);
592 extfunc->glVertexAttribPointer(vertex_loc, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3, 0);
593 extfunc->glEnableVertexAttribArray(vertex_loc);
595 extfunc->glEnableClientState(GL_VERTEX_ARRAY);
596 extfunc->glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
597 extfunc->glLineWidth(lineWidth);
598 extfunc->glVertexPointer(3, GL_FLOAT, 0, 0);
599 extfunc->glDrawArrays(GL_LINES, 0, (number + 1) * 2);
600 extfunc->glDisableClientState(GL_VERTEX_ARRAY);
601 //extfunc->glDisable(GL_BLEND);
608 void GLDraw_3_0::doSetGridsVertical(int pixels, bool force)
610 GLDraw_2_0::doSetGridsVertical(pixels, force);
611 updateGridsVAO(grids_vertical_buffer,
612 grids_vertical_vertex,
617 void GLDraw_3_0::doSetGridsHorizonal(int lines, bool force)
619 if((lines == vert_lines) && !force) return;
620 GLDraw_2_0::doSetGridsHorizonal(lines, force);
621 updateGridsVAO(grids_horizonal_buffer,
622 grids_horizonal_vertex,
627 void GLDraw_3_0::drawGridsHorizonal(void)
629 QVector4D c= QVector4D(0.0f, 0.0f, 0.0f, 1.0f);
630 drawGridsMain_3(grids_shader,
631 grids_horizonal_buffer,
632 grids_horizonal_vertex,
638 void GLDraw_3_0::drawGridsVertical(void)
640 QVector4D c= QVector4D(0.0f, 0.0f, 0.0f, 1.0f);
641 drawGridsMain_3(grids_shader,
642 grids_vertical_buffer,
643 grids_vertical_vertex,
649 void GLDraw_3_0::renderToTmpFrameBuffer_nPass(GLuint src_texture,
652 GLScreenPack *renderObject,
658 QOpenGLShaderProgram *shader = renderObject->getShader();
662 extfunc->glClearColor(0.0, 0.0, 0.0, 1.0);
663 extfunc->glClearDepth(1.0f);
664 extfunc->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
666 if((src_texture != 0) && (shader != NULL)) {
667 extfunc->glEnable(GL_TEXTURE_2D);
668 renderObject->bind();
669 //extfunc->glViewport(0, 0, src_w, src_h);
670 extfunc->glViewport(0, 0, dst_w, dst_h);
671 extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
672 extfunc->glActiveTexture(GL_TEXTURE0);
673 extfunc->glBindTexture(GL_TEXTURE_2D, src_texture);
674 extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
675 extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
676 //extfunc->glColor4f(1.0, 1.0, 1.0, 1.0);
677 shader->setUniformValue("a_texture", 0);
678 //shader->setUniformValue("a_texture", src_texture);
680 ii = shader->uniformLocation("source_size");
682 QVector4D source_size = QVector4D((float)src_w, (float)src_h, 0, 0);
683 shader->setUniformValue(ii, source_size);
685 ii = shader->uniformLocation("target_size");
687 QVector4D target_size = QVector4D((float)dst_w, (float)dst_h, 0, 0);
688 shader->setUniformValue(ii, target_size);
690 ii = shader->uniformLocation("phase");
692 ringing_phase = ringing_phase + 0.093;
693 if(ringing_phase > 1.0) ringing_phase = ringing_phase - 1.0;
694 shader->setUniformValue(ii, ringing_phase);
696 //ii = shader->uniformLocation("luma_filter");
698 // shader->setUniformValueArray(ii, luma_filter, 24 + 1, 1);
700 //ii = shader->uniformLocation("chroma_filter");
702 // shader->setUniformValueArray(ii, chroma_filter, 24 + 1, 1);
706 QVector4D c(fBrightR, fBrightG, fBrightB, 1.0);
707 QVector3D chromakey(0.0, 0.0, 0.0);
709 ii = shader->uniformLocation("color");
711 shader->setUniformValue(ii, c);
713 ii = shader->uniformLocation("do_chromakey");
717 ij = shader->uniformLocation("chromakey");
719 shader->setUniformValue(ij, chromakey);
721 shader->setUniformValue(ii, GL_TRUE);
723 shader->setUniformValue(ii, GL_FALSE);
726 //shader->setUniformValue("tex_width", (float)w);
727 //shader->setUniformValue("tex_height", (float)h);
729 shader->enableAttributeArray("texcoord");
730 shader->enableAttributeArray("vertex");
732 int vertex_loc = shader->attributeLocation("vertex");
733 int texcoord_loc = shader->attributeLocation("texcoord");
734 extfunc->glEnableVertexAttribArray(vertex_loc);
735 extfunc->glEnableVertexAttribArray(texcoord_loc);
736 extfunc->glEnable(GL_VERTEX_ARRAY);
738 extfunc->glDrawArrays(GL_POLYGON, 0, 4);
740 extfunc->glViewport(0, 0, dst_w, dst_h);
741 extfunc->glOrtho(0.0f, (float)dst_w, 0.0f, (float)dst_h, -1.0, 1.0);
742 renderObject->release();
743 extfunc->glBindTexture(GL_TEXTURE_2D, 0);
744 extfunc->glDisable(GL_TEXTURE_2D);
751 void GLDraw_3_0::uploadMainTexture(QImage *p, bool use_chromakey)
754 redraw_required = true;
755 if(p == NULL) return;
756 //redraw_required = true;
758 if(uVramTextureID == NULL) {
759 uVramTextureID = new QOpenGLTexture(*p);
763 // Upload to main texture
764 extfunc->glBindTexture(GL_TEXTURE_2D, uVramTextureID->textureId());
765 extfunc->glTexSubImage2D(GL_TEXTURE_2D, 0,
767 //screen_texture_width * 2,
768 //screen_texture_height * 2,
769 p->width(), p->height(),
770 GL_BGRA, GL_UNSIGNED_BYTE, p->constBits());
771 extfunc->glBindTexture(GL_TEXTURE_2D, 0);
773 if(using_flags->is_support_tv_render() && (config.rendering_type == CONFIG_RENDER_TYPE_TV)) {
774 renderToTmpFrameBuffer_nPass(uVramTextureID->textureId(),
775 screen_texture_width,
776 screen_texture_height,
778 ntsc_pass1->getViewportWidth(),
779 ntsc_pass1->getViewportHeight());
781 renderToTmpFrameBuffer_nPass(ntsc_pass1->getTexture(),
782 ntsc_pass1->getViewportWidth(),
783 ntsc_pass1->getViewportHeight(),
785 ntsc_pass2->getViewportWidth(),
786 ntsc_pass2->getViewportHeight());
787 uTmpTextureID = ntsc_pass2->getTexture();
789 renderToTmpFrameBuffer_nPass(uVramTextureID->textureId(),
790 screen_texture_width,
791 screen_texture_height,
793 std_pass->getViewportWidth(),
794 std_pass->getViewportHeight(),
798 uTmpTextureID = std_pass->getTexture();
799 //std_pass->release();
804 void GLDraw_3_0::drawScreenTexture(void)
806 if(using_flags->is_use_one_board_computer()) {
807 extfunc->glEnable(GL_BLEND);
808 extfunc->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
810 extfunc->glDisable(GL_BLEND);
814 smoosing = config.use_opengl_filters;
816 color = QVector4D(fBrightR, fBrightG, fBrightB, 1.0);
818 color = QVector4D(1.0, 1.0, 1.0, 1.0);
820 if(using_flags->is_use_one_board_computer()) {
822 uTmpTextureID, // v2.0
824 true, QVector3D(0.0, 0.0, 0.0));
825 extfunc->glDisable(GL_BLEND);
828 uTmpTextureID, // v2.0
833 void GLDraw_3_0::drawMain(QOpenGLShaderProgram *prg,
834 QOpenGLVertexArrayObject *vp,
845 extfunc->glEnable(GL_TEXTURE_2D);
849 extfunc->glViewport(0, 0, p_wid->width(), p_wid->height());
850 extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
851 extfunc->glActiveTexture(GL_TEXTURE0);
852 extfunc->glBindTexture(GL_TEXTURE_2D, texid);
854 extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
855 extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
857 extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
858 extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
860 prg->setUniformValue("a_texture", 0);
862 ii = prg->uniformLocation("color");
864 prg->setUniformValue(ii, color);
867 ii = prg->uniformLocation("tex_width");
869 prg->setUniformValue(ii, (float)screen_texture_width);
872 ii = prg->uniformLocation("tex_height");
874 prg->setUniformValue(ii, (float)screen_texture_height);
876 if(using_flags->is_use_screen_rotate()) {
877 if(config.rotate_type) {
878 prg->setUniformValue("rotate", GL_TRUE);
880 prg->setUniformValue("rotate", GL_FALSE);
883 prg->setUniformValue("rotate", GL_FALSE);
887 ii = prg->uniformLocation("chromakey");
889 prg->setUniformValue(ii, chromakey);
891 ii = prg->uniformLocation("do_chromakey");
893 prg->setUniformValue(ii, GL_TRUE);
896 ii = prg->uniformLocation("do_chromakey");
898 prg->setUniformValue(ii, GL_FALSE);
902 prg->enableAttributeArray("texcoord");
903 prg->enableAttributeArray("vertex");
904 int vertex_loc = prg->attributeLocation("vertex");
905 int texcoord_loc = prg->attributeLocation("texcoord");
906 extfunc->glEnableVertexAttribArray(vertex_loc);
907 extfunc->glEnableVertexAttribArray(texcoord_loc);
908 extfunc->glEnable(GL_VERTEX_ARRAY);
909 extfunc->glDrawArrays(GL_POLYGON, 0, 4);
914 extfunc->glBindTexture(GL_TEXTURE_2D, 0);
915 extfunc->glDisable(GL_TEXTURE_2D);
918 extfunc->glDisable(GL_TEXTURE_2D);
922 extfunc->glViewport(0, 0, p_wid->width(), p_wid->height());
923 extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
924 ii = prg->uniformLocation("color");
926 prg->setUniformValue(ii, color);
928 if(using_flags->is_use_screen_rotate()) {
929 if(config.rotate_type) {
930 prg->setUniformValue("rotate", GL_TRUE);
932 prg->setUniformValue("rotate", GL_FALSE);
935 prg->setUniformValue("rotate", GL_FALSE);
939 ii = prg->uniformLocation("chromakey");
941 prg->setUniformValue(ii, chromakey);
943 ii = prg->uniformLocation("do_chromakey");
945 prg->setUniformValue(ii, GL_TRUE);
948 ii = prg->uniformLocation("do_chromakey");
950 prg->setUniformValue(ii, GL_FALSE);
954 prg->enableAttributeArray("vertex");
955 int vertex_loc = prg->attributeLocation("vertex");
956 extfunc->glEnableVertexAttribArray(vertex_loc);
957 extfunc->glEnable(GL_VERTEX_ARRAY);
958 extfunc->glDrawArrays(GL_POLYGON, 0, 4);
959 extfunc->glDisable(GL_VERTEX_ARRAY);
963 extfunc->glBindTexture(GL_TEXTURE_2D, 0);
964 extfunc->glDisable(GL_TEXTURE_2D);
968 void GLDraw_3_0::drawMain(GLScreenPack *obj,
976 QOpenGLShaderProgram *prg = obj->getShader();
977 QOpenGLVertexArrayObject *vp = obj->getVAO();
978 QOpenGLBuffer *bp = obj->getVertexBuffer();
980 drawMain(prg, vp, bp, texid, color, f_smoosing, do_chromakey, chromakey);
983 void GLDraw_3_0::drawButtonsMain(int num, bool f_smoosing)
986 QOpenGLBuffer *bp = buffer_button_vertex[num];
987 QOpenGLShaderProgram *prg = button_shader;
988 QOpenGLVertexArrayObject *vp = vertex_button[num];
991 if(uButtonTextureID[num] == NULL) return;
992 texid = uButtonTextureID[num]->textureId();
993 color = QVector4D(1.0, 1.0, 1.0, 1.0);
994 if((bp != NULL) && (vp != NULL) && (prg != NULL)) {
995 if((bp->isCreated()) && (vp->isCreated()) && (prg->isLinked())) {
999 extfunc->glViewport(0, 0, p_wid->width(), p_wid->height());
1000 extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
1001 extfunc->glActiveTexture(GL_TEXTURE0);
1002 extfunc->glBindTexture(GL_TEXTURE_2D, texid);
1004 extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1005 extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
1007 extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1008 extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1010 prg->setUniformValue("a_texture", 0);
1012 ii = prg->uniformLocation("color");
1014 prg->setUniformValue(ii, color);
1016 ii = prg->uniformLocation("do_chromakey");
1018 prg->setUniformValue(ii, GL_FALSE);
1020 if(using_flags->is_use_screen_rotate()) {
1021 if(config.rotate_type) {
1022 prg->setUniformValue("rotate", GL_TRUE);
1024 prg->setUniformValue("rotate", GL_FALSE);
1027 prg->setUniformValue("rotate", GL_FALSE);
1029 int vertex_loc = prg->attributeLocation("vertex");
1030 int texcoord_loc = prg->attributeLocation("texcoord");
1031 prg->setAttributeBuffer(vertex_loc, GL_FLOAT, 0, 3, sizeof(VertexTexCoord_t));
1032 prg->setAttributeBuffer(texcoord_loc, GL_FLOAT, 3 * sizeof(GLfloat), 2, sizeof(VertexTexCoord_t));
1033 prg->enableAttributeArray(vertex_loc);
1034 prg->enableAttributeArray(texcoord_loc);
1035 extfunc->glEnableVertexAttribArray(vertex_loc);
1036 extfunc->glEnableVertexAttribArray(texcoord_loc);
1037 extfunc->glEnable(GL_VERTEX_ARRAY);
1038 extfunc->glDrawArrays(GL_POLYGON, 0, 4);
1042 extfunc->glBindTexture(GL_TEXTURE_2D, 0);
1043 extfunc->glDisable(GL_TEXTURE_2D);
1050 void GLDraw_3_0::drawButtons(void)
1052 for(int i = 0; i < using_flags->get_max_button(); i++) {
1053 drawButtonsMain(i, false);
1057 void GLDraw_3_0::drawBitmapTexture(void)
1059 QVector4D color = QVector4D(1.0f, 1.0f, 1.0f, 1.0f);
1060 smoosing = config.use_opengl_filters;
1061 if(uBitmapTextureID == NULL) return;
1062 if(using_flags->is_use_one_board_computer()) {
1063 extfunc->glDisable(GL_BLEND);
1064 drawMain(bitmap_block,
1065 uBitmapTextureID->textureId(),
1070 void GLDraw_3_0::drawLedMain(GLScreenPack *obj, int num, QVector4D color)
1072 QOpenGLShaderProgram *prg = obj->getShader();
1073 QOpenGLVertexArrayObject *vp = led_pass_vao[num];
1074 QOpenGLBuffer *bp = led_pass_vbuffer[num];
1078 extfunc->glDisable(GL_TEXTURE_2D);
1079 extfunc->glEnable(GL_BLEND);
1080 extfunc->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1084 extfunc->glViewport(0, 0, p_wid->width(), p_wid->height());
1085 extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
1086 ii = prg->uniformLocation("color");
1088 prg->setUniformValue(ii, color);
1091 prg->enableAttributeArray("vertex");
1092 int vertex_loc = prg->attributeLocation("vertex");
1093 prg->setAttributeBuffer(vertex_loc, GL_FLOAT, 0, 3, sizeof(VertexTexCoord_t));
1094 extfunc->glVertexAttribPointer(vertex_loc, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTexCoord_t), 0);
1096 extfunc->glEnableVertexAttribArray(vertex_loc);
1097 extfunc->glEnable(GL_VERTEX_ARRAY);
1098 extfunc->glDrawArrays(GL_POLYGON, 0, 4);
1103 extfunc->glDisable(GL_TEXTURE_2D);
1104 extfunc->glDisable(GL_BLEND);
1110 void GLDraw_3_0::drawOsdLeds()
1113 QVector4D color_off;
1114 uint32_t bit = 0x00000001;
1116 color_on = QVector4D(0.95, 0.0, 0.05, 1.0);
1117 color_off = QVector4D(0.05,0.05, 0.05, 0.10);
1119 color_on = QVector4D(0.00,0.00, 0.00, 0.0);
1120 color_off = QVector4D(0.00,0.00, 0.00, 0.0);
1123 //if(osd_led_status_bak != osd_led_status) {
1124 for(int i = 0; i < osd_led_bit_width; i++) {
1125 if((bit & osd_led_status) == (bit & osd_led_status_bak)) {
1129 drawLedMain(led_pass, i,
1130 ((osd_led_status & bit) != 0) ? color_on : color_off);
1133 osd_led_status_bak = osd_led_status;
1138 void GLDraw_3_0::drawOsdIcons()
1141 QVector4D color_off;
1142 uint32_t bit = 0x00000001;
1144 color_on = QVector4D(1.0, 1.0, 1.0, 0.8);
1145 color_off = QVector4D(1.0, 1.0, 1.0, 0.00);
1147 color_on = QVector4D(0.00,0.00, 0.00, 0.0);
1148 color_off = QVector4D(0.00,0.00, 0.00, 0.0);
1152 //if(osd_led_status_bak != osd_led_status) {
1153 for(int i = 0; i < osd_led_bit_width; i++) {
1154 if((bit & osd_led_status) == (bit & osd_led_status_bak)) {
1155 if((bit & osd_led_status) == 0) {
1160 if((i >= 2) && (i < 10)) { // FD
1163 } else if((i >= 10) && (i < 12)) { // QD
1166 } else if((i >= 12) && (i < 14)) { // CMT(R)
1169 } else if((i >= 14) && (i < 16)) { // CMT(W)
1176 if((major != 0) && (icon_texid[major][minor] != NULL)) {
1177 drawMain(osd_pass->getShader(), osd_pass_vao[i], osd_pass_vbuffer[i],
1178 icon_texid[major][minor]->textureId(),
1179 ((osd_led_status & bit) != 0) ? color_on : color_off,
1180 false, false, QVector3D(0.0, 0.0, 0.0));
1184 osd_led_status_bak = osd_led_status;
1189 void GLDraw_3_0::paintGL(void)
1191 //p_wid->makeCurrent();
1193 // if(crt_flag || redraw_required) { //return;
1197 redraw_required = false;
1198 extfunc->glViewport(0, 0, p_wid->width(), p_wid->height());
1199 extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
1201 extfunc->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1202 extfunc->glEnable(GL_DEPTH_TEST);
1203 extfunc->glDisable(GL_BLEND);
1204 if(using_flags->is_use_one_board_computer() || using_flags->is_use_bitmap()) {
1205 extfunc->glEnable(GL_BLEND);
1206 drawBitmapTexture();
1208 if(using_flags->get_max_button() > 0) {
1209 extfunc->glEnable(GL_BLEND);
1212 drawScreenTexture();
1213 extfunc->glEnable(GL_BLEND);
1214 extfunc->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1215 extfunc->glDisable(GL_DEPTH_TEST);
1217 if(config.use_osd_virtual_media) drawOsdIcons();
1218 extfunc->glDisable(GL_BLEND);
1219 if(!using_flags->is_use_one_board_computer() && (using_flags->get_max_button() <= 0)) {
1224 // extfunc->glViewport(0, 0, p_wid->width(), p_wid->height());
1225 /// extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
1227 // extfunc->glClear(GL_DEPTH_BUFFER_BIT);
1228 // extfunc->glEnable(GL_DEPTH_TEST);
1229 // extfunc->glEnable(GL_BLEND);
1232 // extfunc->glFlush();
1234 //p_wid->doneCurrent();
1237 void GLDraw_3_0::setBrightness(GLfloat r, GLfloat g, GLfloat b)
1243 if(imgptr != NULL) {
1244 p_wid->makeCurrent();
1245 if(uVramTextureID == NULL) {
1246 uVramTextureID = new QOpenGLTexture(*imgptr);
1248 if(using_flags->is_use_one_board_computer() || (using_flags->get_max_button() > 0)) {
1249 uploadMainTexture(imgptr, true);
1251 uploadMainTexture(imgptr, false);
1254 p_wid->doneCurrent();
1258 void GLDraw_3_0::set_texture_vertex(float wmul, float hmul)
1260 float wfactor = 1.0f;
1261 float hfactor = 1.0f;
1263 vertexTmpTexture[0].x = -1.0f;
1264 vertexTmpTexture[0].y = -1.0f;
1265 vertexTmpTexture[0].z = -0.1f;
1266 vertexTmpTexture[0].s = 0.0f;
1267 vertexTmpTexture[0].t = 0.0f;
1269 vertexTmpTexture[1].x = wfactor;
1270 vertexTmpTexture[1].y = -1.0f;
1271 vertexTmpTexture[1].z = -0.1f;
1272 vertexTmpTexture[1].s = wmul;
1273 vertexTmpTexture[1].t = 0.0f;
1275 vertexTmpTexture[2].x = wfactor;
1276 vertexTmpTexture[2].y = hfactor;
1277 vertexTmpTexture[2].z = -0.1f;
1278 vertexTmpTexture[2].s = wmul;
1279 vertexTmpTexture[2].t = hmul;
1281 vertexTmpTexture[3].x = -1.0f;
1282 vertexTmpTexture[3].y = hfactor;
1283 vertexTmpTexture[3].z = -0.1f;
1284 vertexTmpTexture[3].s = 0.0f;
1285 vertexTmpTexture[3].t = hmul;
1289 void GLDraw_3_0::set_osd_vertex(int xbit)
1291 float xbase, ybase, zbase;
1292 VertexTexCoord_t vertex[4];
1293 int major, minor, nl;
1295 if((xbit < 0) || (xbit >= 32)) return;
1296 if((i >= 2) && (i < 10)) { // FD
1299 nl = using_flags->get_max_drive();
1300 } else if((i >= 10) && (i < 12)) { // QD
1303 nl = using_flags->get_max_qd();
1304 } else if((i >= 12) && (i < 14)) { // CMT(R)
1307 nl = using_flags->get_max_tape();
1308 } else if((i >= 14) && (i < 16)) { // CMT(W)
1311 nl = using_flags->get_max_tape();
1312 } else if(i >= 16) {
1313 major = 4 + (i / 8) - 2;
1321 xbase = 1.0f - (1.0f * 48.0f / 640.0f) * (float)(nl - minor) - (4.0f / 640.0f);;
1322 ybase = -1.0f + (1.0f * 48.0f / 400.0f) * (float)(major + 1) + (4.0f / 400.0f);
1324 vertex[0].x = xbase;
1325 vertex[0].y = ybase;
1326 vertex[0].z = zbase;
1330 vertex[1].x = xbase + (48.0f / 640.0f);
1331 vertex[1].y = ybase;
1332 vertex[1].z = zbase;
1336 vertex[2].x = xbase + (48.0f / 640.0f);
1337 vertex[2].y = ybase - (48.0f / 400.0f);
1338 vertex[2].z = zbase;
1342 vertex[3].x = xbase;
1343 vertex[3].y = ybase - (48.0f / 400.0f);
1344 vertex[3].z = zbase;
1348 setNormalVAO(osd_pass->getShader(), osd_pass_vao[xbit],
1349 osd_pass_vbuffer[xbit],
1353 void GLDraw_3_0::set_led_vertex(int xbit)
1355 float xbase, ybase, zbase;
1356 VertexTexCoord_t vertex[4];
1358 if((xbit < 0) || (xbit >=32)) return;
1359 xbase = 0.0f + (1.0f / 32.0f) * 31.0f - ((1.0f * (float)xbit) / 32.0f) + (1.0f / 128.0f);
1360 ybase = -1.0f + (2.0f / 64.0f) * 1.5f;
1362 vertex[0].x = xbase;
1363 vertex[0].y = ybase;
1364 vertex[0].z = zbase;
1368 vertex[1].x = xbase + (1.0f / 64.0f);
1369 vertex[1].y = ybase;
1370 vertex[1].z = zbase;
1374 vertex[2].x = xbase + (1.0f / 64.0f);
1375 vertex[2].y = ybase - (1.0f / 64.0f);
1376 vertex[2].z = zbase;
1380 vertex[3].x = xbase;
1381 vertex[3].y = ybase - (1.0f / 64.0f);
1382 vertex[3].z = zbase;
1386 setNormalVAO(led_pass->getShader(), led_pass_vao[xbit],
1387 led_pass_vbuffer[xbit],
1391 void GLDraw_3_0::do_set_screen_multiply(float mul)
1393 screen_multiply = mul;
1394 do_set_texture_size(imgptr, screen_texture_width, screen_texture_height);
1397 void GLDraw_3_0::do_set_texture_size(QImage *p, int w, int h)
1399 if(w <= 0) w = using_flags->get_real_screen_width();
1400 if(h <= 0) h = using_flags->get_real_screen_height();
1404 iw = (float)p->width();
1405 ih = (float)p->height();
1407 iw = (float)using_flags->get_real_screen_width();
1408 ih = (float)using_flags->get_real_screen_height();
1410 //if((w == screen_texture_width) && (h == screen_texture_height)) return;
1411 //printf("%dx%d -> %fx%f\n", w, h, iw, ih);
1413 screen_texture_width = w;
1414 screen_texture_height = h;
1416 p_wid->makeCurrent();
1418 set_texture_vertex((float)w / iw, (float)h / ih);
1419 setNormalVAO(std_pass->getShader(), std_pass->getVAO(),
1420 std_pass->getVertexBuffer(),
1421 vertexTmpTexture, 4);
1422 //set_texture_vertex(p, p_wid->width(), p_wid->height(), w, h);
1423 set_texture_vertex((float)w / iw, (float)h / ih);
1424 setNormalVAO(ntsc_pass1->getShader(), ntsc_pass1->getVAO(),
1425 ntsc_pass1->getVertexBuffer(),
1426 vertexTmpTexture, 4);
1428 set_texture_vertex(1.0f, 1.0f);
1429 setNormalVAO(ntsc_pass2->getShader(), ntsc_pass2->getVAO(),
1430 ntsc_pass2->getVertexBuffer(),
1431 vertexTmpTexture, 4);
1435 if(uVramTextureID != NULL) delete uVramTextureID;
1436 uVramTextureID = new QOpenGLTexture(*p);
1438 vertexFormat[0].x = -1.0f;
1439 vertexFormat[0].y = -1.0f;
1440 vertexFormat[0].z = -0.9f;
1441 vertexFormat[1].x = 1.0f;
1442 vertexFormat[1].y = -1.0f;
1443 vertexFormat[1].z = -0.9f;
1444 vertexFormat[2].x = 1.0f;
1445 vertexFormat[2].y = 1.0f;
1446 vertexFormat[2].z = -0.9f;
1447 vertexFormat[3].x = -1.0f;
1448 vertexFormat[3].y = 1.0f;
1449 vertexFormat[3].z = -0.9f;
1451 vertexFormat[0].s = 0.0f;
1452 //vertexFormat[0].t = (float)h / ih;
1453 //vertexFormat[1].s = (float)w / iw;
1454 //vertexFormat[1].t = (float)h / ih;
1455 //vertexFormat[2].s = (float)w / iw;
1456 vertexFormat[0].t = 1.0f;
1457 vertexFormat[1].s = 1.0f;
1458 vertexFormat[1].t = 1.0f;
1459 vertexFormat[2].s = 1.0f;
1460 vertexFormat[2].t = 0.0f;
1461 vertexFormat[3].s = 0.0f;
1462 vertexFormat[3].t = 0.0f;
1464 setNormalVAO(main_pass->getShader(), main_pass->getVAO(),
1465 main_pass->getVertexBuffer(),
1468 if(w > using_flags->get_real_screen_width()) {
1469 w = using_flags->get_real_screen_width();
1471 if(h > using_flags->get_real_screen_height()) {
1472 h = using_flags->get_real_screen_height();
1474 this->doSetGridsHorizonal(h, false);
1475 this->doSetGridsVertical(w, false);
1476 p_wid->doneCurrent();
1479 void GLDraw_3_0::do_set_horiz_lines(int lines)
1481 if(lines > using_flags->get_real_screen_height()) {
1482 lines = using_flags->get_real_screen_height();
1484 this->doSetGridsHorizonal(lines, false);
1487 void GLDraw_3_0::resizeGL_Screen(void)
1489 if(main_pass != NULL) {
1490 setNormalVAO(main_pass->getShader(), main_pass->getVAO(),
1491 main_pass->getVertexBuffer(),
1496 void GLDraw_3_0::resizeGL(int width, int height)
1498 //int side = qMin(width, height);
1499 p_wid->makeCurrent();
1500 extfunc->glViewport(0, 0, width, height);
1501 extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
1503 if(!using_flags->is_use_one_board_computer() && (using_flags->get_max_button() <= 0)) {
1504 doSetGridsHorizonal(vert_lines, true);
1505 if(using_flags->is_use_vertical_pixel_lines()) {
1506 doSetGridsVertical(horiz_pixels, true);
1509 resizeGL_SetVertexs();
1511 if(using_flags->is_use_one_board_computer()) {
1512 setNormalVAO(bitmap_block->getShader(), bitmap_block->getVAO(),
1513 bitmap_block->getVertexBuffer(),
1516 if(using_flags->get_max_button() > 0) {
1517 updateButtonTexture();
1519 p_wid->doneCurrent();