OpenGL 加载透明纹理

一、编译LPNG,ZLIB

依然是以前的老一套,在此不作过多赘述
将编译好的
在这里插入图片描述
在这里插入图片描述
加到工程中

可以参考https://blog.csdn.net/liuyez123/article/details/50629906

二、读取PNG

LPNG有示例,我直接拿来用了

image

namespace image{

	class png {
	public:
		png();
		~png();

		long load(const ::std::string &path);

	public:

		int width;
		int height;
		png_byte color_type;
		png_byte bit_depth;
		std::unique_ptr<unsigned char> data;
	};
}

long image::png::load(const ::std::string &path)
{
	unsigned char header[8];    // 8 is the maximum size that can be checked
	int x, y;
	png_structp png_ptr;
	png_infop info_ptr;
	int number_of_passes;

	/* open file and test for it being a png */
	FILE *fp;
	fopen_s(&fp, path.c_str(), "rb");
	if (!fp)
		return -1;
	fread(header, 1, 8, fp);
	if (png_sig_cmp(header, 0, 8))
		return -2;

	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

	if (!png_ptr)
		return -3;

	info_ptr = png_create_info_struct(png_ptr);
	if (!info_ptr)
		return -4;

	if (setjmp(png_jmpbuf(png_ptr)))
		return -5;

	png_init_io(png_ptr, fp);
	png_set_sig_bytes(png_ptr, 8);

	png_read_info(png_ptr, info_ptr);

	width = png_get_image_width(png_ptr, info_ptr);
	height = png_get_image_height(png_ptr, info_ptr);
	/*获取通道数*/
	int channels = png_get_channels(png_ptr, info_ptr);
	color_type = png_get_color_type(png_ptr, info_ptr);
	bit_depth = png_get_bit_depth(png_ptr, info_ptr);

	number_of_passes = png_set_interlace_handling(png_ptr);
	png_read_update_info(png_ptr, info_ptr);

	if (setjmp(png_jmpbuf(png_ptr)))
		return -6;

	png_bytepp row_pointers;

	row_pointers = new png_bytep[ height]();
	int size = png_get_rowbytes(png_ptr, info_ptr);
	for (y = 0; y < height; y++)
		row_pointers[y] = new png_byte[size]();

	png_read_image(png_ptr, row_pointers);

	fclose(fp);

	unsigned char* p = new unsigned char[height*channels*size];

	// 拷贝到连续内存中,同时因为纹理坐标是由底到上,做一次转换
	int pos = 0;
	for (y = height -1; y >=0; --y) {
		for (x = 0; x < size; ++x) {
			p[pos++] = row_pointers[y][x];
		}
	}

	// 释放内存
	png_destroy_read_struct(&png_ptr, &info_ptr, 0);
	for (y = 0; y < height; ++y) {
		delete[] row_pointers[y];
	}
	delete[] row_pointers;

	data.reset(p);

	return 0;
}

三、添加纹理对象

要应用透明纹理,首先我们启用2D纹理
glEnable(GL_TEXTURE_2D);
然后关闭深度测试
glDepthMask(GL_FALSE);//关掉深度测试
glEnable(GL_BLEND); //开混合模式贴图
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);// 指定混合模式算法

绑定UV坐标

	// 绑定UV缓冲对象
	glGenBuffers(1, &_texcoord);
	glBindBuffer(GL_ARRAY_BUFFER, _texcoord);
	glBufferData(GL_ARRAY_BUFFER, sizeof(texcoord), texcoord, GL_STATIC_DRAW);
	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
	glEnableVertexAttribArray(1);

绑定纹理

	// 生成纹理对象
	glActiveTexture(GL_TEXTURE0);
	glGenTextures(1, &_tex);
	glBindTexture(GL_TEXTURE_2D, _tex);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img.width,img.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.data.get());
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

_vertex.vert

#version 440

uniform mat4 _model_view;
uniform mat4 _projection;

