Fix some video output bugs related to a small maximum texture size which is not an even divisor of the video size.

Originally committed to SVN as r3717.
This commit is contained in:
Thomas Goyne 2009-10-17 03:41:12 +00:00
parent 3d58608230
commit 5b9da0c56a
2 changed files with 27 additions and 25 deletions

View file

@ -98,8 +98,8 @@ VideoOutGL::VideoOutGL()
frameWidth(0), frameWidth(0),
frameHeight(0), frameHeight(0),
frameFormat(0), frameFormat(0),
textureIdList(NULL), textureIdList(),
textureList(NULL), textureList(),
textureCount(0), textureCount(0),
textureRows(0), textureRows(0),
textureCols(0), textureCols(0),
@ -138,21 +138,19 @@ void VideoOutGL::InitTextures(int width, int height, GLenum format, int bpp) {
} }
// Clean up old textures // Clean up old textures
if (textureList != NULL) { if (textureIdList.size() > 0) {
glDeleteTextures(textureCount, textureIdList); glDeleteTextures(textureIdList.size(), &textureIdList[0]);
if (GLenum err = glGetError()) throw VideoOutOpenGLException(L"glDeleteTextures", err); if (GLenum err = glGetError()) throw VideoOutOpenGLException(L"glDeleteTextures", err);
delete textureIdList; textureIdList.clear();
delete textureList; textureList.clear();
textureCount = 0;
textureList = NULL;
} }
textureRows = (int)ceil(double(height) / maxTextureSize); textureRows = (int)ceil(double(height) / maxTextureSize);
textureCols = (int)ceil(double(width) / maxTextureSize); textureCols = (int)ceil(double(width) / maxTextureSize);
textureCount = textureRows * textureCols; textureIdList.resize(textureRows * textureCols);
textureIdList = static_cast<GLuint *>(calloc(textureCount, sizeof(GLint))); textureList.resize(textureRows * textureCols);
glGenTextures(textureCount, textureIdList); glGenTextures(textureIdList.size(), &textureIdList[0]);
textureList = new TextureInfo[textureCount]; if (GLenum err = glGetError()) throw VideoOutOpenGLException(L"glGenTextures", err);
// Calculate the position information for each texture // Calculate the position information for each texture
int sourceY = 0; int sourceY = 0;
@ -162,9 +160,11 @@ void VideoOutGL::InitTextures(int width, int height, GLenum format, int bpp) {
float destX = 0.0f; float destX = 0.0f;
int sourceH = maxTextureSize; int sourceH = maxTextureSize;
int textureH = maxTextureSize;
// If the last row doesn't need a full texture, shrink it to the smallest one possible // If the last row doesn't need a full texture, shrink it to the smallest one possible
if (i == textureRows - 1 && height % maxTextureSize > 0) { if (i == textureRows - 1 && height % maxTextureSize > 0) {
sourceH = height % maxTextureSize; sourceH = height % maxTextureSize;
textureH = SmallestPowerOf2(sourceH);
} }
for (int j = 0; j < textureCols; j++) { for (int j = 0; j < textureCols; j++) {
TextureInfo& ti = textureList[i * textureCols + j]; TextureInfo& ti = textureList[i * textureCols + j];
@ -175,21 +175,23 @@ void VideoOutGL::InitTextures(int width, int height, GLenum format, int bpp) {
ti.sourceH = sourceH; ti.sourceH = sourceH;
ti.sourceW = maxTextureSize; ti.sourceW = maxTextureSize;
int textureW = maxTextureSize;
// If the last column doesn't need a full texture, shrink it to the smallest one possible // If the last column doesn't need a full texture, shrink it to the smallest one possible
if (j == textureCols - 1 && width % maxTextureSize > 0) { if (j == textureCols - 1 && width % maxTextureSize > 0) {
ti.sourceW = width % maxTextureSize; ti.sourceW = width % maxTextureSize;
textureW = SmallestPowerOf2(ti.sourceW);
} }
int w = SmallestPowerOf2(ti.sourceW); int w = textureW;
int h = SmallestPowerOf2(ti.sourceH); int h = textureH;
if (!supportsRectangularTextures) w = h = MAX(w, h); if (!supportsRectangularTextures) w = h = MAX(w, h);
// Calculate what percent of the texture is actually used // Calculate what percent of the texture is actually used
ti.texW = float(ti.sourceW) / w; ti.texW = float(ti.sourceW) / w;
ti.texH = float(ti.sourceH) / h; ti.texH = float(ti.sourceH) / h;
// destW/H is the percent of the output which this texture covers // destW/H is the percent of the output which this texture covers
ti.destW = float(ti.sourceW) / width; ti.destW = float(w) / width;
ti.destH = float(ti.sourceH) / height; ti.destH = float(h) / height;
ti.textureID = textureIdList[i * textureCols + j]; ti.textureID = textureIdList[i * textureCols + j];
ti.dataOffset = sourceY * width * bpp + sourceX * bpp; ti.dataOffset = sourceY * width * bpp + sourceX * bpp;
@ -237,7 +239,7 @@ void VideoOutGL::DisplayFrame(AegiVideoFrame frame, int sw, int sh) {
glPixelStorei(GL_UNPACK_ROW_LENGTH, frame.w); glPixelStorei(GL_UNPACK_ROW_LENGTH, frame.w);
if (GLenum err = glGetError()) throw VideoOutOpenGLException(L"glPixelStorei(GL_UNPACK_ROW_LENGTH, FrameWidth)", err); if (GLenum err = glGetError()) throw VideoOutOpenGLException(L"glPixelStorei(GL_UNPACK_ROW_LENGTH, FrameWidth)", err);
for (int i = 0; i < textureCount; i++) { for (unsigned i = 0; i < textureList.size(); i++) {
TextureInfo& ti = textureList[i]; TextureInfo& ti = textureList[i];
float destX = ti.destX * sw; float destX = ti.destX * sw;
@ -286,11 +288,7 @@ void VideoOutGL::DisplayFrame(AegiVideoFrame frame, int sw, int sh) {
} }
VideoOutGL::~VideoOutGL() { VideoOutGL::~VideoOutGL() {
if (textureList != NULL) { if (textureIdList.size() > 0) {
glDeleteTextures(textureCount, textureIdList); glDeleteTextures(textureIdList.size(), &textureIdList[0]);
delete textureIdList;
delete textureList;
textureCount = 0;
textureList = NULL;
} }
} }

View file

@ -36,6 +36,10 @@
#include "include/aegisub/exception.h" #include "include/aegisub/exception.h"
#ifndef AGI_PRE
#include <vector>
#endif
class AegiVideoFrame; class AegiVideoFrame;
namespace { namespace {
struct TextureInfo; struct TextureInfo;
@ -58,9 +62,9 @@ private:
/// The frame format which the texture grid has been set up for /// The frame format which the texture grid has been set up for
GLenum frameFormat; GLenum frameFormat;
/// List of OpenGL texture ids used in the grid /// List of OpenGL texture ids used in the grid
GLuint *textureIdList; std::vector<GLuint> textureIdList;
/// List of precalculated texture display information /// List of precalculated texture display information
TextureInfo *textureList; std::vector<TextureInfo> textureList;
/// The total texture count /// The total texture count
int textureCount; int textureCount;
/// The number of rows of textures /// The number of rows of textures