OpenGL 围炉夜话

简介: OpenGL 围炉夜话

一、OpenGL

参考资料

OpenGL 官网

OpenGL 参考

Learn OpenGL

Learn OpenGL 中文版

一小时实践入门 OpenGL

OpenGL基础教程

图形学[GLSL]入门小结

OpenGL 简介


计算机图形学编程(使用OpenGL和C++)

OpenGL编程指南

The OpenGL® Programming Guide 9th Edition 官网源码

WebGL编程指南


Vulkan学习指南

Vulkan开发实战详解

Vulkan Programming Guide


一篇搞懂OpenGL中的着色器和如何使用

图形学[GLSL]入门小结

OpenGL基础知识

OpenGL基础知识

OpenGL图像(image)

坐标系统

5个坐标系 - OpenGL开发必读

OpenGL 坐标系统(Perspective)

参考教程

教程 1

【OpenGL】一、Visual Studio 2019 创建 Windows 桌面程序 ( Visual Studio Installer 安装 C++ 桌面开发库 | 创建桌面程序 )

【OpenGL】二、Visual Studio 2019 配置 GitHub ( 下载并安装 GitHub 扩展 | 配置 GitHub )

【OpenGL】三、Visual Studio 2019 配置 GitHub ( 将项目上传到 GitHub )

【OpenGL】四、Visual Studio 2019 配置 GitHub ( 从 GitHub 上克隆项目 )

【OpenGL】五、Visual Studio 2019 配置 GitHub ( 提交代码 )

【OpenGL】六、Visual Studio 2019 配置 GitHub ( 提取和拉取简介 | 拉取远程代码 )

【OpenGL】七、桌面窗口搭建 ( 导入头文件 | 桌面程序入口函数 | 注册窗口 | 创建窗口 | 显示窗口 )

【OpenGL】八、初始化 OpenGL 渲染环境 ( 导入 OpenGL 头文件 | 链接 OpenGL 库 | 将窗口设置为 OpenGL 窗口 | 设置像素格式描述符 | 渲染绘制 ) ★

【OpenGL】九、OpenGL 绘制基础 ( OpenGL 状态机概念 | OpenGL 矩阵概念 )

【OpenGL】十、OpenGL 绘制点 ( 初始化 OpenGL 矩阵 | 设置投影矩阵 | 设置模型视图矩阵 | 绘制点 | 清除缓冲区 | 设置当前颜色值 | 设置点大小 | 绘制点 )

【OpenGL】十一、OpenGL 绘制多个点 ( 绘制单个点 | 绘制多个点 )

【OpenGL】十二、OpenGL 绘制线段 ( 绘制单条线段 | 绘制多条线段 | 依次连接的点组成的线 | 绘制圈 | 绘制彩色的线 )

【OpenGL】十三、OpenGL 绘制三角形 ( 绘制单个三角形 | 三角形绘制顺序 | 绘制多个三角形 )

【OpenGL】十四、OpenGL 绘制三角形 ( 绘制 GL_TRIANGLE_STRIP 三角形 | GL_TRIANGLE_STRIP 三角形绘制分析 )

【OpenGL】十五、OpenGL 绘制三角形 ( 绘制 GL_TRIANGLE_FAN 三角形扇 )

【OpenGL】十六、OpenGL 绘制四边形 ( 绘制 GL_QUADS 四边形 )

【OpenGL】十七、OpenGL 绘制四边形 ( 绘制 GL_QUAD_STRIP 模式四边形 )

【OpenGL】十八、OpenGL 绘制多边形 ( 绘制 GL_POLYGON 模式多边形 )

【OpenGL】十九、OpenGL 绘制模式 ( 绘制线框模式 | 绘制点模式 )

【OpenGL】二十、OpenGL 矩阵变换 ( 矩阵缩放变换 | 矩阵旋转变换 | 矩阵平移变换 )

【OpenGL】二十一、OpenGL 矩阵压栈与出栈 ( 不同类型矩阵变换先后顺序 | 渲染前不设置单位阵 | 压栈出栈原理分析 | 代码示例 )

【OpenGL】二十二、OpenGL 光照效果 ( 模型准备 | 光照设置 | 启用光照 | 启用光源 | 设置光源位置 | 设置光照参数 | 设置环境光 | 设置反射材质 | 设置法线 )