uniform vec4 _light0_position;

layout (location = 0) in vec3 v;
layout (location = 1) in vec2 texcoord;
layout (location = 2) in vec4 c;
layout (location = 3) in vec3 n;

struct v2f{
	vec4 color;
	vec2 coord;
};

out v2f vert_out;

void main(){
	vert_out.color = c;
	vert_out.coord = texcoord;
	gl_Position = _projection * _model_view * vec4(v,1);
}

_fragment.frag

#version 440

uniform vec4 _light0_position;
uniform vec4 _light0_ambient;
uniform vec4 _light0_diffuse;

uniform sampler2D _sampler;

out vec4 o;

struct v2f{
	vec4 color;
	vec2 coord;
};

in v2f vert_out;

void main() {
	vec4 texcolor = texture2D(_sampler,vert_out.coord);
	o = texcolor;
}

效果如图
在这里插入图片描述

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
OpenGL纹理精简技术是一种优化渲染性能的技术,它通过减少不必要的纹理贴图,降低纹理分辨率等方式,来提高渲染效率。本文将介绍OpenGL纹理精简技术的使用方法,包括以下内容: 一、选择适合的纹理格式 OpenGL支持多种纹理格式,如GL_RGB、GL_RGBA、GL_LUMINANCE等。在选择纹理格式时,需要考虑到纹理的大小和颜色深度,以及对渲染性能的影响。一般情况下,如果纹理不需要透明度,可以选择GL_RGB格式,如果需要透明度,可以选择GL_RGBA格式。对于灰度纹理,可以选择GL_LUMINANCE格式。较低的颜色深度可以降低纹理的大小和渲染的开销。 二、压缩纹理 OpenGL支持多种纹理压缩格式,如S3TC、ETC等。这些格式可以将高质量的纹理数据压缩成更小的大小,从而减少纹理加载和渲染的时间。在支持这些格式的硬件上,使用压缩纹理可以显著提高渲染性能。在使用压缩纹理时,需要注意纹理的格式和支持的硬件。 三、减少纹理贴图 纹理贴图是OpenGL中最基本的操作之一。在使用纹理时,需要注意不要过多地使用纹理贴图,尤其是对于不可见的物体。可以使用纹理合并技术,将多个纹理合并成一个纹理,从而减少纹理贴图的次数。这样可以减少纹理的大小和内存的占用,同时提高渲染性能。 四、降低纹理分辨率 纹理的分辨率越高,需要的内存和渲染开销就越大。在使用纹理时,可以根据实际需要,选择合适的纹理分辨率。如果纹理的分辨率过高,可以通过降低纹理分辨率的方式来减少内存的占用和渲染开销。可以使用OpenGL提供的纹理过滤器,如GL_LINEAR、GL_NEAREST等,来控制纹理的分辨率。 五、使用Mipmap技术 Mipmap技术是一种纹理精简技术,它可以根据物体的远近程度,自动选择合适的纹理分辨率。在使用Mipmap技术时,需要先生成多个纹理,每个纹理的分辨率是前一个纹理的一半。然后在渲染时,根据距离远近自动选择合适的纹理。这样可以减少纹理的大小和内存的占用,同时提高渲染性能。 六、使用纹理压缩库 除了OpenGL自带的纹理压缩格式外,还有许多第三方纹理压缩库可以使用。这些库通常提供更高效的压缩算法和更多的压缩格式,可以进一步减小纹理的大小和提高渲染性能。在使用第三方纹理压缩库时,需要注意库的兼容性和使用方式。 总结 OpenGL纹理精简技术是一种优化渲染性能的重要手段。通过选择适合的纹理格式、压缩纹理、减少纹理贴图、降低纹理分辨率、使用Mipmap技术和使用纹理压缩库等方式,可以显著提高渲染效率和降低内存占用。在实际开发中,需要根据具体情况选择合适的技术和方式,以达到最优的渲染性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值