LearnOpenGL1.4:纹理

LearnOpenGL 1.5 纹理 纹理 Textures 本文整理自LearnOpenGL 及LearnOpenGL CN ,后者为前者的中文版, 完整学习的话建议前往原网站。 纹理是一个2D图片(甚至也有1D和3D的纹理),它可以用来添加物体的细节。就像一张纸,可以无缝贴在你创建的物体上。 除了图像以外,纹理也可以被用来储存大量的数据,这些数据可以发送到着色器上。 为了能够把纹理映射(Map)到三角形上,我们需要指定 阅读详情

存在问题:

        1.shader中纹理输出的是texture类型

        2.目前我代码顺序和官方有些不一样,可能是我理解的执行流程还有些问题

#include <glad/glad.h>
#include <GLFW/glfw3.h>

#include <iostream>

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

void framebuffer_size_callback(GLFWwindow *window, int width,int height);
void processInput(GLFWwindow *window);

const unsigned int HEIGHT = 600;
const unsigned int WIDTH = 800;

// shader
const char* vertexShaderSource = "#version 330 core\n"
	"layout (location = 0) in vec3 aPos;\n"
	"layout (location = 1) in vec3 aColor;\n"
	"layout (location = 2) in vec2 aTexCoord;\n"
	"out vec3 ourColor;\n"
	"out vec2 TexCoord;\n"
	"void main()\n"
	"{\n"
	"	gl_Position = vec4(aPos, 1.0);\n"
	"	ourColor = aColor;\n"
	"	TexCoord = aTexCoord;\n"
	"}\0";
	
const char *fragmentShaderSource = "#version 330 core\n"
    "out vec4 FragColor;\n"
	"in vec3 ourColor;\n"
    "in vec2 TexCoord;\n"
	"uniform sampler2D ourTexture;\n"
    "void main()\n"
    "{\n"
    "   FragColor = texture(ourTexture, TexCoord);\n"
    "}\n\0";



