openGL绘制绕顶点旋转的三角形绕一点旋转(运动起来),vs2015环境下运行,

没有更多推荐了,
不良信息举报
举报内容:
OpenGL 环绕和绘制三角形
举报原因:
原文地址:
原因补充:
最多只允许输入30个字
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!查看: 2128|回复: 4
使用VS2015里面的DirectX12 UWP那个通用模板,好绝望
本帖最后由 Gavin 于
18:01 编辑
& && &&&使用VS2015里面的“DirectX12应用(通用Windows)”这个模板,能生成一个旋转的彩色的立方体,我把这个例子好好消化了下,但是不能完全吃透。想把这个demo改成带纹理的选择立方体,以加深印象。
& && & 但是好绝望啊,各种问题,先是加载贴图各种报错,后来使用“DDSTextureLoader”这个类,为什么别人的例子可以,而移植过来,代码都一样的,就是不行,现在还不确定的是不是UWP的问题。接着是根标签和着色代码(着色器代码很简单的),但是加载创建根标签时,运行时好多错啊,各种设置测试,就是不行啊。快一个星期了,好绝望呢!
哪位大仙能用VS2015里面的“DirectX12应用(通用Windows)”这个模板,能生成一个带纹理的旋转的彩色的立方体,发生来让俺学习下,不胜感激,由于无以回报,只能写谢谢了。
Gavin于 17:27补充以下内容:
哪位大仙有空,劳烦伸出手来,拉我一把,谢谢了!
本帖子中包含更多资源
才可以下载或查看,没有帐号?
本帖最后由 Gavin 于
17:52 编辑
DirectX12应用(通用Windows)”这个模板,如上图
Gavin于 17:51补充以下内容:
这个是模板图片,为什么看不到图片呢,奇怪了。编辑的时候能看见图片的。
弄成附件,试试。
本帖子中包含更多资源
才可以下载或查看,没有帐号?
可以看看 zerotutorials.com 的第5個教學
handsomejks 发表于
可以看看 zerotutorials.com 的第5個教學
好的,谢谢了,测试果然可以。只是下载链接被墙了。
Gavin 发表于
好的,谢谢了,测试果然可以。只是下载链接被墙了。
参照着例子,自己练习了下,真的好感谢哦!差点就是《从入门到放弃》了!
本帖子中包含更多资源
才可以下载或查看,没有帐号?
Powered by> 博客详情
以下内容只针对GLSL1.20的版本进行说明的,有些内置的变量在1.20之后,已经被废弃了。
每个顶点着色器都至少输出一个裁剪空间的位置坐标。光照、纹理坐标的生成和其他的一些操作是可选的。例如,你要创建了深度纹理,那你只需要最终的深度值,你就没必要在着色器中处理颜色和纹理坐标,也不需要输出它们。但至少需要输出裁剪空间的坐标给后面的图元组装和光栅化。如果不输出任何东西,行为将是未定义的。如果要让颜色在后面的管道中可见,则至少要把输入的颜色拷贝到输出颜色,虽然着色器不对其进行任何处理。
举个简单的例子来模仿固定管线的方式。在固定管线中,会对顶点进行模型视图变换和投影变换变为裁剪空间的位置坐标。在GLSL中,提供了gl_ModelViewProjectionMatrix,这个矩阵包括模型视图变换和投影变换。所以我们只要把顶点左乘以这个矩阵就能够得到裁剪空间的位置坐标。
//simple.vs
//执行顶点变换
//拷贝主颜色
#version&120
void&main(void)
//顶点变换到裁剪空间位置,作为输出
gl_Position&=&gl_ModelViewProjectionMatrix&*&gl_V
//把主颜色拷贝的正面颜色
gl_FrontColor&=&gl_C
上面的gl_ModelViewProjectionMatrx也可以分成两个来写,写成gl_ProjectionMatrix * gl_ModelViewM
自己执行变换的另一种方式是使用内置函数ftransform,它对需要处理的顶点模拟了固定功能管线的顶点变换。这在混合固定功能和顶点着色器绘制同一个几何图形时很有用,可以防止Z值的细微差异导致的Z-fighting。
简单的写 就是 gl_Position = ftransform();
之前介绍过散射的光照,散射的光照要考虑到物体的面与输入光源的角度。其公式如下:
Cdiff = max{N o L, 0} * Cmat * Cli
其中N代表顶点的单位法线, L代表从顶点指向光源的单位向量。Cmat 是表面的材料颜色, Cli是光源的颜色。Cdiff则计算出来的结果。在例子中我们使用的是白光,所以我们可以直接忽略掉Cli 因为乘以{1, 1, 1, 1}结果不变。下面简单实现散射光照方程。
//基于白色光的散射光照
uniform&vec3&lightP
void&main(void)
&&&&gl_Position&=&gl_ModelViewProjectionMatrix&*&gl_V
&&&&//获得顶点的法线
&&&&vec3&N&=&normalize(gl_NormalMatrix&*&gl_Normal);
&&&&//获得经过视图模型变换后的顶点位置
&&&&vec4&V&=&gl_ModelViewMatrix&*&gl_V
&&&&//计算得到从顶点指向光源的单位向量
&&&&vec3&L&=&normalize(lightPos&-&V.xyz);
&&&&//计算散射颜色
&&&&float&NdotL&=&dot(N,&L);
&&&&gl_FrontColor&=&gl_Color&*&vec4(max(0.0,&NdotL));
其中gl_NormalMatrix是GLSL内置的变量为法线变换矩阵,gl_Normal代表顶点的法线。dot也是GLSL内置的函数提供向量的点乘, normalize也是内置函数。其余的已经在前面介绍过了。,那么我们该如何设置这个lightPos向量呢。GLSL提供了一系列设置uniform变量的方法。这里用到其中一个。
void glUniform3fv(GLintlocation, GLsizeicount, const GLfloat *value);
你可以在渲染函数中, 随意设置这个参数值,来改变光源的位置。整个编译和链接shader并设置变量的函数如下:
float&g_lightPos[3]&=&{20.0f,&10.0f,&20.0f,&1.0f};
void&SetupRC()
&&glClearColor(0.0f,&0.0f,&0.0f,&1.0f);
&&glEnable(GL_DEPTH_TEST);
&&glCullFace(GL_BACK);
&&glFrontFace(GL_CCW);
&&glEnable(GL_CULL_FACE);
&&glEnable(GL_POLYGON_SMOOTH);
&&glEnable(GL_LINE_SMOOTH);
&&GLint&&&const&GLchar*&vsSource[1];
&&vsSource[0]&=&vsC&
&&//这里的vsChar就是着色器代码字符串
&&GLuint&vs&=&glCreateShader(GL_VERTEX_SHADER);
&&glShaderSource(vs,&1,&vsSource,&NULL);
&&glCompileShader(vs);
&&glGetShaderiv(vs,&GL_COMPILE_STATUS,&&success);
&&if(!success)
&&&&GLchar&infoLog[MAX_LENGTH];
&&&&glGetShaderInfoLog(vs,&MAX_LENGTH,&NULL,&infoLog);
&&&&printf(infoLog);
&&&&getchar();
&&&&exit(0);
&&GLuint&program&=&glCreateProgram();
&&glAttachShader(program,&vs);
&&glLinkProgram(program);
&&glGetProgramiv(program,&GL_LINK_STATUS,&&success);
&&&&if&(!success)
&&&&GLchar&infoLog[MAX_LENGTH];
&&&&glGetProgramInfoLog(program,&MAX_LENGTH,&NULL,&infoLog);
&&&&printf(infoLog);
&&&&getchar();
&&&&exit(0);
&&glValidateProgram(program);
&&glGetProgramiv(program,&GL_VALIDATE_STATUS,&&success);
&&if&(!success)
&&&&GLchar&infoLog[MAX_LENGTH];
&&&&glGetProgramInfoLog(program,&MAX_LENGTH,&NULL,&infoLog);
&&&&printf(infoLog);
&&&&getchar();
&&&&exit(0);
&&glUseProgram(program);
&&lightPosLocation&=&glGetUniformLocation(program,&"lightPos");&&
&&if&(lightPosLocation&!=&-1)
&&&&glUniform3fv(lightPosLocation,&1,&g_lightPos);
效果如下:(我光照的位置和物体的位置调的不是很好)
如果你还是想使用固定功能管线的glLight*来设置光源的位置的话,需要改一下shader代码。GLSL提供了一个内置的变量gl_LightSource[n].position 其中n为第几个光源。改一下上面的shader.
#define&FIX_FUNCTION&1
char&vsChar[]&=&{&&"#version&120\n"
&&"uniform&vec3&lightP\n"
&&"void&main(void)"
&&"&&gl_Position&=&gl_ModelViewProjectionMatrix&*&gl_V"
&&"&&vec3&N&=&normalize(gl_NormalMatrix&*&gl_Normal);"
&&"&&vec4&V&=&gl_ModelViewMatrix&*&gl_V"
&&#if&FIX_FUNCTION&&
&&"&vec3&L&=&normalize(gl_LightSource[0].position.xyz&-&V.xyz);"
&&"&&vec3&L&=&normalize(lightPos&-&V.xyz);"
&&"&&float&NdotL&=&dot(N,&L);"
&&"&&gl_FrontColor&=&gl_Color&*&vec4(max(0.0,&NdotL));"
&&void&SetupRC()
#if&FIX_FUNCTION
&&glLightfv(GL_LIGHT0,&GL_POSITION,&g_lightPos);
&&lightPosLocation&=&glGetUniformLocation(program,&"lightPos");
&&&&if&(lightPosLocation&!=&-1)
&&&&glUniform3fv(lightPosLocation,&1,&g_lightPos);
这样效果是等价的。你会发现我并没有调用
glEnable(GL_LIGHTING);glEnable(GL_LIGHT0);
来开启光照。这就是shader的好处,不需要这一堆的开关指令。需要用到的就拿去用吧,没用到就相当于关闭了。shader 可编程管线更加灵活。
镜面光照要考虑光的入射方向,以及眼睛所在的位置。由顶点指向光源的向量,顶点的法线,顶点指向照相机的向量就可以决定镜面光在该顶点的强度。简单起见默认默认照相机在z的正方向上,假设顶点到照相机的单位向量为(0.0, 0.0, 1.0)。根据镜面光的公式:
Cspec = max{N o H, 0}Sexp * Cmat * Cli
H是光线向量与视角向量之间夹角正中方向的单位向量。Sexp代表镜面指数,用于控制镜面光照的紧聚程度。Cmat是材料的颜色,Cli是光的颜色。Cspec 是最终求得的镜面颜色。在下面简单的例子中,假设光是白光(1.0, 1.0, 1.0, 1.0),镜面材料的镜面光属性也为(1.0, 1.0, 1.0, 1.0),所以我们可以忽略掉这一项乘的操作。其中N,L,Cmat 和 Cli 和散射光是一样的。这里镜面指数固定为128.
编写如下的specular.vs:
#version&120
uniform&vec3&lightP
void&main(void)
//MVP&transform
&&gl_Position&=&gl_ModelViewProjectionMatrix&*&gl_V
&&//caculate&diffuse
&&//normal
&&vec3&N&=&normalize(gl_NormalMatrix&*&gl_Normal);
&&//transform&to&view&coordinate
&&vec4&V&=&(gl_ModelViewMatrix&*&gl_Vertex);
&&//light&vector
&&vec3&L&=&normalize(lightPos&-&V.xyz);
&&float&NdotL&=&dot(N,L);
&&vec4&diffuse&=&vec4(max(NdotL,&0.0))&*&gl_C
&&//specular
&&vec3&H&=&normalize(vec3(0.0,&0.0,&1.0)&+&L);
&&float&NdotH&=&max(0.0,&dot(N,H));
&&const&float&expose&=&128.0;
&&vec4&specular&=&vec4(0.0);
&&if&(NdotL&&&0.0)
&&specular&=&vec4(pow(NdotH,&expose));
&&gl_FrontColor&=&diffuse&+&
提升镜面光照
由上图可以看出,镜面光照的高亮在物体表面变化的非常快。在这里我们只是逐顶点的计算镜面亮点然后在三角形内部进行插值。这样的效果较差。我们并不能获得一个漂亮的圆形的亮点,亮点看起来是不规则多边形的。
一种改善的方式是把散射光的效果和镜面光的效果区分开,把散射光照结果输出为主颜色,镜面光照的结果设置为辅助颜色。相比于之前的逐个顶点计算好光照结果,再进行光栅化插值然后进入片段处理。现在是把镜面光的效果放到辅助颜色,而辅助颜色是在纹理等片段处理之后加到片段上的,这样就能够呈现更真实的光照效果。这种基于片段的求和通过启用GL_COLOR_SUM就可以实现了。
#version&120
uniform&vec3&lightP
void&main(void)
//&normal&MVP&transform
&&&gl_Position&=&gl_ModelViewProjectionMatrix&*&gl_V
&&&&vec3&N&=&normalize(gl_NormalMatrix&*&gl_Normal);
&&&&vec4&V&=&gl_ModelViewMatrix&*&gl_V
&&&&vec3&L&=&normalize(lightPos&-&V.xyz);
&&&&vec3&H&=&normalize(L&+&vec3(0.0,&0.0,&1.0));
&&&&const&float&specularExp&=&128.0;
&&&&//&put&diffuse&into&primary&color
&&&&float&NdotL&=&max(0.0,&dot(N,&L));
&&&&gl_FrontColor&=&gl_Color&*&vec4(NdotL);
&&&&//&put&specular&into&secondary&color
&&&&float&NdotH&=&max(0.0,&dot(N,&H));
&&&&gl_FrontSecondaryColor&=&(NdotL&&&0.0)&?&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&vec4(pow(NdotH,&specularExp))&:&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&vec4(0.0);
还需glEanble(GL_COLOR_SUM);
这种方式好像提升了一点点效果。但本质上的原因没有解决,那就是镜面指数的问题。随着镜面系数的提高(N o H),这种基于顶点插值的方式变化的非常快。如果你的物体没有很细的分格化,有可能整个物体都没有得到镜面加亮(比如一个大三角形的三个顶点,都没有得到镜面加亮,那么这个三角形就没有镜面加亮的效果了)。
要避免这个问题的一种有效方法是只输出一个镜面系数(N o H),但是等到片段着色时,才进行幂操作。使用这种方式,可以安全地对变换更慢的镜面系数进行插值。由于现在还没接触到片段着色器。我们可以使用纹理查找的方式来实现这种功能。我们需要做的就是用一个包含S128 个值的表设置一个1D纹理,然后把镜面系数输出为一个纹理坐标。然后再用固定功能管线的方式设置纹理环境把从纹理坐标查找到的镜面颜色与散射光的颜色相加。
着色器代码如下:
#version&120
uniform&vec3&lightP
void&main(void)
//&normal&MVP&transform
&&&&gl_Position&=&gl_ModelViewProjectionMatrix&*&gl_V
&&&&vec3&N&=&normalize(gl_NormalMatrix&*&gl_Normal);
&&&&vec4&V&=&gl_ModelViewMatrix&*&gl_V
&&&&vec3&L&=&normalize(lightPos&-&V.xyz);
&&&&vec3&H&=&normalize(L&+&vec3(0.0,&0.0,&1.0));
&&&&//&put&diffuse&lighting&result&in&primary&color
&&&&float&NdotL&=&max(0.0,&dot(N,&L));
&&&&gl_FrontColor&=&gl_Color&*&vec4(NdotL);
&&&&//&copy&(N.H)*8-7&into&texcoord&if&N.L&is&positive
&&&&float&NdotH&=&0.0;if&(NdotL&&&0.0)
&&&&&&&&NdotH&=&max(0.0,&dot(N,&H)&*&8.0&-&7.0);
&&&&gl_TexCoord[0]&=&vec4(NdotH,&0.0,&0.0,&1.0);
在这里N.H的范围会被截取为[0,1],但如果你对其进行128次幂,那么在[0,1]之间的大部分值,都会非常接近0,这样大部分顶点的纹理坐标就是0了。只有[7/8, 1]的值经过幂之后,会有可度量的纹理值。为了充分利用1D纹理,我们可以把几种在上面的八分之一范围的值填充到整个纹理中,来提高结果的精度。我们可以把(N o H)放大8倍,然后左移7个单位,那么[0,1]就被映射为[-7,1],然后使用GL_CLAMP_TO_EDGE环绕模式,[-7,0]的值将会被截取为0.我们所感兴趣的范围[0,1]中的值将接受(7/8)128&& 和 1之间的纹理单元值。
//创建一个一维的纹理单元
void&CreateTexture(float&r,&float&g,&float&b)
&&GLfloat&texels[512&*&4];
&&GLint&texSize&=&(maxTexSize&&&512)&?&512&:&maxTexS
&&GLint&x;&&
&&for&(x&=&0;&x&&&texS&x++)
&&&&texels[x*4+0]&=&r&*&(float)pow(((double)x&/&(double)(texSize-1))&*&0.125f&+&0.875f,&128.0);
&&&&texels[x*4+1]&=&g&*&(float)pow(((double)x&/&(double)(texSize-1))&*&0.125f&+&0.875f,&128.0);
&&&&texels[x*4+2]&=&b&*&(float)pow(((double)x&/&(double)(texSize-1))&*&0.125f&+&0.875f,&128.0);
&&&&texels[x*4+3]&=&1.0f;
&&//&Make&sure&the&first&texel&is&exactly&zero.&&Most
&&//&incoming&texcoords&will&clamp&to&this&texel.
&&texels[0]&=&texels[1]&=&texels[2]&=&0.0f;
&&glTexImage1D(GL_TEXTURE_1D,&0,&GL_RGBA16,&texSize,&0,&GL_RGBA,&GL_FLOAT,&texels);
....//设置纹理模式
&glGetIntegerv(GL_MAX_TEXTURE_SIZE,&&maxTexSize);
&&glActiveTexture(GL_TEXTURE0);
&&glTexParameteri(GL_TEXTURE_1D,&GL_TEXTURE_MIN_FILTER,&GL_LINEAR);
&&glTexParameteri(GL_TEXTURE_1D,&GL_TEXTURE_MAG_FILTER,&GL_LINEAR);
&&glTexParameteri(GL_TEXTURE_1D,&GL_TEXTURE_WRAP_S,&GL_CLAMP_TO_EDGE);
&&glTexEnvi(GL_TEXTURE_1D,&GL_TEXTURE_ENV_MODE,&GL_ADD);
&&CreateTexture(1.0f,&1.0f,&1.0f);
获得了更好效果
使用前面方式的效果。
下面的shader使用三个光源:
#version&120
uniform&vec3&lightPos[3];
varying&vec4&gl_TexCoord[3];
uniform&vec3&camaraPvoid&main(void)
//MVP&transform
gl_Position&=&gl_ModelViewProjectionMatrix&*&gl_V
//经过视图变换后的点
&&&vec4&V&=&gl_ModelViewMatrix&*&gl_V
&&&&vec3&N[3],&L[3],&H[3];
&&&&gl_FrontColor&=&vec4(0.0);
&&&&for&(int&i&=&0;&i&&&3;&++i)
&&&&&&&&N[i]&=&normalize(gl_NormalMatrix&*&gl_Normal);
&&&&&&&&L[i]&=&normalize(lightPos[i]&-&V.xyz);
&&&&&&&&float&NdotL&=&dot(N[i],&L[i]);
&&&&&&&&//accumalte&diffuse&light
&&&&&&&&gl_FrontColor&+=&vec4(max(0.0,&NdotL))&*&gl_C
&&&&&&&&//指向光源的向量,与指向照相机的向量的。半角向量。
&&&&&&&&H[i]&=&normalize(L[i]&+&normalize(camaraPos));
&&&&&&&&float&NdotH&=&0.0;if&(NdotL&&&0.0)
&&&&&&&&&&&&NdotH&=&max(0.0,&dot(N,&H)&*&8.0&-&7.0);
&&&&&&&&gl_TexCoord[i]&=&vec4(NdotH,&0.0,&0.0,&1.0);
上面的例子也用了对应的三个纹理。
&&glActiveTexture(GL_TEXTURE0);
&&glTexEnvi(GL_TEXTURE_ENV,&GL_TEXTURE_ENV_MODE,&GL_ADD);
&&glBindTexture(GL_TEXTURE_1D,&textures[0]);
&&glTexParameteri(GL_TEXTURE_1D,&GL_TEXTURE_MIN_FILTER,&GL_LINEAR);
&&glTexParameteri(GL_TEXTURE_1D,&GL_TEXTURE_MAG_FILTER,&GL_LINEAR);
&&glTexParameteri(GL_TEXTURE_1D,&GL_TEXTURE_WRAP_S,&GL_CLAMP_TO_EDGE);
&&CreateTexture(1.0f,&0.25f,&0.25f);
&&glEnable(GL_TEXTURE_1D);
&&glActiveTexture(GL_TEXTURE1);
&&glTexEnvi(GL_TEXTURE_ENV,&GL_TEXTURE_ENV_MODE,&GL_ADD);
&&glBindTexture(GL_TEXTURE_1D,&textures[1]);
&&glTexParameteri(GL_TEXTURE_1D,&GL_TEXTURE_MIN_FILTER,&GL_LINEAR);
&&glTexParameteri(GL_TEXTURE_1D,&GL_TEXTURE_MAG_FILTER,&GL_LINEAR);
&&glTexParameteri(GL_TEXTURE_1D,&GL_TEXTURE_WRAP_S,&GL_CLAMP_TO_EDGE);
&&CreateTexture(0.25,&1.0,&0.25);
&&glEnable(GL_TEXTURE_1D);
&&glActiveTexture(GL_TEXTURE2);
&&glTexEnvi(GL_TEXTURE_ENV,&GL_TEXTURE_ENV_MODE,&GL_ADD);
&&glBindTexture(GL_TEXTURE_1D,&textures[2]);
&&glTexParameteri(GL_TEXTURE_1D,&GL_TEXTURE_MIN_FILTER,&GL_LINEAR);
&&glTexParameteri(GL_TEXTURE_1D,&GL_TEXTURE_MAG_FILTER,&GL_LINEAR);
&&glTexParameteri(GL_TEXTURE_1D,&GL_TEXTURE_WRAP_S,&GL_CLAMP_TO_EDGE);
&&CreateTexture(0.25,&0.25,&1.0);
&&glEnable(GL_TEXTURE_1D);
基于顶点的雾
尽管雾是在片段处理阶段中处理的, 但出于性能的考虑,我们可以在顶点阶段对其进行处理,而且也不影响真实性。下面是雾的二次方雾因子的方程式:
ff = e-(d * fc)2
其中d代表雾的浓度,fc是雾坐标,通常情况下是顶点到照相机的距离。下面我们只在shader中计算 雾坐标,雾的方程式用固定功能管线来实现。其中length是GLSL内置的函数,求向量的长度。
float fogColor[4] = {0.5f, 0.8f, 0.5f, 1.0f}; //雾颜色为浅绿
#version&120
uniform&vec3&lightPos[1];
uniform&vec3&camaraPvoid&main(void)
//MVP&transform
&&&&gl_Position&=&gl_ModelViewProjectionMatrix&*&gl_V
&&&&vec4&V&=&gl_ModelViewMatrix&*&gl_V
&&&&vec3&N&=&normalize(gl_NormalMatrix&*&gl_Normal);
&&&&vec3&L&=&normalize(lightPos[0]&-&V.xyz);
&&&&float&NdotL&=&dot(N,&L);
&&&&vec4&diffuse&=&max(0.0,&NdotL)&*&gl_C
&&&&const&float&expose&=&128.0;
&&&&vec3&H&=&normalize(L&+&normalize(camaraPos));
&&&&float&NdotH&=&0.0;if&(NdotL&&&0.0)
&&&&&&&&NdotH&=&max(0.0,&dot(N,&H));
&&&&vec4&specular&=&vec4(pow(NdotH,&expose));
&&&&gl_FrontColor&=&diffuse&+&
&&&&//计算雾坐标
&&&&gl_FogFragCoord&=&length(V);
&&glBlendFunc(GL_SRC_ALPHA,&GL_ONE_MINUS_SRC_ALPHA);
&&glEnable(GL_BLEND);
&&glFogfv(GL_FOG_COLOR,&fogColor);
&&glFogf(GL_FOG_DENSITY,&density);
&&glFogi(GL_FOG_MODE,&GL_EXP2);
&&glFogi(GL_FOG_COORD_SRC,&GL_FOG_COORD);
&&glEnable(GL_FOG);
当然我们也可以在shader中直接实现该方程。
#version&120
uniform&vec3&lightPos[1];
uniform&vec3&camaraP
uniform&float&
void&main(void)
//MVP&transform
&&&&gl_Position&=&gl_ModelViewProjectionMatrix&*&gl_V
&&&&vec4&V&=&gl_ModelViewMatrix&*&gl_V
&&&&vec3&N&=&normalize(gl_NormalMatrix&*&gl_Normal);
&&&&vec3&L&=&normalize(lightPos[0]&-&V.xyz);
&&&&float&NdotL&=&dot(N,&L);
&&&&vec4&diffuse&=&max(0.0,&NdotL)&*&gl_C
&&&&const&float&expose&=&128.0;
&&&&vec3&H&=&normalize(L&+&normalize(camaraPos));
&&&&float&NdotH&=&0.0;if&(NdotL&&&0.0)
&&&&&&&&NdotH&=&max(0.0,&dot(N,&H));
&&&&vec4&specular&=&vec4(pow(NdotH,&expose));
&&&&//计算雾因子
&&&&const&float&e&=&2.71828;
&&&&float&fogFactor&=&density&*&length(V);
&&&&fogFactor&*=&fogF
&&&&fogFactor&=&clamp(pow(e,&-fogFactor),&0.0,&1.0);
&&&&const&vec4&fogColor&=&vec4(0.5,&0.8,&0.5,&1.0);
&&&&//把雾颜色和&光的颜色&根据雾因子进行混合
&&&&gl_FrontColor&=&mix(fogColor,&clamp(diffuse&+&specular,&0.0,&1.0),&fogFactor);
genType (genTypex, genTypey, genTypea);
mix在x,y之间进行插值,a是权值。 插值的公式是x?(1-a)+y?a.
源码参考:& 项目下 specular multilight 和 fogvs。 shader在 shadersource目录下。
”在线下联结了各位 OSCer,推广开源项目和理念,很荣幸有你的参与~
领取条件:参与过开源中国“源创会”的 OSCer 可以领取
不会变啊。lightPos 就是光源的位置。 你在代码里,对它进行变换了吗? lightPosLocation = glGetUniformLocation(program, &lightPos&); if (lightPosLocation != -1) { glUniform3fv(lightPosLocation, 1, g_lightPos); } 这里设置的光源位置。你有调整才会变。
支付宝支付
微信扫码支付
打赏金额: ¥
已支付成功
打赏金额: ¥OpenGL绘制一个三角形要调用多少次顶点和片段着色器的main函数
[问题点数:20分,结帖人szuzsq]
OpenGL绘制一个三角形要调用多少次顶点和片段着色器的main函数
[问题点数:20分,结帖人szuzsq]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
匿名用户不能发表回复!|温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
&html& &head&
&title&WebGL--通过鼠标控制纹理三角形旋转&/title&
&meta http-equiv="Content-Type" content="text/charset=utf-8"/&
&style type="text/css"&
&script type="text/javascript" src="glMatrix-0.9.5.js"&&/script&
&script id="shader-vs" type="x-shader/x-vertex"&
attribute vec3 v3P
uniform mat4 um4R
varying vec2 v2TexC
void main(void) {
v2TexCoord = vec2((v3Position.x+1.0)/2.0, 1.0-(v3Position.y+1.0)/2.0);
gl_Position = um4Rotate * vec4(v3Position, 1.0);
&script id="shader-fs" type="x-shader/x-fragment"&
#ifdef GL_FRAGMENT_PRECISION_HIGH&
uniform sampler2D sT
varying vec2 v2TexC
void main(void){
gl_FragColor = texture2D(sTexture,v2TexCoord);
&script type="text/javascript"&
function start() {
loadImage()&
function loadImage() {
image = new Image();
image.src = "04210.jpg";
image.onload=function(){
var image =
var webgl =
var vsObj =
var fsObj =
var programObject =
var triangleBuffer =
var v3PositionIndex = 0;
var samplerIndex = -1;
var interval = 300;
var angle = 0;
var um4RotateIndex = -1;
var mouse = {
leftDown: false,
rightDown: false
function init() {
var myCanvasObj = document.getElementById('myCanvas');
webgl = myCanvasObj.getContext('experimental-webgl');
// 设置视口尺寸
webgl.viewport(0,0,myCanvasObj.clientWidth,myCanvasObj.clientHeight);
// 创建着色器
vsObj = webgl.createShader(webgl.VERTEX_SHADER);
fsObj = webgl.createShader(webgl.FRAGMENT_SHADER);
// 将着色器对象与源码相关联
webgl.shaderSource(vsObj,shaderSourceFromScript('shader-vs'));
webgl.shaderSource(fsObj,shaderSourceFromScript('shader-fs'));
// 编译着色器对象
webgl.compileShader(vsObj);
webgl.compileShader(fsObj);
// 检测编译状态
if (!webgl.getShaderParameter(vsObj,webgl.COMPILE_STATUS)) {
alert(webgl.getShaderInfoLog(vsObj));
if (!webgl.getShaderParameter(fsObj,webgl.COMPILE_STATUS)) {
alert(webgl.getShaderInfoLog(fsObj));
// 创建程序对象
programObject = webgl.createProgram();
// 将着色器附加到程序对象
webgl.attachShader(programObject,vsObj);
webgl.attachShader(programObject,fsObj);
// 将着色器中的变量关联到程序对象中的一个属性索引
webgl.bindAttribLocation(programObject,v3PositionIndex,'v3Position');
// 链接程序
webgl.linkProgram(programObject);
// 检测程序对象状态
if (!webgl.getProgramParameter(programObject,webgl.LINK_STATUS)) {
alert(webgl.getProgramInfoLog(programObject));
// 获取采样器的索引值
samplerIndex = webgl.getUniformLocation(programObject,"sTexture");
// 获取旋转矩阵索引
um4RotateIndex = webgl.getUniformLocation(programObject,"um4Rotate");
// 使用程序对象
webgl.useProgram(programObject);
var verticesData = [
0.0,0.5,0.0,
-0.5,-0.5,0.0,
0.5,0.0,0.0
// 创建顶点缓存并存入顶点数据
triangleBuffer = webgl.createBuffer();
webgl.bindBuffer(webgl.ARRAY_BUFFER,triangleBuffer);
webgl.bufferData(webgl.ARRAY_BUFFER,new Float32Array(verticesData),webgl.STATIC_DRAW);
// 创建纹理并绑定纹理数据
textureObject = webgl.createTexture();
webgl.bindTexture(webgl.TEXTURE_2D,textureObject);
webgl.texImage2D(webgl.TEXTURE_2D,0,webgl.RGB,webgl.RGB,webgl.UNSIGNED_BYTE,image);
animate();
addEvent(window,'mousedown',mouseDown);
addEvent(window,'mouseup',mouseUp);
document.body.onselectstart = function(e){}
document.oncontextmenu=function(e){}
function mouseDown(e) {
if (e.buttons) {
if (e.buttons==1) {
mouse.leftDown =
else if(e.buttons==2) {
mouse.rightDown =
else if (e.which) {
if (e.which==1) {
mouse.leftDown =
else if(e.which==3) {
mouse.rightDown =
function mouseUp(e) {
if (e.buttons) {
if (e.buttons==1) {
mouse.leftDown =
else if(e.buttons==2) {
mouse.rightDown =
else if (e.which) {
if (e.which==1) {
mouse.leftDown =
else if(e.which==3) {
mouse.rightDown =
function addEvent(elem,evt,func) {
if (window.addEventListener) {
elem.addEventListener(evt,func,false);
else if (window.attachEvent) {
elem.attachEvent('on'+evt,func);
elem['on'+evt]=
function animate() {
if (mouse.leftDown) angle+=10;
else if (mouse.rightDown) angle-= 10;
if (angle&=360) angle -= 360;
if (angle&0) angle += 360;
requestAnimationFrame(animate);
function render() {
// 设置背景色及清除颜色缓存
webgl.clearColor(0.0,0.0,0.0,1.0);
webgl.clear(webgl.COLOR_BUFFER_BIT);
// 指定当前缓存为要绘制三角形的顶点缓存
webgl.bindBuffer(webgl.ARRAY_BUFFER,triangleBuffer);
webgl.enableVertexAttribArray(v3PositionIndex);
webgl.vertexAttribPointer(v3PositionIndex,3,webgl.FLOAT,false,0,0);
// 指定纹理放大及缩小方式
webgl.texParameteri(webgl.TEXTURE_2D,webgl.TEXTURE_MAG_FILTER,webgl.NEAREST);
webgl.texParameteri(webgl.TEXTURE_2D,webgl.TEXTURE_MIN_FILTER,webgl.NEAREST);
// 制定纹理包裹方式
webgl.texParameteri(webgl.TEXTURE_2D,webgl.TEXTURE_WRAP_S,webgl.CLAMP_TO_EDGE);
webgl.texParameteri(webgl.TEXTURE_2D,webgl.TEXTURE_WRAP_T,webgl.CLAMP_TO_EDGE);
// 激活纹理
webgl.activeTexture(webgl.TEXTURE0);
webgl.bindTexture(webgl.TEXTURE_2D,textureObject);
webgl.uniform1i(samplerIndex,0);
var m4Rotate = mat4.create();
mat4.identity(m4Rotate);
mat4.rotateZ(m4Rotate,angle*Math.PI/180);
webgl.uniformMatrix4fv(um4RotateIndex,false,m4Rotate);
// 绘制三角形
webgl.drawArrays(webgl.TRIANGLES,0,3);
// 通过script的id获取其中的文本
function shaderSourceFromScript(scriptId) {
var shaderScript = document.getElementById(scriptId);
if (!shaderScript) return '';
var sourceCode = '';
var child = shaderScript.firstC
while(child) {
if (child.nodeType == child.TEXT_NODE) sourceCode += child.textC
child = child.nextS
return sourceC
&/script& &/head& &body onload="start()"&
&canvas id="myCanvas" width="600px" height="450px"&&/canvas& &/body&&/html&
阅读(385)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
在LOFTER的更多文章
loftPermalink:'',
id:'fks_',
blogTitle:'WebGL--通过鼠标控制纹理三角形旋转',
blogAbstract:'&!DOCTYPE html&&html&\t&head&\t\t&title&WebGL--通过鼠标控制纹理三角形旋转&/title&\t\t&meta http-equiv=\"Content-Type\" content=\"text/charset=utf-8\"/&\t\t&style type=\"text/css\"&\t\t\tcanvas {\t\t\t\tborder: 1\t\t\t}\t\t&/style&',
blogTag:'',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:0,
publishTime:5,
permalink:'blog/static/',
commentCount:0,
mainCommentCount:0,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'',
hmcon:'1',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}}

我要回帖

更多关于 三角形有几个顶点 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信