openGl1
项目里很少用到渲染相关的东西,openGl都忘差不多了,复习一下
长期不用的东西很容易忘,对人来说,这也就是重复的意义
顺便记录一下上次看的时候忽略的
扩展
当一个显卡公司提出一个新特性或者渲染上的大优化,通常会以扩展的方式在驱动中实现
当一个扩展非常流行或者非常有用的时候,它将最终成为未来的OpenGL规范的一部分
多数图形渲染api都是一个状态机,不管是openGl还是vulkan,提供参数不同而已
类型
使用OpenGL的类型的好处是保证了在各平台中每一种类型的大小都是统一的
其他跳过了,直接开始吧
按照vulkan之前教程直接配置,不过发现c/c++没有这个项,得加个cpp才有这个选项
glad。驱动program控制显卡,而驱动版本多,函数位置不固定,所以调用函数常缓存指针,glad用于简化这个过程
配置好了,直接跑一下
#include <glad/glad.h>
int main() {
return 0;
}
双缓冲
文中提到:
双缓冲(Double Buffer)
应用程序使用单缓冲绘图时可能会存在图像闪烁的问题。 这是因为生成的图像不是一下子被绘制出来的,而是按照从左到右,由上而下逐像素地绘制而成的。最终图像不是在瞬间显示给用户,而是通过一步一步生成的,这会导致渲染的结果很不真实。为了规避这些问题,我们应用双缓冲渲染窗口应用程序。前缓冲保存着最终输出的图像,它会在屏幕上显示;而所有的的渲染指令都会在后缓冲上绘制。当所有的渲染指令执行完毕后,我们交换(Swap)前缓冲和后缓冲,这样图像就立即呈显出来,之前提到的不真实感就消除了。
这段话里面有一点,说单缓冲导致图像闪烁,因为图像是逐步生成的。这句话问题很多,为什么逐步生成会导致闪烁、不真实呢。难道双缓冲的图像就不是“逐步”生成的了吗。他像表达的意思可能是,“逐步”是使用双缓冲的原因。我理解的话,闪烁是因为反差过大,就像我先放一张黑图,再切成白图,频率除非快到我能直接看成一张灰色图,不然他就是“闪烁”的。也就是说逐步导致了速度不够快,可能IO原因,可能其他原因,不过不管什么原因,双缓冲这种时空置换的方式肯定比单缓冲快。从逻辑来看,双缓冲逻辑更简单,单缓冲如果渲染的时候有新的写入要怎么处理呢,可能这是更快的原因之一
成功开启黑窗
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include<iostream>
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
class Tool {
public:
static void InitGlfw() {
glfwInit();//glfw初始化
//oenGl主版本号
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
//oenGl次版本号
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
//oenGl 核心模式
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
}
static auto CreateWindow() {
GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL);
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return window;
}
glfwMakeContextCurrent(window);//将我们窗口的上下文设置为当前线程的主上下文
return window;
}
static int InitGlad() {
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
return 0;
}
static void InitGlView() {
glViewport(0, 0, 800, 600);//窗口左下角的坐标、窗口大小
}
static void BindAutoAdaptSize(GLFWwindow* window) {
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
}
static void RenderLoop(GLFWwindow* window) {
while (!glfwWindowShouldClose(window))//检查一次GLFW是否被要求退出
{
glfwSwapBuffers(window);//交换颜色缓冲(它是一个储存着GLFW窗口每一个像素颜色值的大缓冲)
glfwPollEvents();//触发什么事件(比如键盘输入、鼠标移动等)、更新窗口状态,并调用对应的回调函数(可以通过回调方法手动设置)
}
}
static void Free() {
glfwTerminate();
}
private:
};
class MyWindow
{
public:
MyWindow();
~MyWindow();
bool IsSuccess();
private:
GLFWwindow* window;
bool succFlag = true;
};
MyWindow::MyWindow()
{
Tool::InitGlfw();
window = Tool::CreateWindow();
if (window == NULL) {
succFlag = false;
return;
}
int gFlag= Tool::InitGlad();
if (gFlag == -1) {
succFlag = false;
return ;
}
Tool::BindAutoAdaptSize(window);
Tool::RenderLoop(window);
Tool::Free();
}
MyWindow::~MyWindow()
{
}
bool MyWindow::IsSuccess()
{
return succFlag;
}
int main()
{
auto myWindow = MyWindow();
if (myWindow.IsSuccess()==false) {
return -1;
}
return 0;
}

浙公网安备 33010602011771号