Browse Source

Bugfixing the new texture format

Panagiotis Christopoulos Charitos 12 years ago
parent
commit
3cee3c6863

+ 7 - 3
include/anki/gl/Texture.h

@@ -163,20 +163,20 @@ public:
 	{
 		struct Data
 		{
-			const void* location;
+			const void* ptr;
 			PtrSize size;
 		};
 
 		U width = 0;
 		U height = 0;
-		U depth = 0;
+		U depth = 0; ///< Relevant only for 3D and 2DArray textures
 		GLenum target = GL_TEXTURE_2D;
 		GLenum internalFormat = GL_NONE;
 		GLenum format = GL_NONE;
 		GLenum type = GL_NONE;
 		U mipmapsCount = 0;
 		TextureFilteringType filteringType = TFT_NEAREST;
-		Bool repeat = true;
+		Bool repeat = false;
 		I anisotropyLevel = 0;
 		Bool genMipmaps = false;
 
@@ -265,6 +265,10 @@ public:
 	/// Create a texture
 	void create(const Initializer& init);
 
+	/// Create a FAI
+	void create2dFai(
+		U w, U h, GLenum internalFormat, GLenum format, GLenum type);
+
 	/// Bind the texture to a unit that the texture unit system will decide
 	/// @return The texture init
 	U bind() const;

+ 0 - 4
include/anki/renderer/Renderer.h

@@ -250,10 +250,6 @@ public:
 	/// Used by blurring where we draw the same quad many times
 	void drawQuadMultiple(U times);
 
-	/// Create FAI texture
-	static void createFai(U32 width, U32 height, int internalFormat,
-		int format, int type, Texture& fai);
-
 	/// Calculate the planes needed for the calculation of the fragment
 	/// position z in view space. Having the fragment's depth, the camera's
 	/// zNear and zFar the z of the fragment is being calculated inside the

+ 7 - 0
src/core/NativeWindowGlxX11.cpp

@@ -164,8 +164,15 @@ void NativeWindowImpl::createContext(NativeWindowInitializer& init)
 	int ctxAttribs[] = {
 		GLX_CONTEXT_MAJOR_VERSION_ARB, (int)init.majorVersion,
 		GLX_CONTEXT_MINOR_VERSION_ARB, (int)init.minorVersion,
+		None, None,
 		None};
 
+	if(init.debugContext)
+	{
+		ctxAttribs[4] = GLX_CONTEXT_FLAGS_ARB;
+		ctxAttribs[5] = GLX_CONTEXT_DEBUG_BIT_ARB;
+	}
+
 	glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
 
 	glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)

+ 36 - 38
src/gl/Texture.cpp

@@ -31,27 +31,6 @@ static Bool isCompressedInternalFormat(const GLenum internalFormat)
 	return out;
 }
 
-//==============================================================================
-static Bool isLayeredTarget(const GLenum target)
-{
-	Bool out = false;
-	switch(target)
-	{
-	case GL_TEXTURE_2D:
-	case GL_TEXTURE_CUBE_MAP:
-		out = false;
-		break;
-	case GL_TEXTURE_3D:
-	case GL_TEXTURE_2D_ARRAY:
-		out = true;
-		break;
-	default:
-		ANKI_ASSERT(0);
-		break;
-	}
-	return out;
-}
-
 //==============================================================================
 // TextureManager                                                              =
 //==============================================================================
@@ -252,6 +231,7 @@ void Texture::create(const Initializer& init)
 	// Load data
 	U w = width;
 	U h = height;
+	ANKI_ASSERT(init.mipmapsCount > 0);
 	for(U level = 0; level < init.mipmapsCount; level++)
 	{
 		switch(target)
@@ -271,6 +251,9 @@ void Texture::create(const Initializer& init)
 			}
 			else
 			{
+				ANKI_ASSERT(init.data[level][0].ptr 
+					&& init.data[level][0].size > 0);
+
 				glCompressedTexImage2D(
 					target, 
 					level, 
@@ -278,8 +261,8 @@ void Texture::create(const Initializer& init)
 					w, 
 					h, 
 					0, 
-					init.data[level][0].ptr, 
-					init.data[level][0].size);
+					init.data[level][0].size, 
+					init.data[level][0].ptr);
 			}
 			break;
 		case GL_TEXTURE_CUBE_MAP:
@@ -301,14 +284,14 @@ void Texture::create(const Initializer& init)
 				else
 				{
 					glCompressedTexImage2D(
-						target, 
+						GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 
 						level, 
 						internalFormat,
 						w, 
 						h, 
 						0, 
-						init.data[level][0].ptr, 
-						init.data[level][0].size);
+						init.data[level][0].size, 
+						init.data[level][0].ptr);
 				}
 			}
 			break;