【OpenGL】二十三、OpenGL 光照中的法线原理

【OpenGL】二十四、OpenGL 纹理贴图 ( 读取文件内容 | 桌面程序添加控制台窗口 | ‘fopen‘: This function may be unsafe 错误处理 )

教程 2

OpenGL学习随笔 —— 简介(一)

OpenGL学习随笔 —— 着色器(二)

OpenGL学习随笔 —— 坐标系统(三)

OpenGL学习随笔 —— 局部空间和世界空间(四)

OpenGL学习随笔 —— 缓冲区和顶点(五)

相关库

GLFW

    GLFW 是配合 OpenGL 使用的轻量级工具程序库,缩写自 Graphics Library Framework(图形库框架)。GLFW 的主要功能是创建并管理窗口和 OpenGL 上下文,同时还提供了处理手柄、键盘、鼠标输入的功能。 有类似功能的库还有 GLUT和 SDL。

GLFW

GLFW Getting started

示例

CMakeLists.txt

cmake_minimum_required(VERSION 3.0.0)
project(ch1 VERSION 0.1.0 LANGUAGES C CXX)

add_executable(ch1 main.cpp)

target_include_directories(ch1 PRIVATE "D:/work/learnOpenGl/glfw-3.3.8.bin.WIN64/include")
target_link_directories(ch1 PRIVATE "D:/work/learnOpenGl/glfw-3.3.8.bin.WIN64/lib-vc2019")
target_link_libraries(ch1 glfw3 opengl32)

代码:main.cpp

#include <GLFW/glfw3.h>
#include <gl/GL.h>
#include <iostream>

// #pragma comment(lib, "opengl32.lib")
// #pragma comment(lib, "glfw3.lib")

void error_callback(int code, const char *description);

void display() {
  glLineWidth(2.0f);
  // glColor4ub(255, 255, 255, 255);
  glColor3f(1.f, 0.f, 0.f);

  glBegin(GL_LINES);
  glVertex3f(0.0f, 0.0f, 1.0f);
  glVertex3f(-5.0f, 3.0f, -0.5f);
  glEnd();
}

int main(int argc, char **argv) {
  GLFWwindow *window;

  /* Handle GLFW Error */
  glfwSetErrorCallback(error_callback);

  /* Initialize the library */
  if (!glfwInit())
    return -1;

  /* Create a windowed mode window and its OpenGL context */
  window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
  if (!window) {
    glfwTerminate();
    return -1;
  }

  /* Make the window's context current */
  glfwMakeContextCurrent(window);
  // glfwSwapInterval(1);

  /* Loop until the user closes the window */
  while (!glfwWindowShouldClose(window)) {
    /* Render here */
    glClear(GL_COLOR_BUFFER_BIT);

    display();

    /* Swap front and back buffers */
    glfwSwapBuffers(window);

    /* Poll for and process events */
    glfwPollEvents();
  }

  glfwTerminate();
  return 0;
}

void error_callback(int code, const char *description) {
  std::cout << code << ":" << description << std::endl;
}

运行结果:

基于GLFW和GL3W库的OPEN GL环境配置

GL3W

GL3W

gl3w是获得OpenGL核心配置文件规范提供的功能的最简单方法。

它的主要部分是一个简单的gl3w_gen.py Python脚本,该脚本下载Khronos支持的glcorearb.h标头,并从中生成gl3w.h和

gl3w.c。然后可以将这些文件添加并链接(静态或动态)到您的项目中。

Note that GL/gl3w.h must be included before any other OpenGL related headers

#include <Windows.h>

#include <GL/gl3w.h>

#include <GL/GL.h>
#include <GLFW/glfw3.h>
API Reference

The gl3w API consists of just three functions:

int gl3wInit(void)

Initializes the library. Should be called once after an OpenGL context has been created. Returns 0 when gl3w was initialized successfully, non-zero if there was an error.

  glfwMakeContextCurrent(window);
  gl3wInit();

int gl3wIsSupported(int major, int minor)

Returns 1 when OpenGL core profile version major.minor is available and 0 otherwise.

GL3WglProc gl3wGetProcAddress(const char *proc)

Returns the address of an OpenGL extension function. Generally, you won’t need to use it since gl3w loads all functions defined in the OpenGL core profile on initialization. It allows you to load OpenGL extensions outside of the core profile.

