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 ...@@ -26,7 +26,7 @@ enum
MAX_TEXTURE_SIZE = 2048, MAX_TEXTURE_SIZE = 2048,
MAX_CUBE_MAP_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 class Texture : public Colorbuffer
...@@ -43,48 +43,54 @@ class Texture : public Colorbuffer ...@@ -43,48 +43,54 @@ class Texture : public Colorbuffer
bool setWrapS(GLenum wrap); bool setWrapS(GLenum wrap);
bool setWrapT(GLenum wrap); bool setWrapT(GLenum wrap);
GLenum getMinFilter(); GLenum getMinFilter() const;
GLenum getMagFilter(); GLenum getMagFilter() const;
GLenum getWrapS(); GLenum getWrapS() const;
GLenum getWrapT(); GLenum getWrapT() const;
virtual bool isComplete() = 0; virtual bool isComplete() const = 0;
IDirect3DBaseTexture9 *getTexture(); IDirect3DBaseTexture9 *getTexture();
protected: protected:
// Helper structure representing a single image layer // Helper structure representing a single image layer
struct Image struct Image
{ {
GLenum internalFormat;
GLsizei width; GLsizei width;
GLsizei height; GLsizei height;
GLenum format; GLenum format;
GLenum type;
std::vector<unsigned char> pixels; 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 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 mMinFilter;
GLenum mMagFilter; GLenum mMagFilter;
GLenum mWrapS; GLenum mWrapS;
GLenum mWrapT; 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. // 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 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: private:
DISALLOW_COPY_AND_ASSIGN(Texture); DISALLOW_COPY_AND_ASSIGN(Texture);
IDirect3DBaseTexture9 *mBaseTexture; // This is a weak pointer. The derived class is assumed to own a strong pointer. 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 class Texture2D : public Texture
...@@ -97,24 +103,16 @@ class Texture2D : public Texture ...@@ -97,24 +103,16 @@ class Texture2D : public Texture
GLenum getTarget() const; GLenum getTarget() const;
void setImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); 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 isComplete() const;
bool setMagFilter(GLenum filter);
bool setWrapS(GLenum wrap);
bool setWrapT(GLenum wrap);
GLenum getMinFilter();
GLenum getMagFilter();
GLenum getWrapS();
GLenum getWrapT();
bool isComplete();
IDirect3DSurface9 *getRenderTarget(); IDirect3DSurface9 *getRenderTarget();
private: private:
DISALLOW_COPY_AND_ASSIGN(Texture2D); DISALLOW_COPY_AND_ASSIGN(Texture2D);
virtual IDirect3DBaseTexture9 *createTexture(); virtual IDirect3DBaseTexture9 *createTexture();
virtual void updateTexture();
Image mImageArray[MAX_TEXTURE_LEVELS]; Image mImageArray[MAX_TEXTURE_LEVELS];
...@@ -137,12 +135,17 @@ class TextureCubeMap : public Texture ...@@ -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 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); 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: private:
DISALLOW_COPY_AND_ASSIGN(TextureCubeMap); DISALLOW_COPY_AND_ASSIGN(TextureCubeMap);
virtual IDirect3DBaseTexture9 *createTexture(); 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); void setImage(int face, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
......
...@@ -10,6 +10,9 @@ ...@@ -10,6 +10,9 @@
#include <GLES2/gl2.h> #include <GLES2/gl2.h>
#include <GLES2/gl2ext.h> #include <GLES2/gl2ext.h>
#include <exception>
#include <limits>
#include "Context.h" #include "Context.h"
#include "main.h" #include "main.h"
#include "Program.h" #include "Program.h"
...@@ -20,8 +23,7 @@ ...@@ -20,8 +23,7 @@
#include "Framebuffer.h" #include "Framebuffer.h"
#include "mathutil.h" #include "mathutil.h"
#include "debug.h" #include "debug.h"
#include "utilities.h"
#include <exception>
extern "C" extern "C"
{ {
...@@ -3147,12 +3149,62 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint ...@@ -3147,12 +3149,62 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
try 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); 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&) catch(std::bad_alloc&)
{ {
......
...@@ -355,4 +355,40 @@ bool ConvertPrimitiveType(GLenum primitiveType, GLsizei primitiveCount, ...@@ -355,4 +355,40 @@ bool ConvertPrimitiveType(GLenum primitiveType, GLsizei primitiveCount,
return true; 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); ...@@ -39,6 +39,8 @@ unsigned int GetDepthSize(D3DFORMAT depthFormat);
unsigned int GetStencilSize(D3DFORMAT stencilFormat); unsigned int GetStencilSize(D3DFORMAT stencilFormat);
bool ConvertPrimitiveType(GLenum primitiveType, GLsizei primitiveCount, bool ConvertPrimitiveType(GLenum primitiveType, GLsizei primitiveCount,
D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount); 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