@@ -344,7 +327,7 @@ void Texture::create(const Initializer& init)
 						0, 
 						format, 
 						type, 
-						(data.size()) > 0 ? &data[0] : nullptr);
+						(data.size() > 0) ? &data[0] : nullptr);
 				}
 				else
 				{
@@ -357,7 +340,7 @@ void Texture::create(const Initializer& init)
 						depth, 
 						0, 
 						data.size(), 
-						(data.size()) > 0 ? &data[0] : nullptr);
+						(data.size() > 0) ? &data[0] : nullptr);
 				}
 			}
 			break;
@@ -383,20 +366,13 @@ void Texture::create(const Initializer& init)
 		glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 	}
 
-	if(init.mipmapping && init.data[0])
+	if(init.genMipmaps)
 	{
 		glGenerateMipmap(target);
 	}
 
-	// If not mipmapping then the filtering cannot be trilinear
-	if(init.filteringType == TFT_TRILINEAR && !init.mipmapping)
-	{
-		setFilteringNoBind(TFT_LINEAR);
-	}
-	else
-	{
-		setFilteringNoBind(init.filteringType);
-	}
+	// Set filtering type
+	setFilteringNoBind(init.filteringType);
 
 #if ANKI_GL == ANKI_GL_DESKTOP
 	if(init.anisotropyLevel > 1)
@@ -409,6 +385,28 @@ void Texture::create(const Initializer& init)
 	ANKI_CHECK_GL_ERROR();
 }
 
