您的位置:首页 > 运维架构

小白学opengl之三维物体绘制

2014-12-08 20:00 330 查看
#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>
#include <GL/glu.h>

using namespace std;

bool mouseLeftDown;
bool mouseRightDown;
float mouseX, mouseY;
float cameraDistance;
float cameraAngleX;
float cameraAngleY;

void init()
{
glClearColor(0,0,0,0);
GLfloat light_position[]={1,1,1,0};
glLightfv(GL_LIGHT0,GL_POSITION,light_position);
GLfloat light_diffuse[]={1,1,1,1};
glLightfv(GL_LIGHT0,GL_DIFFUSE,light_diffuse);
GLfloat mat_emission[] = {1, 0, 0, 0.0}; //决定了三为物体表面颜色
glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);

//glColorMaterial(GL_FRONT,GL_DIFFUSE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
}

void reshape(int w,int h)
{
glViewport(0,0,(GLsizei)w,(GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

}

void display()
{

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

glTranslatef(0, 0, cameraDistance);
glRotatef(cameraAngleX, 1, 0, 0);
glRotatef(cameraAngleY, 0, 1, 0);

//glColorMaterial(GL_FRONT,GL_DIFFUSE);

//glColor3f(1,0,0);//这个函数只对二维图形绘制起作用
glutSolidCube(1);

glFlush();

}

void mouse(int button,int state,int x,int y)
{
//printf("mouse\n");
mouseX = x;
mouseY = y;

if(button == GLUT_LEFT_BUTTON)
{
if(state == GLUT_DOWN)
{
mouseLeftDown = true;
}
else if(state == GLUT_UP)
mouseLeftDown = false;
}

else if(button == GLUT_RIGHT_BUTTON)
{
if(state == GLUT_DOWN)
{
mouseRightDown = true;
}
else if(state == GLUT_UP)
mouseRightDown = false;
}
//glutPostRedisplay();
}

void motion(int x,int y)
{
//printf("motion\n");
if(mouseLeftDown)
{
cameraAngleY += (x - mouseX);
cameraAngleX += (y - mouseY);

mouseX = x;
mouseY = y;
}
if(mouseRightDown)
{
cameraDistance += (y - mouseY) * 0.2f;
mouseY = y;
}

glutPostRedisplay();
}

int main(int argc,char* argv[])
{

glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(500,500);
glutInitWindowPosition(100,100);
glutCreateWindow("test");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);

glutMotionFunc(motion);
glutMouseFunc(mouse);

glutMainLoop();
return 0;
}




#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>
#include <GL/glu.h>
#include <fstream>
#include <iostream>
#include <ctime>
#include <cmath>
#include <string.h>

using namespace std;

static int window_width, window_height;
static int start_x, start_y;
static double current_rotation[16], start_rotation[16];

void arcball_rotation(int start_x, int start_y, int end_x, int end_y)
{
double sx, sy, sz, ex, ey, ez;
double scale;
double sl, el;
double dotprod;

// find vectors from center of window
sx = start_x - (window_width  / 2);
sy = start_y - (window_height / 2);
ex = end_x -   (window_width  / 2);
ey = end_y -   (window_height / 2);

// invert y coordinates (raster versus device coordinates)
sy = -sy;
ey = -ey;

// scale by inverse of size of window
if (window_width > window_height) {
scale = 1.0 / (double) window_height;
} else {
scale = 1.0 / (double) window_width;
}

sx *= scale;
sy *= scale;
ex *= scale;
ey *= scale;

// project points to unit circle
sl = hypot(sx, sy);
el = hypot(ex, ey);

if (sl > 1.0) {
sx /= sl;
sy /= sl;
sl = 1.0;
}

if (el > 1.0) {
ex /= el;
ey /= el;
el = 1.0;
}

// project up to unit sphere - find Z coordinate
sz = sqrt(1.0 - sl * sl);
ez = sqrt(1.0 - el * el);

// rotate (sx,sy,sz) into (ex,ey,ez)

// compute angle from dot-product of unit vectors (and double it).
// compute axis from cross product.
dotprod = sx * ex + sy * ey + sz * ez;
glRotatef(2.0 * acos(dotprod) * 180.0 / M_PI,
sy * ez - ey * sz,
sz * ex - ez * sx,
sx * ey - ex * sy);

}

void mouse(int button, int state, int x, int y)
{
if (state == GLUT_DOWN) {
// Start of drag.
int i;

// Store off mouse location and current rotation matrix
start_x = x;
start_y = y;
for (i = 0; i < 16; i++) start_rotation[i] = current_rotation[i];
} else {
// nothing to do here, as rotation has already been
// multiplied into current_rotation
;
}

// redraw.
glutPostRedisplay();
}

void
motion(int x, int y)
{
// Mouse has been dragged.

// Update the current rotation matrix.
glLoadIdentity();
arcball_rotation(start_x, start_y, x, y);
glMultMatrixd(start_rotation);
glGetDoublev(GL_MODELVIEW_MATRIX, current_rotation);

// redraw.
glutPostRedisplay();
}

void init(void)
{
// Use depth buffering for hidden surface elimination.
glEnable(GL_DEPTH_TEST);

// Enable a single OpenGL light.
// White diffuse light.
GLfloat light_diffuse[] = {1.0, 1.0, 1.0, 1.0};
// Put the light at infinity in the direction (1,1,1)
GLfloat light_position[] = {1.0, 1.0, 1.0, 0.0};
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);

// Turn on the light and enable lighting.
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);

// Set up a perspective view, with square aspect ratio
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// 50 degree fov, uniform aspect ratio, near = 1, far = 10
gluPerspective(20.0,
1.0,
1.0, 10.0);

// Initialize rotation of the cube
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glGetDoublev(GL_MODELVIEW_MATRIX, current_rotation);
glEnable(GL_NORMALIZE);
}

void reshape(int w, int h)
{
// store window dimensions (needed to compute rotations)
window_width = w;
window_height = h;

// Always use the largest square viewport possible
if (w > h) {
glViewport((w - h) / 2, 0, h, h);
} else {
glViewport(0, (h - w) / 2, w, w);
}
}

void display(void)
{
GLfloat red[] = {1.0, 0.0, 0.0, 1.0};
GLfloat green[] = {0.0, 1.0, 0.0, 1.0};

// Clear the back buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// Make the cube red
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red);

// Set up viewing transformation
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

// look from (0,0,5) to (0,0,0) with up vector of (0,1,0)
gluLookAt(0.0, 0.0, 5.0,
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);

// apply the current rotation
glMultMatrixd(current_rotation);

glPolygonMode(GL_FRONT,GL_FILL);
//glPolygonMode(GL_BACK,GL_LINE);
glutSolidCube(1);

// Swap front and back buffers
glutSwapBuffers();
}

int main(int argc,char* argv[])
{

glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);//最后一个选项必须要加,否则效果就会透视
glutInitWindowSize(500,500);
glutInitWindowPosition(100,100);
glutCreateWindow("test");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);

glutMotionFunc(motion);
glutMouseFunc(mouse);

glutMainLoop();
return 0;
}



ps:如果要想多面体每个表面看起来光泽、模棱分明,需要给出每个点的法向量
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: