1 /******************************************************************************
2 * Arachnoid Graphics Plugin for Mupen64Plus
3 * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
5 * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
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.
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.
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 *****************************************************************************/
22 #include "FrameBuffer.h"
26 #ifndef GL_GLEXT_VERSION
28 //-----------------------------------------------------------------------------
29 //OpenGL Texture Definitions
30 //-----------------------------------------------------------------------------
31 typedef GLvoid (APIENTRY *PFNGLACTIVETEXTUREPROC) (GLenum texture);
32 PFNGLACTIVETEXTUREPROC glActiveTexture = NULL;
37 #define GL_TEXTURE0 0x84C0
39 #ifndef GL_CLAMP_TO_EDGE
40 #define GL_CLAMP_TO_EDGE 0x812F
43 //-----------------------------------------------------------------------------
45 //-----------------------------------------------------------------------------
46 FrameBuffer::FrameBuffer()
51 //-----------------------------------------------------------------------------
53 //-----------------------------------------------------------------------------
54 FrameBuffer::~FrameBuffer()
59 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
64 void FrameBuffer::initialize(int width, int height)
69 int channels = 3; //!< RGB=3 or RGBA=4
72 unsigned char* data = new unsigned char[width * height * channels];
73 memset(data, 0, width * height * channels * sizeof(unsigned char));
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);
79 //Create the texture and store it on the video card
82 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
84 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
86 glTexImage2D(GL_TEXTURE_2D, 0, channels, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
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);
94 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
95 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
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);
101 //Delete data (no need for it when it is stored in video card)
106 //-----------------------------------------------------------------------------
108 //-----------------------------------------------------------------------------
109 void FrameBuffer::dispose()
113 glDeleteTextures(1, &m_id);
118 //-----------------------------------------------------------------------------
120 //-----------------------------------------------------------------------------
121 void FrameBuffer::resize(int width, int height)
124 initialize(width, height);
127 //-----------------------------------------------------------------------------
130 //-----------------------------------------------------------------------------
131 void FrameBuffer::beginRendering()
134 glGetIntegerv(GL_VIEWPORT, m_oldViewport);
136 //Set new viewport for texture
137 //glViewport(0, 20, m_width, m_height);
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);
144 // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
147 //-----------------------------------------------------------------------------
149 //! Will save all rendering to a texture
150 //-----------------------------------------------------------------------------
151 void FrameBuffer::endRendering()
157 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 20, m_width, m_height );
159 //TODO Deactivate texture?
163 //glViewport(m_oldViewport[0], m_oldViewport[1], m_oldViewport[2], m_oldViewport[3]);
166 //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
169 //-----------------------------------------------------------------------------
171 //! Will render frame buffer to screen.
172 //-----------------------------------------------------------------------------
173 void FrameBuffer::render()
176 glMatrixMode(GL_PROJECTION);
179 //glOrtho( 0, m_width, 0, m_height, -1.0f, 1.0f );
180 //glViewport( 0, 0, m_width, m_height );
181 glMatrixMode(GL_MODELVIEW);
184 //glPushAttrib(GL_LIGHTING_BIT);
185 glDisable(GL_LIGHTING);
187 //Render QUAD (using framebuffer texture)
203 glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
205 GLboolean glcol = glIsEnabled(GL_COLOR_ARRAY);
206 if (glcol) glDisableClientState(GL_COLOR_ARRAY);
207 GLboolean glvtx = glIsEnabled(GL_VERTEX_ARRAY);
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);
218 glDrawArrays(GL_TRIANGLE_FAN,0,4);
220 if (glcol) glEnableClientState(GL_COLOR_ARRAY);
221 glActiveTexture( GL_TEXTURE1 );
222 if (gltex1) glEnable(GL_TEXTURE_2D);
224 glDisableClientState(GL_VERTEX_ARRAY);
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 );
230 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
234 glColor3f(0.0f, 0.0f, 1.0f);
243 glColor3f(1.0f, 1.0f, 1.0f);
252 glMatrixMode(GL_MODELVIEW);
254 glMatrixMode(GL_PROJECTION);
258 //-----------------------------------------------------------------------------
260 //! Will render frame buffer to screen.
261 //-----------------------------------------------------------------------------
262 void FrameBuffer::render2()
265 glMatrixMode(GL_PROJECTION);
268 //glOrtho( 0, m_width, 0, m_height, -1.0f, 1.0f );
269 //glViewport( 0, 0, m_width, m_height );
270 glMatrixMode(GL_MODELVIEW);
273 //glPushAttrib(GL_LIGHTING_BIT);
274 glDisable(GL_LIGHTING);
276 //Render QUAD (using framebuffer texture)
293 GLboolean glcol = glIsEnabled(GL_COLOR_ARRAY);
294 if (glcol) glDisableClientState(GL_COLOR_ARRAY);
295 GLboolean glvtx = glIsEnabled(GL_VERTEX_ARRAY);
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);
306 glDrawArrays(GL_TRIANGLE_FAN,0,4);
308 if (glcol) glEnableClientState(GL_COLOR_ARRAY);
309 glActiveTexture( GL_TEXTURE1 );
310 if (gltex1) glEnable(GL_TEXTURE_2D);
312 glDisableClientState(GL_VERTEX_ARRAY);
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 );
318 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
330 glColor3f(1.0f, 1.0f, 1.0f);
339 glMatrixMode(GL_MODELVIEW);
341 glMatrixMode(GL_PROJECTION);
345 //-----------------------------------------------------------------------------
347 //-----------------------------------------------------------------------------
348 void FrameBuffer::_activate()
350 //Activate Texture (so we can copy to it)
351 #ifndef GL_GLEXT_VERSION
353 if ( glActiveTexture == 0 ) {
354 glActiveTexture = (PFNGLACTIVETEXTUREPROC) CoreVideo_GL_GetProcAddress("glActiveTexture");
358 glActiveTexture(GL_TEXTURE0);
359 glEnable(GL_TEXTURE_2D);
360 glBindTexture(GL_TEXTURE_2D, m_id);
363 //-----------------------------------------------------------------------------
365 //-----------------------------------------------------------------------------
366 void FrameBuffer::_deactivate()
368 glActiveTexture((GLuint)GL_TEXTURE0);
369 glDisable(GL_TEXTURE_2D);
370 glBindTexture(GL_TEXTURE_2D, 0);