//源程序
#include "GLTools.h"
#include "GLShaderManager.h"
#ifdef __APPLE__
#include
#else
#define FREEGLUT_STATIC
#include
#endif
GLuint v, f, f2,p;
GLint loc;
//文件读取(将本地shader文件读取为字符串形式加载)
char *textFileRead(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 changeSize(int w, int h)
{
if(h == 0)
h = 1;
float ratio = 1.0* w/h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, w, h);
gluPerspective(45, ratio, 1, 1000);
glMatrixMode(GL_MODELVIEW);
}
float time = 0;
void renderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor4f(1.0, 0.0, 0.0, 1.0);//初始化了gl_Color值,可给着色器使用
glLoadIdentity();
gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glUniform1f(loc, time);//给uniform属性loc所指地址赋值
time+=0.01;
glutSolidTeapot(1);//绘制茶壶
glutSwapBuffers();
}
//着色器:自己处理渲染管线中的顶点着色器和片段着色器阶段
void setShaders()
{
char *vs = NULL, *fs = NULL, *fs2 = NULL;
/*第一阶段*/
//创建着色器对象(类似C中的函数,可以复用)
v = glCreateShader(GL_VERTEX_SHADER);//顶点着色器
f = glCreateShader(GL_FRAGMENT_SHADER);//片段着色器
f2 = glCreateShader(GL_FRAGMENT_SHADER);
vs = textFileRead("/Users/app05/Desktop/opengl/opengl/minimal.vert");
fs = textFileRead("/Users/app05/Desktop/opengl/opengl/minimal.frag");
const char *vv = vs;
const char *ff = fs;
//将着色器代码添加到创建的着色器容器中
glShaderSource(v, 1, &vv, NULL);
glShaderSource(f, 1, &ff, NULL);
free(vs);
free(fs);
//编译着色器源代码
glCompileShader(v);
glCompileShader(f);
/*第二阶段*/
p = glCreateProgram();//创建着色器程序
glAttachShader(p, v);//将着色器对象关联到这个着色器程序
glAttachShader(p, f);
glLinkProgram(p); //链接着色器程序
glUseProgram(p);//使用着色器
//得到着色器程序中unifrom属性的time变量地址,以便外面修改它
loc = glGetUniformLocation(p,"time");
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(320,320);
glutCreateWindow("OpenGL Shader 入门");
glutDisplayFunc(renderScene);
glutIdleFunc(renderScene);
glutReshapeFunc(changeSize);
glEnable(GL_DEPTH_TEST);
glClearColor(1.0,1.0,1.0,1.0);
// glEnable(GL_CULL_FACE);
glewInit();
setShaders();
glutMainLoop();
return 0;
}
//顶点着色器程序(minimal.vert)
uniform float time;//uniform属性的变量值可以由opengl程序传进来
void main()
{
//顶点颜色
gl_FrontColor = gl_Color;
//模型矩阵变换,将3D坐标投影到2D屏幕坐标
//gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;
//gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
//gl_Position = ftransform();
//实例:顶点z值正旋变化
vec4 v = vec4(gl_Vertex);
v.z = sin(5.0 * v.x + time) * 0.5;
gl_Position = gl_ModelViewProjectionMatrix * v;
}
//片段着色器程序(minimal.frag)
void main()
{
/*gl_FragColor:是设置片段的颜色,gl_Color:是外部glColor()默认初始化的uniform值*/
gl_FragColor = gl_Color;
}