示例

CMakeLists.txt

cmake_minimum_required(VERSION 3.0.0)
project(ch4 VERSION 0.1.0 LANGUAGES C CXX)

include_directories("D:/work/learnOpenGl/gl3w-master/include")
set(gl3w_src D:/work/learnOpenGl/gl3w-master/src/gl3w.c)
# include_directories("D:/work/learnOpenGl/gl3w-master/build/include")
# set(gl3w_src D:/work/learnOpenGl/gl3w-master/build/src/gl3w.c)

add_executable(ch4 main.cpp ${gl3w_src})

include_directories("D:/work/learnOpenGl/glfw-3.3.8.bin.WIN64/include")
target_link_directories(ch4 PRIVATE "D:/work/learnOpenGl/glfw-3.3.8.bin.WIN64/lib-vc2019")
target_link_libraries(ch4 glfw3 opengl32)

代码:main.cpp

#include <Windows.h>

#include <GL/gl3w.h>

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

#include <iostream>

// #pragma comment(lib, "opengl32.lib")
// #pragma comment(lib, "glu32.lib")

float vertices[] = {-0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, 0.0f, 0.5f, 0.0f};
const char *vertexShaderSource =
    "#version 330 core\n"
    "layout (location = 0) in vec3 aPos;\n"
    "void main()\n"
    "{\n"
    " gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
    "}\0";

const char *fragmentShaderSource =
    "#version 330 core\n"
    "out vec4 FragColor;\n"
    "void main()\n"
    "{\n"
    " FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
    "}\n\0";

static void error_callback(int error, const char *description) {
  fputs(description, stderr);
}

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

int main() {
  glfwSetErrorCallback(error_callback);

  if (!glfwInit()) {
    std::cout << "glfwInit error" << std::endl;
    exit(EXIT_FAILURE);
  }
  // glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  // glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
  // glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

  GLFWwindow *window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL);
  if (window == NULL) {
    std::cout << "Failed to create GLFW window" << std::endl;
    glfwTerminate();
    return -1;
  }
  
  glfwMakeContextCurrent(window);
  gl3wInit();
  
  glfwSwapInterval(1);
  glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

  std::cout << "[Debug] " << __LINE__ << std::endl;

  unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
  glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
  glCompileShader(vertexShader);

  int success;
  char infoLog[512];
  glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
  if (!success) {
    glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
    std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n"
              << infoLog << std::endl;
  }

  std::cout << "[Debug] " << __LINE__ << std::endl;

  unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
  glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
  glCompileShader(fragmentShader);
  glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
  if (!success) {
    glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
    std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n"
              << infoLog << std::endl;
  }

  std::cout << "[Debug] " << __LINE__ << std::endl;

  unsigned int shaderProgram = glCreateProgram();
  glAttachShader(shaderProgram, vertexShader);
  glAttachShader(shaderProgram, fragmentShader);
  glLinkProgram(shaderProgram);
  glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
  if (!success) {
    glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
    std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n"
              << infoLog << std::endl;
  }

  glDeleteShader(vertexShader);
  glDeleteShader(fragmentShader);

  std::cout << "[Debug] " << __LINE__ << std::endl;

  unsigned int VBO, VAO;
  glGenVertexArrays(1, &VAO);
  glGenBuffers(1, &VBO);
  glBindVertexArray(VAO);
  glBindBuffer(GL_ARRAY_BUFFER, VBO);
  glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

  glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0);

  glEnableVertexAttribArray(0);
  glBindBuffer(GL_ARRAY_BUFFER, 0);
  glBindVertexArray(0);

  glUseProgram(shaderProgram);

  std::cout << "[Debug] " << __LINE__ << std::endl;

  while (!glfwWindowShouldClose(window)) {

    glClearColor(0.2f, 0.3f, 0.3f, 1.0f); // 状态设置
    glClear(GL_COLOR_BUFFER_BIT);         // 状态使用

    // 需要注意的是前面我们已经解绑了VAO,所以现在是无法解析数据的,所以我们需要重新绑定,
    // 至于数据我们已经存到缓冲区了
    glBindVertexArray(VAO);
    // 从数据数组中indexwei0处开始读取,每三个做一个三角形的顶点。第三个参数是说一共绘制三个顶点数据(每个顶点由vertices数组中的3个元素组成)
    glDrawArrays(GL_TRIANGLES, 0, 3);

    glfwSwapBuffers(window);
    glfwPollEvents();
  }

  // glfw: 回收前面分配的GLFW先关资源.
  // 一定要注意,只有关闭窗体之后才会跳出while循环走到这一步!!!
  glfwDestroyWindow(window);
  glfwTerminate();

  // 在while循环退出后释放内存:
  glDeleteVertexArrays(1, &VAO);
  glDeleteBuffers(1, &VBO);
  glDeleteProgram(shaderProgram);

  return 0;
}

