Enable FBO support; fix a couple bugs.
Enable framebuffer object support. I'm starting to see the value of
GLEW, but the implementations available don't handle GLES very well. A
primitive attempt at cross-platform compatibility at the source code
level was attempted, but the Correct Solution is runtime adaptation.
Fixed a bug in PCM.cpp; it now properly scales int16_t values to the
range -1.0 - 1.0.
Fixed a bug in Renderable.cpp; 'size' can be zero, leading to an attempt
to allocate and render a buffer of zero size. While the code correctly
handles zero-sized buffers, it's better to avoid it entirely.
diff --git a/src/libprojectM/PCM.cpp b/src/libprojectM/PCM.cpp
index 1caebd4..03aafe9 100644
--- a/src/libprojectM/PCM.cpp
+++ b/src/libprojectM/PCM.cpp
@@ -146,8 +146,8 @@
for (i = 0; i < samples; ++i) {
j = i + start;
- PCMd[0][j % maxsamples] = (pcm_data[i * 2 + 0] / 16384.0);
- PCMd[1][j % maxsamples] = (pcm_data[i * 2 + 1] / 16384.0);
+ PCMd[0][j % maxsamples] = (pcm_data[i * 2 + 0] / 32768.0);
+ PCMd[1][j % maxsamples] = (pcm_data[i * 2 + 1] / 32768.0);
}
start = (start + samples) % maxsamples;
@@ -172,8 +172,8 @@
for (i = 0; i < samples; i++) {
j = i + start;
if (PCMdata[0][i] != 0 && PCMdata[1][i] != 0) {
- PCMd[0][j % maxsamples] = (PCMdata[0][i] / 16384.0);
- PCMd[1][j % maxsamples] = (PCMdata[1][i] / 16384.0);
+ PCMd[0][j % maxsamples] = (PCMdata[0][i] / 32768.0);
+ PCMd[1][j % maxsamples] = (PCMdata[1][i] / 32768.0);
} else {
PCMd[0][j % maxsamples] = (float) 0;
PCMd[1][j % maxsamples] = (float) 0;
diff --git a/src/libprojectM/Renderer/FBO.cpp b/src/libprojectM/Renderer/FBO.cpp
index fe86e8f..06aa4fd 100644
--- a/src/libprojectM/Renderer/FBO.cpp
+++ b/src/libprojectM/Renderer/FBO.cpp
@@ -24,6 +24,7 @@
* Render this methods
*/
#include <stdio.h>
+#include <string.h>
//#include <GL/gl.h>
#include <iostream>
#include "Common.hpp"
@@ -39,13 +40,13 @@
if (useFBO)
{
glDeleteTextures (1, &this->textureID[1]);
- glDeleteRenderbuffersEXT (1, &this->depthb[0]);
- glDeleteFramebuffersEXT (1, &this->fbuffer[0]);
+ glDeleteRenderbuffers (1, &this->depthb[0]);
+ glDeleteFramebuffers (1, &this->fbuffer[0]);
if (renderToTexture)
{
glDeleteTextures (1, &this->textureID[2]);
- glDeleteRenderbuffersEXT (1, &this->depthb[1]);
- glDeleteFramebuffersEXT (1, &this->fbuffer[1]);
+ glDeleteRenderbuffers (1, &this->depthb[1]);
+ glDeleteFramebuffers (1, &this->fbuffer[1]);
}
}
#endif
@@ -60,13 +61,13 @@
GLuint fb2, depth_rb2;
- glGenFramebuffersEXT (1, &fb2);
- glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, fb2);
- glGenRenderbuffersEXT (1, &depth_rb2);
- glBindRenderbufferEXT (GL_RENDERBUFFER_EXT, depth_rb2);
+ glGenFramebuffers (1, &fb2);
+ glBindFramebuffer (GL_FRAMEBUFFER, fb2);
+ glGenRenderbuffers (1, &depth_rb2);
+ glBindRenderbuffer (GL_RENDERBUFFER, depth_rb2);
- glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, this->texsize,this->texsize );
- glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_rb2);
+ glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, this->texsize,this->texsize );
+ glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_rb2);
this->fbuffer[1] = fb2;
this->depthb[1]= depth_rb2;
glGenTextures (1, &this->textureID[2]);
@@ -74,9 +75,14 @@
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, texsize, texsize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+#ifdef USE_GLES1
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+#else
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
- glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, this->textureID[2], 0);
+#endif
+ glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, this->textureID[2], 0);
return this->textureID[2];
}
#endif
@@ -94,25 +100,49 @@
this->texsize = texsize;
#ifdef USE_FBO
- // Forceably disable FBO if user requested it but the video card / driver lacks
+ // Forcibly disable FBO if user requested it but the video card / driver lacks
// the appropraite frame buffer extension.
- useFBO = !!strstr ((char const *) glGetString (GL_EXTENSIONS),
+
#ifdef USE_GLES1
- "GL_OES_framebuffer_object"
+ /*
+ * FBO support is never part of GLES1 core; check for extension.
+ */
+ useFBO = !!strstr ((char const *) glGetString (GL_EXTENSIONS),
+ "GL_OES_framebuffer_object");
#else
- "GL_EXT_framebuffer_object"
-#endif
- );
+ /*
+ * If GL 3.0 or later is in scope, then framebuffer object support is present
+ * by default, and we just use the user's preference.
+ */
+ {
+ long majorvers;
+ char const *glvers;
+ char *endptr;
+
+ glvers = glGetString (GL_VERSION);
+ majorvers = strtol (glvers, &endptr, 10);
+ if (endptr == glvers || *endptr != '.') {
+ /* Unparseable version number; force extension check. */
+ majorvers = 0;
+ }
+ if (majorvers < 3) {
+ /* GL 3.0 not in scope; check for FBO support by extension. */
+ useFBO = !!strstr ((char const *) glGetString (GL_EXTENSIONS),
+ "GL_EXT_framebuffer_object");
+ }
+ }
+#endif /* USE_GLES1 */
+
if (useFBO)
{
GLuint fb, depth_rb, rgba_tex, other_tex;
- glGenFramebuffersEXT (1, &fb);
- glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, fb);
+ glGenFramebuffers (1, &fb);
+ glBindFramebuffer (GL_FRAMEBUFFER, fb);
- glGenRenderbuffersEXT (1, &depth_rb);
- glBindRenderbufferEXT (GL_RENDERBUFFER_EXT, depth_rb);
- glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, this->texsize,this->texsize );
- glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_rb);
+ glGenRenderbuffers (1, &depth_rb);
+ glBindRenderbuffer (GL_RENDERBUFFER, depth_rb);
+ glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, this->texsize,this->texsize );
+ glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_rb);
this->fbuffer[0] = fb;
this->depthb[0]= depth_rb;
@@ -121,9 +151,14 @@
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, texsize, texsize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- //glGenerateMipmapEXT (GL_TEXTURE_2D);
+ //glGenerateMipmap (GL_TEXTURE_2D);
+#ifdef USE_GLES1
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+#else
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+#endif
@@ -132,21 +167,26 @@
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, texsize, texsize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- //glGenerateMipmapEXT (GL_TEXTURE_2D);
+ //glGenerateMipmap (GL_TEXTURE_2D);
+#ifdef USE_GLES1
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+#else
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+#endif
- glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, rgba_tex, 0);
+ glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rgba_tex, 0);
this->textureID[0] = rgba_tex;
this->textureID[1] = other_tex;
- GLenum status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);
+ GLenum status = glCheckFramebufferStatus (GL_FRAMEBUFFER);
- glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);
+ glBindFramebuffer (GL_FRAMEBUFFER, 0);
- if (status == GL_FRAMEBUFFER_COMPLETE_EXT) {
+ if (status == GL_FRAMEBUFFER_COMPLETE) {
return;
}
std::cerr << "[projecM] warning: FBO support not detected. Using fallback." << std::endl;
@@ -232,7 +272,7 @@
#ifdef USE_FBO
if (this->useFBO)
{
- glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, this->fbuffer[0]);
+ glBindFramebuffer (GL_FRAMEBUFFER, this->fbuffer[0]);
}
#endif
}
@@ -248,7 +288,7 @@
glCopyTexSubImage2D (GL_TEXTURE_2D,
0, 0, 0, 0, 0,
this->texsize, this->texsize);
- glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);
+ glBindFramebuffer (GL_FRAMEBUFFER, 0);
return;
}
#endif
diff --git a/src/libprojectM/Renderer/FBO.hpp b/src/libprojectM/Renderer/FBO.hpp
index 21f13ec..5eb90e3 100644
--- a/src/libprojectM/Renderer/FBO.hpp
+++ b/src/libprojectM/Renderer/FBO.hpp
@@ -46,6 +46,8 @@
#endif
#endif
+#include "fbodefs.h"
+
typedef enum {
SCALE_NEAREST,
diff --git a/src/libprojectM/Renderer/Renderable.cpp b/src/libprojectM/Renderer/Renderable.cpp
index 224f846..8e513c5 100644
--- a/src/libprojectM/Renderer/Renderable.cpp
+++ b/src/libprojectM/Renderer/Renderable.cpp
@@ -301,25 +301,27 @@
{
int size = x_num * y_num ;
- floatPair *points = new float[size][2];
+ if (size) {
+ floatPair *points = new float[size][2];
- for (int x=0;x<(int)x_num;x++)
- {
- for(int y=0;y<(int)y_num;y++)
+ for (int x=0;x<(int)x_num;x++)
{
- float lx, ly, lz;
- lx = x_offset+x*intervalx;
- ly = y_offset+y*intervaly;
+ for(int y=0;y<(int)y_num;y++)
+ {
+ float lx, ly, lz;
+ lx = x_offset+x*intervalx;
+ ly = y_offset+y*intervaly;
- points[(x * (int)y_num) + y][0] = lx;
- points[(x * (int)y_num) + y][1] = ly;
+ points[(x * (int)y_num) + y][0] = lx;
+ points[(x * (int)y_num) + y][1] = ly;
+ }
}
+
+ glVertexPointer(2,GL_FLOAT,0,points);
+ glDrawArrays(GL_POINTS,0,size);
+
+ delete[] points;
}
-
- glVertexPointer(2,GL_FLOAT,0,points);
- glDrawArrays(GL_POINTS,0,size);
-
- delete[] points;
}
}
diff --git a/src/libprojectM/Renderer/Renderer.cpp b/src/libprojectM/Renderer/Renderer.cpp
index 0e72cb9..78c1501 100644
--- a/src/libprojectM/Renderer/Renderer.cpp
+++ b/src/libprojectM/Renderer/Renderer.cpp
@@ -1,4 +1,5 @@
#include "Renderer.hpp"
+#include "fbodefs.h"
#include "wipemalloc.h"
#include "math.h"
#include "Common.hpp"
@@ -219,10 +220,11 @@
//video texture memory and render fullscreen.
/** Reset the viewport size */
+
#ifdef USE_FBO
if (renderTarget->renderToTexture)
{
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, this->renderTarget->fbuffer[1]);
+ glBindFramebuffer(GL_FRAMEBUFFER, this->renderTarget->fbuffer[1]);
glViewport(0, 0, this->renderTarget->texsize, this->renderTarget->texsize);
}
else
@@ -265,7 +267,7 @@
#ifdef USE_FBO
if (renderTarget->renderToTexture)
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
#endif
}
diff --git a/src/libprojectM/Renderer/fbodefs.h b/src/libprojectM/Renderer/fbodefs.h
new file mode 100644
index 0000000..e7dfa7c
--- /dev/null
+++ b/src/libprojectM/Renderer/fbodefs.h
@@ -0,0 +1,94 @@
+/**
+ * projectM -- Milkdrop-esque visualisation SDK
+ * Copyright (C)2003-2007 projectM Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * See 'LICENSE.txt' included within this release
+ *
+ */
+/**
+ * $Id: $
+ *
+ */
+#ifndef _FBODEFS_H
+#define _FBODEFS_H
+
+
+#if defined (USE_FBO)
+
+#if defined (USE_GLES1)
+
+/*
+ * Map OES API names to GL names.
+ */
+#define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES
+#define GL_RENDERBUFFER GL_RENDERBUFFER_OES
+#define GL_RGBA4 GL_RGBA4_OES
+#define GL_RGB5_A1 GL_RGB5_A1_OES
+#define GL_RGB565 GL_RGB565_OES
+#define GL_DEPTH_COMPONENT16 GL_DEPTH_COMPONENT16_OES
+#define GL_RENDERBUFFER_WIDTH GL_RENDERBUFFER_WIDTH_OES
+#define GL_RENDERBUFFER_HEIGHT GL_RENDERBUFFER_HEIGHT_OES
+#define GL_RENDERBUFFER_INTERNAL_FORMAT GL_RENDERBUFFER_INTERNAL_FORMAT_OES
+#define GL_RENDERBUFFER_RED_SIZE GL_RENDERBUFFER_RED_SIZE_OES
+#define GL_RENDERBUFFER_GREEN_SIZE GL_RENDERBUFFER_GREEN_SIZE_OES
+#define GL_RENDERBUFFER_BLUE_SIZE GL_RENDERBUFFER_BLUE_SIZE_OES
+#define GL_RENDERBUFFER_ALPHA_SIZE GL_RENDERBUFFER_ALPHA_SIZE_OES
+#define GL_RENDERBUFFER_DEPTH_SIZE GL_RENDERBUFFER_DEPTH_SIZE_OES
+#define GL_RENDERBUFFER_STENCIL_SIZE GL_RENDERBUFFER_STENCIL_SIZE_OES
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_OES
+#define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_OES
+#define GL_DEPTH_ATTACHMENT GL_DEPTH_ATTACHMENT_OES
+#define GL_STENCIL_ATTACHMENT GL_STENCIL_ATTACHMENT_OES
+#define GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE_OES
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES
+#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES
+#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES
+#define GL_FRAMEBUFFER_UNSUPPORTED GL_FRAMEBUFFER_UNSUPPORTED_OES
+#define GL_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING_OES
+#define GL_RENDERBUFFER_BINDING GL_RENDERBUFFER_BINDING_OES
+#define GL_MAX_RENDERBUFFER_SIZE GL_MAX_RENDERBUFFER_SIZE_OES
+#define GL_INVALID_FRAMEBUFFER_OPERATION GL_INVALID_FRAMEBUFFER_OPERATION_OES
+
+#define glIsRenderbuffer glIsRenderbufferOES
+#define glBindRenderbuffer glBindRenderbufferOES
+#define glDeleteRenderbuffers glDeleteRenderbuffersOES
+#define glGenRenderbuffers glGenRenderbuffersOES
+#define glRenderbufferStorage glRenderbufferStorageOES
+#define glGetRenderbufferParameteriv glGetRenderbufferParameterivOES
+#define glIsFramebuffer glIsFramebufferOES
+#define glBindFramebuffer glBindFramebufferOES
+#define glDeleteFramebuffers glDeleteFramebuffersOES
+#define glGenFramebuffers glGenFramebuffersOES
+#define glCheckFramebufferStatus glCheckFramebufferStatusOES
+#define glFramebufferRenderbuffer glFramebufferRenderbufferOES
+#define glFramebufferTexture2D glFramebufferTexture2DOES
+#define glGetFramebufferAttachmentParameteriv glGetFramebufferAttachmentParameterivOES
+#define glGenerateMipmap glGenerateMipmapOES
+
+#elif !defined (GL_VERSION_3_0)
+
+/*
+ * FIXME: Do a complete mapping from *EXT and/or *ARB API names.
+ */
+
+#endif /* GL_VERSION_3_0 */
+#endif /* USE_FBO */
+
+#endif /* _FBODEFS_H */