]> Shamusworld >> Repos - virtualjaguar/blob - src/gui/glwidget.cpp
65ccd57982ccd7f7ea42d6658333c67e0e17fb5d
[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 #warning "!!! Remove all backbuffer stuff, since it's unneeded !!!"
121 /*
122 We do this here just as a quick 'n' dirty shortcut. We don't need a backbuffer,
123 as OpenGL takes care of all that crap for us. This means we also have to fix the
124 Jaguar core, giving it a setup function for setting things like the video buffer,
125 etc.
126 */
127                 backbuffer = buffer;
128
129 //???
130 memset(buffer, 0x00, textureWidth * textureHeight * sizeof(uint32_t));
131                 glGenTextures(1, &texture);
132                 glBindTexture(GL_TEXTURE_2D, texture);
133                 glPixelStorei(GL_UNPACK_ROW_LENGTH, textureWidth);
134                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
135                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
136 //              glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, textureWidth, textureHeight, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
137                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, NULL);
138         }
139 }
140
141 #if 0
142 class RubyGLWidget: public QGLWidget
143 {
144   public:
145     GLuint texture;
146     unsigned textureWidth, textureHeight;
147
148     uint32_t * buffer;
149     unsigned rasterWidth, rasterHeight;
150
151     bool synchronize;
152     unsigned filter;
153
154     void updateSynchronization() {
155       #ifdef __APPLE__
156       makeCurrent();
157       CGLContextObj context = CGLGetCurrentContext();
158       GLint value = synchronize;  //0 = draw immediately (no vsync), 1 = draw once per frame (vsync)
159       CGLSetParameter(context, kCGLCPSwapInterval, &value);
160       #endif
161     }
162 } * widget;
163 #endif