// 当改变窗口的大小的时候,视口也应该被调整。我们可以对窗口注册一个回调函数(Callback
// Function),它会在每次窗口大小被调整的时候被调用
void framebuffer_size_callback(GLFWwindow *window, int width, int height) {
  // 设置窗口维度
  // glViewport(前两参数为窗口左下角位置,3.宽度,4.高度)
  glViewport(0, 0, width, height);
}

运行结果:

GLEW

GLEW

GLEW 是一个跨平台的 C++ 扩展库,基于 OpenGL 图形接口。使用 OpenGL 的朋友都知道,window 目前只支持 OpenGL1.1 的涵数,但 OpenGL 现在都发展到 2.0 以上了,要使用这些 OpenGL 的高级特性,就必须下载最新的扩展,另外,不同的显卡公司,也会发布一些只有自家显卡才支 持的扩展函数,你要想用这数涵数,不得不去寻找最新的 glext.h, 有了 GLEW 扩展库,你就再也不用为找不到函数的接口而烦恼,因为 GLEW 能自动识 别你的平台所支持的全部 OpenGL 高级扩展涵数。也就是说,只要包含一个 glew.h 头文件,你就能使用 gl,glu,glext,wgl,glx 的全 部函数。GLEW 支持目前流行的各种操作系统(including Windows, Linux, Mac OS X, FreeBSD, Irix, and Solaris)。

openGl新手入门学习笔记(二)下载glew,配置glew的环境与glew的初始化

GlEW 的配置与使用

根据官方文档我们可以知道Initializing GLEW的步骤:

First you need to create a valid OpenGL rendering context and call glewInit() to initialize the extension entry points. If glewInit() returns GLEW_OK, the initialization succeeded and you can use the available extensions as well as core OpenGL functionality.


即在调用 glewInit() 来初始化前必须先创造一个OpenGL的渲染上下文。使用 glfwMakeContextCurrent(window) 函数创建了渲染上下文,再调用 glewInit() 即可初始化成功。

示例

CMakeLists.txt

cmake_minimum_required(VERSION 3.0.0)
project(ch3 VERSION 0.1.0 LANGUAGES C CXX)

add_executable(ch3 main.cpp)

target_include_directories(ch3 PRIVATE "D:/work/learnOpenGl/glfw-3.3.8.bin.WIN64/include")
target_link_directories(ch3 PRIVATE "D:/work/learnOpenGl/glfw-3.3.8.bin.WIN64/lib-vc2019")
target_link_libraries(ch3 glfw3 opengl32)

target_include_directories(ch3 PRIVATE "D:/work/learnOpenGl/glew-2.2.0/include")
target_link_directories(ch3 PRIVATE "D:/work/learnOpenGl/glew-2.2.0/lib/Release/x64")
target_link_libraries(ch3 glew32)

代码:main.cpp

与 GL3W 的差异如下:

GLM

GLM

OpenGL Mathematics (GLM) is a C++ mathematics library for 3D software based on the OpenGL Shading Language (GLSL) specification.

对于实现矩阵变化的C++库,可以使用GLM(OpenGL Mathematics)库。GLM是一个只包含头文件的库,专为需要数学运算的图形软件设计,它基于OpenGL Shading Language (GLSL) 规范,并提供了类似GLSL的接口。

GLM提供的功能包括基本向量操作,矩阵变换(如平移、缩放、旋转)、投影变换等。GLM非常适合用于OpenGL的计算,因为它的设计目标就是与GLSL和OpenGL的数据类型匹配。

GLM(OpenGL Mathematics)库

其它库

Equalizer GLEW GLUS GLM

SOIL2

SOIL2 Github

