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 f = grids_shader->addShaderFromSourceFile(QOpenGLShader::Vertex, vertex_rotate);
339 f &= grids_shader->addShaderFromSourceFile(QOpenGLShader::Fragment, fragment);
340 f &= grids_shader->link();
345 bool GLDraw_3_0::initGridVertexObject(QOpenGLBuffer **vbo, QOpenGLVertexArrayObject **vao, int alloc_size)
347 QOpenGLBuffer *bp = NULL;
348 QOpenGLVertexArrayObject *ap = NULL;
351 *vbo = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
356 bp->allocate(alloc_size * sizeof(GLfloat) * 3 * 2);
366 *vao = new QOpenGLVertexArrayObject;
383 void GLDraw_3_0::initLocalGLObjects(void)
386 int _width = using_flags->get_screen_width();
387 int _height = using_flags->get_screen_height();
389 if((_width * 4) <= texture_max_size) {
391 low_resolution_screen = true;
395 p_wid->makeCurrent();
397 vertexFormat[0].x = -1.0f;
398 vertexFormat[0].y = -1.0f;
399 vertexFormat[0].z = -0.9f;
400 vertexFormat[0].s = 0.0f;
401 vertexFormat[0].t = 1.0f;
403 vertexFormat[1].x = +1.0f;
404 vertexFormat[1].y = -1.0f;
405 vertexFormat[1].z = -0.9f;
406 vertexFormat[1].s = 1.0f;
407 vertexFormat[1].t = 1.0f;
409 vertexFormat[2].x = +1.0f;
410 vertexFormat[2].y = +1.0f;
411 vertexFormat[2].z = -0.9f;
412 vertexFormat[2].s = 1.0f;
413 vertexFormat[2].t = 0.0f;
415 vertexFormat[3].x = -1.0f;
416 vertexFormat[3].y = +1.0f;
417 vertexFormat[3].z = -0.9f;
418 vertexFormat[3].s = 0.0f;
419 vertexFormat[3].t = 0.0f;
421 if(using_flags->is_use_one_board_computer() || (using_flags->get_max_button() > 0)) {
422 initPackedGLObject(&main_pass,
423 using_flags->get_screen_width() * 2, using_flags->get_screen_height() * 2,
424 ":/gl3/vertex_shader.glsl" , ":/gl3/chromakey_fragment_shader2.glsl",
427 initPackedGLObject(&main_pass,
428 using_flags->get_screen_width() * 2, using_flags->get_screen_height() * 2,
429 ":/gl3/vertex_shader.glsl" , ":/gl3/fragment_shader.glsl",
432 if(main_pass != NULL) {
433 setNormalVAO(main_pass->getShader(), main_pass->getVAO(),
434 main_pass->getVertexBuffer(),
437 initPackedGLObject(&std_pass,
438 using_flags->get_screen_width(), using_flags->get_screen_height(),
439 ":/gl3/vertex_shader.glsl" , ":/gl3/chromakey_fragment_shader.glsl",
441 initPackedGLObject(&led_pass,
443 ":/gl3/led_vertex_shader.glsl" , ":/gl3/led_fragment_shader.glsl",
445 for(int i = 0; i < 32; i++) {
446 led_pass_vao[i] = new QOpenGLVertexArrayObject;
447 led_pass_vbuffer[i] = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
448 if(led_pass_vao[i]->create()) {
449 if(led_pass_vbuffer[i]->create()) {
450 led_pass_vbuffer[i]->setUsagePattern(QOpenGLBuffer::DynamicDraw);
451 led_pass_vao[i]->bind();
452 led_pass_vbuffer[i]->bind();
453 led_pass_vbuffer[i]->allocate(sizeof(VertexTexCoord_t) * 4);
454 led_pass_vbuffer[i]->release();
455 led_pass_vao[i]->release();
460 initPackedGLObject(&osd_pass,
462 ":/gl3/vertex_shader.glsl" , ":/gl3/icon_fragment_shader.glsl",
464 for(int i = 0; i < 32; i++) {
465 osd_pass_vao[i] = new QOpenGLVertexArrayObject;
466 osd_pass_vbuffer[i] = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
467 if(osd_pass_vao[i]->create()) {
468 if(osd_pass_vbuffer[i]->create()) {
469 osd_pass_vbuffer[i]->setUsagePattern(QOpenGLBuffer::DynamicDraw);
470 osd_pass_vao[i]->bind();
471 osd_pass_vbuffer[i]->bind();
472 osd_pass_vbuffer[i]->allocate(sizeof(VertexTexCoord_t) * 4);
473 osd_pass_vbuffer[i]->release();
474 osd_pass_vao[i]->release();
480 initPackedGLObject(&ntsc_pass1,
482 ":/gl3/vertex_shader.glsl" , ":/gl3/ntsc_pass1.glsl",
483 "NTSC Shader Pass1");
484 initPackedGLObject(&ntsc_pass2,
486 ":/gl3/vertex_shader.glsl" , ":/gl3/ntsc_pass2.glsl",
487 "NTSC Shader Pass2");
490 QOpenGLShaderProgram *shader = ntsc_pass2->getShader();
492 ii = shader->uniformLocation("luma_filter");
494 shader->setUniformValueArray(ii, luma_filter, 24 + 1, 1);
496 ii = shader->uniformLocation("chroma_filter");
498 shader->setUniformValueArray(ii, chroma_filter, 24 + 1, 1);
503 if(using_flags->is_use_one_board_computer()) {
505 initPackedGLObject(&bitmap_block,
506 _width * 2, _height * 2,
507 ":/gl3/vertex_shader.glsl", ":/gl3/normal_fragment_shader.glsl",
508 "Background Bitmap Shader");
509 if(bitmap_block != NULL) {
510 setNormalVAO(bitmap_block->getShader(), bitmap_block->getVAO(),
511 bitmap_block->getVertexBuffer(),
515 initGridShaders(":/gl3/grids_vertex_shader_fixed.glsl", ":/gl3/grids_vertex_shader.glsl", ":/gl3/grids_fragment_shader.glsl");
517 initGridVertexObject(&grids_horizonal_buffer, &grids_horizonal_vertex, using_flags->get_real_screen_height() + 3);
518 doSetGridsHorizonal(using_flags->get_real_screen_height(), true);
520 initGridVertexObject(&grids_vertical_buffer, &grids_vertical_vertex, using_flags->get_real_screen_width() + 3);
521 doSetGridsVertical(using_flags->get_real_screen_width(), true);
523 do_set_texture_size(NULL, -1, -1);
524 p_wid->doneCurrent();
527 void GLDraw_3_0::updateGridsVAO(QOpenGLBuffer *bp,
528 QOpenGLVertexArrayObject *vp,
534 if((bp != NULL) && (vp != NULL)) {
535 if(bp->isCreated()) {
536 if(bp->size() < (int)((number + 1) * sizeof(GLfloat) * 3 * 2)) {
548 bp->allocate((number + 1) * sizeof(GLfloat) * 3 * 2);
551 bp->write(0, tp, (number + 1) * sizeof(GLfloat) * 3 * 2);
557 void GLDraw_3_0::drawGridsMain_3(QOpenGLShaderProgram *prg,
559 QOpenGLVertexArrayObject *vp,
564 if(number <= 0) return;
565 extfunc->glDisable(GL_TEXTURE_2D);
566 extfunc->glDisable(GL_DEPTH_TEST);
567 extfunc->glDisable(GL_BLEND);
569 if((bp == NULL) || (vp == NULL) || (prg == NULL)) return;
570 if((!bp->isCreated()) || (!vp->isCreated()) || (!prg->isLinked())) return;
576 //bp->read(8, &ff, sizeof(GLfloat) * 2);
577 //printf("%d %f %f\n", number, ff[0], ff[1]);
579 prg->setUniformValue("color", color);
580 prg->enableAttributeArray("vertex");
581 int vertex_loc = prg->attributeLocation("vertex");
583 extfunc->glViewport(0, 0, p_wid->width(), p_wid->height());
584 extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
585 //extfunc->glEnable(GL_BLEND);
586 //extfunc->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
587 //extfunc->glBlendFunc(GL_SRC_ALPHA, GL_ONE);
588 extfunc->glVertexAttribPointer(vertex_loc, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3, 0);
589 extfunc->glEnableVertexAttribArray(vertex_loc);
591 extfunc->glEnableClientState(GL_VERTEX_ARRAY);
592 extfunc->glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
593 extfunc->glLineWidth(lineWidth);
594 extfunc->glVertexPointer(3, GL_FLOAT, 0, 0);
595 extfunc->glDrawArrays(GL_LINES, 0, (number + 1) * 2);
596 extfunc->glDisableClientState(GL_VERTEX_ARRAY);
597 //extfunc->glDisable(GL_BLEND);
604 void GLDraw_3_0::doSetGridsVertical(int pixels, bool force)
606 GLDraw_2_0::doSetGridsVertical(pixels, force);
607 updateGridsVAO(grids_vertical_buffer,
608 grids_vertical_vertex,
613 void GLDraw_3_0::doSetGridsHorizonal(int lines, bool force)
615 if((lines == vert_lines) && !force) return;
616 GLDraw_2_0::doSetGridsHorizonal(lines, force);
617 updateGridsVAO(grids_horizonal_buffer,
618 grids_horizonal_vertex,
623 void GLDraw_3_0::drawGridsHorizonal(void)
625 QVector4D c= QVector4D(0.0f, 0.0f, 0.0f, 1.0f);
626 drawGridsMain_3(grids_shader,
627 grids_horizonal_buffer,
628 grids_horizonal_vertex,
634 void GLDraw_3_0::drawGridsVertical(void)
636 QVector4D c= QVector4D(0.0f, 0.0f, 0.0f, 1.0f);
637 drawGridsMain_3(grids_shader,
638 grids_vertical_buffer,
639 grids_vertical_vertex,
645 void GLDraw_3_0::renderToTmpFrameBuffer_nPass(GLuint src_texture,
648 GLScreenPack *renderObject,
654 QOpenGLShaderProgram *shader = renderObject->getShader();
658 extfunc->glClearColor(0.0, 0.0, 0.0, 1.0);
659 extfunc->glClearDepth(1.0f);
660 extfunc->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
662 if((src_texture != 0) && (shader != NULL)) {
663 extfunc->glEnable(GL_TEXTURE_2D);
664 renderObject->bind();
665 //extfunc->glViewport(0, 0, src_w, src_h);
666 extfunc->glViewport(0, 0, dst_w, dst_h);
667 extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
668 extfunc->glActiveTexture(GL_TEXTURE0);
669 extfunc->glBindTexture(GL_TEXTURE_2D, src_texture);
670 extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
671 extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
672 //extfunc->glColor4f(1.0, 1.0, 1.0, 1.0);
673 shader->setUniformValue("a_texture", 0);
674 //shader->setUniformValue("a_texture", src_texture);
676 ii = shader->uniformLocation("source_size");
678 QVector4D source_size = QVector4D((float)src_w, (float)src_h, 0, 0);
679 shader->setUniformValue(ii, source_size);
681 ii = shader->uniformLocation("target_size");
683 QVector4D target_size = QVector4D((float)dst_w, (float)dst_h, 0, 0);
684 shader->setUniformValue(ii, target_size);
686 ii = shader->uniformLocation("phase");
688 ringing_phase = ringing_phase + 0.093;
689 if(ringing_phase > 1.0) ringing_phase = ringing_phase - 1.0;
690 shader->setUniformValue(ii, ringing_phase);
692 //ii = shader->uniformLocation("luma_filter");
694 // shader->setUniformValueArray(ii, luma_filter, 24 + 1, 1);
696 //ii = shader->uniformLocation("chroma_filter");
698 // shader->setUniformValueArray(ii, chroma_filter, 24 + 1, 1);
702 QVector4D c(fBrightR, fBrightG, fBrightB, 1.0);
703 QVector3D chromakey(0.0, 0.0, 0.0);
705 ii = shader->uniformLocation("color");
707 shader->setUniformValue(ii, c);
709 ii = shader->uniformLocation("do_chromakey");
713 ij = shader->uniformLocation("chromakey");
715 shader->setUniformValue(ij, chromakey);
717 shader->setUniformValue(ii, GL_TRUE);
719 shader->setUniformValue(ii, GL_FALSE);
722 //shader->setUniformValue("tex_width", (float)w);
723 //shader->setUniformValue("tex_height", (float)h);
725 shader->enableAttributeArray("texcoord");
726 shader->enableAttributeArray("vertex");
728 int vertex_loc = shader->attributeLocation("vertex");
729 int texcoord_loc = shader->attributeLocation("texcoord");
730 extfunc->glEnableVertexAttribArray(vertex_loc);
731 extfunc->glEnableVertexAttribArray(texcoord_loc);
732 extfunc->glEnable(GL_VERTEX_ARRAY);
734 extfunc->glDrawArrays(GL_POLYGON, 0, 4);
736 extfunc->glViewport(0, 0, dst_w, dst_h);
737 extfunc->glOrtho(0.0f, (float)dst_w, 0.0f, (float)dst_h, -1.0, 1.0);
738 renderObject->release();
739 extfunc->glBindTexture(GL_TEXTURE_2D, 0);
740 extfunc->glDisable(GL_TEXTURE_2D);
747 void GLDraw_3_0::uploadMainTexture(QImage *p, bool use_chromakey)
750 redraw_required = true;
751 if(p == NULL) return;
752 //redraw_required = true;
754 if(uVramTextureID == NULL) {
755 uVramTextureID = new QOpenGLTexture(*p);
759 // Upload to main texture
760 extfunc->glBindTexture(GL_TEXTURE_2D, uVramTextureID->textureId());
761 extfunc->glTexSubImage2D(GL_TEXTURE_2D, 0,
763 //screen_texture_width * 2,
764 //screen_texture_height * 2,
765 p->width(), p->height(),
766 GL_BGRA, GL_UNSIGNED_BYTE, p->constBits());
767 extfunc->glBindTexture(GL_TEXTURE_2D, 0);
769 if(using_flags->is_support_tv_render() && (p_config->rendering_type == CONFIG_RENDER_TYPE_TV)) {
770 renderToTmpFrameBuffer_nPass(uVramTextureID->textureId(),
771 screen_texture_width,
772 screen_texture_height,
774 ntsc_pass1->getViewportWidth(),
775 ntsc_pass1->getViewportHeight());
777 renderToTmpFrameBuffer_nPass(ntsc_pass1->getTexture(),
778 ntsc_pass1->getViewportWidth(),
779 ntsc_pass1->getViewportHeight(),
781 ntsc_pass2->getViewportWidth(),
782 ntsc_pass2->getViewportHeight());
783 uTmpTextureID = ntsc_pass2->getTexture();
785 // renderToTmpFrameBuffer_nPass(uVramTextureID->textureId(),
786 // screen_texture_width,
787 // screen_texture_height,
789 // std_pass->getViewportWidth(),
790 // std_pass->getViewportHeight(),
794 //uTmpTextureID = std_pass->getTexture();
795 uTmpTextureID = uVramTextureID->textureId(); //std_pass->release();
800 void GLDraw_3_0::drawScreenTexture(void)
802 if(using_flags->is_use_one_board_computer()) {
803 extfunc->glEnable(GL_BLEND);
804 extfunc->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
806 extfunc->glDisable(GL_BLEND);
810 smoosing = p_config->use_opengl_filters;
812 color = QVector4D(fBrightR, fBrightG, fBrightB, 1.0);
814 color = QVector4D(1.0, 1.0, 1.0, 1.0);
816 if(using_flags->is_use_one_board_computer()) {
818 uTmpTextureID, // v2.0
820 true, QVector3D(0.0, 0.0, 0.0));
821 extfunc->glDisable(GL_BLEND);
824 uTmpTextureID, // v2.0
829 void GLDraw_3_0::drawMain(QOpenGLShaderProgram *prg,
830 QOpenGLVertexArrayObject *vp,
841 extfunc->glEnable(GL_TEXTURE_2D);
845 extfunc->glViewport(0, 0, p_wid->width(), p_wid->height());
846 extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
847 extfunc->glActiveTexture(GL_TEXTURE0);
848 extfunc->glBindTexture(GL_TEXTURE_2D, texid);
850 extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
851 extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
853 extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
854 extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
856 prg->setUniformValue("a_texture", 0);
858 ii = prg->uniformLocation("color");
860 prg->setUniformValue(ii, color);
863 ii = prg->uniformLocation("tex_width");
865 prg->setUniformValue(ii, (float)screen_texture_width);
868 ii = prg->uniformLocation("tex_height");
870 prg->setUniformValue(ii, (float)screen_texture_height);
874 switch(p_config->rotate_type) {
876 rot = QMatrix2x2(rot0);
879 rot = QMatrix2x2(rot90);
882 rot = QMatrix2x2(rot180);
885 rot = QMatrix2x2(rot270);
888 rot = QMatrix2x2(rot0);
891 prg->setUniformValue("rotate_mat", rot);
894 ii = prg->uniformLocation("chromakey");
896 prg->setUniformValue(ii, chromakey);
898 ii = prg->uniformLocation("do_chromakey");
900 prg->setUniformValue(ii, GL_TRUE);
903 ii = prg->uniformLocation("do_chromakey");
905 prg->setUniformValue(ii, GL_FALSE);
909 prg->enableAttributeArray("texcoord");
910 prg->enableAttributeArray("vertex");
911 int vertex_loc = prg->attributeLocation("vertex");
912 int texcoord_loc = prg->attributeLocation("texcoord");
913 extfunc->glEnableVertexAttribArray(vertex_loc);
914 extfunc->glEnableVertexAttribArray(texcoord_loc);
915 extfunc->glEnable(GL_VERTEX_ARRAY);
916 extfunc->glDrawArrays(GL_POLYGON, 0, 4);
921 extfunc->glBindTexture(GL_TEXTURE_2D, 0);
922 extfunc->glDisable(GL_TEXTURE_2D);
925 extfunc->glDisable(GL_TEXTURE_2D);
929 extfunc->glViewport(0, 0, p_wid->width(), p_wid->height());
930 extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
931 ii = prg->uniformLocation("color");
933 prg->setUniformValue(ii, color);
936 switch(p_config->rotate_type) {
938 rot = QMatrix2x2(rot0);
941 rot = QMatrix2x2(rot90);
944 rot = QMatrix2x2(rot180);
947 rot = QMatrix2x2(rot270);
950 rot = QMatrix2x2(rot0);
953 prg->setUniformValue("rotate_mat", rot);
956 ii = prg->uniformLocation("chromakey");
958 prg->setUniformValue(ii, chromakey);
960 ii = prg->uniformLocation("do_chromakey");
962 prg->setUniformValue(ii, GL_TRUE);
965 ii = prg->uniformLocation("do_chromakey");
967 prg->setUniformValue(ii, GL_FALSE);
971 prg->enableAttributeArray("vertex");
972 int vertex_loc = prg->attributeLocation("vertex");
973 extfunc->glEnableVertexAttribArray(vertex_loc);
974 extfunc->glEnable(GL_VERTEX_ARRAY);
975 extfunc->glDrawArrays(GL_POLYGON, 0, 4);
976 extfunc->glDisable(GL_VERTEX_ARRAY);
980 extfunc->glBindTexture(GL_TEXTURE_2D, 0);
981 extfunc->glDisable(GL_TEXTURE_2D);
985 void GLDraw_3_0::drawMain(GLScreenPack *obj,
993 QOpenGLShaderProgram *prg = obj->getShader();
994 QOpenGLVertexArrayObject *vp = obj->getVAO();
995 QOpenGLBuffer *bp = obj->getVertexBuffer();
997 drawMain(prg, vp, bp, texid, color, f_smoosing, do_chromakey, chromakey);
1000 void GLDraw_3_0::drawButtonsMain(int num, bool f_smoosing)
1003 QOpenGLBuffer *bp = buffer_button_vertex[num];
1004 QOpenGLShaderProgram *prg = button_shader;
1005 QOpenGLVertexArrayObject *vp = vertex_button[num];
1008 if(uButtonTextureID[num] == NULL) return;
1009 texid = uButtonTextureID[num]->textureId();
1010 color = QVector4D(1.0, 1.0, 1.0, 1.0);
1011 if((bp != NULL) && (vp != NULL) && (prg != NULL)) {
1012 if((bp->isCreated()) && (vp->isCreated()) && (prg->isLinked())) {
1016 extfunc->glViewport(0, 0, p_wid->width(), p_wid->height());
1017 extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
1018 extfunc->glActiveTexture(GL_TEXTURE0);
1019 extfunc->glBindTexture(GL_TEXTURE_2D, texid);
1021 extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1022 extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
1024 extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1025 extfunc->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1027 prg->setUniformValue("a_texture", 0);
1029 ii = prg->uniformLocation("color");
1031 prg->setUniformValue(ii, color);
1033 ii = prg->uniformLocation("do_chromakey");
1035 prg->setUniformValue(ii, GL_FALSE);
1038 switch(p_config->rotate_type) {
1040 rot = QMatrix2x2(rot0);
1043 rot = QMatrix2x2(rot90);
1046 rot = QMatrix2x2(rot180);
1049 rot = QMatrix2x2(rot270);
1052 rot = QMatrix2x2(rot0);
1055 prg->setUniformValue("rotate_mat", rot);
1056 int vertex_loc = prg->attributeLocation("vertex");
1057 int texcoord_loc = prg->attributeLocation("texcoord");
1058 prg->setAttributeBuffer(vertex_loc, GL_FLOAT, 0, 3, sizeof(VertexTexCoord_t));
1059 prg->setAttributeBuffer(texcoord_loc, GL_FLOAT, 3 * sizeof(GLfloat), 2, sizeof(VertexTexCoord_t));
1060 prg->enableAttributeArray(vertex_loc);
1061 prg->enableAttributeArray(texcoord_loc);
1062 extfunc->glEnableVertexAttribArray(vertex_loc);
1063 extfunc->glEnableVertexAttribArray(texcoord_loc);
1064 extfunc->glEnable(GL_VERTEX_ARRAY);
1065 extfunc->glDrawArrays(GL_POLYGON, 0, 4);
1069 extfunc->glBindTexture(GL_TEXTURE_2D, 0);
1070 extfunc->glDisable(GL_TEXTURE_2D);
1077 void GLDraw_3_0::drawButtons(void)
1079 for(int i = 0; i < using_flags->get_max_button(); i++) {
1080 drawButtonsMain(i, false);
1084 void GLDraw_3_0::drawBitmapTexture(void)
1086 QVector4D color = QVector4D(1.0f, 1.0f, 1.0f, 1.0f);
1087 smoosing = p_config->use_opengl_filters;
1088 if(uBitmapTextureID == NULL) return;
1089 if(using_flags->is_use_one_board_computer()) {
1090 extfunc->glDisable(GL_BLEND);
1091 drawMain(bitmap_block,
1092 uBitmapTextureID->textureId(),
1097 void GLDraw_3_0::drawLedMain(GLScreenPack *obj, int num, QVector4D color)
1099 QOpenGLShaderProgram *prg = obj->getShader();
1100 QOpenGLVertexArrayObject *vp = led_pass_vao[num];
1101 QOpenGLBuffer *bp = led_pass_vbuffer[num];
1105 extfunc->glDisable(GL_TEXTURE_2D);
1106 extfunc->glEnable(GL_BLEND);
1107 extfunc->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1111 extfunc->glViewport(0, 0, p_wid->width(), p_wid->height());
1112 extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
1113 ii = prg->uniformLocation("color");
1115 prg->setUniformValue(ii, color);
1118 prg->enableAttributeArray("vertex");
1119 int vertex_loc = prg->attributeLocation("vertex");
1120 prg->setAttributeBuffer(vertex_loc, GL_FLOAT, 0, 3, sizeof(VertexTexCoord_t));
1121 extfunc->glVertexAttribPointer(vertex_loc, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTexCoord_t), 0);
1123 extfunc->glEnableVertexAttribArray(vertex_loc);
1124 extfunc->glEnable(GL_VERTEX_ARRAY);
1125 extfunc->glDrawArrays(GL_POLYGON, 0, 4);
1130 extfunc->glDisable(GL_TEXTURE_2D);
1131 extfunc->glDisable(GL_BLEND);
1137 void GLDraw_3_0::drawOsdLeds()
1140 QVector4D color_off;
1141 uint32_t bit = 0x00000001;
1143 color_on = QVector4D(0.95, 0.0, 0.05, 1.0);
1144 color_off = QVector4D(0.05,0.05, 0.05, 0.10);
1146 color_on = QVector4D(0.00,0.00, 0.00, 0.0);
1147 color_off = QVector4D(0.00,0.00, 0.00, 0.0);
1150 //if(osd_led_status_bak != osd_led_status) {
1151 for(int i = 0; i < osd_led_bit_width; i++) {
1152 if((bit & osd_led_status) == (bit & osd_led_status_bak)) {
1156 drawLedMain(led_pass, i,
1157 ((osd_led_status & bit) != 0) ? color_on : color_off);
1160 osd_led_status_bak = osd_led_status;
1165 void GLDraw_3_0::drawOsdIcons()
1168 QVector4D color_off;
1169 uint32_t bit = 0x00000001;
1171 color_on = QVector4D(1.0, 1.0, 1.0, 0.8);
1172 color_off = QVector4D(1.0, 1.0, 1.0, 0.00);
1174 color_on = QVector4D(0.00,0.00, 0.00, 0.0);
1175 color_off = QVector4D(0.00,0.00, 0.00, 0.0);
1179 //if(osd_led_status_bak != osd_led_status) {
1180 for(int i = 0; i < osd_led_bit_width; i++) {
1181 if((bit & osd_led_status) == (bit & osd_led_status_bak)) {
1182 if((bit & osd_led_status) == 0) {
1187 if((i >= 2) && (i < 10)) { // FD
1190 } else if((i >= 10) && (i < 12)) { // QD
1193 } else if((i >= 12) && (i < 14)) { // CMT(R)
1196 } else if((i >= 14) && (i < 16)) { // CMT(W)
1203 if((major != 0) && (icon_texid[major][minor] != NULL)) {
1204 drawMain(osd_pass->getShader(), osd_pass_vao[i], osd_pass_vbuffer[i],
1205 icon_texid[major][minor]->textureId(),
1206 ((osd_led_status & bit) != 0) ? color_on : color_off,
1207 false, false, QVector3D(0.0, 0.0, 0.0));
1211 osd_led_status_bak = osd_led_status;
1216 void GLDraw_3_0::paintGL(void)
1218 //p_wid->makeCurrent();
1220 // if(crt_flag || redraw_required) { //return;
1224 redraw_required = false;
1225 extfunc->glViewport(0, 0, p_wid->width(), p_wid->height());
1226 extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
1228 extfunc->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1229 extfunc->glEnable(GL_DEPTH_TEST);
1230 extfunc->glDisable(GL_BLEND);
1231 if(using_flags->is_use_one_board_computer() || using_flags->is_use_bitmap()) {
1232 extfunc->glEnable(GL_BLEND);
1233 drawBitmapTexture();
1235 if(using_flags->get_max_button() > 0) {
1236 extfunc->glEnable(GL_BLEND);
1239 drawScreenTexture();
1240 extfunc->glEnable(GL_BLEND);
1241 extfunc->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1242 extfunc->glDisable(GL_DEPTH_TEST);
1244 if(p_config->use_osd_virtual_media) drawOsdIcons();
1245 extfunc->glDisable(GL_BLEND);
1246 if(!using_flags->is_use_one_board_computer() && (using_flags->get_max_button() <= 0)) {
1251 // extfunc->glViewport(0, 0, p_wid->width(), p_wid->height());
1252 /// extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
1254 // extfunc->glClear(GL_DEPTH_BUFFER_BIT);
1255 // extfunc->glEnable(GL_DEPTH_TEST);
1256 // extfunc->glEnable(GL_BLEND);
1259 // extfunc->glFlush();
1261 //p_wid->doneCurrent();
1264 void GLDraw_3_0::setBrightness(GLfloat r, GLfloat g, GLfloat b)
1270 if(imgptr != NULL) {
1271 p_wid->makeCurrent();
1272 if(uVramTextureID == NULL) {
1273 uVramTextureID = new QOpenGLTexture(*imgptr);
1275 if(using_flags->is_use_one_board_computer() || (using_flags->get_max_button() > 0)) {
1276 uploadMainTexture(imgptr, true);
1278 uploadMainTexture(imgptr, false);
1281 p_wid->doneCurrent();
1285 void GLDraw_3_0::set_texture_vertex(float wmul, float hmul)
1287 float wfactor = 1.0f;
1288 float hfactor = 1.0f;
1290 vertexTmpTexture[0].x = -1.0f;
1291 vertexTmpTexture[0].y = -1.0f;
1292 vertexTmpTexture[0].z = -0.1f;
1293 vertexTmpTexture[0].s = 0.0f;
1294 vertexTmpTexture[0].t = 0.0f;
1296 vertexTmpTexture[1].x = wfactor;
1297 vertexTmpTexture[1].y = -1.0f;
1298 vertexTmpTexture[1].z = -0.1f;
1299 vertexTmpTexture[1].s = wmul;
1300 vertexTmpTexture[1].t = 0.0f;
1302 vertexTmpTexture[2].x = wfactor;
1303 vertexTmpTexture[2].y = hfactor;
1304 vertexTmpTexture[2].z = -0.1f;
1305 vertexTmpTexture[2].s = wmul;
1306 vertexTmpTexture[2].t = hmul;
1308 vertexTmpTexture[3].x = -1.0f;
1309 vertexTmpTexture[3].y = hfactor;
1310 vertexTmpTexture[3].z = -0.1f;
1311 vertexTmpTexture[3].s = 0.0f;
1312 vertexTmpTexture[3].t = hmul;
1316 void GLDraw_3_0::set_osd_vertex(int xbit)
1318 float xbase, ybase, zbase;
1319 VertexTexCoord_t vertex[4];
1320 int major, minor, nl;
1322 if((xbit < 0) || (xbit >= 32)) return;
1323 if((i >= 2) && (i < 10)) { // FD
1326 nl = using_flags->get_max_drive();
1327 } else if((i >= 10) && (i < 12)) { // QD
1330 nl = using_flags->get_max_qd();
1331 } else if((i >= 12) && (i < 14)) { // CMT(R)
1334 nl = using_flags->get_max_tape();
1335 } else if((i >= 14) && (i < 16)) { // CMT(W)
1338 nl = using_flags->get_max_tape();
1339 } else if(i >= 16) {
1340 major = 4 + (i / 8) - 2;
1348 xbase = 1.0f - (1.0f * 48.0f / 640.0f) * (float)(nl - minor) - (4.0f / 640.0f);;
1349 ybase = -1.0f + (1.0f * 48.0f / 400.0f) * (float)(major + 1) + (4.0f / 400.0f);
1351 vertex[0].x = xbase;
1352 vertex[0].y = ybase;
1353 vertex[0].z = zbase;
1357 vertex[1].x = xbase + (48.0f / 640.0f);
1358 vertex[1].y = ybase;
1359 vertex[1].z = zbase;
1363 vertex[2].x = xbase + (48.0f / 640.0f);
1364 vertex[2].y = ybase - (48.0f / 400.0f);
1365 vertex[2].z = zbase;
1369 vertex[3].x = xbase;
1370 vertex[3].y = ybase - (48.0f / 400.0f);
1371 vertex[3].z = zbase;
1375 setNormalVAO(osd_pass->getShader(), osd_pass_vao[xbit],
1376 osd_pass_vbuffer[xbit],
1380 void GLDraw_3_0::set_led_vertex(int xbit)
1382 float xbase, ybase, zbase;
1383 VertexTexCoord_t vertex[4];
1385 if((xbit < 0) || (xbit >=32)) return;
1386 xbase = 0.0f + (1.0f / 32.0f) * 31.0f - ((1.0f * (float)xbit) / 32.0f) + (1.0f / 128.0f);
1387 ybase = -1.0f + (2.0f / 64.0f) * 1.5f;
1389 vertex[0].x = xbase;
1390 vertex[0].y = ybase;
1391 vertex[0].z = zbase;
1395 vertex[1].x = xbase + (1.0f / 64.0f);
1396 vertex[1].y = ybase;
1397 vertex[1].z = zbase;
1401 vertex[2].x = xbase + (1.0f / 64.0f);
1402 vertex[2].y = ybase - (1.0f / 64.0f);
1403 vertex[2].z = zbase;
1407 vertex[3].x = xbase;
1408 vertex[3].y = ybase - (1.0f / 64.0f);
1409 vertex[3].z = zbase;
1413 setNormalVAO(led_pass->getShader(), led_pass_vao[xbit],
1414 led_pass_vbuffer[xbit],
1418 void GLDraw_3_0::do_set_screen_multiply(float mul)
1420 screen_multiply = mul;
1421 do_set_texture_size(imgptr, screen_texture_width, screen_texture_height);
1424 void GLDraw_3_0::do_set_texture_size(QImage *p, int w, int h)
1426 if(w <= 0) w = using_flags->get_real_screen_width();
1427 if(h <= 0) h = using_flags->get_real_screen_height();
1431 iw = (float)p->width();
1432 ih = (float)p->height();
1434 iw = (float)using_flags->get_real_screen_width();
1435 ih = (float)using_flags->get_real_screen_height();
1437 //if((w == screen_texture_width) && (h == screen_texture_height)) return;
1438 //printf("%dx%d -> %fx%f\n", w, h, iw, ih);
1440 screen_texture_width = w;
1441 screen_texture_height = h;
1443 p_wid->makeCurrent();
1445 set_texture_vertex((float)w / iw, (float)h / ih);
1446 setNormalVAO(std_pass->getShader(), std_pass->getVAO(),
1447 std_pass->getVertexBuffer(),
1448 vertexTmpTexture, 4);
1449 //set_texture_vertex(p, p_wid->width(), p_wid->height(), w, h);
1450 set_texture_vertex((float)w / iw, (float)h / ih);
1451 setNormalVAO(ntsc_pass1->getShader(), ntsc_pass1->getVAO(),
1452 ntsc_pass1->getVertexBuffer(),
1453 vertexTmpTexture, 4);
1455 set_texture_vertex(1.0f, 1.0f);
1456 setNormalVAO(ntsc_pass2->getShader(), ntsc_pass2->getVAO(),
1457 ntsc_pass2->getVertexBuffer(),
1458 vertexTmpTexture, 4);
1462 if(uVramTextureID != NULL) delete uVramTextureID;
1463 uVramTextureID = new QOpenGLTexture(*p);
1465 vertexFormat[0].x = -1.0f;
1466 vertexFormat[0].y = -1.0f;
1467 vertexFormat[0].z = -0.9f;
1468 vertexFormat[1].x = 1.0f;
1469 vertexFormat[1].y = -1.0f;
1470 vertexFormat[1].z = -0.9f;
1471 vertexFormat[2].x = 1.0f;
1472 vertexFormat[2].y = 1.0f;
1473 vertexFormat[2].z = -0.9f;
1474 vertexFormat[3].x = -1.0f;
1475 vertexFormat[3].y = 1.0f;
1476 vertexFormat[3].z = -0.9f;
1478 vertexFormat[0].s = 0.0f;
1479 //vertexFormat[0].t = (float)h / ih;
1480 //vertexFormat[1].s = (float)w / iw;
1481 //vertexFormat[1].t = (float)h / ih;
1482 //vertexFormat[2].s = (float)w / iw;
1483 vertexFormat[0].t = 1.0f;
1484 vertexFormat[1].s = 1.0f;
1485 vertexFormat[1].t = 1.0f;
1486 vertexFormat[2].s = 1.0f;
1487 vertexFormat[2].t = 0.0f;
1488 vertexFormat[3].s = 0.0f;
1489 vertexFormat[3].t = 0.0f;
1491 setNormalVAO(main_pass->getShader(), main_pass->getVAO(),
1492 main_pass->getVertexBuffer(),
1495 if(w > using_flags->get_real_screen_width()) {
1496 w = using_flags->get_real_screen_width();
1498 if(h > using_flags->get_real_screen_height()) {
1499 h = using_flags->get_real_screen_height();
1501 this->doSetGridsHorizonal(h, false);
1502 this->doSetGridsVertical(w, false);
1503 p_wid->doneCurrent();
1506 void GLDraw_3_0::do_set_horiz_lines(int lines)
1508 if(lines > using_flags->get_real_screen_height()) {
1509 lines = using_flags->get_real_screen_height();
1511 this->doSetGridsHorizonal(lines, false);
1514 void GLDraw_3_0::resizeGL_Screen(void)
1516 if(main_pass != NULL) {
1517 setNormalVAO(main_pass->getShader(), main_pass->getVAO(),
1518 main_pass->getVertexBuffer(),
1523 void GLDraw_3_0::resizeGL(int width, int height)
1525 //int side = qMin(width, height);
1526 p_wid->makeCurrent();
1527 extfunc->glViewport(0, 0, width, height);
1528 extfunc->glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0, 1.0);
1530 if(!using_flags->is_use_one_board_computer() && (using_flags->get_max_button() <= 0)) {
1531 doSetGridsHorizonal(vert_lines, true);
1532 if(using_flags->is_use_vertical_pixel_lines()) {
1533 doSetGridsVertical(horiz_pixels, true);
1536 resizeGL_SetVertexs();
1538 if(using_flags->is_use_one_board_computer()) {
1539 setNormalVAO(bitmap_block->getShader(), bitmap_block->getVAO(),
1540 bitmap_block->getVertexBuffer(),
1543 if(using_flags->get_max_button() > 0) {
1544 updateButtonTexture();
1546 p_wid->doneCurrent();