【OpenGL】【3D】一个OpenGL示例程序
本帖最后由 lophyxp 于 2017-1-19 20:38 编辑[*]先上源代码
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include "GL/glew.h"
#include "GL/glut.h"
#ifdef WIN32
#define filename "d:\\tex03.bmp"
#elif LINUX
#define filename "/home/lophyxp/tex03.bmp"
#endif
static GLint imagewidth;
static GLint imageheight;
static GLint pixellength;
static GLubyte* pixeldata;
void readBMP() {
//打开文件
FILE* pfile = fopen(filename, "rb");
if (pfile == 0) {
printf("%s is not a BMP file.\n", filename);
exit(0);
}
//读取图像大小
fseek(pfile, 0x0012, SEEK_SET);
fread(&imagewidth, sizeof(imagewidth), 1, pfile);
fread(&imageheight, sizeof(imageheight), 1, pfile);
//计算像素数据长度,处理对齐
pixellength = imagewidth * 3;
while (pixellength % 4 != 0)pixellength++;
pixellength *= imageheight;
//读取像素数据
pixeldata = (GLubyte*)malloc(pixellength);
if (pixeldata == 0) exit(0);
fseek(pfile, 54, SEEK_SET);
fread(pixeldata, pixellength, 1, pfile);
//关闭文件
fclose(pfile);
}
typedef struct materialStruct {
GLfloat ambient;
GLfloat diffuse;
GLfloat specular;
GLfloat shininess;
}materialStruct;
materialStruct brassMaterials = {
{ 0.33, 0.22, 0.03, 1.0 },
{ 0.78, 0.57, 0.11, 1.0 },
{ 0.99, 0.91, 0.81, 1.0 },
27.8
};
materialStruct redPlasticMaterials = {
{ 0.3, 0.0, 0.0, 1.0 },
{ 0.6, 0.0, 0.0, 1.0 },
{ 0.8, 0.6, 0.6, 1.0 },
32.0
};
materialStruct whiteShinyMaterials = {
{ 1.0, 1.0, 1.0, 1.0 },
{ 1.0, 1.0, 1.0, 1.0 },
{ 1.0, 1.0, 1.0, 1.0 },
100.0
};
void materials(materialStruct *materials) {
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, materials->ambient);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, materials->diffuse);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, materials->specular);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, materials->shininess);
}
typedef struct lightingStruct {
GLfloat ambient;
GLfloat diffuse;
GLfloat specular;
}lightingStruct;
lightingStruct whiteLighting = {
{ 0.0, 0.0, 0.0, 1.0 },
{ 1.0, 1.0, 1.0, 1.0 },
{ 1.0, 1.0, 1.0, 1.0 }
};
lightingStruct coloredLighting = {
{ 0.2, 0.0, 0.0, 1.0 },
{ 0.0, 1.0, 0.0, 1.0 },
{ 0.0, 0.0, 1.0, 1.0 }
};
void lighting(lightingStruct *lighting) {
glLightfv(GL_LIGHT0, GL_AMBIENT, lighting->ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lighting->diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, lighting->specular);
}
void init() {
glViewport(0, 0, 500, 500);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-2.0, 2.0, -2.0,
2.0, -10.0, 10.0);
// Texture_2d ================================
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, imagewidth, imageheight, 0, GL_BGR, GL_UNSIGNED_BYTE, pixeldata);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
//glDisable(GL_TEXTURE_2D);
// Blend ======================================
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//glBlendFunc(GL_SRC_ALPHA, GL_ONE);
// Lighting ================================
//GLfloat light_pos[] = { 1.0,2.0,3.0,1.0 };
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
/*glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLightfv(GL_LIGHT0, GL_POSITION, light_pos);*/
lighting(&whiteLighting);
materials(&brassMaterials);
glShadeModel(GL_SMOOTH);
// Fog ===================================
GLuint filter = 2;
GLuint fogMode[] = { GL_EXP, GL_EXP2, GL_LINE };
GLuint fogfilter = 0;
GLfloat fogColor = { 0.5f, 0.5f, 0.5f, 1.0f };
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glFogi(GL_FOG_MODE, fogMode);
glFogfv(GL_FOG_COLOR, fogColor);
glFogf(GL_FOG_DENSITY, 0.35f);
glHint(GL_FOG_HINT, GL_DONT_CARE);
glFogf(GL_FOG_START, 1.0f);
glFogf(GL_FOG_END, 5.0f);
glEnable(GL_FOG);
}
GLfloat vertics[]={
{-1.0, -1.0, 1.0}, {-1.0,1.0,1.0}, //0, 1
{1.0,1.0,1.0}, {1.0,-1.0,1.0}, //2, 3
{-1.0,-1.0,-1.0}, {-1.0,1.0,-1.0}, //4, 5
{1.0,1.0,-1.0}, {1.0,-1.0,-1.0} //6, 7
};
GLfloat colors[] = {
{1.0,0.0,0.0,0.5},{0.0,1.0,1.0,0.5},
{1.0,1.0,0.0,0.5},{0.0,1.0,0.0,0.5},
{0.0,0.0,1.0,0.5},{1.0,0.0,1.0,0.5},
{0.0,0.0,0.0,0.5},{1.0,1.0,1.0,0.5}
};
GLfloat normals[] = {
{-1.0, 0.0, 0.0}, {1.0, 0.0, 0.0},
{0.0, -1.0, 0.0}, {0.0, 1.0, 0.0},
{0.0, 0.0, -1.0}, {0.0, 0.0, 1.0}
};
void polygon(int a, int b, int c, int d) {
glBegin(GL_POLYGON);
glColor3fv(colors);
glTexCoord2f(0.0, 0.0);
glVertex3fv(vertics);
glColor3fv(colors);
glTexCoord2f(0.0, 1.0);
glVertex3fv(vertics);
glColor3fv(colors);
glTexCoord2f(1.0, 1.0);
glVertex3fv(vertics);
glColor3fv(colors);
glTexCoord2f(1.0, 0.0);
glVertex3fv(vertics);
glEnd();
}
void cube() {
glNormal3fv(normals); //z
polygon(0, 3, 2, 1);
glNormal3fv(normals); //x
polygon(2, 3, 7, 6);
glNormal3fv(normals); //-y
polygon(3, 0, 4, 7);
glNormal3fv(normals); //y
polygon(1, 2, 6, 5);
glNormal3fv(normals); //-z
polygon(4, 5, 6, 7);
glNormal3fv(normals); //-x
polygon(5, 4, 0, 1);
}
GLUquadricObj* Quadric;
void quadric() {
Quadric = gluNewQuadric();
gluQuadricDrawStyle(Quadric, GLU_FILL);
gluQuadricNormals(Quadric, GLU_SMOOTH);
gluQuadricTexture(Quadric, GL_TRUE);
gluSphere(Quadric, 1.5, 120, 120);
//gluCylinder(Quadric, 0.5, 0.5, 2.0, 120, 120);
//gluDisk(Quadric, 0.5, 1.0, 120, 120);
//gluPartialDisk(Quadric, 0.5, 1.0, 120, 120, 90.0, 180.0);
gluDeleteQuadric(Quadric);
}
static GLfloat theta[] = { 0.0, 0.0, 0.0 };
static GLint axis = 1; //0:x, 1:y, 2:z
static GLfloat position0[] = { 10.0,20.0,30.0,1.0 };
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//gluLookAt(1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glPushMatrix();
glRotatef(theta, 1.0, 0.0, 0.0);
glRotatef(theta, 0.0, 1.0, 0.0);
glRotatef(theta, 0.0, 0.0, 1.0);
glLightfv(GL_LIGHT0, GL_POSITION, position0);
//cube();
//glutSolidTeapot(1.0);
glRotatef(-90.0, 1.0, 0.0, 0.0);//quardic round axis-z to round axis-y
quadric();
glPopMatrix();
//glDrawPixels(imagewidth, imageheight, GL_BGR_EXT, GL_UNSIGNED_BYTE, pixeldata);
glFlush();
glutSwapBuffers();
}
void myMouse(int btn, int state, int x, int y) {
if (btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
axis = 0;
if (btn == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN)
axis = 1;
if (btn == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
axis = 2;
}
void myIdle() {
theta += 0.1;
if (theta > 360.0) theta -= 360.0;
glutPostRedisplay();
}
void myKeyboard(unsigned char k, int x, int y) {
static bool gp = true;
switch (k) {
case '1':
glutIdleFunc(NULL);
break;
case '2':
glutIdleFunc(&myIdle);
break;
case '3':
glEnable(GL_TEXTURE_2D);
break;
case '4':
glDisable(GL_TEXTURE_2D);
break;
case 'w':
materials(&redPlasticMaterials);
break;
case 'e':
materials(&brassMaterials);
break;
case 'r':
materials(&whiteShinyMaterials);
break;
case 's':
lighting(&whiteLighting);
break;
case 'd':
lighting(&coloredLighting);
break;
case 'f':
if (gp == true) {
glDisable(GL_FOG);
gp = false;
}
else {
glEnable(GL_FOG);
gp = true;
}
break;
case 'q':
exit(0);
break;
}
}
void myReshape(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(w<=h)
glOrtho(-2.0, 2.0, -2.0*(GLfloat)h / (GLfloat)w,
2.0*(GLfloat)h / (GLfloat)w, -10.0, 10.0);
else
glOrtho(-2.0*(GLfloat)w / (GLfloat)h,
2.0*(GLfloat)w / (GLfloat)h, -2.0, 2.0,-10.0, 10.0);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char* argv[]) {
readBMP();
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowPosition(10, 10);
glutInitWindowSize(500, 500);
glutCreateWindow(filename);
init();
glutDisplayFunc(&display);
glutReshapeFunc(&myReshape);
glutIdleFunc(&myIdle);
glutMouseFunc(&myMouse);
glutKeyboardFunc(&myKeyboard);
glutMainLoop();
//-------------------------------------
free(pixeldata);
return 0;
}
[*]下载纹理文件
Windows下,解压缩后得到tex.bmp文件,放到D盘根目录下;Linux下,解压缩以后放到/home/lophyxp/目录下。
[*]Windows下编译
下载oglEarth.rar五个文件,解压缩到
我的文档\Visual Studio 2015\Projects目录下,打开Visual Studio 2015,打开项目,选择oglEarth\oglEarth.sln,点“本地Windows调试器”前面的绿色箭头。
[*]Linux下编译
下载,执行tar xzvf oglEarth.tar.gz
make main
./main
[*]运行效果
页:
[1]