int main() {
	// 配置
	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
	// MacOSX
	//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);


	GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", NULL, NULL);
	if (window == NULL) {
		std::cout << "Failed to create GLFW window" << std::endl;
		return -1;
	}
	// 设置当前线程的主上下文
	glfwMakeContextCurrent(window);
	glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

	// glad管理函数指针
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
		std::cout << "Failed to initialize GLAD" << std::endl;
		return -1;
	}

	// 坐标转换
	//glViewport(0, 0, HEIGHT, HEIGHT);

	unsigned int vertexShader;
	vertexShader = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
	// 动态编译
	glCompileShader(vertexShader);

	unsigned int fragmentShader;
	fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
	glCompileShader(fragmentShader);

	// link
	unsigned int shaderProgram;
	shaderProgram = glCreateProgram();
	glAttachShader(shaderProgram, vertexShader);
	glAttachShader(shaderProgram, fragmentShader);
	glLinkProgram(shaderProgram);

	glDeleteShader(vertexShader);
	glDeleteShader(fragmentShader);

	//float vertices[] = {
	//-0.5f,-0.5f,0.0f,
	//0.5f,-0.5f,0.0f,
	//0.0f,0.5f,0.0f,

	//0.5f,-0.5f,0.0f,
	//1.0f,0.5f,0.0f,
	//0.0f,0.5f,0.0f,
	//};

	// 使用索引缓冲区
	float vertices[] = {
		// 位置			// 颜色				// 纹理坐标
		0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,// 右上角
		0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,// 右下角
		-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,// 左下角
		-0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f,  0.0f, 1.0f// 左上角
	};


	unsigned int indices[] =
	{
		0, 1, 3,
		1, 2, 3
	};

	unsigned int VBO, VAO;
	// create obj
	glGenVertexArrays(1, &VAO);
	glGenBuffers(1, &VBO);

	glBindVertexArray(VAO);

	// bind to target
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	// copy vertices to gpu
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

	unsigned int EBO;
	glGenBuffers(1, &EBO);

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

	// 纹理
	int width, height, nrChannels;
	unsigned int texture;
	glGenTextures(1, &texture);
	glBindTexture(GL_TEXTURE_2D, texture);
	// 设置纹理环绕方式
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);	// set texture wrapping to GL_REPEAT (default wrapping method)
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	// 设置纹理过滤方式
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	// 生成纹理
	unsigned char* data = stbi_load("D:/OpenGL/Resource/wall.jpg", &width, &height, &nrChannels, 0);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE,
	data);
	glGenerateMipmap(GL_TEXTURE_2D);

	stbi_image_free(data);

	// 告知opengl如何解析
	// 位置属性  0为layout=0
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
	// 启用顶点属性
	glEnableVertexAttribArray(0);
	// 颜色属性  最后一个参数为offset
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3*sizeof(float)));
	glEnableVertexAttribArray(1);
	// 纹理
	glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
	glEnableVertexAttribArray(2);

	// note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind
	//glBindBuffer(GL_ARRAY_BUFFER, 0);

	// You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
	// VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
	//glBindVertexArray(0);

	// uncomment this call to draw in wireframe polygons.
	//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	// shader很少变化,所以不是动态改变的也行
	//glUseProgram(shaderProgram);
	// 
    // render
	while (!glfwWindowShouldClose(window)) {

		processInput(window);

		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);


		// ourColor随着时间变化
		//float timeValue = glfwGetTime();
		//// 0-1  不知道为啥这么写
		//float newColorValue = (sin(timeValue) / 2.0f) + 0.5f;
		//// 查询位置值
		//int vertextColorLocation = glGetUniformLocation(shaderProgram, "ourColor");
		//// 设置
		//glUniform4f(vertextColorLocation, 1.0f, newColorValue, 0.0f, 1.0f);

		// 自动把纹理赋值给片段着色器的采样器
		glBindTexture(GL_TEXTURE_2D, texture);
		glUseProgram(shaderProgram);


		glBindVertexArray(VAO);
		glDrawArrays(GL_TRIANGLES, 0, 6);

		//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
		
		// 代替glDrawArrays   0:指定EBO中的偏移量
		glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

		glfwSwapBuffers(window);
		// 检查事件,调用对应的回调函数
		glfwPollEvents();
	}

	glDeleteVertexArrays(1, &VAO);
	glDeleteBuffers(1, &VBO);
	glDeleteBuffers(1, &EBO);
	glDeleteProgram(shaderProgram);
	// 释放/删除资源
	glfwTerminate();


	return 0;
}



void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
	glViewport(0, 0, HEIGHT, HEIGHT);
}

void processInput(GLFWwindow* window) {
	if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
		glfwSetWindowShouldClose(window, true);
}

运行结果:​​​​​​​                 ​​​​​​​        ​​​​​​​

 

【LearnOpenGL学习笔记】——04.纹理 文章目录1.纹理2.纹理环绕方式3.纹理过滤4.多级渐远纹理5.加载与创建纹理——stb_image.h6.生成纹理步骤7.纹理应用——OpenGL部分(待补充) 1.纹理 (1)用图片控制模型的外观,而不需要通过逐顶点设置模型的外观 (2)OpenGL中纹理坐标原点位于左下角,DirectX中位于左上角 (3)纹理采样:使用纹理坐标(u,v)获取纹理颜色 (4)纹理可以是1D、2D、3D,各个对应坐标轴数量不同(S、T、R) 2.纹理环绕方式 环绕方式 描述 GL_REPEAT 对纹理 阅读详情

相关推荐

跟着LearnOpenGL学习5--纹理

