顶点着色器VertexShader.txt:

  1. uniform vec3 lightposition;//光源位置
  2. uniform vec3 eyeposition;//相机位置
  3. uniform vec4 ambient;//环境光颜色
  4. uniform vec4 lightcolor;//光源颜色
  5. uniform float Ns;//高光系数
  6. uniform float attenuation;//光线的衰减系数
  7. varying vec4 color;//向片段着色其传递的参数
  8. void main()
  9. {
  10. vec3 ECPosition = vec3(gl_ModelViewMatrix * gl_Vertex);
  11. vec3 N = normalize(gl_NormalMatrix * gl_Normal);
  12. vec3 L = normalize(lightposition - ECPosition);
  13. vec3 V = normalize(eyeposition - ECPosition);
  14. vec3 H = normalize(V + L);
  15. vec3 diffuse = lightcolor * max(dot(N , L) , 0);
  16. vec3 specular = lightcolor * pow(max(dot(N , H) , 0) , Ns) * attenuation;
  17. color = vec4(clamp((diffuse + specular) , 0.0 , 1.0) , 1.0);
  18. color = color + ambient;
  19. gl_Position = ftransform();
  20. }

片段着色器FragmentShader.txt:

  1. varying vec4 color;
  2. void main()
  3. {
  4. gl_FragColor = color;
  5. }