OpenGL学习预备篇——使用premake配置SOIL2库

SOIL是简易OpenGL图像库(Simple OpenGL Image Library)的缩写,它支持大多数流行的图像格式,使用起来也很简单。当前的最新版本是SOIL2。

GLSL

   GLSL(OpenGL Shading Language) 全称 OpenGL 着色语言,是用来在 OpenGL 中着色编程的语言,也即开发人员写的短小的自定义程序,他们是在图形卡的 GPU上执行的,代替了固定的渲染管线的一部分,使渲染管线中不同层次具有可编程性。 GLSL 其使用 C 语言作为基础高阶着色语言,避免了使用汇编语言或硬件规格语言的复杂性。

GLSL API

GLSL 参考手册 4.60

GLSL 布局限定符

openGL之API学习layout作用详解

// 基本语法为:
layout(qualifier1, qualifier2 = value, ...) variable definition
// 顶点着色器的属性索引
layout(location = attribute index) in vec3 position;

OpenGL学习(十)-- 着色语言 GLSL 语法介绍

作者吃代码的兔子窝的《初探 GLSL 着色器(一)》

作者吃代码的兔子窝的《初探 GLSL 着色器(二)》

作者jeffasd的《glsl语言基础》

GLSL 中文手册 Github

3D 建模工具

3D建模工具有很多种,以下是一些常用的:

  1. 3ds Max :这是一款广泛使用的3D建模软件,它速度快,功能全面,常用于建筑、动画、视频游戏等领域。
  2. Maya :Maya功能完善,工作灵活,易学易用,制作效率极高,渲染真实感极强,被广泛应用于电影级别的CG制作。
  3. ZBrush :ZBrush是一款独立的三维雕塑和建模应用,以其强大的数字雕刻功能而闻名,常用于游戏影视行业的UV贴图和绘制纹理。
  4. Substance Painter :随着PBR(Physically Based Rendering,基于物理的渲染)工作流的应用,Substance Painter已经成为行业标准贴图处理软件。
  5. Blender :Blender是一个开源的跨平台3D创作套件,它的功能包括建模、动画、视觉特效等,适用于各种类型的3D艺术项目。
  6. Marvelous Designer :MD主要用于制作逼真的衣物和道具,特别适合写实风格的3D设计。
  7. Rizom UV :Rizom UV是一款展UV的神器,其内建的快速测试查看功能非常方便。
  8. Photoshop :虽然Photoshop主要用作图像编辑,但它也可以进行一些基本的贴图修改。

选择哪种3D建模工具取决于你的具体需求,比如你要制作的类型、预算和时间限制等因素1。

blender

blender 官网

blender 参考手册

blender 2.82中文参考手册

blender 教程

目录
相关文章
|
3月前
|
存储 缓存 图形学
Vulkan 围炉夜话3
Vulkan 围炉夜话
48 9
Vulkan 围炉夜话3
|
3月前
|
缓存 API 开发工具
Vulkan 围炉夜话1
Vulkan 围炉夜话
43 15
|
3月前
|
缓存 并行计算 算法
Vulkan 围炉夜话2
Vulkan 围炉夜话
55 13
|
3月前
|
存储 缓存 API
Vulkan 围炉夜话4
Vulkan 围炉夜话
48 5
|
3月前
|
Java 虚拟化 数据安全/隐私保护
MacOs 围炉夜话
MacOs 围炉夜话
83 10
|
3月前
|
存储 缓存 算法
Vulkan 围炉夜话5
Vulkan 围炉夜话
57 4
|
3月前
|
开发工具 Android开发 iOS开发
多端开发围炉夜话
多端开发围炉夜话
33 12
|
3月前
|
Linux
BuildRoot 围炉夜话
BuildRoot 围炉夜话
73 9
|
Windows
微软可折叠双屏 Surface 诞生前的辛酸往事
传闻已久的可折叠双屏 Surface 的亮相提上了日程。
1096 0
|
存储 XML 安全
艾伟:Silverlight 2.0 之旋转木马
序言:记得去年8月就开始接触Silverlight 1.0了,那时候刚出来,接触的人还不是很多,一位MVP讲师朋友说国内精通的也就几千人吧,因为自己对RIA一直也比较有兴趣,所以学起来也很快,想不到MS终于放出了2.
1118 0