读取bmp等图片格式中的像素还有难度,就先用这个棋盘图象素来弄了
代码打错一个就一直First-chance exception ,貌似还有一个要用q或者Q才能成功退出,不知道缺少哪句,我用窗口红叉退出也会First-chance exception
glTexParameterf写错成glTextureParameteri
随手来个链接https://www.opengl.org/sdk/docs/man/html/glTexParameter.xhtml
// // 绘制一个旋转的OpenGL立方体在世界坐标系中_缩放_旋转_平移_顶点片源着色器_光照作用 // 使用空闲回调函数增加旋转的角度 // 立方体的旋转角度被发送到用于实现立方体旋转的顶点着色器中 #include "Angel.h" #pragma comment(lib, "glew32.lib") typedef Angel::vec4 color4; typedef Angel::vec4 point4; const int NumVertices = 36; //(6 faces)(2 triangles/face)(3 vertices/triangle) point4 points[NumVertices]; vec3 normals[NumVertices];//法向量标记 // Vertices of a unit cube centered at origin, sides aligned with axes point4 vertices[8] = { point4(-0.5, -0.5, 0.5, 1.0), point4(-0.5, 0.5, 0.5, 1.0), point4(0.5, 0.5, 0.5, 1.0), point4(0.5, -0.5, 0.5, 1.0), point4(-0.5, -0.5, -0.5, 1.0), point4(-0.5, 0.5, -0.5, 1.0), point4(0.5, 0.5, -0.5, 1.0), point4(0.5, -0.5, -0.5, 1.0) }; const int texturesize = 64; //新增或有更改 GLuint textureloc;//新增或有更改 GLubyte imageRBG[texturesize][texturesize][3];//新增或有更改 vec2 tex_coords[NumVertices];//新增或有更改 void imageinit()//新增或有更改 { for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { GLubyte c = (((i & 0x8) == 0) ^ ((j & 0x8) == 0) )*255; imageRBG[i][j][0] = imageRBG[i][j][1] = imageRBG[i][j][2] = c; } } glGenTextures(1, &textureloc);//产生一个纹理对象标志符并存在地址textureloc中 glBindTexture(GL_TEXTURE_2D, textureloc); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texturesize, texturesize, 0, GL_RGB, GL_UNSIGNED_BYTE, imageRBG); //target90FL_TEXTURE_[1,2,3]D或者GL_TEXTURE_CUBE_MAP;level,iformat,width,height,border,format,type,&textureeloc; glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);//写错成glTextureParameteri glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, textureloc); }//新增或有更改 // Array of rotation angles (in degrees) for each coordinate axis //enum { Xaxis = 0, Yaxis = 1, Zaxis = 2, NumAxes = 3 }; //enum { Xdist = 0, Ydist = 1, Zdist = 2, NumAxes1 = 3 }; color4 gr = color4(1.0, 1.0, 1.0, 1.0); color4 onecolor = color4(1.0, 0.0, 0.0, 1.0); color4 light_ex; int Axi = 0;//Xaxis; GLfloat Thet[3] = { 0.0, 0.0, 0.0 }; //GLfloat Atha[3] = { 0.0, 0.0, 0.0 }; GLfloat Disx = 0; GLfloat Dis = 0; GLfloat fd = 1; GLuint thet; // The location of the "theta" shader uniform variable GLuint atha; GLuint direct; GLuint f; GLuint vam; //---------------------------------------------------------------------------- // quad generates two triangles for each face and assigns colors // to the vertices int Index = 0; void quad(int a, int b, int c, int d) { vec4 u = vertices[b] - vertices[a]; vec4 v = vertices[c] - vertices[b]; vec3 normal = normalize(cross(u, v));//normalize叉乘得到法向量 normals[Index] = normal; points[Index] = vertices[a]; tex_coords[Index] = vec2(0.0, 0.0); Index++;////新增或有更改 normals[Index] = normal; points[Index] = vertices[b]; tex_coords[Index] = vec2(0.0, 1.0); Index++;////新增或有更改 normals[Index] = normal; points[Index] = vertices[c]; tex_coords[Index] = vec2(1.0, 1.0); Index++;////新增或有更改 normals[Index] = normal; points[Index] = vertices[a]; tex_coords[Index] = vec2(0.0, 0.0); Index++;////新增或有更改 normals[Index] = normal; points[Index] = vertices[c]; tex_coords[Index] = vec2(1.0, 1.0); Index++;////新增或有更改 normals[Index] = normal; points[Index] = vertices[d]; tex_coords[Index] = vec2(1.0, 0.0); Index++;////新增或有更改 } //---------------------------------------------------------------------------- // generate 12 triangles: 36 vertices and 36 colors void colorcube() { quad(1, 0, 3, 2); quad(2, 3, 7, 6); quad(3, 0, 4, 7); quad(6, 5, 1, 2); quad(4, 5, 6, 7); quad(5, 4, 0, 1); } //---------------------------------------------------------------------------- // OpenGL initialization void init() { colorcube();//新增或有更改 imageinit();//新增或有更改 // Create a vertex array object GLuint vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); // Create and initialize a buffer object GLuint buffer; glGenBuffers(1, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(points) + sizeof(normals) + sizeof(tex_coords), NULL, GL_STATIC_DRAW);// glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(points), points); glBufferSubData(GL_ARRAY_BUFFER, sizeof(points), sizeof(normals), normals); glBufferSubData(GL_ARRAY_BUFFER, sizeof(points) + sizeof(normals), sizeof(tex_coords), tex_coords);//新增或有更改 // Load shaders and use the resulting shader program GLuint program = InitShader("vshader.glsl", "fshader.glsl"); glUseProgram(program); // set up vertex arrays GLuint vPosition = glGetAttribLocation(program, "vPosition"); glEnableVertexAttribArray(vPosition); glVertexAttribPointer(vPosition, 4, GL_FLOAT, GL_FALSE, 0,BUFFER_OFFSET(0)); GLuint vNormal = glGetAttribLocation(program, "vNormal"); glEnableVertexAttribArray(vNormal); glVertexAttribPointer(vNormal, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(points))); GLuint vTexCoord = glGetAttribLocation(program, "vtexCoord");////新增或有更改 glEnableVertexAttribArray(vTexCoord);////新增或有更改 glVertexAttribPointer(vTexCoord, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(points) + sizeof(normals)));////新增或有更改 //初始化光照参数la,ld,ls环境,漫反射,镜面反射 point4 light_position(0.0, 0.0, 2.0,-0.0); //color4 light_ambient(1.0,0.0,0.0,1.0);//R红_G绿_B蓝 color4 light_diffuse(1.0, 1.0, 1.0, 1.0); color4 light_specular(1.0, 1.0, 1.0, 1.0); color4 material_ambient(1.0, 0.0, 1.0, 1.0); color4 material_diffuse(1.0, 0.8, 0.0, 1.0); color4 material_specular(1.0, 0.8, 0.0, 1.0); float material_shininess = 20.0;//高光系数 高金属 低塑料 light_ex = material_ambient; //color4 ambient_product = light_ambient*material_ambient; color4 diffuse_product = light_diffuse*material_diffuse; color4 specular_product = light_specular*material_specular; glUniform4fv(glGetUniformLocation(program, "DiffuseProduct"), 1, diffuse_product); glUniform4fv(glGetUniformLocation(program, "SpecularProduct"), 1, specular_product); glUniform4fv(glGetUniformLocation(program, "LightPosition"), 1, light_position); glUniform1f(glGetUniformLocation(program,"Shininess"),material_shininess); vam = glGetUniformLocation(program, "AmbientProduct"); thet = glGetUniformLocation(program, "theta"); atha = glGetUniformLocation(program, "athat"); direct = glGetUniformLocation(program, "direct"); f = glGetUniformLocation(program, "ff"); glUniform1i(glGetUniformLocation(program, "texture"), 1);//新增或有更改 //texture在vshader里面,后面的1对应glActiveTexture(GL_TEXTURE1); //如果0,那么对应glActiveTexture(GL_TEXTURE0); //如果3,那么对应glActiveTexture(GL_TEXTURE3); glEnable(GL_DEPTH_TEST);///开启深度缓存测试 glEnable(GL_CULL_FACE);///启动多边形剔除功能 //glOrtho(1.0, 0.0, 0.0, 1.0, 0.0, 1.0); } //---------------------------------------------------------------------------- void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //glMatrixMode(GL_PROJECTION); //glMatrixMode(GL_MODELVIEW); //glLoadIdentity(); //gluLookAt(1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.1, 0.0); glUniform4fv(vam, 1, light_ex*onecolor); glUniform3fv(thet, 1, Thet); glUniform1f(atha, Disx); glUniform1f(direct, Dis);//传递单个的 glUniform1f(f, fd); glDrawArrays(GL_TRIANGLES, 0, NumVertices); glClearColor(gr[0], gr[1], gr[2], gr[3]); glFlush(); } void ProcessMenu(int value) { if (value == 0) exit(0); if (value == 100) { gr = vec4(1.0f, 1.0f, 1.0f, 1.0f); onecolor = vec4(1.0, 0.0, 1.0, 1.0); } else{ switch (value) { case 21:gr = vec4(0.75f, 0.0f, 1.0f, 1.0f); break; case 22:gr = vec4(0.75f, 0.75f, 1.0f, 1.0f); break; case 23:gr = vec4(1.75f, 1.75f, 0.75f, 1.0f); break; case 24:gr = vec4(1.75f, 1.0f, 1.55f, 1.0f); break; case 25:gr = vec4(0.0f, 1.0f, 0.75f, 0.0f); break; case 1:onecolor = color4(0.0, 0.0, 0.0, 1.0); break;//黑色 case 2:onecolor = color4(0.0, 0.0, 1.0, 1.0); break;//蓝色 case 3:onecolor = color4(1.0, 0.0, 1.0, 1.0); break;//品红色 case 4:onecolor = color4(0.0, 1.0, 1.0, 1.0); break;//青色 } } glutSwapBuffers(); glutPostRedisplay(); } //---------------------------------------------------------------------------- void keyboard(unsigned char key, int x, int y) { switch (key) { case 'x': Axi = 0; break; //Xaxis; break; case 'y': Axi = 1; break;//Yaxis; break; case 'z': Axi = 2; break;//Zaxis; break;选择对应的x,y,z旋转角度来变化 case 'f':fd += 0.1; break;//Xdist; break; case 's':fd -= 0.1; break;//Ydist; break; case 033: // Escape Key case 'q': case 'Q': exit(EXIT_SUCCESS); break; } if (fd == 0)fd = 0.1; } void SpecialKeys(int key, int x, int y) { switch (key) { case GLUT_KEY_UP:Dis += 0.01; break; case GLUT_KEY_DOWN:Dis -= 0.01; break;//Ydist; break; case GLUT_KEY_LEFT:Disx -= 0.01; break; case GLUT_KEY_RIGHT:Disx += 0.01; break;//Xdist; break; case 033: // Escape Key case 'q': case 'Q': exit(EXIT_SUCCESS); break; } } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- void idle(void) { Thet[Axi] += 0.01; if (Thet[Axi] > 360.0) { Thet[Axi] -= 360.0; } glutSwapBuffers(); glutPostRedisplay(); } //---------------------------------------------------------------------------- int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(512, 512); glutInitContextVersion(3, 1); //这里在舍友的电脑上用3,2可以用,在我的电脑上会出现 //freeglut(dll地址):unableto create OpenGL3.2 context(flags 0, profile 1) //我改成3,1就可以了。不知道会不会是版本问题。这里用的是比较旧的版本freeglut。 glutInitContextProfile(GLUT_CORE_PROFILE); glutCreateWindow("Color Cube"); glewExperimental = true; glewInit(); int nGlutColorMenu1 = glutCreateMenu(ProcessMenu); glutAddMenuEntry("black", 1); glutAddMenuEntry("blue", 2); glutAddMenuEntry("magenta", 3); glutAddMenuEntry("cyan", 4); int nGlutColorMenu2 = glutCreateMenu(ProcessMenu); glutAddMenuEntry("background1", 21); glutAddMenuEntry("background2", 22); glutAddMenuEntry("background3", 23); glutAddMenuEntry("background4", 24); glutAddMenuEntry("background5", 25); int nGlutColorMenu3 = glutCreateMenu(ProcessMenu); glutAddMenuEntry("return", 100); int nGlutColorMenu = glutCreateMenu(ProcessMenu); glutAddSubMenu("coclor", nGlutColorMenu1); glutAddSubMenu("background", nGlutColorMenu2); glutAddSubMenu("return", nGlutColorMenu3); glutAttachMenu(GLUT_RIGHT_BUTTON); init(); glutDisplayFunc(display); glutSpecialFunc(SpecialKeys); glutKeyboardFunc(keyboard); //glutMouseFunc(mouse); glutIdleFunc(idle); glutMainLoop(); return 0; }
vshader.glsl
#version 150 in vec2 vtexCoord;////新增或有更改 in vec4 vPosition; in vec3 vNormal; out vec2 texCoord;////新增或有更改 out vec4 color; uniform vec4 AmbientProduct,DiffuseProduct,SpecularProduct; uniform vec4 LightPosition; uniform float Shininess; uniform vec3 theta; uniform float athat; uniform float direct; uniform float ff; void main() { texCoord=vtexCoord;////新增或有更改 vec3 angles = radians( theta ); vec3 c = cos( angles ); vec3 s = sin( angles ); mat4 rx = mat4( 1.0, 0.0, 0.0, 0.0, 0.0, c.x, s.x, 0.0, 0.0, -s.x, c.x, 0.0, 0.0, 0.0, 0.0, 1.0 ); mat4 ry = mat4( c.y, 0.0, -s.y, 0.0, 0.0, 1.0, 0.0, 0.0, s.y, 0.0, c.y, 0.0, 0.0, 0.0, 0.0, 1.0 ); // Workaround for bug in ATI driver ry[1][0] = 0.0; ry[1][1] = 1.0; mat4 rz = mat4( c.z, s.z, 0.0, 0.0, -s.z, c.z, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ); // Workaround for bug in ATI driver rz[2][2] = 1.0; //color = vColor; mat4 t=mat4(1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, athat,direct,0.0,1.0); mat4 sf=mat4(ff,0.0,0,0, 0.0,ff,0.0,0.0, 0.0,0.0,ff,0.0, 0.0,0.0,0.0,1.0); mat4 modeview=t*rx*rz*ry; vec3 pos=(modeview*vPosition).xyz; vec3 L=normalize(LightPosition.xyz-pos); vec3 E=normalize(-pos); vec3 H=normalize(L+E); vec3 N=normalize(modeview*vec4(vNormal,0.0)).xyz; vec4 ambient=AmbientProduct; float Kd=max(dot(L,N),0.0); vec4 diffuse=Kd*DiffuseProduct; float Ks=pow(max(dot(N,H),0.0),Shininess); vec4 specular=Ks*SpecularProduct; if(dot(L,N)<0.0) specular=vec4(0.0,0.0,0.0,1.0); gl_Position =modeview*sf*vPosition; color=ambient+diffuse+specular; color.a=1.0; }
fshader.glsl
#version 150 in vec2 texCoord;////新增或有更改 in vec4 color; out vec4 fColor; uniform sampler2D texture;////新增或有更改 void main() { fColor = color*texture2D(texture,texCoord);////新增或有更改 }
InitShader.cpp
#include "Angel.h" namespace Angel { // Create a NULL-terminated string by reading the provided file static char* readShaderSource(const char* shaderFile) { //FILE* fp = fopen(shaderFile, "r"); //由于vs甚么安全性的原因,不让使用fopen,用下面的fopen_s代替; FILE *fp; fopen_s(&fp, shaderFile, "r"); if ( fp == NULL ) { return NULL; } fseek(fp, 0L, SEEK_END); long size = ftell(fp); fseek(fp, 0L, SEEK_SET); char* buf = new char[size + 1]; fread(buf, 1, size, fp); buf[size] = '