Raw File
TextureUtil.cpp
#include "TextureUtil.h"
#include <iostream>

void CreateFrameBuffer( GLuint& buffer_obj, GLuint& texture, GLuint& depth_stencil, 
					   int width, int height, int depth, int channels, GLenum format, 
					   GLenum type, bool mipmaps )
{
	bool is_3d_tex = depth > 1;
	glGenTextures( 1, &texture );
	GLenum tex_type = GL_TEXTURE_2D;
	if (is_3d_tex)
	{
		tex_type = GL_TEXTURE_3D;
	}

	glBindTexture( tex_type, texture );
	
	glTexParameteri(tex_type, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(tex_type, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(tex_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(tex_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	
	if (is_3d_tex)
	{
		glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
	}

	// generate the top level
	if (is_3d_tex)
	{
		glTexImage3D(GL_TEXTURE_3D, 0, channels, width, height, depth, 0, format, type, 0);
	}
	else
	{
		glTexImage2D(GL_TEXTURE_2D, 0, channels, width, height, 0, format, type, 0);
	}

	// generate the mips
	if ( mipmaps )
	{
		glTexParameteri(tex_type, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
		glEnable(tex_type);
		glGenerateMipmap(tex_type);
	}

	glBindTexture(tex_type, 0);
	
	// depth buffer
	glGenRenderbuffers(1, &depth_stencil);
	glBindRenderbuffer(GL_RENDERBUFFER, depth_stencil);
	glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height );
	glBindRenderbuffer(GL_RENDERBUFFER, 0);

	// linked depth stencil and render texture
	glGenFramebuffers(1, &buffer_obj);
	if (is_3d_tex)
	{
		glBindFramebuffer(GL_RENDERBUFFER, buffer_obj);
		glFramebufferTexture(GL_RENDERBUFFER, GL_COLOR_ATTACHMENT0, texture, 0);

	}
	else
	{
		glBindFramebuffer(GL_FRAMEBUFFER, buffer_obj);
#ifdef _LINUX_
		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
#else
		glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0);
#endif
		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_stencil );
	}

	GLenum status;
	GLenum z = GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER;
	if ((status = glCheckFramebufferStatus(GL_FRAMEBUFFER)) != GL_FRAMEBUFFER_COMPLETE) {
		if (is_3d_tex)
		{
			std::cout <<"fail to create 3d texture\n";
		}
		else
		{
			std::cout << "texture is incomplete\n";
		}
	}

	glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

void DeleteFrameBuffer( GLuint& buffer_obj, GLuint& texture, GLuint& depth_stencil )
{
	glDeleteRenderbuffersEXT(1, &depth_stencil);
	glDeleteTextures(1, &texture);
	glDeleteFramebuffersEXT(1, &buffer_obj);
}

tVector ReadTexel(int x, int y, int w, int h, const std::vector<GLubyte>& data)
{
	const int num_channels = 4;
	size_t idx = static_cast<size_t>((w * y + x) * num_channels);
	GLubyte r = data[idx];
	GLubyte g = data[idx + 1];
	GLubyte b = data[idx + 2];
	GLubyte a = data[idx + 3];

	tVector texel = tVector(r, g, b, a) / 255;
	return texel;
}
back to top