通过前面着色器博文的学习,我们已经了解到,我们可以为每个顶点添加颜色来增加图形的细节,从而创建出有趣的图像。但是,如果想让图形看起来更真实,我们就必须有足够多的顶点,从而指定足够多的颜色。这将会产生很多额外开销,因为每个模型都会需求更多的顶点,每个顶点又需求一个颜色属性。为了解决这一问题,我们可以使用纹理,纹理是一个2D图片(甚至也有1D和3D的纹理),纹理可以理解为贴图,将图片贴到我们创建的几何图形上。你可以想象纹理是一张绘有砖块的纸,无缝折叠贴合到你的3D的房子上,这样你的房子看起来就像有砖墙外表了。

贝勒里恩的博客 1806

opengl 全景图像拼接程序

使用VS2008和opengl编写的全景图像拼接程序,可以完成图像拼接的立体显示,可以旋转,缩放,控制键为空格,和上下左右的四个箭头键,以及上下翻页两个键。包括立方体,圆柱面和球面全景图的生成,附有测试图片。

Android OpenGLES2.0(九)——利用OpenGL进行图片处理

在之前的博客中我们就有提过OpenGLES的常见应用范围,其中有一个就是图片的处理。为了保证效率,Android手机中许多美颜相机、图片处理应用,都用到了OpenGLES来处理图片。上一篇博客中,我们利用OpenGLES 显示出了一张图片,并保证图片正常显示,不会被拉伸和压缩。在本篇博客中,我们来了解下利用OpenGLES来处理图片的一些简单方法。相关原理本篇博客以简单的图片色彩处理、模糊和放大镜效

偶尔记录的一些学习笔记 1万+

OpenGL库文件安装包

文件中包含freeglut,glew,gltools,glut,正确安装之后就可以运行OpenGL小程序了啦

LPDDR4协议规范之 (四)命令和时序

LPDDR4协议规范之 (四)命令和时序命令真值表激活操作读写访问操作读前沿和后沿突发读取操作流程读操作时序写前沿和后沿突发写操作写入均衡(待更新) 命令真值表 激活操作 ACTIVATE命令由两个连续命令组成,Activate-1命令和Activate-2。通过在(Activate-1)时钟的第一个上升沿保持CS HIGH,CA0 HIGH和CA1 LOW来发出Activate-1命令,通过...

YJFeiii的博客 2万+

LearnOpenGL从入门到入魔(3):绘制纹理

总目录 LearnOpenGL从入门到入魔(1):OpenGL简介 LearnOpenGL从入门到入魔(2):绘制2D图形 LearnOpenGL从入门到入魔(3):绘制纹理 LearnOpenGL从入门到入魔(4):绘制3D图形 LearnOpenGL从入门到入魔(5):简单滤镜效果 LearnOpenGL从入门到入魔(6):光照(光照基础,材质) LearnOpenGL从入门到入魔(7):光照(光照贴图,投光物) 1. GLSL  GLSL,OpenGL Shader Language缩写,即OpenG

老蒋也疯狂 2173

DAIC-WOZ数据集文件结构详解:CLNF特征文件、音频转录与PHQ8评分全解读

本文深入解析DAIC-WOZ数据集的文件结构,重点介绍CLNF特征文件、音频转录与PHQ8评分的详细内容。通过多模态数据处理实战指南,帮助研究者高效利用这一抑郁分析领域的重要资源,掌握面部动作单元、声学特征和文本转录的科学解读与应用技巧。

weixin_29159711的博客 182

LearnOpenGL 入门—纹理

