OPEN GL学习笔记 (一)基础、纹理-程序员宅基地

技术标签: opengl  


此博客为学习笔记,参考:https://learnopengl-cn.github.io/

Texture

Texture Coordinate

在这里插入图片描述

  • 坐标轴:s - t - r
  • 纹理坐标范围是(0, 0) ~ (1, 1), 如果大于此范围,需要 wrap,小于此范围,则相当于截取

Texture Wrapping

在这里插入图片描述

  • Each of the aforementioned options can be set per coordinate axis (s, t (and r if you’re using 3D textures) equivalent to x,y,z) with the glTexParameter* function:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
  • If we choose the GL_CLAMP_TO_BORDER option we should also specify a border color. This is done using the fv equivalent of the glTexParameter function with GL_TEXTURE_BORDER_COLOR as its option where we pass in a float array of the border’s color value:
float borderColor[] = {
   
     1.0f, 1.0f, 0.0f, 1.0f };
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);  

Texture Filtering

  • Texture filtering can be set for magnifying and minifying operations (when scaling up or downwards) so you could for example use nearest neighbor filtering when textures are scaled downwards and linear filtering for upscaled textures. We thus have to specify the filtering method for both options via glTexParameter*. The code should look similar to setting the wrapping method:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

mipmaps

  • a collection of texture images where each subsequent texture is twice as small compared to the previous one.
    -在这里插入图片描述

Creating a collection of mipmapped textures for each texture image is cumbersome to do manually, but luckily OpenGL is able to do all the work for us with a single call to glGenerateMipmaps after we’ve created a texture.

When switching between mipmaps levels during rendering OpenGL might show some artifacts like sharp edges visible between the two mipmap layers. Just like normal texture filtering, it is also possible to filter between mipmap levels using NEAREST and LINEAR filtering for switching between mipmap levels. To specify the filtering method between mipmap levels we can replace the original filtering methods with one of the following four options:

  • GL_NEAREST_MIPMAP_NEAREST: takes the nearest mipmap to match the pixel size and uses nearest neighbor interpolation for texture sampling.
  • GL_LINEAR_MIPMAP_NEAREST: takes the nearest mipmap level and samples using linear interpolation.
  • GL_NEAREST_MIPMAP_LINEAR: linearly interpolates between the two mipmaps that most closely match the size of a pixel and samples via nearest neighbor interpolation.
  • GL_LINEAR_MIPMAP_LINEAR: linearly interpolates between the two closest mipmaps and samples the texture via linear interpolation.

Just like texture filtering we can set the filtering method to one of the 4 aforementioned methods using glTexParameteri

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
// mag filter can't use mipmaps
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

workflow

  • vertex shader: pass texture coordinate to fragment shader
#version 330 core
layout (location=0) in vec3 aPos;
layout (location=2) in vec2 aTexCoord;

out vec2 TexCoord;
void main(){
   
    
	gl_Position = vec4(aPos, 1.0);
	TexCoord = aTexCoord;
}
  • fragment shader: use sampler and texture to get fragcolor
#version 330 core

out vec4 FragColor;
uniform sampler2D texture1;
uniform sampler2D texture2;
uniform float mixvalue;
in vec2 TexCoord;
void main(){
   
    
	// linearly interpolate between both textures (80% container, 20% awesomeface)
	FragColor = mix(texture(texture1, TexCoord), texture(texture2,vec2(1.0 -  TexCoord.x, TexCoord.y)), mixvalue);
}
  • create texture
	unsigned int texture1, texture2;
	glGenTextures(1, &texture1);
	glBindTexture(GL_TEXTURE_2D, texture1);
	// set the texture wrapping parameters
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);	// set texture wrapping to GL_REPEAT (default wrapping method)
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);	// GL_REAPAT  GL_MIRRORED_REPEAT GL_CLAMP_TO_EDGE
	// set texture filtering parameters
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // GL_LINEAR, GL_NEAREST
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	// load image, create texture and generate mipmaps
	int width, height, nrChannels;
	stbi_set_flip_vertically_on_load(true); // tell stb_image.h to flip loaded texture's on the y-axis.
	// The FileSystem::getPath(...) is part of the GitHub repository so we can find files on any IDE/platform; replace it with your own image path.
	unsigned char *data = stbi_load("container.jpg", &width, &height, &nrChannels, 0);
	if (data)
	{
   
    
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
		glGenerateMipmap(GL_TEXTURE_2D);
	}
	else
	{
   
    
		std::cout << "Failed to load texture" << std::endl;
	}
	stbi_image_free(data);