完整程序:

  1. #include <GL/glew.h>
  2. #include <GL/freeglut.h>
  3. #include <iostream>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #pragma comment(lib,"glew32.lib")
  8. using namespace std;
  9. GLfloat lightPosition[3] = { 30.0,30.0,30.0 };
  10. GLfloat ambient[4] = { 0.0 , 0.0 , 1.0 , 1.0 };
  11. GLfloat lightcolor[4] = { 1.0 , 1.0 , 1.0 , 1.0 };
  12. GLfloat eyeposition[3] = { 0.0 , 10.0 , 30.0 };
  13. GLfloat Ns = 30;
  14. GLfloat attenuation = 0.01;
  15. GLfloat objectSize = 15.0;
  16. GLuint programHandle;
  17. GLuint vShader, fShader;
  18. //读入字符流
  19. char *textFileRead(const char *fn)
  20. {
  21. FILE *fp;
  22. char *content = NULL;
  23. int count = 0;
  24. if (fn != NULL)
  25. {
  26. fp = fopen(fn, "rt");
  27. if (fp != NULL)
  28. {
  29. fseek(fp, 0, SEEK_END);
  30. count = ftell(fp);
  31. rewind(fp);
  32. if (count > 0)
  33. {
  34. content = (char *)malloc(sizeof(char) * (count + 1));
  35. count = fread(content, sizeof(char), count, fp);
  36. content[count] = '\0';
  37. }
  38. fclose(fp);
  39. }
  40. }
  41. return content;
  42. }
  43. void initShader(const char *VShaderFile, const char *FShaderFile)
  44. {
  45. //1、查看显卡、GLSL和OpenGL的信息
  46. const GLubyte *vendor = glGetString(GL_VENDOR);
  47. const GLubyte *renderer = glGetString(GL_RENDERER);
  48. const GLubyte *version = glGetString(GL_VERSION);
  49. const GLubyte *glslVersion = glGetString(GL_SHADING_LANGUAGE_VERSION);
  50. cout << "显卡供应商 : " << vendor << endl;
  51. cout << "显卡型号 : " << renderer << endl;
  52. cout << "OpenGL版本 : " << version << endl;
  53. cout << "GLSL版本 : " << glslVersion << endl;
  54. //2、编译着色器
  55. //创建着色器对象:顶点着色器
  56. vShader = glCreateShader(GL_VERTEX_SHADER);
  57. //错误检测
  58. if (0 == vShader)
  59. {
  60. cerr << "ERROR : Create vertex shader failed" << endl;
  61. exit(1);
  62. }
  63. //把着色器源代码和着色器对象相关联
  64. const GLchar *vShaderCode = textFileRead(VShaderFile);
  65. const GLchar *vCodeArray[1] = { vShaderCode };
  66. //将字符数组绑定到对应的着色器对象上
  67. glShaderSource(vShader, 1, vCodeArray, NULL);
  68. //编译着色器对象
  69. glCompileShader(vShader);
  70. //检查编译是否成功
  71. GLint compileResult;
  72. glGetShaderiv(vShader, GL_COMPILE_STATUS, &compileResult);
  73. if (GL_FALSE == compileResult)
  74. {
  75. GLint logLen;
  76. //得到编译日志长度
  77. glGetShaderiv(vShader, GL_INFO_LOG_LENGTH, &logLen);
  78. if (logLen > 0)
  79. {
  80. char *log = (char *)malloc(logLen);
  81. GLsizei written;
  82. //得到日志信息并输出
  83. glGetShaderInfoLog(vShader, logLen, &written, log);
  84. cerr << "vertex shader compile log : " << endl;
  85. cerr << log << endl;
  86. free(log);//释放空间
  87. }
  88. }
  89. //创建着色器对象:片断着色器
  90. fShader = glCreateShader(GL_FRAGMENT_SHADER);
  91. //错误检测
  92. if (0 == fShader)
  93. {
  94. cerr << "ERROR : Create fragment shader failed" << endl;
  95. exit(1);
  96. }
  97. //把着色器源代码和着色器对象相关联
  98. const GLchar *fShaderCode = textFileRead(FShaderFile);
  99. const GLchar *fCodeArray[1] = { fShaderCode };
  100. glShaderSource(fShader, 1, fCodeArray, NULL);
  101. //编译着色器对象
  102. glCompileShader(fShader);
  103. //检查编译是否成功
  104. glGetShaderiv(fShader, GL_COMPILE_STATUS, &compileResult);
  105. if (GL_FALSE == compileResult)
  106. {
  107. GLint logLen;
  108. //得到编译日志长度
  109. glGetShaderiv(fShader, GL_INFO_LOG_LENGTH, &logLen);
  110. if (logLen > 0)
  111. {
  112. char *log = (char *)malloc(logLen);
  113. GLsizei written;
  114. //得到日志信息并输出
  115. glGetShaderInfoLog(fShader, logLen, &written, log);
  116. cerr << "fragment shader compile log : " << endl;
  117. cerr << log << endl;
  118. free(log);//释放空间
  119. }
  120. }
  121. //3、链接着色器对象
  122. //创建着色器程序
  123. programHandle = glCreateProgram();
  124. if (!programHandle)
  125. {
  126. cerr << "ERROR : create program failed" << endl;
  127. exit(1);
  128. }
  129. //将着色器程序链接到所创建的程序中
  130. glAttachShader(programHandle, vShader);
  131. glAttachShader(programHandle, fShader);
  132. //将这些对象链接成一个可执行程序
  133. glLinkProgram(programHandle);
  134. //查询链接的结果
  135. GLint linkStatus;
  136. glGetProgramiv(programHandle, GL_LINK_STATUS, &linkStatus);
  137. if (GL_FALSE == linkStatus)
  138. {
  139. cerr << "ERROR : link shader program failed" << endl;
  140. GLint logLen;
  141. glGetProgramiv(programHandle, GL_INFO_LOG_LENGTH,
  142. &logLen);
  143. if (logLen > 0)
  144. {
  145. char *log = (char *)malloc(logLen);
  146. GLsizei written;
  147. glGetProgramInfoLog(programHandle, logLen,
  148. &written, log);
  149. cerr << "Program log : " << endl;
  150. cerr << log << endl;
  151. }
  152. }
  153. }
  154. //完成glew初始化和加载顶点、片段着色器
  155. void init()
  156. {
  157. //初始化glew扩展库
  158. GLenum err = glewInit();
  159. if (GLEW_OK != err)
  160. {
  161. cout << "Error initializing GLEW: " << glewGetErrorString(err) << endl;
  162. }
  163. glEnable(GL_DEPTH_TEST);
  164. //加载顶点和片段着色器对象并链接到一个程序对象上
  165. initShader("VertexShader.txt", "FragmentShader.txt");
  166. glClearColor(0.0, 0.0, 0.0, 0.0);
  167. }
  168. void Reshape(int w, int h)
  169. {
  170. glViewport(0, 0, (GLsizei)w, (GLsizei)h);
  171. glMatrixMode(GL_PROJECTION);
  172. glLoadIdentity();
  173. gluPerspective(90, 1, 0.1, 1000.0);
  174. glMatrixMode(GL_MODELVIEW);
  175. glLoadIdentity();
  176. gluLookAt(eyeposition[0], eyeposition[1], eyeposition[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
  177. }
  178. void display()
  179. {
  180. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  181. glColor3f(1.0, 1.0, 1.0);
  182. glUseProgram(programHandle);
  183. glUniform3f(glGetUniformLocation(programHandle, "lightposition"), lightPosition[0], lightPosition[1], lightPosition[2]);
  184. glUniform3f(glGetUniformLocation(programHandle, "eyeposition"), eyeposition[0], eyeposition[1], eyeposition[2]);
  185. glUniform4f(glGetUniformLocation(programHandle, "ambient"), ambient[0], ambient[1], ambient[2], ambient[3]);
  186. glUniform4f(glGetUniformLocation(programHandle, "lightcolor"), lightcolor[0], lightcolor[1], lightcolor[2], lightcolor[3]);
  187. glUniform1f(glGetUniformLocation(programHandle, "Ns"), Ns);
  188. glUniform1f(glGetUniformLocation(programHandle, "attenuation"), attenuation);
  189. glutSolidTeapot(objectSize);
  190. //glutSolidSphere(objectSize-3, 100, 100);
  191. glutSwapBuffers();
  192. }
  193. void SpecialKey(GLint key, GLint x, GLint y)
  194. {
  195. if (key == GLUT_KEY_UP)
  196. {
  197. //do something
  198. }
  199. display();
  200. }
  201. int main(int argc, char** argv)
  202. {
  203. glutInit(&argc, argv);
  204. glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  205. glutInitWindowSize(600, 600);
  206. glutInitWindowPosition(100, 100);
  207. glutCreateWindow("Hello GLSL");
  208. init();
  209. glutReshapeFunc(Reshape);
  210. glutDisplayFunc(display);
  211. glutSpecialFunc(SpecialKey);
  212. glutMainLoop();
  213. return 0;
  214. }

执行效果:

再绘制一个实心球体:

OpenGL中GLSL渲染茶壶光照完整程序的更多相关文章

  1. OpenGL中的渲染方式—— GL_TRIANGLE_STRIP

    OpenGL值绘制三角形的方式常用的有三种,分别是GL_TRIANGLES.GL_TRIANGLE_STRIP.GL_TRIANGLE_FAN,其效果如依次是: 从左起:第一个方式是GL_TRIANG ...

  2. 通过OpenGL理解前端渲染原理(1)

    一.OpenGL OpenGL,是一套绘制3D图形的API,当然它也可以用来绘制2D的物体.OpenGL有一大套可以用来操作模型和图片的函数,通常编写OpenGL库的人是显卡的制造者.我们买的显卡都支 ...

  3. OpenGL中的拾取模式( Picking)

    1. Opengl中的渲染模式有三种:(1)渲染模式,默认的模式:(2)选择模式, (3)反馈模式.如下 GLint glRenderMode(GLenum mode) mode可以选取以下三种模式之 ...

  4. OpenGl中使用着色器的基本步骤及GLSL渲染简单示例

    OpenGL着色语言(OpenGL Shading Language,GLSL)是用来在OpenGL中着色编程的语言,是一种具有C/C++风格的高级过程语言,同样也以main函数开始,只不过执行过程是 ...

  5. GLSL 在OpenGL中向shader传递信息【转】

    http://blog.csdn.net/hgl868/article/details/7872219 引言 一个OpenGL程序可以用多种方式和shader通信.注意这种通信是单向的,因为shade ...

  6. 【GLSL教程】(三)在OpenGL中向shader传递信息 【转】

    http://blog.csdn.net/racehorse/article/details/6634830 引言 一个OpenGL程序可以用多种方式和shader通信.注意这种通信是单向的,因为sh ...

  7. 【GLSL教程】(二)在OpenGL中使用GLSL 【转】

    http://blog.csdn.net/racehorse/article/details/6616256 设置GLSL 这一节讲述在OpenGL中配置GLSL,假设你已经写好了顶点shader和像 ...

  8. CSharpGL(26)在opengl中实现控件布局/渲染文字

    CSharpGL(26)在opengl中实现控件布局/渲染文字 效果图 如图所示,可以将文字.坐标轴固定在窗口的一角. 下载 CSharpGL已在GitHub开源,欢迎对OpenGL有兴趣的同学加入( ...

  9. OpenGL中的光照技术(翻译)

    Lighting:https://www.evl.uic.edu/julian/cs488/2005-11-03/index.html 光照 OpenGL中的光照(Linghting)是很重要的,为什 ...

随机推荐

  1. AE开发概念辨析

    樱木 原文 AE开发之概念辨析2,AE开发涉及相关概念,AE开发相关概念 1 AE中的类库 AE总共包括了21个子库,分别是SYSTEM,SYSTEMUI,GEOMETRY,DISPLAY,SERVE ...

  2. Python——管理属性(2)

    __getattr__和__getattribute__ 眼下已经介绍了特性property和描写叙述符来管理特定属性[參考这里],而__getattr__和__getattribute__操作符重载 ...

  3. [RxJS] Implement pause and resume feature correctly through RxJS

    Eventually you will feel the need for pausing the observation of an Observable and resuming it later ...

  4. Android 节日短信送祝福(UI篇:3-选择短信与发送短信的Activity的实现)

    一.ChooseMsgActivity的实现 1.布局文件 <RelativeLayout xmlns:android="http://schemas.android.com/apk/ ...

  5. [React Unit Testing] React unit testing demo

    import React from 'react' const Release = React.createClass({ render() { const { title, artist, outO ...

  6. 《编程导论(Java)&#183;3.2.4 循环语句》

    本文全然复制<编程导论(Java)·3.2.4 循环语句>的内容.除[]中的说明文字.请阅读和比較其它编程教材. 我知道.假设我是一个刚開始学习的人,<编程导论(Java)>非 ...

  7. mysql zip文件安装

    bin目录下执行mysqld -install再执行mysqld --initialize-insecure 启动服务:net start mysql

  8. xv6 gdb

    The "remote" target does not support "run". https://sourceware.org/gdb/onlinedoc ...

  9. ajax跳转到新的jsp页面(局部刷新)

    ajax可以实现局部刷新页面,即在不刷新整个页面的情况下更新页面的局部信息. 项目中遇到一个问题:在用户列表也,当点击某个按钮时需要去查询用户的信息,查询成功跳转到用户详情界面:查询失败,则在原页面弹 ...

  10. ios app初始化和数据迁移的设计思路

    整体思路 一般app启动之后,都有一个初始化的过程. 此外兴许app升级,还须要考虑数据迁移.所以初始化和数据迁移的框架.在初期的版本号就要考虑好 总结一下我们的app採取的方案: 1.在持久化的文件 ...