forked from mia/Aegisub
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:
parent
3d58608230
commit
5b9da0c56a
2 changed files with 27 additions and 25 deletions
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue