OpenGL学习笔记:Compute Shader

概念

  • 区别于vs 、fs,compute shader虽然从名字上有个shader,但是在用途上是与shader区别开的。
  • shader从词义上是着色器的意思,因此它的核心用途是参与渲染。而compute shader可以看做是跑在GPU上的program,它可以完全是不参与渲染,而仅仅是运行一些我们想要的计算。

用法

  • 下面是一个用compute shader反转图片的例子

shader上的变化

  • gl_GlobalInvocationID是一个全局的变量,标记当前是在绘制哪个顶点,依靠这个变量来进行采样,compute shader专用。
  • In the compute language, gl_GlobalInvocationID is a derived input variable containing the n-dimensional index of the work invocation within the global work group that the current shader is executing on. The value of gl_GlobalInvocationID is equal to gl_WorkGroupID * gl_WorkGroupSize + gl_LocalInvocationID.
  • image2D:a handle for accessing a 2D texture

OpenGL学习笔记:Subroutine

概念

  • Subroutine赋予了代码动态调用shader中函数的能力
  • 写法比较固定,直接上代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#version 400 core
subroutine vec4 SurfaceColor();
uniform sampler2D U_MainTexture;
subroutine uniform SurfaceColor U_SurfaceColor;
varying vec3 V_Normal;
varying vec4 V_WorldPos;
varying vec2 V_Texcoord;

subroutine (SurfaceColor) vec4 Ambient()
{
return texture2D(U_MainTexture,V_Texcoord)*ambientColor;
}

subroutine (SurfaceColor) vec4 Diffuse()
{
return ambientColor+texture2D(U_MainTexture,V_Texcoord)*diffuseColor;
}

subroutine (SurfaceColor) vec4 Specular()
{
return ambientColor+texture2D(U_MainTexture,V_Texcoord)*diffuseColor+specularColor+vec4(1f, 0.7f, 0.72f,1.0f);
}

void main()
{
gl_FragColor=U_SurfaceColor();
}

OpenGL学习笔记:Instance

步骤

  • 定义多个实例之间不同的数据(posOffsets),类似unity中的constantbuffer数据。
  • shader中定义一个变量,代表这这些变化的数据。例子代码中用了位置的偏移量。
  • 在draw的时候给这个变量赋值,这个和position、normal那些变量的赋值方式是一样的。
  • 使用glVertexAttribDivisor说明posOffsets的使用频率
  • 使用glDrawArraysInstanced函数,替换glDrawArrays

OpenGL学习笔记:截图生成图片

获得窗口数据

  • 利用glReadPixels得到屏幕的像素值
  • 然后利用glTexImage2D获得GPU中的纹理

OpenGL学习笔记 第三周:shader的使用

前言

  • 一周时间学会了一件事,怎么把前两周的纯OpenGL绘制改成shader绘制。
  • 之前对unityshader比较熟悉,因此编写shader本身没啥新收获。但是对于C++代码层面如何的包装shader和调用上收获颇丰。
  • 学完后更加深入的体会到,shader作为在GPU上执行的函数的意义。同时对于渲染一个物体都需要哪些数据有了更深刻的认知。

OpenGL学习笔记 第二周:2D

几个概念

  • glutInitWindowPosition(int x, int y) // 定义窗口位置

  • glViewport(GLint x, GLint y, GLsizei width, GLsizei height) // 定义视口大小

  • glutInitWindowSize(int width, int height) // 定义窗口大小

OpenGL学习笔记 第二周:摄像机操作

OpenGL中如何设置摄像机

  • 在OpenGL中设置camera只需要下面的API即可
    • 前三个是camera的position,可以理解为眼睛的位置,变量命名很贴切。
    • 中间三个是视点的位置,可以理解为你看着那里
    • 后面三个是摄像机的Y轴向量
    • 实际上center-pos产生的向量是作用于x、z两个轴,因此这9个变量就决定了摄像机的位置和朝向。

OpenGL学习笔记 第二周:光

光源基础

  • glEnable(GL_LIGHTING) 开启光的使用
  • glEnable(GL_LIGHT0) 使用第一个光,在OpenGL中默认有8个light可以使用

DirectionLight

  • 平行光最重要的属性是位置。可以通过下面的代码设置:
1
2
   float LightPos[] = { 0.0f,1.0f,0.0f,0.0 };
glLightfv(GL_LIGHT0, GL_POSITION, LightPos);

OpenGL学习笔记 第二周:模型的显示

模型数据的解析

  • 以下是读取到的数据,从这个数据可以看出来第一部分是顶点数据。这个只是不重复的数据而已。
  • 第二部分叫做绘制指令,一行有三组数据,表示一个三角型的三个顶点。所以有几行就说明这个模型由几个三角型组成。
  • 每一组数据说明了这个顶点的pos、texcoord和normal 在第一部分的索引,就是得到的数字-1。
  • 例如:F中第一组数据是 1/1/1 (pos/texcoord/normal)代表的含义是这个顶点的数据是v、vt、vn的第一行。
  • 因为顶点是会共用的,所以可以看到第二行数据有重复,但是因为绘制模型是按照三角型逐个绘制的,因此这些数据还是必须记录下来。

OpenGL学习笔记 第一周:环境构建、OpenGL基础

构建环境

windows上创建一个窗体

  • 定义窗体类,用到了WNDCLASSEXRegisterClassEx函数。

  • 创建窗体

    • 计算一个合适的窗体大小,用到了AdjustWindowRect
    • 创建HWND hwnd = CreateWindowEx(NULL, "GLWindow", "OpenGL Window", WS_OVERLAPPEDWINDOW, 100, 100, windowWidth, windowHight, NULL, NULL, hInstance, NULL);
  • 展示窗体:ShowWindow(hwnd, SW_SHOW);

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×