//
//移动三角形,版本2:通过shader实现位置变化.
//作者:青丝成霜
//
#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
#include "readtext.h"
#ifdef _APPLE_
#include <glut/glut.h>
#else
#define FREEGLUT_STATIC
#include <GL/glut.h>
#endif
GLuint vShader, fShader, programHandle;
GLint vaoHandle, vboHandles[2], positionBufferHandle, colorBufferHandle;
GLint elapseTimeUniformLocation, loopDurationLocation;
GLint positionLocation, colorLocation;
//
//
int infoLogLength =0;
int charWritten =0;
char *infoLog;
/
//
float positionData[]={ 0.8f, 0.0f, 0.0f,
-0.8f, 0.0f, 0.0f,
0.0f, 0.8f, 0.0f};
//
float colorData[]= { 1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0};
void SetupShader()
{
char *renderer;
char *vender;
char *version;
char *glslVersion;
char *vs, *fs;
char *vv, *ff;
char *txt;
/
renderer =glGetString(GL_RENDERER);
vender =glGetString(GL_VENDOR);
version =glGetString(GL_VERSION);
glslVersion =glGetString(GL_SHADING_LANGUAGE_VERSION);
printf("graphic card:\t%s \n", renderer);
printf("graphic company:\t%s \n", vender);
printf("openGL version:\t%s \n", version);
printf("GLSL version:\t %s \n", glslVersion);
printf("*****************************************************\n");
//
//txt =readText("2.txt");
//printf("%s\n",txt);
//putchar(10);
vShader =glCreateShader(GL_VERTEX_SHADER);
vs =readText("shader/triangle.vert");
printf("%s\n",vs);
vv =vs;
if(vShader ==0)
{
printf("Error: fail to create shader!");
exit(1);
}
glShaderSource(vShader, 1, &vv, NULL);
glCompileShader(vShader);
free(vs);
glGetShaderiv(vShader, GL_INFO_LOG_LENGTH, &infoLogLength);
if(infoLogLength >0)
{
infoLog =(char *)malloc(infoLogLength);
glGetShaderInfoLog(vShader, infoLogLength, &charWritten, infoLog);
printf("%s\n", infoLog);
printf("********************************************************\n");
free(infoLog);
}
/
fShader =glCreateShader(GL_FRAGMENT_SHADER);
if(fShader ==0)
{
printf("can't create fragment shader! \n");
exit(1);
}
fs =readText("shader/triangle.frag");
printf("%s \n",fs);
ff= fs;
glShaderSource(fShader, 1, &ff, NULL);
glCompileShader(fShader);
free(fs);
glGetShaderiv(fShader, GL_INFO_LOG_LENGTH, &infoLogLength);
if(infoLogLength >0)
{
infoLog =(char *)malloc(infoLogLength);
glGetShaderInfoLog(fShader, infoLogLength, &charWritten, infoLog);
charWritten is
printf("%s \n",infoLog);
printf("*********************************************************\n");
free(infoLog);
}
//
programHandle =glCreateProgram();
glAttachShader(programHandle, vShader);
glAttachShader(programHandle, fShader);
glLinkProgram(programHandle);
glGetProgramiv(programHandle, GL_INFO_LOG_LENGTH, &infoLogLength);
if(infoLogLength >0)
{
infoLog =(char *)malloc(infoLogLength);
glGetProgramInfoLog(programHandle, infoLogLength, &charWritten, infoLog);
printf("%s \n", infoLog);
printf("*********************************************************\n");
free(infoLog);
}
glUseProgram(programHandle);
}
/
/
void InitVBO()
{
glGenBuffers(2, vboHandles);
positionBufferHandle =vboHandles[0];
colorBufferHandle =vboHandles[1];
//
glBindBuffer(GL_ARRAY_BUFFER, positionBufferHandle);
glBufferData(GL_ARRAY_BUFFER, sizeof(positionData), positionData,GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, colorBufferHandle);
glBufferData(GL_ARRAY_BUFFER, sizeof(colorData), colorData, GL_STATIC_DRAW);
//
glGenVertexArrays(1, &vaoHandle);
glBindVertexArray(vaoHandle);//必须绑定方可使用,通过glVertexAttribPointer将VAO与VBO联系起来
/
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);//必须在glVertexAttribPointer之前
glBindBuffer(GL_ARRAY_BUFFER, positionBufferHandle);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL); //联系VAO VBO的关键.
glBindBuffer(GL_ARRAY_BUFFER, colorBufferHandle);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
}
/
//
void SetupRC()
{
glewInit();
SetupShader();
InitVBO();
glClearColor(1.0, 0.0, 0.0, 1.0);
}
/
///
void RenderScene()
{
glClear(GL_COLOR_BUFFER_BIT );
glBindVertexArray(vaoHandle);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
elapseTimeUniformLocation =glGetUniformLocation(programHandle, "time");
loopDurationLocation =glGetUniformLocation(programHandle, "loopDuration");
//printf("%d\t%d\t",elapseTimeUniformLocation, loopDurationLocation);
glUniform1f(loopDurationLocation, 5.0f);
glUniform1f(elapseTimeUniformLocation, glutGet(GLUT_ELAPSED_TIME)/1000.0f );
glutSwapBuffers();
glutPostRedisplay();
}
///
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(800, 600);
glutInitWindowPosition(0,0);
glutCreateWindow("second triangle:active!");
SetupRC();
glutDisplayFunc(RenderScene);
glutMainLoop();
return 0;
}
triangle.vert
#version 400
layout(location =0) in vec3 vertexPosition;
layout(location =1) in vec3 vertexColor;
out vec3 vColor;
uniform float loopDuration;
uniform float time;
void main()
{
float timeScale = 3.14159f * 2.0f / loopDuration;
float currTime = mod(time, loopDuration);
vec4 totalOffset = vec4(cos(currTime * timeScale) * 0.5f,
sin(currTime * timeScale) * 0.5f,
0.0f,
0.0f);
gl_Position = vec4(vertexPosition,1.0) + totalOffset;
vColor =vertexColor;
}
triangle.frag
#version 400
in vec3 vColor;
out vec4 fragColor;
void main()
{
fragColor =vec4(vColor, 1.0);
}