]> Shamusworld >> Repos - virtualjaguar/blob - src/gui/glwidget.cpp
2501ad8296a1d100c9bd3a2815718ef675edc878
[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 L. Hammons
5 // (C) 2010 Underground Software
6 //
7 // JLH = James L. 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(320), rasterHeight(240)
27 {
28 //      tomDeviceWidth = rasterWidth;
29         tomDeviceWidth = 1024;  // It has to be the texture width...
30
31         // Set up the backbuffer
32         // To be safe, this should be 1280 * 625 * 2...
33         backbuffer = (uint32_t *)malloc(1280 * 625 * sizeof(uint32_t));
34 //      memset(backbuffer, 0x44, rasterWidth *
35         memset(backbuffer, 0xFF, 1024 *
36                 (vjs.hardwareTypeNTSC ? rasterHeight : VIRTUAL_SCREEN_HEIGHT_PAL)
37                 * sizeof(uint32_t));
38 }
39
40 GLWidget::~GLWidget()
41 {
42         free(backbuffer);
43 }
44
45 void GLWidget::initializeGL()
46 {
47         format().setDoubleBuffer(true);
48         resizeGL(rasterWidth, rasterHeight);
49
50         glDisable(GL_ALPHA_TEST);
51         glDisable(GL_BLEND);
52         glDisable(GL_DEPTH_TEST);
53         glDisable(GL_POLYGON_SMOOTH);
54         glDisable(GL_STENCIL_TEST);
55         glEnable(GL_DITHER);
56         glEnable(GL_TEXTURE_2D);
57         glClearColor(0.0, 0.0, 0.0, 0.0);
58 }
59
60 void GLWidget::paintGL()
61 {
62 //kludge
63 rasterHeight = (vjs.hardwareTypeNTSC ? 240 : 256);
64
65         unsigned outputWidth  = width();
66         unsigned outputHeight = height();
67
68         glMatrixMode(GL_PROJECTION);
69         glLoadIdentity();
70         glOrtho(0, outputWidth, 0, outputHeight, -1.0, 1.0);
71         glViewport(0, 0, outputWidth, outputHeight);
72
73         glMatrixMode(GL_MODELVIEW);
74         glLoadIdentity();
75
76         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (vjs.glFilter ? GL_LINEAR : GL_NEAREST));
77         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (vjs.glFilter ? GL_LINEAR : GL_NEAREST));
78 //      glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, rasterWidth, rasterHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, buffer);
79 //more kludge
80         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, TOMGetVideoModeWidth(), rasterHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, buffer);
81 //      glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, rasterWidth, rasterHeight, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, buffer);
82
83         double w = (double)TOMGetVideoModeWidth()  / (double)textureWidth;
84 //      double w = (double)rasterWidth  / (double)textureWidth;
85         double h = (double)rasterHeight / (double)textureHeight;
86         unsigned u = outputWidth;
87         unsigned v = outputHeight;
88
89         glBegin(GL_TRIANGLE_STRIP);
90         glTexCoord2f(0, 0); glVertex3i(0, v, 0);
91         glTexCoord2f(w, 0); glVertex3i(u, v, 0);
92         glTexCoord2f(0, h); glVertex3i(0, 0, 0);
93         glTexCoord2f(w, h); glVertex3i(u, 0, 0);
94         glEnd();
95 }
96
97 void GLWidget::resizeGL(int width, int height)
98 {
99         if (width > textureWidth || height > textureHeight)
100         {
101 //              textureWidth  = max(width,  textureWidth);
102 //              textureHeight = max(height, textureHeight);
103 // Seems that power of 2 sizes are still mandatory...
104                 textureWidth  = 1024;//(width > textureWidth ? width : textureWidth);
105                 textureHeight = 512;//(height > textureHeight ? height : textureHeight);
106 //              textureWidth  = (width > textureWidth ? width : textureWidth);
107 //              textureHeight = (height > textureHeight ? height : textureHeight);
108 #if 0
109 printf("Resizing: new texture width/height = %i x %i\n", textureWidth, textureHeight);
110 printf("Resizing: new raster width/height = %i x %i\n", rasterWidth, rasterHeight);
111 #endif
112
113                 if (buffer)
114                 {
115                         delete[] buffer;
116                         glDeleteTextures(1, &texture);
117                 }
118
119                 buffer = new uint32_t[textureWidth * textureHeight];
120 //???
121 memset(buffer, 0x00, textureWidth * textureHeight * sizeof(uint32_t));
122                 glGenTextures(1, &texture);
123                 glBindTexture(GL_TEXTURE_2D, texture);
124                 glPixelStorei(GL_UNPACK_ROW_LENGTH, textureWidth);
125                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
126                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
127 //              glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, textureWidth, textureHeight, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
128                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, NULL);
129         }
130 }
131
132 #if 0
133 class RubyGLWidget: public QGLWidget
134 {
135   public:
136     GLuint texture;
137     unsigned textureWidth, textureHeight;
138
139     uint32_t * buffer;
140     unsigned rasterWidth, rasterHeight;
141
142     bool synchronize;
143     unsigned filter;
144
145     void updateSynchronization() {
146       #ifdef __APPLE__
147       makeCurrent();
148       CGLContextObj context = CGLGetCurrentContext();
149       GLint value = synchronize;  //0 = draw immediately (no vsync), 1 = draw once per frame (vsync)
150       CGLSetParameter(context, kCGLCPSwapInterval, &value);
151       #endif
152     }
153 } * widget;
154 #endif