Support glTexSubImage2D.

TRAC #1167 Signed-off-by: Shannon Woods Signed-off-by: Daniel Koch Author: Andrew Lewycky <andrew.lewycky@transgaming.com> git-svn-id: https://angleproject.googlecode.com/svn/trunk@18 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent c21c2271
......@@ -26,7 +26,7 @@ enum
MAX_TEXTURE_SIZE = 2048,
MAX_CUBE_MAP_TEXTURE_SIZE = 2048,
MAX_TEXTURE_LEVELS = 11 // log2 of MAX_TEXTURE_SIZE
MAX_TEXTURE_LEVELS = 12 // 1+log2 of MAX_TEXTURE_SIZE
};
class Texture : public Colorbuffer
......@@ -43,48 +43,54 @@ class Texture : public Colorbuffer
bool setWrapS(GLenum wrap);
bool setWrapT(GLenum wrap);
GLenum getMinFilter();
GLenum getMagFilter();
GLenum getWrapS();
GLenum getWrapT();
GLenum getMinFilter() const;
GLenum getMagFilter() const;
GLenum getWrapS() const;
GLenum getWrapT() const;
virtual bool isComplete() = 0;
virtual bool isComplete() const = 0;
IDirect3DBaseTexture9 *getTexture();
protected:
// Helper structure representing a single image layer
struct Image
{
GLenum internalFormat;
GLsizei width;
GLsizei height;
GLenum format;
GLenum type;
std::vector<unsigned char> pixels;
};
void copyImage(const D3DLOCKED_RECT &lock, D3DFORMAT format, Image *image);
void copyImage(const D3DLOCKED_RECT &lock, D3DFORMAT format, const Image &image);
static D3DFORMAT selectFormat(const Image &image);
static int pixelSize(const Image &image);
static int pixelSize(GLenum format, GLenum type);
int imagePitch(const Image& img) const;
GLenum mMinFilter;
GLenum mMagFilter;
GLenum mWrapS;
GLenum mWrapT;
void setImage(GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels, Image *img);
void setImage(GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels, Image *img);
void subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels, Image *img);
// The pointer returned is weak and it is assumed the derived class will keep a strong pointer until the next createTexture() call.
virtual IDirect3DBaseTexture9 *createTexture() = 0;
virtual void updateTexture() = 0;
bool mDirtyImageData; // FIXME: would be private but getRenderTarget is still implemented through the derived classes and they need it.
bool mDirtyMetaData; // FIXME: would be private but getRenderTarget is still implemented through the derived classes and they need it.
private:
DISALLOW_COPY_AND_ASSIGN(Texture);
IDirect3DBaseTexture9 *mBaseTexture; // This is a weak pointer. The derived class is assumed to own a strong pointer.
bool mDirtyImageData;
void loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type,
const void *input, std::size_t outputPitch, void *output) const;
};
class Texture2D : public Texture
......@@ -97,24 +103,16 @@ class Texture2D : public Texture
GLenum getTarget() const;
void setImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
bool setMinFilter(GLenum filter);
bool setMagFilter(GLenum filter);
bool setWrapS(GLenum wrap);
bool setWrapT(GLenum wrap);
GLenum getMinFilter();
GLenum getMagFilter();
GLenum getWrapS();
GLenum getWrapT();
bool isComplete();
bool isComplete() const;
IDirect3DSurface9 *getRenderTarget();
private:
DISALLOW_COPY_AND_ASSIGN(Texture2D);
virtual IDirect3DBaseTexture9 *createTexture();
virtual void updateTexture();
Image mImageArray[MAX_TEXTURE_LEVELS];
......@@ -137,12 +135,17 @@ class TextureCubeMap : public Texture
void setImagePosZ(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
void setImageNegZ(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
bool isComplete();
void subImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
bool isComplete() const;
private:
DISALLOW_COPY_AND_ASSIGN(TextureCubeMap);
virtual IDirect3DBaseTexture9 *createTexture();
virtual void updateTexture();
static unsigned int faceIndex(GLenum face);
void setImage(int face, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
......
......@@ -10,6 +10,9 @@
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <exception>
#include <limits>
#include "Context.h"
#include "main.h"
#include "Program.h"
......@@ -20,8 +23,7 @@
#include "Framebuffer.h"
#include "mathutil.h"
#include "debug.h"
#include <exception>
#include "utilities.h"
extern "C"
{
......@@ -3147,12 +3149,62 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
try
{
if (width < 0 || height < 0)
if (target != GL_TEXTURE_2D && !es2dx::IsCubemapTextureTarget(target))
{
return error(GL_INVALID_ENUM);
}
if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
{
return error(GL_INVALID_VALUE);
}
UNIMPLEMENTED(); // FIXME
if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
{
return error(GL_INVALID_VALUE);
}
if (!es2dx::CheckTextureFormatType(format, type))
{
return error(GL_INVALID_ENUM);
}
if (width == 0 || height == 0 || pixels == NULL)
{
return;
}
gl::Context *context = gl::getContext();
if (context)
{
if (target == GL_TEXTURE_2D)
{
gl::Texture2D *texture = context->getTexture2D();
if (!texture)
{
return error(GL_INVALID_OPERATION);
}
texture->subImage(level, xoffset, yoffset, width, height, format, type, pixels);
}
else if (es2dx::IsCubemapTextureTarget(target))
{
gl::TextureCubeMap *texture = context->getTextureCubeMap();
if (!texture)
{
return error(GL_INVALID_OPERATION);
}
texture->subImage(target, level, xoffset, yoffset, width, height, format, type, pixels);
}
else
{
UNREACHABLE();
}
}
}
catch(std::bad_alloc&)
{
......
......@@ -355,4 +355,40 @@ bool ConvertPrimitiveType(GLenum primitiveType, GLsizei primitiveCount,
return true;
}
bool IsCubemapTextureTarget(GLenum target)
{
return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
}
// Verify that format/type are one of the combinations from table 3.4.
bool CheckTextureFormatType(GLenum format, GLenum type)
{
switch (type)
{
case GL_UNSIGNED_BYTE:
switch (format)
{
case GL_RGBA:
case GL_RGB:
case GL_ALPHA:
case GL_LUMINANCE:
case GL_LUMINANCE_ALPHA:
return true;
default:
return false;
}
case GL_UNSIGNED_SHORT_4_4_4_4:
case GL_UNSIGNED_SHORT_5_5_5_1:
return (format == GL_RGBA);
case GL_UNSIGNED_SHORT_5_6_5:
return (format == GL_RGB);
default:
return false;
}
}
}
......@@ -39,6 +39,8 @@ unsigned int GetDepthSize(D3DFORMAT depthFormat);
unsigned int GetStencilSize(D3DFORMAT stencilFormat);
bool ConvertPrimitiveType(GLenum primitiveType, GLsizei primitiveCount,
D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount);
bool IsCubemapTextureTarget(GLenum target);
bool CheckTextureFormatType(GLenum format, GLenum type);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment