OpenGL的学习

立即渲染模式(Immediate mode):
早期的OpenGL使用的模式(也就是固定渲染管线)
OpenGL的大多数功能都被库隐藏起来,容易使用和理解,但是效率太低
开发者很少能控制OpenGL如何进行计算
因此从OpenGL3.2开始,推出核心模式。
核心模式:
也叫可编程管线,提供了更多的灵活性,更高的效率,更重要的是可以更深入的理解图形编程

在这里插入图片描述
在这里插入图片描述

glfw
glfw解决操作系统层面的不同

  • 创建窗口
  • 定义上下文
  • 处理用户输入

glad
glad使得代码可以用于不同的OpenGL驱动

  • OpenGL本身只是标准/规范
  • 各个厂家具体实现方式可以不同
  • 不同操作系统处理方式也不同
//1.获取vbo的index
//2.绑定vbo的index
//3.给vbo分配现存空间,传输数据
//4.告诉shader数据解析方式
//5.激活锚点

#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
unsigned int VBO, VAO,shaderProgram;
void processInput(GLFWwindow* window) {
	if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
		glfwSetWindowShouldClose(window, true);
	}
}

void initModel() {
	float vertices[] = { -0.5f,-0.5f,0.0f,
						0.5f,-0.5f,0.0f,
						0.0f,0.5f,0.0f };
	glGenVertexArrays(1, &VAO);
	glBindVertexArray(VAO);

	glGenBuffers(1, &VBO);//1代表生成一个
	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
	//param1:第0个锚定点;param2:包含几个数据(x,y,z),param5:步长,param6:读取位置
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
	glEnableVertexAttribArray(0);//将第0个锚定点启用
	glBindBuffer(GL_ARRAY_BUFFER, 0);//解绑
	glBindVertexArray(0);
}

void initShader(const char*_vertexPath,const char* _fragPath) {
	std::string _vertexCode("");
	std::string _fragCode("");
	std::ifstream _vShaderFile;
	std::ifstream _fShaderFile;
	_vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
	_fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
	try
	{
		_vShaderFile.open(_vertexPath);
		_fShaderFile.open(_fragPath);
		std::stringstream _vShaderStream, _fShaderStream;
		_vShaderStream << _vShaderFile.rdbuf();
		_fShaderStream << _fShaderFile.rdbuf();
		_vertexCode = _vShaderStream.str();
		_fragCode = _fShaderStream.str();
	}
	catch(std::ifstream::failure e){
		std::string errStr = "read shader fail";
		std::cout << errStr << std::endl;

	}
	
	const char* _vShadeStr = _vertexCode.c_str();
	const char* _fShadeStr = _fragCode.c_str();
	std::cout << "vertexcode=" << _vShadeStr << std::endl;
	std::cout << "fragcode=" << _fShadeStr << std::endl;

	//shader的编译链接
	unsigned int _vertexID = 0, _fragID = 0;
	char _infoLog[512] = {};
	int _succeesFlag = 0;
	//编译
	_vertexID = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(_vertexID,1,&_vShadeStr,NULL);
	glCompileShader(_vertexID);
	glGetShaderiv(_vertexID, GL_COMPILE_STATUS, &_succeesFlag);
	if (!_succeesFlag) {
		glGetShaderInfoLog(_vertexID, 512, NULL, _infoLog);
		std::string errStr(_infoLog);
		std::cout << errStr << std::endl;
	}

	_fragID = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(_fragID, 1, &_fShadeStr, NULL);
	glCompileShader(_fragID);
	glGetShaderiv(_fragID, GL_COMPILE_STATUS, &_succeesFlag);
	if (!_succeesFlag) {
		glGetShaderInfoLog(_fragID, 512, NULL, _infoLog);
		std::string errStr(_infoLog);
		std::cout << errStr << std::endl;
	}
	//链接
	shaderProgram = glCreateProgram();
	glAttachShader(shaderProgram,_vertexID);
	glAttachShader(shaderProgram,_fragID);
	glLinkProgram(shaderProgram);
	glGetProgramiv(shaderProgram, GL_LINK_STATUS, &_succeesFlag);
	if (!_succeesFlag) {
		glGetProgramInfoLog(shaderProgram, 512, NULL, _infoLog);
		std::string errStr(_infoLog);
		std::cout << errStr << std::endl;
	}
	glDeleteShader(_vertexID);
	glDeleteShader(_fragID);
}

void render() {

	glBindVertexArray(VAO);
	glUseProgram(shaderProgram);
	glDrawArrays(GL_TRIANGLES, 0, 3);//从第0个顶点开始话,起作用的是3个顶点
	glUseProgram(0);
}
int main() {
	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
	//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
	GLFWwindow* windows  = glfwCreateWindow(800, 640, "learn oepngl", NULL, NULL);
	if (windows == NULL) {
		glfwTerminate();
		std::cout << "Failed to create GLFW window" << std::endl;
		return -1;
	}
	glfwMakeContextCurrent(windows);
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
		std::cout << "failed to initialize GLAD" << std::endl;
		return -1;
	}
	initModel();
	initShader("vertexShader.glsl","fragmentShader.glsl");

	
	
	

	while (!glfwWindowShouldClose(windows)) {
		processInput(windows);
		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);//状态设置
		glClear(GL_COLOR_BUFFER_BIT);//状态使用
		//glDrawArrays(GL_TRIANGLES, 0, 3);
		render();
		glfwSwapBuffers(windows);
		glfwPollEvents();
	}
	glfwTerminate();
	return 0;

}








在这里插入图片描述
顶点着色器处理后,顶点值应该是NDC坐标
在这里插入图片描述

编译定点着色器
#version 330 core
layout(location=0) in vec3 aPos;
void main(){
gl_Position=vec4(aPos.x,aPos,y,aPos.z,1.0);
}
gl_Position是顶点着色器的内置变量
片段着色器
#version 330 core
out vec4 FragColor;
void main(){
FragColor = vec4(1.0f,0.5f,0.2f,1.0f);
}

bilibili视频资源:
https://www.bilibili.com/video/BV1vU4y1w7Ke?p=6&spm_id_from=pageDriver&vd_source=a5875ea8ec83ce8d44c0383d088f16e4

OpenGL函数命名含义:

OpenGL库

  • 包含115个基本函数
  • 函数以gl开头
    例: glColor3f(), glTranslate3f()
  • 完成图元的定义,几何变换,投影等功能

OpenGL实用库

  • 实用函数43个
  • 函数以glu开头
    例: gluPerspective()
  • 完成更高层的图形处理如曲线曲面的生成,图像操作等

OpenGL辅助库

  • 包括函数31个
  • 函数以aux开头
    例: auxInitWindow()
  • 主要用于窗口管理

命名规则

  • OpenGL函数都遵循一个命名约定,即采用以下格式:
    <库前缀><根命令><可选的参数个数><可选的参数类型>
  • void glVertex3fv(Glfloat *vertex)
    前缀:
  • gl,glu,aux,glut 该函数属于哪个函数库
    后缀:
  • 2,3,4 参数维数
  • b,s,l,f,d,ub,us,ui 参数的数据类型
  • v 以数组方式传递参数

数据类型

在这里插入图片描述
参考:
https://blog.youkuaiyun.com/qq_33934427/article/details/127046119

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值