文章目录写在前面纹理纹理环绕方式纹理过滤多级渐远纹理stb_image.h生成纹理应用纹理纹理单元总结练习 写在前面   原文链接。原文应该是github上的一个项目,本文主要用来记录一些知识点和自己遇到的问题。 纹理   我们已经了解到,我们可以为每个顶点添加颜色来增加图形的细节,从而创建出有趣的图像。但是,如果想让图形看起来更真实,我们就必须有足够多的顶点,从而指定足够多的颜色。这将会产生很多额外开销,因为每个模型都会需求更多的顶点,每个顶点又需求一个颜色属性。   艺术家和程序员更喜欢使用纹理(Tex

xiji333的博客 1037

DAC8760高精度数模转换器原理与工业级嵌入式应用

数模转换器(DAC)是工业测控系统中实现数字指令到模拟执行的关键接口,其核心性能由分辨率、线性度、温漂及系统级TUE(总未调整误差)共同决定。DAC8760作为一款16位四象限精密DAC,集成了可编程增益放大器(PGA)、内部基准源与SPI高速接口,支持电压/电流双模输出,显著提升闭环控制精度与硬件适配灵活性。其技术价值在于将高精度模拟前端与数字控制深度耦合,满足PLC、ATE及激光偏置等严苛场景对长期稳定性与多通道同步性的要求。本文围绕DAC8760的寄存器配置、HAL/LL驱动实践、PCB布局规范、现场

weixin_42315569的博客 580

开关电源EMC整改案例-辐射骚扰

2.4.1 获得原始数据。同样的分析可以应用在差模电流的情况, 唯一不同的是, 两根导线的磁场分布是相反的, 磁 场互相抵消, 由于导线中的电流大小相等, 产生的磁场 H 大小相同, 在互相靠近的情况下, 在磁 环内的两个感应磁场大小相同、方向相反, 因此合成之后的感应磁场 B 几乎为 0,对任意一根导 线而言,相当于是一段“无感导线”,对差模电流不会产生任何抑制作用。众所周知, 共模电感的匝数越多, 感量越大, 按道 理来说对共模干扰电流的抑制也会越强烈,对抗辐射 也越有利,然而事实真的如此吗?

经营范围: CTA、SRRC、CCC、移动、电信、联通入库 3496

LearnOpenGL(四)之纹理

LearnOpenGL(三)之纹理

ckg3824278的博客 962

图形学基础知识:着色(三)Rendering Pipeline与Shader

管线(Pipeline) 什么是管线? 管线我们可以理解为流水线,流水线大家都懂,就是工厂里面生产东西的一整套流程。例如饮料厂要生产饮料,需要洗瓶子,倒饮料,加盖,包装等等,这一整套过程就是流水线。那么我们要把一个三维场景渲染成一幅二维的图像,同样需要一个先干嘛再干嘛然后干嘛最后干嘛的过程,这个过程或流水线,我们就称之为管线。 实时渲染管线(Real-time Rendering Pipeline) 通过前面几篇的学习,我们知道了要把一个三维场景渲染成一幅二维的图像大致分为以下几个步骤: M.

王王王渣渣的博客 2531

06_LearnOpenGL 纹理

我们已经了解到,我们可以为每个顶点添加颜色来增加图形的细节,从而创建出有趣的图像。但是,如果想让图形看起来更真实,我们就必须有足够多的顶点,从而指定足够多的颜色。这将会产生很多额外开销,因为每个模型都会需求更多的顶点,每个顶点又需求一个颜色属性。艺术家和程序员更喜欢使用纹理(Texture)。纹理是一个2D图片(甚至也有1D和3D的纹理),它可以用来添加物体的细节;你可以想象纹理是一张绘有砖块的纸,无缝折叠贴合到你的3D的房子上,这样你的房子看起来就像有砖墙外表了。

成长需要沉淀。 1140

【Claude Code 实战】第十章:DevOps 与 CI/CD 集成 / 光子AI

本章摘要:探讨Claude Code在DevOps与CI/CD集成中的应用。DevOps作为现代软件工程核心,结合AI技术实现自动化全流程,从代码提交到生产部署。通过CALMS模型(文化、自动化、精益、度量、分享)解析DevOps理念,对比传统瀑布模式与DevOps模式差异,展示AI如何加速Dockerfile编写、CI/CD配置等任务。典型示例显示AI可将原本30-60分钟的手动配置缩短至1-2分钟,大幅提升DevOps效率。

AI天才研究院 367

Android系统开发面试指南:系统Launcher岗位解析

本文针对上海礼聪Android系统开发岗位(侧重系统Launcher、充电/电池/USB底层开发)提供面试指南。内容涵盖应用开发(启动流程优化)、系统底层(充电状态机、USBOTG)、编程能力(线程安全LRU实现)、问题排查(ANR分析)及沟通协作等核心考点。通过5类典型问题及技术深度解析,帮助候选人系统准备,重点考察Framework源码理解、系统调试能力和工程思维。建议结合PowerManagerService等模块源码和systrace工具进行实践准备,同时注重技术表达与协作能力的展现。

郑伟强dev的专栏 927

LearnOpenGL笔记4纹理

纹理textures纹理映射纹理环绕方式纹理过滤多级渐远纹理加载与创建纹理生成纹理应用纹理纹理单元 纹理是个2d图片,可以添加物体的细节,这个壁纸可以不用额外指定顶点。 纹理映射 纹理映射(map)到三角形上,我们需要指定三角形每个顶点各自对应纹理哪个部分,每个顶点关联一个纹理坐标,表明纹理图像哪个部分采样,之后在图形其他片段上进行片段插值。 纹理坐标在x和y轴上,范围为0到1之间(注意我们使用的是2D纹理图像)。使用纹理坐标获取纹理颜色叫做采样(Sampling)。纹理坐标起始于(0, 0),也就是纹理图

Suqiaoyi的博客 357

STM32(HAL库)驱动OLED

通过STM32F103C8T6单片机采用HAL库方式对0.96寸OLED(IIC通讯)屏幕进行驱动。

weixin_44597885的博客 8789

LearnOpenGL学习笔记:纹理

( 本文对应学习章节:https://learnopengl-cn.github.io/01%20Getting%20started/06%20Textures/) 0.前言 之前我们是用顶点和颜色来完成几何图形的绘制,但是遇到复杂的图形就会变得很复杂,这时候纹理(Texture)就登场了。纹理是一个2D图片(甚至也有1D和3D的纹理),它可以用来添加物体的细节。因为我们可以在一张图片上插入...

龚建波 1116

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

LearnOpenGL-入门-6.纹理

纹理简介:若给每个顶点添加颜色来增加图形的细节,会增加开销,所以用纹理。 纹理是一个2D图片,可以认为纹理附在物体表面上,其实是根据当前片段的uv值,采样纹理- 的颜色值作为当前片段的颜色。

qq_34060370的博客 2087

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

LearnOpenGL - 纹理

纹理 ©shuan9999 1. 了解纹理 简而言之就是一张图,把他附着在一个物体上,让这个物体看起来更逼真。说白了,OpenGL不就是为了渲染更真实的物体,让虚拟的物体在屏幕上看起来更像一个真实的物件,但是前面说了,计算机绘制就会画点线三角形,而那些特别复杂的形状无非就是成千上万的三角形组成的,完了我们在这每一个三角形上上一上色,贴上贴纸让这个物体看起来更真实,而这些贴纸就是纹理。其实就是让...

shuan9999的博客 665

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

【OpenGL】LearnOpenGL学习笔记04 - 纹理

LearnOpenGL学习笔记 - 纹理

Duo1J的随笔 1221

07_LearnOpenGL 纹理单元

我们对上一博客的内容,再进一步学习。比如还可以把得到的纹理颜色与顶点颜色混合,来获得更有趣的效果。330330我猜你会说我们的箱子喜欢跳70年代的迪斯科。

成长需要沉淀。 1057

【LearnOpenGL基础入门——6】纹理

【LearnOpenGL基础入门——6】纹理

尘海折柳的博客 1163
上一篇: LearnOpenGL1.3:着色器
下一篇: 三角网格库Triangle的使用
LearnToStick
博客等级 码龄9年 11粉丝 50原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值