Support FBO attachment to cubemaps

TRAC #11364 Signed-off-by: Nicolas Capens Signed-off-by: Daniel Koch Author: Andrew Lewycky git-svn-id: https://angleproject.googlecode.com/svn/trunk@172 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent e6842296
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "libGLESv2/main.h" #include "libGLESv2/main.h"
#include "libGLESv2/Renderbuffer.h" #include "libGLESv2/Renderbuffer.h"
#include "libGLESv2/Texture.h" #include "libGLESv2/Texture.h"
#include "libGLESv2/utilities.h"
namespace gl namespace gl
{ {
...@@ -51,7 +52,8 @@ void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer) ...@@ -51,7 +52,8 @@ void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer)
void Framebuffer::detachTexture(GLuint texture) void Framebuffer::detachTexture(GLuint texture)
{ {
if (mColorbufferHandle == texture && mColorbufferType == GL_TEXTURE) if (mColorbufferHandle == texture
&& (mColorbufferType == GL_TEXTURE_2D || es2dx::IsCubemapTextureTarget(mColorbufferType)))
{ {
mColorbufferType = GL_NONE; mColorbufferType = GL_NONE;
mColorbufferHandle = 0; mColorbufferHandle = 0;
...@@ -109,15 +111,19 @@ Colorbuffer *Framebuffer::getColorbuffer() ...@@ -109,15 +111,19 @@ Colorbuffer *Framebuffer::getColorbuffer()
gl::Context *context = gl::getContext(); gl::Context *context = gl::getContext();
Colorbuffer *colorbuffer = NULL; Colorbuffer *colorbuffer = NULL;
if (mColorbufferType == GL_RENDERBUFFER) if (mColorbufferType == GL_NONE)
{
UNREACHABLE();
colorbuffer = NULL;
}
else if (mColorbufferType == GL_RENDERBUFFER)
{ {
colorbuffer = context->getColorbuffer(mColorbufferHandle); colorbuffer = context->getColorbuffer(mColorbufferHandle);
} }
else if (mColorbufferType == GL_TEXTURE) else
{ {
colorbuffer = context->getTexture(mColorbufferHandle); colorbuffer = context->getTexture(mColorbufferHandle)->getColorbuffer(mColorbufferType);
} }
else UNREACHABLE();
if (colorbuffer && colorbuffer->isColorbuffer()) if (colorbuffer && colorbuffer->isColorbuffer())
{ {
......
...@@ -32,7 +32,7 @@ Texture::Image::~Image() ...@@ -32,7 +32,7 @@ Texture::Image::~Image()
if (surface) surface->Release(); if (surface) surface->Release();
} }
Texture::Texture(Context *context) : Colorbuffer(0), mContext(context) Texture::Texture(Context *context) : mContext(context)
{ {
mMinFilter = GL_NEAREST_MIPMAP_LINEAR; mMinFilter = GL_NEAREST_MIPMAP_LINEAR;
mMagFilter = GL_LINEAR; mMagFilter = GL_LINEAR;
...@@ -40,6 +40,7 @@ Texture::Texture(Context *context) : Colorbuffer(0), mContext(context) ...@@ -40,6 +40,7 @@ Texture::Texture(Context *context) : Colorbuffer(0), mContext(context)
mWrapT = GL_REPEAT; mWrapT = GL_REPEAT;
mDirtyMetaData = true; mDirtyMetaData = true;
mIsRenderable = false;
} }
Texture::~Texture() Texture::~Texture()
...@@ -133,6 +134,16 @@ GLenum Texture::getWrapT() const ...@@ -133,6 +134,16 @@ GLenum Texture::getWrapT() const
return mWrapT; return mWrapT;
} }
GLuint Texture::getWidth() const
{
return mWidth;
}
GLuint Texture::getHeight() const
{
return mHeight;
}
// Selects an internal Direct3D 9 format for storing an Image // Selects an internal Direct3D 9 format for storing an Image
D3DFORMAT Texture::selectFormat(GLenum format) D3DFORMAT Texture::selectFormat(GLenum format)
{ {
...@@ -361,6 +372,7 @@ IDirect3DBaseTexture9 *Texture::getTexture() ...@@ -361,6 +372,7 @@ IDirect3DBaseTexture9 *Texture::getTexture()
if (mDirtyMetaData) if (mDirtyMetaData)
{ {
mBaseTexture = createTexture(); mBaseTexture = createTexture();
mIsRenderable = false;
} }
if (mDirtyMetaData || dirtyImageData()) if (mDirtyMetaData || dirtyImageData())
...@@ -375,18 +387,12 @@ IDirect3DBaseTexture9 *Texture::getTexture() ...@@ -375,18 +387,12 @@ IDirect3DBaseTexture9 *Texture::getTexture()
} }
// Returns the top-level texture surface as a render target // Returns the top-level texture surface as a render target
IDirect3DSurface9 *Texture::getRenderTarget(GLenum target) void Texture::needRenderTarget()
{ {
if (mDirtyMetaData && mRenderTarget) if (!mIsRenderable)
{
mRenderTarget->Release();
mRenderTarget = NULL;
}
if (!mRenderTarget)
{ {
mBaseTexture = convertToRenderTarget(); mBaseTexture = convertToRenderTarget();
mRenderTarget = getSurface(target); mIsRenderable = true;
} }
if (dirtyImageData()) if (dirtyImageData())
...@@ -395,38 +401,36 @@ IDirect3DSurface9 *Texture::getRenderTarget(GLenum target) ...@@ -395,38 +401,36 @@ IDirect3DSurface9 *Texture::getRenderTarget(GLenum target)
} }
mDirtyMetaData = false; mDirtyMetaData = false;
return mRenderTarget;
} }
void Texture::dropTexture() void Texture::dropTexture()
{ {
if (mRenderTarget)
{
mRenderTarget->Release();
mRenderTarget = NULL;
}
if (mBaseTexture) if (mBaseTexture)
{ {
mBaseTexture = NULL; mBaseTexture = NULL;
} }
mIsRenderable = false;
} }
void Texture::pushTexture(IDirect3DBaseTexture9 *newTexture) void Texture::pushTexture(IDirect3DBaseTexture9 *newTexture, bool renderable)
{ {
mBaseTexture = newTexture; mBaseTexture = newTexture;
mDirtyMetaData = false; mDirtyMetaData = false;
mIsRenderable = renderable;
} }
Texture2D::Texture2D(Context *context) : Texture(context) Texture2D::Texture2D(Context *context) : Texture(context)
{ {
mTexture = NULL; mTexture = NULL;
mColorbufferProxy = NULL;
} }
Texture2D::~Texture2D() Texture2D::~Texture2D()
{ {
delete mColorbufferProxy;
if (mTexture) if (mTexture)
{ {
mTexture->Release(); mTexture->Release();
...@@ -543,7 +547,7 @@ void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, ...@@ -543,7 +547,7 @@ void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y,
if (redefineTexture(level, internalFormat, width, height)) if (redefineTexture(level, internalFormat, width, height))
{ {
convertToRenderTarget(); convertToRenderTarget();
pushTexture(mTexture); pushTexture(mTexture, true);
} }
if (width != 0 && height != 0) if (width != 0 && height != 0)
...@@ -576,7 +580,7 @@ void Texture2D::copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x, ...@@ -576,7 +580,7 @@ void Texture2D::copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x,
if (redefineTexture(0, mImageArray[0].format, mImageArray[0].width, mImageArray[0].height)) if (redefineTexture(0, mImageArray[0].format, mImageArray[0].width, mImageArray[0].height))
{ {
convertToRenderTarget(); convertToRenderTarget();
pushTexture(mTexture); pushTexture(mTexture, true);
} }
else else
{ {
...@@ -599,9 +603,10 @@ void Texture2D::copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x, ...@@ -599,9 +603,10 @@ void Texture2D::copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x,
// Tests for GL texture object completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81. // Tests for GL texture object completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
bool Texture2D::isComplete() const bool Texture2D::isComplete() const
{ {
ASSERT(mWidth == mImageArray[0].width && mHeight == mImageArray[0].height); GLsizei width = mImageArray[0].width;
GLsizei height = mImageArray[0].height;
if (mWidth <= 0 || mHeight <= 0) if (width <= 0 || height <= 0)
{ {
return false; return false;
} }
...@@ -625,7 +630,7 @@ bool Texture2D::isComplete() const ...@@ -625,7 +630,7 @@ bool Texture2D::isComplete() const
if (mipmapping) if (mipmapping)
{ {
int q = log2(std::max(mWidth, mHeight)); int q = log2(std::max(width, height));
for (int level = 1; level <= q; level++) for (int level = 1; level <= q; level++)
{ {
...@@ -773,18 +778,6 @@ IDirect3DBaseTexture9 *Texture2D::convertToRenderTarget() ...@@ -773,18 +778,6 @@ IDirect3DBaseTexture9 *Texture2D::convertToRenderTarget()
return mTexture; return mTexture;
} }
IDirect3DSurface9 *Texture2D::getSurface(GLenum target)
{
ASSERT(target == GL_TEXTURE_2D);
IDirect3DSurface9 *surface = NULL;
HRESULT result = mTexture->GetSurfaceLevel(0, &surface);
ASSERT(SUCCEEDED(result));
return surface;
}
bool Texture2D::dirtyImageData() const bool Texture2D::dirtyImageData() const
{ {
int q = log2(std::max(mWidth, mHeight)); int q = log2(std::max(mWidth, mHeight));
...@@ -821,7 +814,7 @@ void Texture2D::generateMipmaps() ...@@ -821,7 +814,7 @@ void Texture2D::generateMipmaps()
mImageArray[i].height = std::max(mImageArray[0].height >> i, 1); mImageArray[i].height = std::max(mImageArray[0].height >> i, 1);
} }
getRenderTarget(); needRenderTarget();
for (unsigned int i = 1; i <= q; i++) for (unsigned int i = 1; i <= q; i++)
{ {
...@@ -841,13 +834,50 @@ void Texture2D::generateMipmaps() ...@@ -841,13 +834,50 @@ void Texture2D::generateMipmaps()
} }
} }
Colorbuffer *Texture2D::getColorbuffer(GLenum target)
{
if (target != GL_TEXTURE_2D)
{
return error(GL_INVALID_OPERATION, (Colorbuffer *)NULL);
}
if (mColorbufferProxy == NULL)
{
mColorbufferProxy = new TextureColorbufferProxy(this, target);
}
return mColorbufferProxy;
}
IDirect3DSurface9 *Texture2D::getRenderTarget(GLenum target)
{
ASSERT(target == GL_TEXTURE_2D);
needRenderTarget();
IDirect3DSurface9 *renderTarget = NULL;
mTexture->GetSurfaceLevel(0, &renderTarget);
return renderTarget;
}
TextureCubeMap::TextureCubeMap(Context *context) : Texture(context) TextureCubeMap::TextureCubeMap(Context *context) : Texture(context)
{ {
mTexture = NULL; mTexture = NULL;
for (int i = 0; i < 6; i++)
{
mFaceProxies[i] = NULL;
}
} }
TextureCubeMap::~TextureCubeMap() TextureCubeMap::~TextureCubeMap()
{ {
for (int i = 0; i < 6; i++)
{
delete mFaceProxies[i];
}
if (mTexture) if (mTexture)
{ {
mTexture->Release(); mTexture->Release();
...@@ -934,7 +964,9 @@ void TextureCubeMap::subImage(GLenum face, GLint level, GLint xoffset, GLint yof ...@@ -934,7 +964,9 @@ void TextureCubeMap::subImage(GLenum face, GLint level, GLint xoffset, GLint yof
// Tests for GL texture object completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81. // Tests for GL texture object completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
bool TextureCubeMap::isComplete() const bool TextureCubeMap::isComplete() const
{ {
if (mWidth <= 0 || mHeight <= 0 || mWidth != mHeight) int size = mImageArray[0][0].width;
if (size <= 0)
{ {
return false; return false;
} }
...@@ -958,7 +990,7 @@ bool TextureCubeMap::isComplete() const ...@@ -958,7 +990,7 @@ bool TextureCubeMap::isComplete() const
for (int face = 0; face < 6; face++) for (int face = 0; face < 6; face++)
{ {
if (mImageArray[face][0].width != mWidth || mImageArray[face][0].height != mHeight) if (mImageArray[face][0].width != size || mImageArray[face][0].height != size)
{ {
return false; return false;
} }
...@@ -966,7 +998,7 @@ bool TextureCubeMap::isComplete() const ...@@ -966,7 +998,7 @@ bool TextureCubeMap::isComplete() const
if (mipmapping) if (mipmapping)
{ {
int q = log2(mWidth); int q = log2(size);
for (int face = 0; face < 6; face++) for (int face = 0; face < 6; face++)
{ {
...@@ -1119,15 +1151,6 @@ IDirect3DBaseTexture9 *TextureCubeMap::convertToRenderTarget() ...@@ -1119,15 +1151,6 @@ IDirect3DBaseTexture9 *TextureCubeMap::convertToRenderTarget()
return mTexture; return mTexture;
} }
IDirect3DSurface9 *TextureCubeMap::getSurface(GLenum target)
{
ASSERT(es2dx::IsCubemapTextureTarget(target));
IDirect3DSurface9 *surface = getCubeMapSurface(target, 0);
ASSERT(surface != NULL);
return surface;
}
void TextureCubeMap::setImage(int face, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) void TextureCubeMap::setImage(int face, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
{ {
redefineTexture(level, internalFormat, width); redefineTexture(level, internalFormat, width);
...@@ -1220,7 +1243,7 @@ void TextureCubeMap::copyImage(GLenum face, GLint level, GLenum internalFormat, ...@@ -1220,7 +1243,7 @@ void TextureCubeMap::copyImage(GLenum face, GLint level, GLenum internalFormat,
if (redefineTexture(level, internalFormat, width)) if (redefineTexture(level, internalFormat, width))
{ {
convertToRenderTarget(); convertToRenderTarget();
pushTexture(mTexture); pushTexture(mTexture, true);
} }
ASSERT(width == height); ASSERT(width == height);
...@@ -1287,7 +1310,7 @@ void TextureCubeMap::copySubImage(GLenum face, GLint level, GLint xoffset, GLint ...@@ -1287,7 +1310,7 @@ void TextureCubeMap::copySubImage(GLenum face, GLint level, GLint xoffset, GLint
if (redefineTexture(0, mImageArray[0][0].format, mImageArray[0][0].width)) if (redefineTexture(0, mImageArray[0][0].format, mImageArray[0][0].width))
{ {
convertToRenderTarget(); convertToRenderTarget();
pushTexture(mTexture); pushTexture(mTexture, true);
} }
else else
{ {
...@@ -1352,7 +1375,7 @@ void TextureCubeMap::generateMipmaps() ...@@ -1352,7 +1375,7 @@ void TextureCubeMap::generateMipmaps()
} }
} }
getRenderTarget(); needRenderTarget();
for (unsigned int f = 0; f < 6; f++) for (unsigned int f = 0; f < 6; f++)
{ {
...@@ -1372,4 +1395,57 @@ void TextureCubeMap::generateMipmaps() ...@@ -1372,4 +1395,57 @@ void TextureCubeMap::generateMipmaps()
} }
} }
Colorbuffer *TextureCubeMap::getColorbuffer(GLenum target)
{
if (!es2dx::IsCubemapTextureTarget(target))
{
return error(GL_INVALID_OPERATION, (Colorbuffer *)NULL);
}
unsigned int face = faceIndex(target);
if (mFaceProxies[face] == NULL)
{
mFaceProxies[face] = new TextureColorbufferProxy(this, target);
}
return mFaceProxies[face];
}
IDirect3DSurface9 *TextureCubeMap::getRenderTarget(GLenum target)
{
ASSERT(es2dx::IsCubemapTextureTarget(target));
needRenderTarget();
IDirect3DSurface9 *renderTarget = NULL;
mTexture->GetCubeMapSurface(static_cast<D3DCUBEMAP_FACES>(faceIndex(target)), 0, &renderTarget);
return renderTarget;
}
Texture::TextureColorbufferProxy::TextureColorbufferProxy(Texture *texture, GLenum target)
: Colorbuffer(NULL), mTexture(texture), mTarget(target)
{
ASSERT(target == GL_TEXTURE_2D || es2dx::IsCubemapTextureTarget(target));
latchTextureInfo();
}
IDirect3DSurface9 *Texture::TextureColorbufferProxy::getRenderTarget()
{
latchTextureInfo();
if (mRenderTarget) mRenderTarget->Release();
mRenderTarget = mTexture->getRenderTarget(mTarget);
return mRenderTarget;
}
void Texture::TextureColorbufferProxy::latchTextureInfo()
{
mWidth = mTexture->getWidth();
mHeight = mTexture->getHeight();
}
} }
...@@ -11,13 +11,15 @@ ...@@ -11,13 +11,15 @@
#ifndef LIBGLESV2_TEXTURE_H_ #ifndef LIBGLESV2_TEXTURE_H_
#define LIBGLESV2_TEXTURE_H_ #define LIBGLESV2_TEXTURE_H_
#include <vector>
#define GL_APICALL #define GL_APICALL
#include <GLES2/gl2.h> #include <GLES2/gl2.h>
#include <d3d9.h> #include <d3d9.h>
#include <vector>
#include "libGLESv2/Renderbuffer.h" #include "libGLESv2/Renderbuffer.h"
#include "libGLESv2/utilities.h"
#include "common/debug.h"
namespace gl namespace gl
{ {
...@@ -32,12 +34,12 @@ enum ...@@ -32,12 +34,12 @@ enum
MAX_TEXTURE_LEVELS = 12 // 1+log2 of MAX_TEXTURE_SIZE MAX_TEXTURE_LEVELS = 12 // 1+log2 of MAX_TEXTURE_SIZE
}; };
class Texture : public Colorbuffer class Texture
{ {
public: public:
explicit Texture(Context *context); explicit Texture(Context *context);
~Texture(); virtual ~Texture();
virtual GLenum getTarget() const = 0; virtual GLenum getTarget() const = 0;
...@@ -51,15 +53,33 @@ class Texture : public Colorbuffer ...@@ -51,15 +53,33 @@ class Texture : public Colorbuffer
GLenum getWrapS() const; GLenum getWrapS() const;
GLenum getWrapT() const; GLenum getWrapT() const;
GLuint getWidth() const;
GLuint getHeight() const;
virtual bool isComplete() const = 0; virtual bool isComplete() const = 0;
IDirect3DBaseTexture9 *getTexture(); IDirect3DBaseTexture9 *getTexture();
IDirect3DSurface9 *getRenderTarget(GLenum target); virtual Colorbuffer *getColorbuffer(GLenum target) = 0;
IDirect3DSurface9 *getRenderTarget() { return getRenderTarget(GL_TEXTURE_2D); } // FIXME: to be removed once FBO rendering is completed.
virtual void generateMipmaps() = 0; virtual void generateMipmaps() = 0;
protected: protected:
class TextureColorbufferProxy;
friend class TextureColorbufferProxy;
class TextureColorbufferProxy : public Colorbuffer
{
public:
TextureColorbufferProxy(Texture *texture, GLenum target); // target is a 2D-like texture target (GL_TEXTURE_2D or one of the cube face targets)
virtual IDirect3DSurface9 *getRenderTarget();
private:
Texture *mTexture;
GLenum mTarget;
void latchTextureInfo();
};
// Helper structure representing a single image layer // Helper structure representing a single image layer
struct Image struct Image
{ {
...@@ -87,19 +107,24 @@ class Texture : public Colorbuffer ...@@ -87,19 +107,24 @@ class Texture : public Colorbuffer
void setImage(GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img); void setImage(GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img);
void subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img); void subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img);
void needRenderTarget();
// 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; virtual void updateTexture() = 0;
virtual IDirect3DBaseTexture9 *convertToRenderTarget() = 0; virtual IDirect3DBaseTexture9 *convertToRenderTarget() = 0;
virtual IDirect3DSurface9 *getSurface(GLenum target) = 0; virtual IDirect3DSurface9 *getRenderTarget(GLenum target) = 0;
virtual bool dirtyImageData() const = 0; virtual bool dirtyImageData() const = 0;
void dropTexture(); void dropTexture();
void pushTexture(IDirect3DBaseTexture9 *newTexture); void pushTexture(IDirect3DBaseTexture9 *newTexture, bool renderable);
Blit *getBlitter(); Blit *getBlitter();
unsigned int mWidth;
unsigned int mHeight;
private: private:
DISALLOW_COPY_AND_ASSIGN(Texture); DISALLOW_COPY_AND_ASSIGN(Texture);
...@@ -107,6 +132,7 @@ class Texture : public Colorbuffer ...@@ -107,6 +132,7 @@ class Texture : public Colorbuffer
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 mDirtyMetaData; bool mDirtyMetaData;
bool mIsRenderable;
void loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, void loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type,
GLint unpackAlignment, const void *input, std::size_t outputPitch, void *output) const; GLint unpackAlignment, const void *input, std::size_t outputPitch, void *output) const;
...@@ -132,13 +158,14 @@ class Texture2D : public Texture ...@@ -132,13 +158,14 @@ class Texture2D : public Texture
virtual void generateMipmaps(); virtual void generateMipmaps();
virtual Colorbuffer *getColorbuffer(GLenum target);
private: private:
DISALLOW_COPY_AND_ASSIGN(Texture2D); DISALLOW_COPY_AND_ASSIGN(Texture2D);
virtual IDirect3DBaseTexture9 *createTexture(); virtual IDirect3DBaseTexture9 *createTexture();
virtual void updateTexture(); virtual void updateTexture();
virtual IDirect3DBaseTexture9 *convertToRenderTarget(); virtual IDirect3DBaseTexture9 *convertToRenderTarget();
virtual IDirect3DSurface9 *getSurface(GLenum target);
virtual bool dirtyImageData() const; virtual bool dirtyImageData() const;
...@@ -148,7 +175,11 @@ class Texture2D : public Texture ...@@ -148,7 +175,11 @@ class Texture2D : public Texture
IDirect3DTexture9 *mTexture; IDirect3DTexture9 *mTexture;
TextureColorbufferProxy *mColorbufferProxy;
bool redefineTexture(GLint level, GLenum internalFormat, GLsizei width, GLsizei height); bool redefineTexture(GLint level, GLenum internalFormat, GLsizei width, GLsizei height);
virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
}; };
class TextureCubeMap : public Texture class TextureCubeMap : public Texture
...@@ -175,13 +206,14 @@ class TextureCubeMap : public Texture ...@@ -175,13 +206,14 @@ class TextureCubeMap : public Texture
virtual void generateMipmaps(); virtual void generateMipmaps();
virtual Colorbuffer *getColorbuffer(GLenum target);
private: private:
DISALLOW_COPY_AND_ASSIGN(TextureCubeMap); DISALLOW_COPY_AND_ASSIGN(TextureCubeMap);
virtual IDirect3DBaseTexture9 *createTexture(); virtual IDirect3DBaseTexture9 *createTexture();
virtual void updateTexture(); virtual void updateTexture();
virtual IDirect3DBaseTexture9 *convertToRenderTarget(); virtual IDirect3DBaseTexture9 *convertToRenderTarget();
virtual IDirect3DSurface9 *getSurface(GLenum target);
virtual bool dirtyImageData() const; virtual bool dirtyImageData() const;
...@@ -200,6 +232,10 @@ class TextureCubeMap : public Texture ...@@ -200,6 +232,10 @@ class TextureCubeMap : public Texture
Image mImageArray[6][MAX_TEXTURE_LEVELS]; Image mImageArray[6][MAX_TEXTURE_LEVELS];
IDirect3DCubeTexture9 *mTexture; IDirect3DCubeTexture9 *mTexture;
TextureColorbufferProxy *mFaceProxies[6];
virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
}; };
} }
......
...@@ -1636,34 +1636,40 @@ void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum t ...@@ -1636,34 +1636,40 @@ void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum t
if (context) if (context)
{ {
if (texture) if (texture == 0)
{ {
textarget = GL_NONE;
}
else
{
gl::Texture *tex = context->getTexture(texture);
if (tex == NULL)
{
return error(GL_INVALID_OPERATION);
}
switch (textarget) switch (textarget)
{ {
case GL_TEXTURE_2D: case GL_TEXTURE_2D:
if (!context->getTexture2D()) if (tex->getTarget() != GL_TEXTURE_2D)
{ {
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
break; break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_X: case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
UNIMPLEMENTED(); // FIXME
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
UNIMPLEMENTED(); // FIXME
break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
UNIMPLEMENTED(); // FIXME
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
UNIMPLEMENTED(); // FIXME
break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
UNIMPLEMENTED(); // FIXME
break;
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
UNIMPLEMENTED(); // FIXME if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
{
return error(GL_INVALID_OPERATION);
}
break; break;
default: default:
return error(GL_INVALID_ENUM); return error(GL_INVALID_ENUM);
} }
...@@ -1681,7 +1687,7 @@ void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum t ...@@ -1681,7 +1687,7 @@ void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum t
return error(GL_INVALID_OPERATION); return error(GL_INVALID_OPERATION);
} }
framebuffer->setColorbuffer(GL_TEXTURE, texture); framebuffer->setColorbuffer(textarget, texture);
} }
} }
catch(std::bad_alloc&) catch(std::bad_alloc&)
......
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