OpenGL中GLSL渲染茶壶光照完整程序
来源:互联网 发布:淘宝客服就是卖家吗 编辑:程序博客网 时间:2024/04/28 14:43
顶点着色器VertexShader.txt:
uniform vec3 lightposition;//光源位置uniform vec3 eyeposition;//相机位置uniform vec4 ambient;//环境光颜色uniform vec4 lightcolor;//光源颜色uniform float Ns;//高光系数uniform float attenuation;//光线的衰减系数varying vec4 color;//向片段着色其传递的参数void main(){vec3 ECPosition = vec3(gl_ModelViewMatrix * gl_Vertex);vec3 N = normalize(gl_NormalMatrix * gl_Normal);vec3 L = normalize(lightposition - ECPosition);vec3 V = normalize(eyeposition - ECPosition);vec3 H = normalize(V + L);vec3 diffuse = lightcolor * max(dot(N , L) , 0);vec3 specular = lightcolor * pow(max(dot(N , H) , 0) , Ns) * attenuation;color = vec4(clamp((diffuse + specular) , 0.0 , 1.0) , 1.0);color = color + ambient;gl_Position = ftransform();}
片段着色器FragmentShader.txt:
varying vec4 color;void main(){gl_FragColor = color;}
#include <GL/glew.h> #include <GL/freeglut.h> #include <iostream>#include <stdio.h> #include <stdlib.h> #include <string.h> #pragma comment(lib,"glew32.lib") using namespace std;GLfloat lightPosition[3] = { 30.0,30.0,30.0 };GLfloat ambient[4] = { 0.0 , 0.0 , 1.0 , 1.0 };GLfloat lightcolor[4] = { 1.0 , 1.0 , 1.0 , 1.0 };GLfloat eyeposition[3] = { 0.0 , 10.0 , 30.0 };GLfloat Ns = 30;GLfloat attenuation = 0.01;GLfloat objectSize = 15.0;GLuint programHandle;GLuint vShader, fShader;//读入字符流 char *textFileRead(const char *fn){FILE *fp;char *content = NULL;int count = 0;if (fn != NULL){fp = fopen(fn, "rt");if (fp != NULL){fseek(fp, 0, SEEK_END);count = ftell(fp);rewind(fp);if (count > 0){content = (char *)malloc(sizeof(char) * (count + 1));count = fread(content, sizeof(char), count, fp);content[count] = '\0';}fclose(fp);}}return content;}void initShader(const char *VShaderFile, const char *FShaderFile){//1、查看显卡、GLSL和OpenGL的信息 const GLubyte *vendor = glGetString(GL_VENDOR);const GLubyte *renderer = glGetString(GL_RENDERER);const GLubyte *version = glGetString(GL_VERSION);const GLubyte *glslVersion = glGetString(GL_SHADING_LANGUAGE_VERSION);cout << "显卡供应商 : " << vendor << endl;cout << "显卡型号 : " << renderer << endl;cout << "OpenGL版本 : " << version << endl;cout << "GLSL版本 : " << glslVersion << endl;//2、编译着色器 //创建着色器对象:顶点着色器 vShader = glCreateShader(GL_VERTEX_SHADER);//错误检测 if (0 == vShader){cerr << "ERROR : Create vertex shader failed" << endl;exit(1);}//把着色器源代码和着色器对象相关联 const GLchar *vShaderCode = textFileRead(VShaderFile);const GLchar *vCodeArray[1] = { vShaderCode };//将字符数组绑定到对应的着色器对象上 glShaderSource(vShader, 1, vCodeArray, NULL);//编译着色器对象 glCompileShader(vShader);//检查编译是否成功 GLint compileResult;glGetShaderiv(vShader, GL_COMPILE_STATUS, &compileResult);if (GL_FALSE == compileResult){GLint logLen;//得到编译日志长度 glGetShaderiv(vShader, GL_INFO_LOG_LENGTH, &logLen);if (logLen > 0){char *log = (char *)malloc(logLen);GLsizei written;//得到日志信息并输出 glGetShaderInfoLog(vShader, logLen, &written, log);cerr << "vertex shader compile log : " << endl;cerr << log << endl;free(log);//释放空间 }}//创建着色器对象:片断着色器 fShader = glCreateShader(GL_FRAGMENT_SHADER);//错误检测 if (0 == fShader){cerr << "ERROR : Create fragment shader failed" << endl;exit(1);}//把着色器源代码和着色器对象相关联 const GLchar *fShaderCode = textFileRead(FShaderFile);const GLchar *fCodeArray[1] = { fShaderCode };glShaderSource(fShader, 1, fCodeArray, NULL);//编译着色器对象 glCompileShader(fShader);//检查编译是否成功 glGetShaderiv(fShader, GL_COMPILE_STATUS, &compileResult);if (GL_FALSE == compileResult){GLint logLen;//得到编译日志长度 glGetShaderiv(fShader, GL_INFO_LOG_LENGTH, &logLen);if (logLen > 0){char *log = (char *)malloc(logLen);GLsizei written;//得到日志信息并输出 glGetShaderInfoLog(fShader, logLen, &written, log);cerr << "fragment shader compile log : " << endl;cerr << log << endl;free(log);//释放空间 }}//3、链接着色器对象 //创建着色器程序 programHandle = glCreateProgram();if (!programHandle){cerr << "ERROR : create program failed" << endl;exit(1);}//将着色器程序链接到所创建的程序中 glAttachShader(programHandle, vShader);glAttachShader(programHandle, fShader);//将这些对象链接成一个可执行程序 glLinkProgram(programHandle);//查询链接的结果 GLint linkStatus;glGetProgramiv(programHandle, GL_LINK_STATUS, &linkStatus);if (GL_FALSE == linkStatus){cerr << "ERROR : link shader program failed" << endl;GLint logLen;glGetProgramiv(programHandle, GL_INFO_LOG_LENGTH,&logLen);if (logLen > 0){char *log = (char *)malloc(logLen);GLsizei written;glGetProgramInfoLog(programHandle, logLen,&written, log);cerr << "Program log : " << endl;cerr << log << endl;}}}//完成glew初始化和加载顶点、片段着色器void init(){//初始化glew扩展库 GLenum err = glewInit();if (GLEW_OK != err){cout << "Error initializing GLEW: " << glewGetErrorString(err) << endl;}glEnable(GL_DEPTH_TEST);//加载顶点和片段着色器对象并链接到一个程序对象上 initShader("VertexShader.txt", "FragmentShader.txt");glClearColor(0.0, 0.0, 0.0, 0.0);}void Reshape(int w, int h){glViewport(0, 0, (GLsizei)w, (GLsizei)h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(90, 1, 0.1, 1000.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(eyeposition[0], eyeposition[1], eyeposition[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);}void display(){glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glColor3f(1.0, 1.0, 1.0);glUseProgram(programHandle);glUniform3f(glGetUniformLocation(programHandle, "lightposition"), lightPosition[0], lightPosition[1], lightPosition[2]);glUniform3f(glGetUniformLocation(programHandle, "eyeposition"), eyeposition[0], eyeposition[1], eyeposition[2]);glUniform4f(glGetUniformLocation(programHandle, "ambient"), ambient[0], ambient[1], ambient[2], ambient[3]);glUniform4f(glGetUniformLocation(programHandle, "lightcolor"), lightcolor[0], lightcolor[1], lightcolor[2], lightcolor[3]);glUniform1f(glGetUniformLocation(programHandle, "Ns"), Ns);glUniform1f(glGetUniformLocation(programHandle, "attenuation"), attenuation);glutSolidTeapot(objectSize);//glutSolidSphere(objectSize-3, 100, 100);glutSwapBuffers();}void SpecialKey(GLint key, GLint x, GLint y){if (key == GLUT_KEY_UP){//do something}display();}int main(int argc, char** argv){glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);glutInitWindowSize(600, 600);glutInitWindowPosition(100, 100);glutCreateWindow("Hello GLSL");init();glutReshapeFunc(Reshape);glutDisplayFunc(display);glutSpecialFunc(SpecialKey);glutMainLoop();return 0;}
执行效果:
再绘制一个实心球体:
0 0
- OpenGL中GLSL渲染茶壶光照完整程序
- Opengl光照(茶壶)
- [OpenGL] 茶壶与光照
- OpenGL-渲染光照球体
- [实例]OpenGL绘制茶壶(光照、三维变换)
- OpenGL进阶(十三) - GLSL光照(Lighting)
- OpenGL进阶(十三) - GLSL光照(Lighting)
- OpenGL 4.0 GLSL 用多个光照模型
- OpenGL 4.0 GLSL 采用平行光照模型
- 现代OpenGL+Qt学习笔记之七:Phong光照及在GLSL中使用函数
- 【WebGL】茶壶和光照
- OpenGL 4.0 用GLSL实现双面渲染
- OpenGL 4.0 GLSL 延迟渲染 Deferred shading
- OpenGL 4.0 用GLSL实现双面渲染
- 如何在自己的opengl程序中使用GLSL
- [GLSL] 光照
- Opengl中光照、材质
- GLSL 在OpenGL中使用GLSL
- 64位系统调用32位库出错原因
- 找X(简单查找)
- PAT 乙级 1021 个位数统计 (15)
- Javascript闭包——懂不懂由你,反正我是懂了
- Java内存模型——重排序
- OpenGL中GLSL渲染茶壶光照完整程序
- git链接github
- 超时设置脚本pp.sh
- leetcode217
- SpringMVC对比Struts2
- 用管道实现进程间通信
- Intellj Idea 远程调试
- Java 跳出多重循环的方法总结
- 用gitHub pages搭建自己的博客