glTexImage2D:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);

  • The second argument specifies the mipmap level for which we want to create a texture for if you want to set each mipmap level manually, but we’ll leave it at the base level which is 0.
  • The third argument tells OpenGL in what kind of format we want to store the texture. Our image has only RGB values so we’ll store the texture with RGB values as well.
  • The 7th and 8th argument specify the format and datatype of the source image. We loaded the image with RGB values and stored them as chars (bytes) so we’ll pass in the corresponding values.

Once glTexImage2D is called, the currently bound texture object now has the texture image attached to it. However, currently it only has the base-level of the texture image loaded and if we want to use mipmaps we have to specify all the different images manually (by continually incrementing the second argument) or, we could call glGenerateMipmap after generating the texture. This will automatically generate all the required mipmaps for the currently bound texture.

  • setting uniform
ourShader.use();
glUniform1i(glGetUniformLocation
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_41956860/article/details/102620280

智能推荐

Python计算机视觉-第9章_img_as_uint()-程序员宅基地

文章浏览阅读622次。图像分割是将一幅图像分割成有意义区域的过程。区域可以是图像的前景与背景或 图像中一些单独的对象。这些区域可以利用一些诸如颜色、边界或近邻相似性等特 征进行构建。本章中,我们将看到一些不同的分割技术。1、图割(1)从图像创建图割(2)用户交互式分割2、利用聚类进行分割3、变分法当优化的对象是函数时,该问题称为变分问题,解决这类问题的算法称为变分法。 我们看一个简单而有效的变分模型。Chan-Vese 分割模型由分片常数图像 U=χ1c1+χ2c2,我们可以将上式重写为:_img_as_uint()

pixel 3 android 12下root简易过程_pixel3安卓12root-程序员宅基地

文章浏览阅读1k次。介绍Android 12 系统下的pixel 3进行root的过程。提示:以下是本篇文章正文内容,下面案例可供参考。_pixel3安卓12root

python将字典数据保存为 excle或csv文件-程序员宅基地

文章浏览阅读1.6w次,点赞14次,收藏45次。参考:python对CSV、Excel、txt、dat、mat文件的处理dict_data = [{'Address': 'CKYsrEiJBrUGXfKYGrr4PkCLbRQn5TiXCm', 'miner_balance': 197561652, 'miner_recieved': 197561652, 'miner_sent': 0, 'top': 98, 'turn..._pf.to_csv

【cropperjs】优秀、优雅的前端图片裁剪库_js图片裁剪库-程序员宅基地

文章浏览阅读1k次。cropperjs组件 图片处理库_js图片裁剪库

基于STM32的门禁系统_基于stm32的远程控制门禁系统-程序员宅基地

文章浏览阅读1k次,点赞9次,收藏37次。硬件准备:STM32f103c8t6开发板RFID-RC522 射频模块(感应M1卡)s90舵机(用于开门)3.3v稳压模块(将6v电压转为3.3v给stm32 供电)四节南孚电池加有盖电池盒(用于供电)OLED显示屏(用于获取M1卡的卡号)_基于stm32的远程控制门禁系统

微信小程序使用Echarts全步骤_echarts小程序插件使用option-程序员宅基地

文章浏览阅读3.4k次,点赞4次,收藏22次。要有遥不可及的梦想,也要有脚踏实地的本事。----------- Grapefruit.Banuit Gang(香柚帮)今天分享一个小程序使用Echarts插件的步骤,下面开始讲解:1、首先要想在微信小程序中使用Echarts,就要先去下载Echarts包并引入, 下载地址:https://github.com/ecomfe/echarts-for-weixi..._echarts小程序插件使用option

随便推点

HyperLynx(八)带状线串扰的仿真_hyperlynx 窜扰-程序员宅基地

文章浏览阅读5k次,点赞2次,收藏12次。TL8 和 TL11为底层的传输线,传输线到参考层的距离为5m il,线宽为8.25mil,传输线的阻抗都为单端 50Ω。在电阻R3上测得的近端串扰值分别为:62.31mV,61.37mV,58.37mV,54.05mV,48.24mV,从测得的数据和仿真波形来看,说明相邻布线层相互耦合的距离越近,串扰越大。在高速、高密度的 PCB 设计中普遍存在串扰,而串扰对系统的影响一般都是负面的但串扰无法被彻底消除,那么就需要找到相应的优化或减小串扰的措施,在不影响系统设计成本和功能的情况下,使串扰尽量变小。..._hyperlynx 窜扰

Spring Boot 日志文件_springboot打印日志-程序员宅基地

文章浏览阅读7.5k次。我们日常在写代码的时候,出现了异常,都会在编译器的控制台上,找出问题。这些问题并不是我们盲猜的,而是控制台上有明显的日志打印,我们就可以根据日志打印发现问题、解决问题。所以说,日志是调试程序重要的一环。_springboot打印日志

【python】判断字符串是否包含子串,居然有七种方法?_python字符串包含子串-程序员宅基地

文章浏览阅读1.1k次。1、使用 in 和 not inin和not in在 Python 中是很常用的关键字,我们将它们归类为成员运算符。_python字符串包含子串

使用Python识别滑块验证码中的缺口位置_python 滑块验证码 没有缺口的位置-程序员宅基地

文章浏览阅读79次。首先使用imread函数读取背景图片和缺口图片,然后使用Canny函数识别出图片的边缘。最后,选出其中“概率最高”的点,即为缺口匹配的位置。缺口的X轴坐标就是匹配结果中“概率最高”的点的X坐标。而识别滑块验证码中的缺口位置是破解滑块验证码的一种常见方式。min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) # 寻找最优匹配。cv2.rectangle(bg_img, tl, br, (0, 0, 255), 2) # 绘制矩形。_python 滑块验证码 没有缺口的位置

asp.net+C#大学生高校运动会比赛综合管理系统_.net用c#的运动会管理系统-程序员宅基地

文章浏览阅读927次。系统主要的模块有学生的信息管理模块,学生报名后的审核管理模块,比赛新闻管理的模块,学生的比赛报名管理模块以及学生的比赛成绩管理模块等多个模块[1]。它可以极大地提高体育比赛报名的灵活性,使得比赛管理人员从复杂的报名管理过程中解脱出来,节约出来大量的时间,从而提高了体育比赛报名和赛事管理的效率。管理员后台可以对运动员的账号以及报名项目进行审核,可以对分组的信息、对报名的信息、新闻信息进行整体的管理。而裁判后台主要是对运动员的赛后的成绩进行一个录入,对参加运动会的运动员的信息进行管理,也可以查看赛道分配情况。_.net用c#的运动会管理系统

异常之自定义异常类-程序员宅基地

文章浏览阅读6.3k次。自定义的异常类一般步骤: 1.自定义异常类要继承于Exception类或其子类,或其它异常类。 2.为自定义异常类声明字段(属性)成员、方法成员或重写父类的字段和方法。 3.自定义异常类至少要定义两个构造方法:一个是无参的;另外一个是带 String参数的,目的是将此字符串传递给父构造方法,同时这个String的 信息作为该异常对象的描述信息。 4.最后,起一个能标识异常情况的有意义的名字。示例代码: ..._自定义异常类

推荐文章

热门文章

相关标签