Arachnoid GLESv1.1 plugin. Compile and run (a bit glitchy and no frameskip) on the...
[mupen64plus-pandora.git] / source / mupen64plus-video-arachnoid / src / framebuffer / FrameBuffer.cpp
CommitLineData
22726e4d 1/******************************************************************************
2 * Arachnoid Graphics Plugin for Mupen64Plus
3 * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
4 *
5 * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *****************************************************************************/
21
22#include "FrameBuffer.h"
23#include "m64p.h"
24#include "OpenGL.h"
25
26#ifndef GL_GLEXT_VERSION
27#ifndef HAVE_GLES
28 //-----------------------------------------------------------------------------
29 //OpenGL Texture Definitions
30 //-----------------------------------------------------------------------------
31 typedef GLvoid (APIENTRY *PFNGLACTIVETEXTUREPROC) (GLenum texture);
32 PFNGLACTIVETEXTUREPROC glActiveTexture = NULL;
33#endif
34#endif
35
36#ifndef GL_TEXTURE0
37 #define GL_TEXTURE0 0x84C0
38#endif
39#ifndef GL_CLAMP_TO_EDGE
40 #define GL_CLAMP_TO_EDGE 0x812F
41#endif
42
43//-----------------------------------------------------------------------------
44//! Constructor
45//-----------------------------------------------------------------------------
46FrameBuffer::FrameBuffer()
47{
48 m_id = ~0U;
49}
50
51//-----------------------------------------------------------------------------
52//! Destructor
53//-----------------------------------------------------------------------------
54FrameBuffer::~FrameBuffer()
55{
56
57}
58
59//-----------------------------------------------------------------------------
60//* Initialize
61//! @param width Width of framebuffer, usually equal to window-client-width
62//! @param height Height of framebuffer, usually equal to window-client-height
63//-----------------------------------------------------------------------------
64void FrameBuffer::initialize(int width, int height)
65{
66 //Save parameters
67 m_width = width;
68 m_height = height;
69 int channels = 3; //!< RGB=3 or RGBA=4
70
71 //Allocate memory
72 unsigned char* data = new unsigned char[width * height * channels];
73 memset(data, 0, width * height * channels * sizeof(unsigned char));
74
75 //Register the texture with OpenGL and bind it to the texture ID
76 glGenTextures(1, &m_id);
77 glBindTexture(GL_TEXTURE_2D, m_id);
78
79 //Create the texture and store it on the video card
80#ifdef HAVE_GLES
81 if (channels == 3)
82 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
83 else
84 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
85#else
86 glTexImage2D(GL_TEXTURE_2D, 0, channels, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
87#endif
88
89 //No texure filtering
90 //glPixelStorei(GL_UNPACK_ALIGNMENT, 1 );
91 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
92 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
93
94 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
95 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
96
97 //Clamp texture to edges
98 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
99 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
100
101 //Delete data (no need for it when it is stored in video card)
102 delete[] data;
103 data = 0;
104}
105
106//-----------------------------------------------------------------------------
107// Dispose
108//-----------------------------------------------------------------------------
109void FrameBuffer::dispose()
110{
111 if ( m_id != ~0U )
112 {
113 glDeleteTextures(1, &m_id);
114 m_id = -1;
115 }
116}
117
118//-----------------------------------------------------------------------------
119// Resize
120//-----------------------------------------------------------------------------
121void FrameBuffer::resize(int width, int height)
122{
123 dispose();
124 initialize(width, height);
125}
126
127//-----------------------------------------------------------------------------
128//* Begin Rendering
129//!
130//-----------------------------------------------------------------------------
131void FrameBuffer::beginRendering()
132{
133 //Get viewport
134 glGetIntegerv(GL_VIEWPORT, m_oldViewport);
135
136 //Set new viewport for texture
137 //glViewport(0, 20, m_width, m_height);
138
139 //glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
140 //glClear(GL_COLOR_BUFFER_BIT);
141 //glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
142
143 //Clear Buffers
144 // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
145}
146
147//-----------------------------------------------------------------------------
148//* End Rendering
149//! Will save all rendering to a texture
150//-----------------------------------------------------------------------------
151void FrameBuffer::endRendering()
152{
153 //Activate texture
154 _activate();
155
156 //Render to Texture
157 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 20, m_width, m_height );
158
159 //TODO Deactivate texture?
160 //_deactivate();
161
162 //Reset Viewport
163 //glViewport(m_oldViewport[0], m_oldViewport[1], m_oldViewport[2], m_oldViewport[3]);
164
165 //Clear Buffers
166 //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
167}
168
169//-----------------------------------------------------------------------------
170//* Render
171//! Will render frame buffer to screen.
172//-----------------------------------------------------------------------------
173void FrameBuffer::render()
174{
175 //Push states
176 glMatrixMode(GL_PROJECTION);
177 glPushMatrix();
178 glLoadIdentity();
179 //glOrtho( 0, m_width, 0, m_height, -1.0f, 1.0f );
180 //glViewport( 0, 0, m_width, m_height );
181 glMatrixMode(GL_MODELVIEW);
182 glPushMatrix();
183 glLoadIdentity();
184 //glPushAttrib(GL_LIGHTING_BIT);
185 glDisable(GL_LIGHTING);
186
187 //Render QUAD (using framebuffer texture)
188 _activate();
189 {
190#ifdef HAVE_GLES
191 GLfloat tex[] = {
192 0, 0,
193 1, 0,
194 1, 1,
195 0, 1
196 };
197 GLfloat vtx[] = {
198 -1, -1, 0,
199 0, -1, 0,
200 0, 0, 0,
201 -1, 0, 0
202 };
203 glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
204
205 GLboolean glcol = glIsEnabled(GL_COLOR_ARRAY);
206 if (glcol) glDisableClientState(GL_COLOR_ARRAY);
207 GLboolean glvtx = glIsEnabled(GL_VERTEX_ARRAY);
208 if (!glvtx)
209 glEnableClientState(GL_VERTEX_ARRAY);
210 glVertexPointer(3,GL_FLOAT, 0,&vtx);
211 glActiveTexture( GL_TEXTURE1 );
212 GLboolean gltex1 = glIsEnabled(GL_TEXTURE_2D);
213 if (gltex1) glDisable(GL_TEXTURE_2D);
214 glActiveTexture( GL_TEXTURE0 );
215 glClientActiveTexture( GL_TEXTURE0 );
216 glTexCoordPointer(2, GL_FLOAT, 0, &tex);
217 // draw
218 glDrawArrays(GL_TRIANGLE_FAN,0,4);
219 // restaure
220 if (glcol) glEnableClientState(GL_COLOR_ARRAY);
221 glActiveTexture( GL_TEXTURE1 );
222 if (gltex1) glEnable(GL_TEXTURE_2D);
223 if (!glvtx)
224 glDisableClientState(GL_VERTEX_ARRAY);
225 else
226 glVertexPointer(glsav_vtx_size, glsav_vtx_type, glsav_vtx_stride, glsav_vtx_array );
227 glActiveTexture( GL_TEXTURE0 );
228 glTexCoordPointer( glsav_tex_size, glsav_tex_type, glsav_tex_stride, glsav_tex_array );
229
230 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
231#else
232 glBegin(GL_QUADS);
233 {
234 glColor3f(0.0f, 0.0f, 1.0f);
235 glTexCoord2f(0,0);
236 glVertex3f(-1,-1,0);
237 glTexCoord2f(1,0);
238 glVertex3f( 0,-1,0);
239 glTexCoord2f(1,1);
240 glVertex3f( 0, 0,0);
241 glTexCoord2f(0,1);
242 glVertex3f(-1, 0,0);
243 glColor3f(1.0f, 1.0f, 1.0f);
244 }
245 glEnd();
246#endif
247 }
248 _deactivate();
249
250 //Pop states
251 //glPopAttrib();
252 glMatrixMode(GL_MODELVIEW);
253 glPopMatrix();
254 glMatrixMode(GL_PROJECTION);
255 glPopMatrix();
256}
257
258//-----------------------------------------------------------------------------
259//* Render
260//! Will render frame buffer to screen.
261//-----------------------------------------------------------------------------
262void FrameBuffer::render2()
263{
264 //Push states
265 glMatrixMode(GL_PROJECTION);
266 glPushMatrix();
267 glLoadIdentity();
268 //glOrtho( 0, m_width, 0, m_height, -1.0f, 1.0f );
269 //glViewport( 0, 0, m_width, m_height );
270 glMatrixMode(GL_MODELVIEW);
271 glPushMatrix();
272 glLoadIdentity();
273 //glPushAttrib(GL_LIGHTING_BIT);
274 glDisable(GL_LIGHTING);
275
276 //Render QUAD (using framebuffer texture)
277 _activate();
278 {
279#ifdef HAVE_GLES
280 GLfloat tex[] = {
281 0, 0,
282 1, 0,
283 1, 1,
284 0, 1
285 };
286 GLfloat vtx[] = {
287 -1, -1, 0,
288 0, -1, 0,
289 0, 0, 0,
290 -1, 0, 0
291 };
292
293 GLboolean glcol = glIsEnabled(GL_COLOR_ARRAY);
294 if (glcol) glDisableClientState(GL_COLOR_ARRAY);
295 GLboolean glvtx = glIsEnabled(GL_VERTEX_ARRAY);
296 if (!glvtx)
297 glEnableClientState(GL_VERTEX_ARRAY);
298 glVertexPointer(3,GL_FLOAT, 0,&vtx);
299 glActiveTexture( GL_TEXTURE1 );
300 GLboolean gltex1 = glIsEnabled(GL_TEXTURE_2D);
301 if (gltex1) glDisable(GL_TEXTURE_2D);
302 glActiveTexture( GL_TEXTURE0 );
303 glClientActiveTexture( GL_TEXTURE0 );
304 glTexCoordPointer(2, GL_FLOAT, 0, &tex);
305 // draw
306 glDrawArrays(GL_TRIANGLE_FAN,0,4);
307 // restaure
308 if (glcol) glEnableClientState(GL_COLOR_ARRAY);
309 glActiveTexture( GL_TEXTURE1 );
310 if (gltex1) glEnable(GL_TEXTURE_2D);
311 if (!glvtx)
312 glDisableClientState(GL_VERTEX_ARRAY);
313 else
314 glVertexPointer(glsav_vtx_size, glsav_vtx_type, glsav_vtx_stride, glsav_vtx_array );
315 glActiveTexture( GL_TEXTURE0 );
316 glTexCoordPointer( glsav_tex_size, glsav_tex_type, glsav_tex_stride, glsav_tex_array );
317
318 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
319#else
320 glBegin(GL_QUADS);
321 {
322 glTexCoord2f(0,0);
323 glVertex3f(-1,-1,0);
324 glTexCoord2f(1,0);
325 glVertex3f( 1,-1,0);
326 glTexCoord2f(1,1);
327 glVertex3f( 1, 1,0);
328 glTexCoord2f(0,1);
329 glVertex3f(-1, 1,0);
330 glColor3f(1.0f, 1.0f, 1.0f);
331 }
332 glEnd();
333#endif
334 }
335 _deactivate();
336
337 //Pop states
338 //glPopAttrib();
339 glMatrixMode(GL_MODELVIEW);
340 glPopMatrix();
341 glMatrixMode(GL_PROJECTION);
342 glPopMatrix();
343}
344
345//-----------------------------------------------------------------------------
346// Activate
347//-----------------------------------------------------------------------------
348void FrameBuffer::_activate()
349{
350 //Activate Texture (so we can copy to it)
351#ifndef GL_GLEXT_VERSION
352#ifndef HAVE_GLES
353 if ( glActiveTexture == 0 ) {
354 glActiveTexture = (PFNGLACTIVETEXTUREPROC) CoreVideo_GL_GetProcAddress("glActiveTexture");
355 }
356#endif
357#endif
358 glActiveTexture(GL_TEXTURE0);
359 glEnable(GL_TEXTURE_2D);
360 glBindTexture(GL_TEXTURE_2D, m_id);
361}
362
363//-----------------------------------------------------------------------------
364// Deactivate
365//-----------------------------------------------------------------------------
366void FrameBuffer::_deactivate()
367{
368 glActiveTexture((GLuint)GL_TEXTURE0);
369 glDisable(GL_TEXTURE_2D);
370 glBindTexture(GL_TEXTURE_2D, 0);
371}