+//==============================================================================
+void Texture::create2dFai(U w, U h, 
+	GLenum internalFormat_, GLenum format_, GLenum type_)
+{
+	Initializer init;
+
+	init.width = w;
+	init.height = h;
+	init.depth = 0;
+	init.target = GL_TEXTURE_2D;
+	init.internalFormat = internalFormat_;
+	init.format = format_;
+	init.type = type_;
+	init.mipmapsCount = 1;
+	init.filteringType = TFT_NEAREST;
+	init.repeat = false;
+	init.anisotropyLevel = 0;
+	init.genMipmaps = false;
+
+	create(init);
+}
+
 //==============================================================================
 U Texture::bind() const
 {

+ 1 - 1
src/renderer/Hdr.cpp

@@ -10,7 +10,7 @@ Hdr::~Hdr()
 //==============================================================================
 void Hdr::initFbo(Fbo& fbo, Texture& fai)
 {
-	Renderer::createFai(width, height, GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, fai);
+	fai.create2dFai(width, height, GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE);
 
 	// Set to bilinear because the blurring techniques take advantage of that
 	fai.setFiltering(Texture::TFT_LINEAR);

+ 2 - 2
src/renderer/Is.cpp

@@ -468,8 +468,8 @@ void Is::initInternal(const RendererInitializer& initializer)
 	//
 
 	// IS FBO
-	Renderer::createFai(r->getWidth(), r->getHeight(), GL_RGB8,
-		GL_RGB, GL_UNSIGNED_BYTE, fai);
+	fai.create2dFai(r->getWidth(), r->getHeight(), GL_RGB8,
+		GL_RGB, GL_UNSIGNED_BYTE);
 	fbo.create();
 	fbo.setColorAttachments({&fai});
 	fbo.setOtherAttachment(GL_DEPTH_ATTACHMENT, r->getMs().getDepthFai());

+ 4 - 4
src/renderer/Ms.cpp

@@ -17,11 +17,11 @@ void Ms::init(const RendererInitializer& initializer)
 {
 	try
 	{
-		Renderer::createFai(r->getWidth(), r->getHeight(), GL_RG32UI,
-			GL_RG_INTEGER, GL_UNSIGNED_INT, fai0);
-		Renderer::createFai(r->getWidth(), r->getHeight(),
+		fai0.create2dFai(r->getWidth(), r->getHeight(), GL_RG32UI,
+			GL_RG_INTEGER, GL_UNSIGNED_INT);
+		depthFai.create2dFai(r->getWidth(), r->getHeight(),
 			GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL,
-			GL_UNSIGNED_INT_24_8, depthFai);
+			GL_UNSIGNED_INT_24_8);
 
 		fbo.create();
 		fbo.setColorAttachments({&fai0});

+ 2 - 2
src/renderer/Pps.cpp

@@ -25,8 +25,8 @@ void Pps::initInternal(const RendererInitializer& initializer)
 	height = initializer.height / initializer.renderingQuality;
 
 	// FBO
-	Renderer::createFai(r->getWidth(), r->getHeight(), GL_RGB, GL_RGB,
-		GL_UNSIGNED_BYTE, fai);
+	fai.create2dFai(r->getWidth(), r->getHeight(), GL_RGB, GL_RGB,
+		GL_UNSIGNED_BYTE);
 
 	fbo.create();
 	fbo.setColorAttachments({&fai});

+ 0 - 19
src/renderer/Renderer.cpp

@@ -162,25 +162,6 @@ Vec3 Renderer::unproject(const Vec3& windowCoords, const Mat4& modelViewMat,
 	return Vec3(final);
 }
 
-//==============================================================================
-void Renderer::createFai(U32 width, U32 height, int internalFormat,
-	int format, int type, Texture& fai)
-{
-	Texture::Initializer init;
-	init.width = width;
-	init.height = height;
-	init.internalFormat = internalFormat;
-	init.format = format;
-	init.type = type;
-	init.data[0] = nullptr;
-	init.mipmapping = false;
-	init.filteringType = Texture::TFT_NEAREST;
-	init.repeat = false;
-	init.anisotropyLevel = 0;
-
-	fai.create(init);
-}
-
 //==============================================================================
 void Renderer::calcPlanes(const Vec2& cameraRange, Vec2& planes)
 {

+ 1 - 0
src/renderer/Sm.cpp

@@ -38,6 +38,7 @@ void Sm::init(const RendererInitializer& initializer)
 	sminit.format = GL_DEPTH_COMPONENT;
 	sminit.internalFormat = GL_DEPTH_COMPONENT16;
 	sminit.type = GL_UNSIGNED_SHORT;
+	sminit.mipmapsCount = 1;
 	if(bilinearEnabled)
 	{
 		sminit.filteringType = Texture::TFT_LINEAR;

+ 1 - 1
src/renderer/Ssao.cpp

@@ -15,7 +15,7 @@ struct ShaderCommonUniforms
 //==============================================================================
 void Ssao::createFbo(Fbo& fbo, Texture& fai, F32 width, F32 height)
 {
-	Renderer::createFai(width, height, GL_RED, GL_RED, GL_UNSIGNED_BYTE, fai);
+	fai.create2dFai(width, height, GL_RED, GL_RED, GL_UNSIGNED_BYTE);
 
 	// Set to bilinear because the blurring techniques take advantage of that
 	fai.setFiltering(Texture::TFT_LINEAR);

+ 2 - 2
src/renderer/Tiler.cpp

@@ -218,8 +218,8 @@ void Tiler::initInternal(Renderer* r_)
 	depthMapUniform = &(prog->findUniformVariable("depthMap"));
 
 	// Create FBO
-	Renderer::createFai(TILES_X_COUNT, TILES_Y_COUNT, GL_RG32UI,
-		GL_RG_INTEGER, GL_UNSIGNED_INT, fai);
+	fai.create2dFai(TILES_X_COUNT, TILES_Y_COUNT, GL_RG32UI,
+		GL_RG_INTEGER, GL_UNSIGNED_INT);
 	fai.setFiltering(Texture::TFT_NEAREST);
 
 	fbo.create();

+ 11 - 14
src/resource/Image.cpp

@@ -445,7 +445,7 @@ static PtrSize calcSurfaceSize(const U width, const U height,
 		break;
 	case Image::DC_S3TC:
 		out = ((width + 3) / 4) * ((height + 3) / 4) 
-			* (cf == Image::CF_RGB8) ? 4 : 8; // This is the block size
+			* (cf == Image::CF_RGB8) ? 8 : 16; // This is the block size
 		break;
 	case Image::DC_ETC:
 		out = (width / 4) * (height / 4) * 8;
@@ -620,12 +620,9 @@ static void loadAnkiTexture(
 
 	// Read all surfaces
 	U mipSize = header.width;
-	U mip = header.mipLevels;
-	while(mip-- != 0)
+	for(U mip = 0; mip < header.mipLevels; mip++)
 	{
-		U d = depth;
-
-		while(d-- != 0)
+		for(U d = 0; d < depth; d++)
 		{
 			Image::Surface& surf = surfaces[mip * depth + d];
 			surf.width = mipSize;
@@ -636,11 +633,11 @@ static void loadAnkiTexture(
 			{
 			case Image::DC_RAW:
 				dataSize = mipSize * mipSize 
-					* (header.type == Image::CF_RGB8) ? 3 : 4;
+					* ((header.type == Image::CF_RGB8) ? 3 : 4);
 				break;
 			case Image::DC_S3TC:
 				dataSize = ((mipSize + 3) / 4) * ((mipSize + 3) / 4)
-					* (header.type == Image::CF_RGB8) ? 4 : 8;
+					* ((header.type == Image::CF_RGB8) ? 8 : 16);
 				break;
 			case Image::DC_ETC:
 				dataSize = (mipSize / 4) * (mipSize / 4) * 8;
@@ -746,23 +743,23 @@ void Image::load(const char* filename)
 }
 
 //==============================================================================
-const Image::Surface& Image::getSurface(U mipLevel, U depthOrFace) const
+const Image::Surface& Image::getSurface(U mipLevel, U layer) const
 {
 	ANKI_ASSERT(mipLevel < mipLevels);
 
-	U depthSize = 0;
+	U layers = 0;
 
 	switch(textureType)
 	{
 	case TT_2D:
-		depthSize = 1;
+		layers = 1;
 		break;
 	case TT_CUBE:
-		depthSize = 6;
+		layers = 6;
 		break;
 	case TT_3D:
 	case TT_2D_ARRAY:
-		depthSize = depth;
+		layers = depth;
 		break;
 	default:
 		ANKI_ASSERT(0);
@@ -770,7 +767,7 @@ const Image::Surface& Image::getSurface(U mipLevel, U depthOrFace) const
 
 
 	// [mip][depthFace]
-	U index = mipLevel * depthSize + depthOrFace;
+	U index = mipLevel * layers + layer;
 	
 	ANKI_ASSERT(index < surfaces.size());
 

+ 20 - 7
src/resource/TextureResource.cpp

@@ -30,15 +30,18 @@ void TextureResource::load(const Image& img)
 {
 	Initializer init;
 	U layers = 0;
+	Bool driverShouldGenMipmaps = false;
 	
 	// width + height
 	init.width = img.getSurface(0, 0).width;
 	init.height = img.getSurface(0, 0).height;
 	
 	// depth
-	if(img.getType() == Image::TT_2D_ARRAY || img.getType() == Image::TT_3D)
+	if(img.getTextureType() == Image::TT_2D_ARRAY 
+		|| img.getTextureType() == Image::TT_3D)
 	{
 		init.depth = img.getDepth();
+		ANKI_ASSERT(init.depth > 1);
 	}
 	else
 	{
@@ -46,7 +49,7 @@ void TextureResource::load(const Image& img)
 	}
 
 	// target
-	switch(img.getType())
+	switch(img.getTextureType())
 	{
 	case Image::TT_2D:
 		init.target = GL_TEXTURE_2D;
@@ -78,10 +81,11 @@ void TextureResource::load(const Image& img)
 #else
 			init.internalFormat = GL_RGB;
 #endif
+			driverShouldGenMipmaps = true;
 			break;
 #if ANKI_GL == ANKI_GL_DESKTOP
 		case Image::DC_S3TC:
-			init.internalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT
+			init.internalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
 			break;
 #else
 		case Image::DC_ETC:
@@ -102,10 +106,11 @@ void TextureResource::load(const Image& img)
 #else
 			init.internalFormat = GL_RGBA;
 #endif
+			driverShouldGenMipmaps = true;
 			break;
 #if ANKI_GL == ANKI_GL_DESKTOP
 		case Image::DC_S3TC:
-			init.internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
+			init.internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
 			break;
 #else
 		case Image::DC_ETC:
@@ -125,10 +130,10 @@ void TextureResource::load(const Image& img)
 	switch(img.getColorFormat())
 	{
 	case Image::CF_RGB8:
-		init.target = GL_RGB;
+		init.format = GL_RGB;
 		break;
 	case Image::CF_RGBA8:
-		init.target = GL_RGBA;
+		init.format = GL_RGBA;
 		break;
 	default:
 		ANKI_ASSERT(0);
@@ -143,15 +148,23 @@ void TextureResource::load(const Image& img)
 	// filteringType
 	init.filteringType = TFT_TRILINEAR;
 
+	// repeat
+	init.repeat = true;
+
 	// anisotropyLevel
 	init.anisotropyLevel = TextureManagerSingleton::get().getAnisotropyLevel();
 
+	// genMipmaps
+	init.genMipmaps = driverShouldGenMipmaps;
+
 	// Now assign the data
 	for(U layer = 0; layer < layers; layer++)
 	{
 		for(U level = 0; level < init.mipmapsCount; level++)
 		{
-			init.data[level][layer] = img.getSurface(level, layer);
+			init.data[level][layer].ptr = &img.getSurface(level, layer).data[0];
+			init.data[level][layer].size = 
+				img.getSurface(level, layer).data.size();
 		}
 	}
 

+ 13 - 1
testapp/Main.cpp

@@ -469,7 +469,7 @@ void mainLoop()
 
 		// Sleep
 		//
-#if 0
+#if 1
 		timer.stop();
 		if(timer.getElapsedTime() < AppSingleton::get().getTimerTick())
 		{
@@ -494,6 +494,15 @@ void mainLoop()
 	ANKI_COUNTERS_FLUSH();
 }
 
+
+//==============================================================================
+void glDebugCallback(GLenum source,
+	GLenum type, GLuint id, GLenum severity, GLsizei length,
+	const char* message, GLvoid* userParam)
+{
+	ANKI_LOGI("GL driver reports: " << message);
+}
+
 //==============================================================================
 // initSubsystems                                                              =
 //==============================================================================
@@ -519,12 +528,15 @@ void initSubsystems(int argc, char* argv[])
 	nwinit.depthBits = 0;
 	nwinit.stencilBits = 0;
 	nwinit.fullscreenDesktopRez = true;
+	nwinit.debugContext = true;
 	win = new NativeWindow;	
 	win->create(nwinit);
 
 	// GL stuff
 	GlStateCommonSingleton::get().init(glmajor, glminor);
 
+	glDebugMessageCallback(glDebugCallback, nullptr);
+
 	// Input
 	InputSingleton::get().init(win);
 	InputSingleton::get().hideCursor(true);

+ 17 - 14
tools/texture/ankitexture.py

@@ -150,24 +150,27 @@ def parse_commandline():
 	parser = optparse.OptionParser("usage: %prog [options]")
 
 	parser.add_option("-i", "--input", dest = "inp",
-		type = "string", help = "specify the image(s) to convert. " \
+			type = "string", help = "specify the image(s) to convert. " \
 			"Seperate with :")
+
+	parser.add_option("-o", "--output", dest = "out",
+			type = "string", help = "specify new image. ")
 	
 	parser.add_option("-d", "--tmp-dir", dest = "tmp_dir",
-		type = "string", default = False, 
-		help = "temporary directory")
+			type = "string", default = False, 
+			help = "temporary directory")
 
 	parser.add_option("-t", "--type", dest = "type",
-		type = "string", default = "2D", 
-		help = "type of the image (2D or cube or 3D or 2DArray)")
+			type = "string", default = "2D", 
+			help = "type of the image (2D or cube or 3D or 2DArray)")
 
 	parser.add_option("-f", "--fast", dest = "fast",
-		action = "store_true", default = False, 
-		help = "run the fast version of the converters")
+			action = "store_true", default = False, 
+			help = "run the fast version of the converters")
 
 	parser.add_option("-n", "--normal", dest = "normal",
-		action = "store_true", default = False, 
-		help = "assume the texture is normal")
+			action = "store_true", default = False, 
+			help = "assume the texture is normal")
 
 	(options, args) = parser.parse_args()
 
@@ -185,7 +188,7 @@ def parse_commandline():
 	else:
 		parser.error("Unrecognized type: " + options.type)
 
-	return (options.inp.split(":"), options.tmp_dir, options.fast,
+	return (options.inp.split(":"), options.out, options.tmp_dir, options.fast,
 			typ, options.normal)
 
 def get_internal_format_and_size(in_file):
@@ -388,9 +391,9 @@ def write_s3tc(out_file, fname, width, height, internal_format):
 
 	# Read and write the data
 	if internal_format == COLOR_FORMAT_RGB8:
-		block_size = 4
-	else:
 		block_size = 8
+	else:
+		block_size = 16
 
 	data_size = ((width + 3) / 4) * ((height + 3) / 4) * block_size
 
@@ -421,7 +424,7 @@ def main():
 	""" The main """
 
 	# Parse cmd line args
-	(in_files, tmp_dir, fast, typ, normal) = parse_commandline();
+	(in_files, out, tmp_dir, fast, typ, normal) = parse_commandline();
 	tmp_dir = os.path.abspath(tmp_dir)
 
 	if typ == TYPE_CUBE and len(in_files) != 6:
@@ -464,7 +467,7 @@ def main():
 		create_dds_images(mips_fnames, tmp_dir, fast, internal_format, normal)
 
 	# Open file
-	fname = os.path.splitext(os.path.basename(in_file))[0] + ".ankitex"
+	fname = out
 	fname = os.path.join(tmp_dir,  fname)
 	tex_file = open(fname, "wb")