OpenGl着色器简单范例
1、首先会使用vs2013英语倘愁版创建C++的ConsoleApplication并且会增加相关的文件.cpp或者.h (特别说明,添加完也可以通过对增加的文件rename/重命名 修改后缀,比如下面的.vert就是那样修改的),相关经验已经发率率塑布;
依次增加5个文珠裹件,五个文件明明如图(这里的名字是因为这些文档中相关调用是这样的,如果要自己命名,就要知道到哪里改,代码后面依次放出)

2、其次,下载完需要的opengl 的相关include的 .h,.lib.dll(去官网,或者相关的程序学习网站)

3、接着就是配置。相关经验已经上传
1、在文件名字为 minimal.vert里面填上如下(图代码)
void main()
{
gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;
}

2、在文件名字为 minimal.frag里面填上如下(图代码)
void main()
{
gl_FragColor = vec4(0.6,0.4,0.2,1.0);
}

3、在文件名字为 textfile.h里面填上如下(图代码)
char *textFileRead(char *fn);///读取文件
int textFileWrite(char *fn, char *s);///写入文件

4、 在文件名字为 textfile.cpp里面填上如下代码
#include <stdio.h>
#include <malloc.h>
#include <string.h>
char *textFileRead(char *fn)
{
FILE *fp;
char *content = NULL;
int count = 0;
if (fn != NULL)
{
///打开文件
fopen_s(&fp,fn, "r");
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;
}
int textFileWrite(char *fn, char *s)
{
FILE *fp;
int status = 0;
if (fn != NULL)
{
///打开文件
fopen_s(&fp, fn, "w");
//fp = fopen(fn, "w");
if (fp != NULL)
{
if (fwrite(s, sizeof(char), strlen(s), fp) == strlen(s))
status = 1;
fclose(fp);
}
}
return(status);
}


5、 在文件名字为 textfile.cpp里面填上如下代码,效果是图一,可以自己去片源着色器改颜色哈
#include <iostream>
#include<glew.h>
#include<glut.h>
#include<gl.h>
#include "textfile.h"
#pragma comment(lib,"glew32.lib")
#define printOpenGLError() printOglError(__FILE__, __LINE__)
static float degree = 0;///茶壶旋转的度数
/**
* @brief 处理窗口大小改变
* @param w 窗口的宽
* @param h 窗口的高
**/
void changeSize(int w, int h)
{
///重新定义视口
glViewport(0, 0, w, h);
///重新设置投影变换
if (h == 0) h = 1;/// 防止高为0产生除0错误
float ratio = 1.0 * w / h;///宽高比
glMatrixMode(GL_PROJECTION);///当前矩阵设为投影矩阵
glLoadIdentity();///清空投影矩阵
gluPerspective(45, ratio, 1, 1000);//重设投影矩阵
///模型视点变换
glMatrixMode(GL_MODELVIEW);///当前矩阵设为模型视点矩阵
}
/**
* @brief 显示函数
**/
void renderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);///清空颜色缓存和深度缓存
glLoadIdentity();///清空模型视点矩阵
///视点变换
gluLookAt(0.0, 0.0, 5.0,
0.0, 0.0, -1.0,
0.0f, 1.0f, 0.0f);
///模型变换 旋转茶壶
glRotatef(degree, 0, 1, 1);
///绘制茶壶
glutSolidTeapot(1);
degree += 0.1;///旋转度数增加
glutSwapBuffers();///交换缓存(双缓存模式)
}
/**
* @brief 处理键盘事件 按下 Esc 退出程序
**/
void processNormalKeys(unsigned char key, int x, int y)
{
if (key == 27)
exit(0);
}
/**
* @brief 打印OpenGL错误信息
* @param file 错误所在的文件
* @param line 错误所在的行
* @return 1 OpenGL error
* @return 0 other error
**/
int printOglError(char *file, int line)
{
GLenum glErr;
int retCode = 0;
glErr = glGetError();///获取错误
while (glErr != GL_NO_ERROR)
{
printf("glError in file %s @ line %d: %s\n", file, line, gluErrorString(glErr));
retCode = 1;
glErr = glGetError();///获取下一个错误
}
return retCode;
}
/**
* @brief 打印日志
**/
void printInfoLog(GLhandleARB obj)
{
int infologLength = 0;
int charsWritten = 0;
char *infoLog;
glGetObjectParameterivARB(obj, GL_OBJECT_INFO_LOG_LENGTH_ARB,
&infologLength);
if (infologLength > 0)
{
infoLog = (char *)malloc(infologLength);
glGetInfoLogARB(obj, infologLength, &charsWritten, infoLog);
printf("%s\n", infoLog);
free(infoLog);
}
}
/**
* @brief 设置着色器
**/
void setShaders()
{
GLhandleARB v, f, p;
char *vs = NULL, *fs = NULL;
///创造空白顶点着色器对象并返回其句柄
v = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB); ///顶点着色器 v
f = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB); ///片元着色器 f
///读取着色器源代码文件
vs = textFileRead("minimal.vert");///顶点着色器源代码字符串
fs = textFileRead("minimal.frag");///片元着色器源代码字符串
///加入到字符串数组
const char * vv = vs;
const char * ff = fs;
/// 将着色器源代码字符串数组提交给空白的着色器
/// glShaderSourceARB() 参数表:
/// GLhandleARB shader --- 着色器
/// GLuint nstrings --- 字符串数组中多少个元素 本例子就只有1个字符串
/// const GLcharARB **strings --- 字符串数组
/// GLint *lengths --- 对应字符串数组的长度数组 NULL表示所有字符串以null结束
glShaderSourceARB(v, 1, &vv, NULL);
glShaderSourceARB(f, 1, &ff, NULL);
///释放字符串所占用的内存空间
free(vs);
free(fs);
///编译源代码
glCompileShaderARB(v);
glCompileShaderARB(f);
///打印日志
printInfoLog(v);
printInfoLog(f);
///创造空白程序对象并返回其句柄
p = glCreateProgramObjectARB();
///将着色器对象附加到程序对象
glAttachObjectARB(p, v);
glAttachObjectARB(p, f);
///链接程序对象 打印日志
glLinkProgramARB(p);
printInfoLog(p);
///安装程序对象
glUseProgramObjectARB(p);
}
/**
* @brief 主函数 程序入口
**/
int main(int argc, char **argv)
{
//创建窗口相关函数
glutInit(&argc, argv);///初始化GLUT并处理命令行参数
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);///深度缓存 双缓存 RGBA颜色模式
glutInitWindowPosition(100, 100);///窗口左上角位置
glutInitWindowSize(320, 320);///窗口大小
glutCreateWindow("GLSL的第一步");///创建窗口
///注册各种回调函数
glutDisplayFunc(renderScene);///注册显示回调函数 renderScene
glutIdleFunc(renderScene);///注册后台管理函数(事件循环空闲时运行) renderScene
glutReshapeFunc(changeSize);///注册窗口大小改变时的回调函数 changeSize
glutKeyboardFunc(processNormalKeys);///注册键盘输入回调函数 processNormalKeys
///启动必须的功能
glEnable(GL_DEPTH_TEST);///开启深度缓存测试
glEnable(GL_CULL_FACE);///启动多边形剔除功能
glClearColor(1.0, 1.0, 1.0, 1.0);///指定清除颜色
glewInit();///glew初始化
///检测是否支持基本的顶点着色器和片元着色器
if (GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader)
{
printf("Ready for GLSL\n");
}
else
{
printf("No GLSL support\n");
exit(1);
}
setShaders();///设置着色器
glutMainLoop();///进入主循环
return 0;
}

