//CPP file
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <GL/glew.h>
#include <GL/glut.h>
float vertexArray[50][50*4*3];
float textureArray[50][50*4*2];
float normalArray[50][50*4*3];
#define BMP_Header_Length 54
GLuint loadTexture(char *file)
{
GLint width, height, total_bytes;
GLubyte* pixels = 0;
GLuint last_texture_ID, texture_ID = 0;
//打开文件,如果失败,返回
FILE* pFile = fopen(file, "rb");
if(pFile == 0)
{
printf("Can not open file %s...", file);
return 0;
}
//读取文件中图象的宽度和高度
fseek(pFile, 0x0012, SEEK_SET);
fread(&width, 4, 1, pFile);
fread(&height, 4, 1, pFile);
fseek(pFile, BMP_Header_Length, SEEK_SET);
//计算每行像素所占字节数,并根据此数据计算总像素字节数
{
GLint line_bytes = width * 3;
while(line_bytes % 4 != 0)
{
++line_bytes;
}
total_bytes = line_bytes * height;
}
//根据总像素字节数分配内存
pixels = (GLubyte*)malloc(total_bytes);
if(pixels == 0)
{
printf("Pixeles in file %s is NULL...", file);
fclose(pFile);
return 0;
}
//读取像素数据
if(fread(pixels, total_bytes, 1, pFile) <= 0)
{
free(pixels);
fclose(pFile);
return 0;
}
// 分配一个新的纹理编号
glGenTextures(1, &texture_ID);
if( texture_ID == 0 )
{
free(pixels);
fclose(pFile);
return 0;
}
//绑定新的纹理,载入纹理并设置纹理参数
//在绑定前,先获得原来绑定的纹理编号,以便在最后进行恢复
glGetIntegerv(GL_TEXTURE_BINDING_2D,(GLint*)&last_texture_ID);
glBindTexture(GL_TEXTURE_2D, texture_ID);
//纹理过滤设定
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
//颜色混合模式
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, pixels);
glBindTexture(GL_TEXTURE_2D, last_texture_ID);
//之前为pixels分配的内存可在使用glTexImage2D以后释放
//因为此时像素数据已经被OpenGL另行保存了一份(可能被保存到专门的图形硬件中)
free(pixels);
return texture_ID;
}
int texture01 = 0;
int texture02 = 0;
void setupRS()
{
glClearColor(0.0f,0.0f,0.0f,1.0f);
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
texture01 = loadTexture("../../Resources/texture01.bmp");
texture02 = loadTexture("../../Resources/texture02.bmp");
}
#define printOpenGLError() printOglError(__FILE__, __LINE__)
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;
}
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);
}
}
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;
}
GLhandleARB v,f,p; //Handlers for our vertex, geometry, and fragment shaders
int gw,gh; //Keep track of window width and height
GLint loc;
void setShaders()
{
glClearColor(0.0f,0.0f,0.0f,1.0f);
glEnable(GL_DEPTH_TEST);
char *vs = NULL,*fs = NULL;
v = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
f = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
vs = textFileRead("MyTest.vert");
fs = textFileRead("MyTest.frag");
const char * vv = vs;
const char * ff = fs;
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);
printInfoLog(v);
printInfoLog(f);
printInfoLog(p);
glUniform3fARB(glGetUniformLocationARB(p, "LightPosition"), 200.0f, 200.0f, 200.0f);
glUniform1iARB(glGetUniformLocationARB(p, "tex01"), 0);
glUniform1iARB(glGetUniformLocationARB(p, "tex02"), 1);
loc = glGetUniformLocation(p,"time");
}
void reshape(int w, int h)
{
float range = 50.0f;
if (0 == h)
h = 1;
glViewport(0,0,w,h);
float as = (float)w/h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
/*if (w <= h)
glOrtho(-range, range, -range/as, range/as, -range, range);
else
glOrtho(-range*as, range*as, -range, range, -range, range);*/
gluPerspective(100.0f, as, 1, 150);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void setXYZ(float *vector, int offset, float x, float y, float z)
{
int index = 3 * offset;
vector[index] = x;
vector[index + 1] = y;
vector[index + 2] = z;
}
void setXY(float *vector, int offset, float x, float y)
{
int index = 2 * offset;
vector[index] = x;
vector[index + 1] = y;
}
void initQuad(float width, float height)
{
const float halfW = width/2.0f;
const float halfH = height/2.0f;
const float deltaW = width/50;
const float deltaH = height/50;
for (int i = 0; i < 50; ++i)
{
float verX = -halfW + deltaW*i;
float verX_next = -halfW + deltaW*(i+1);
float coorX = (float)i/50;
float coorX_next = (float)(i+1)/50;
for (int j = 0; j < 50; ++j)
{
float verY = -halfH + deltaH*j;
float verY_next = -halfH + deltaH*(j+1);
float coorY = (float)j/50;
float coorY_next = (float)(j+1)/50;
setXYZ(vertexArray[i], j*4, verX, verY, 0.0f);
setXYZ(vertexArray[i], j*4+1, verX_next, verY, 0.0f);
setXYZ(vertexArray[i], j*4+2, verX_next, verY_next, 0.0f);
setXYZ(vertexArray[i], j*4+3, verX, verY_next, 0.0f);
setXYZ(normalArray[i], j*4, 0.0f, 0.0f, 1.0f);
setXYZ(normalArray[i], j*4+1, 0.0f, 0.0f, 1.0f);
setXYZ(normalArray[i], j*4+2, 0.0f, 0.0f, 1.0f);
setXYZ(normalArray[i], j*4+3, 0.0f, 0.0f, 1.0f);
setXY(textureArray[i], j*4, coorX, coorY);
setXY(textureArray[i], j*4+1, coorX_next, coorY);
setXY(textureArray[i], j*4+2, coorX_next, coorY_next);
setXY(textureArray[i], j*4+3, coorX, coorY_next);
}
}
}
void draw()
{
for (int i = 0; i < 50; i++)
{
glVertexPointer(3, GL_FLOAT, 0, vertexArray[i]);
glTexCoordPointer(2, GL_FLOAT, 0, textureArray[i]);
glNormalPointer(GL_FLOAT, 0, normalArray[i]);
//glDrawArrays(GL_POINTS, 0, 50*4);
glDrawArrays(GL_QUADS, 0, 50*4);
}
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
}
float angle = 0.0f;
float t = 0.0f;
void display()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glColor4f(1.0f,1.0f,0.0f,1.0f);
//glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glUseProgram(p);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture01);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture02);
glLoadIdentity();
glTranslatef(0.0f,0.0f, -100.0f);
glPushMatrix();
glRotatef(angle, 1.0f, 1.0f,1.0f);
glPushMatrix();
glTranslatef(0.0f,0.0f, 25.0f);
draw();
glPopMatrix();
glPushMatrix();
glRotatef(180.0f, 0.0f, 1.0f, 0.0f);
glTranslatef(0.0f,0.0f, 25.0f);
draw();
glPopMatrix();
glPushMatrix();
glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
glTranslatef(0.0f,0.0f, 25.0f);
draw();
glPopMatrix();
glPushMatrix();
glRotatef(-90.0f, 0.0f, 1.0f, 0.0f);
glTranslatef(0.0f,0.0f, 25.0f);
draw();
glPopMatrix();
glPushMatrix();
glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
glTranslatef(0.0f,0.0f, 25.0f);
draw();
glPopMatrix();
glPushMatrix();
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
glTranslatef(0.0f,0.0f, 25.0f);
draw();
glPopMatrix();
glPopMatrix();
glutSwapBuffers();
glutPostRedisplay();
angle += 0.5f;
if (angle >= 360.0f)
{
angle -= 360.0f;
}
glUniform1f(loc, t);
t += 0.1f;
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH|GLUT_RGBA);
glutInitWindowSize(500, 500);
glutInitWindowPosition(500,200);
glutCreateWindow("<<-- My Test -->>");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
setupRS();
initQuad(50.0f, 50.0f);
glewInit();
if (glewIsSupported("GL_VERSION_2_1"))
{
printf("Ready for OpenGL 2.1\n");
}
else
{
printf("OpenGL 2.1 not supported\n");
exit(1);
}
if (GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader && GL_EXT_geometry_shader4)
{
printf("Ready for GLSL - vertex, fragment, and geometry units\n");
}
else
{
printf("Not totally ready :( \n");
exit(1);
}
setShaders();
glutMainLoop();
return 0;
}
//MyTest.vert
varying vec3 lightDir,normal;
uniform float time;
void main()
{
normal = normalize(gl_NormalMatrix * gl_Normal);
lightDir = normalize(vec3(gl_LightSource[0].position));
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
//gl_Position = ftransform();
vec4 v = vec4(gl_Vertex);
float temp = sqrt(pow(v.x,2)+pow(v.y,2));
v.z = v.z + sin(5.0*temp+time)*2.0;
//v.z = v.z + sin(5.0*v.x+time)*2.0;
gl_Position = gl_ModelViewProjectionMatrix * v;
}
//MyTest.frag
varying vec3 lightDir,normal;
uniform sampler2D tex01, tex02;
void main()
{
vec3 ct,cf,c;
vec4 texel;
float intensity,at,af,a;
intensity = max(dot(lightDir,normalize(normal)),0.0);
cf = intensity * (gl_FrontMaterial.diffuse).rgb + gl_FrontMaterial.ambient.rgb;
af = gl_FrontMaterial.diffuse.a;
texel = texture2D(tex01,gl_TexCoord[0].st);
ct = texel.rgb;
at = texel.a;
c = cf * ct;
a = af * at;
float coef = smoothstep(1.0,0.2,intensity);
c += coef * vec3(texture2D(tex02,gl_TexCoord[0].st));
gl_FragColor = vec4(c, a);
}