]> Shamusworld >> Repos - virtualjaguar/blob - src/gui/glwidget.cpp
56fcd0ed824de8490a95cf8e3440b935310dbe8a
[virtualjaguar] / src / gui / glwidget.cpp
1 // OpenGL implementation in Qt
2 // Parts of this are blantantly ripped off from BSNES (thanks Byuu!)
3 //
4 // by James Hammons
5 // (C) 2010 Underground Software
6 //
7 // JLH = James Hammons <jlhamm@acm.org>
8 //
9 // Who  When        What
10 // ---  ----------  -------------------------------------------------------------
11 // JLH  01/14/2010  Created this file
12 //
13
14 #include "glwidget.h"
15
16 #include "jaguar.h"
17 #include "settings.h"
18 #include "tom.h"
19
20 #ifdef __GCCWIN32__
21 // Apparently on win32, various OpenGL constants aren't pulled in.
22 #include <GL/glext.h>
23 #endif
24
25 GLWidget::GLWidget(QWidget * parent/*= 0*/): QGLWidget(parent), texture(0),
26         textureWidth(0), textureHeight(0), buffer(0), rasterWidth(340), rasterHeight(240)
27 {
28         // Screen pitch has to be the texture width (in 32-bit pixels)...
29         JaguarSetScreenPitch(1024);
30 }
31
32 GLWidget::~GLWidget()
33 {
34 //      free(backbuffer);
35 }
36
37 void GLWidget::initializeGL()
38 {
39         format().setDoubleBuffer(true);
40         resizeGL(rasterWidth, rasterHeight);
41
42         glDisable(GL_ALPHA_TEST);
43         glDisable(GL_BLEND);
44         glDisable(GL_DEPTH_TEST);
45         glDisable(GL_POLYGON_SMOOTH);
46         glDisable(GL_STENCIL_TEST);
47         glEnable(GL_DITHER);
48         glEnable(GL_TEXTURE_2D);
49         glClearColor(0.0, 0.0, 0.0, 0.0);
50 }
51
52 void GLWidget::paintGL()
53 {
54 //kludge
55 rasterHeight = (vjs.hardwareTypeNTSC ? VIRTUAL_SCREEN_HEIGHT_NTSC : VIRTUAL_SCREEN_HEIGHT_PAL);
56
57         unsigned outputWidth  = width();
58         unsigned outputHeight = height();
59
60         glMatrixMode(GL_PROJECTION);
61         glLoadIdentity();
62         glOrtho(0, outputWidth, 0, outputHeight, -1.0, 1.0);
63         glViewport(0, 0, outputWidth, outputHeight);
64
65         glMatrixMode(GL_MODELVIEW);
66         glLoadIdentity();
67
68         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (vjs.glFilter ? GL_LINEAR : GL_NEAREST));
69         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (vjs.glFilter ? GL_LINEAR : GL_NEAREST));
70 //      glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, rasterWidth, rasterHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, buffer);
71 //more kludge
72         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, TOMGetVideoModeWidth(), rasterHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, buffer);
73 //      glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, rasterWidth, rasterHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, buffer);
74
75         double w = (double)TOMGetVideoModeWidth()  / (double)textureWidth;
76 //      double w = (double)rasterWidth  / (double)textureWidth;
77         double h = (double)rasterHeight / (double)textureHeight;
78         unsigned u = outputWidth;
79         unsigned v = outputHeight;
80
81         glBegin(GL_TRIANGLE_STRIP);
82         glTexCoord2f(0, 0); glVertex3i(0, v, 0);
83         glTexCoord2f(w, 0); glVertex3i(u, v, 0);
84         glTexCoord2f(0, h); glVertex3i(0, 0, 0);
85         glTexCoord2f(w, h); glVertex3i(u, 0, 0);
86         glEnd();
87 }
88
89 void GLWidget::resizeGL(int width, int height)
90 {
91         if (width > textureWidth || height > textureHeight)
92         {
93                 // Seems that power of 2 sizes are still mandatory...
94                 textureWidth  = 1024;
95                 textureHeight = 512;
96 #if 0
97 printf("Resizing: new texture width/height = %i x %i\n", textureWidth, textureHeight);
98 printf("Resizing: new raster width/height = %i x %i\n", rasterWidth, rasterHeight);
99 #endif
100
101                 if (buffer)
102                 {
103                         delete[] buffer;
104                         glDeleteTextures(1, &texture);
105                 }
106
107                 buffer = new uint32_t[textureWidth * textureHeight];
108                 JaguarSetScreenBuffer(buffer);
109
110 //???
111 memset(buffer, 0xFF, textureWidth * textureHeight * sizeof(uint32_t));
112                 glGenTextures(1, &texture);
113                 glBindTexture(GL_TEXTURE_2D, texture);
114                 glPixelStorei(GL_UNPACK_ROW_LENGTH, textureWidth);
115                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
116                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
117                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, NULL);
118         }
119 }
120
121 #if 0
122 class RubyGLWidget: public QGLWidget
123 {
124   public:
125     GLuint texture;
126     unsigned textureWidth, textureHeight;
127
128     uint32_t * buffer;
129     unsigned rasterWidth, rasterHeight;
130
131     bool synchronize;
132     unsigned filter;
133
134     void updateSynchronization() {
135       #ifdef __APPLE__
136       makeCurrent();
137       CGLContextObj context = CGLGetCurrentContext();
138       GLint value = synchronize;  //0 = draw immediately (no vsync), 1 = draw once per frame (vsync)
139       CGLSetParameter(context, kCGLCPSwapInterval, &value);
140       #endif
141     }
142 } * widget;
143 #endif