OpenGL项目:绘制简单场景
计算机图形学报告
(项目一)
专业:计算机科学与技术
姓名:
学号:
班级:
目录
1.引言 (3)
1.1编写目的 (3)
1.2项目背景 (3)
2.开发结果 (3)
2.1开发环境 (3)
2.2主要功能及性能 (4)
2.3场景介绍 (4)
2.4操作介绍 (5)
2.5灯光介绍 (7)
3.总结 .......................................................................................................... 错误!未定义书签。4.参考文献 .................................................................................................. 错误!未定义书签。5.代码 .......................................................................................................... 错误!未定义书签。
1.引言
1.1编写目的
利用OpenGL绘制一个简单的场景
–包含球、正方形、网格数据
–交互操作:平移、缩放、旋转
–可以使用不同的灯光
1.2项目背景
openGL编程在计算机图形学中具有非常重要的作用,是实现计算机图形的一个重要工具,通过openGL编程,我们能更好的学习计算机图形学,同时也能提高我们自己的实际动手能力。
2.开发结果
2.1开发环境
Windows7旗舰版
Vs2012
2.2主要功能及性能
利用OpenGL绘制一个简单的场景
–包含球、正方形、网格数据
–交互操作:平移、缩放、旋转
–可以使用不同的灯光
2.3场景介绍
绘制一个简单的场景,包含球、正方形、网格数据。如图:
2.4操作介绍
利用上下左右方向键进行上下左右移动,如图:
利用home,end,pgup,insertj进行上下左右的旋转,如图:
2.5灯光介绍
包括三中灯光:环境光,漫射光,平面光
利用鼠标右键进行灯光选择:
漫射光如图:
3.总结
4.参考文献
1、OpenGL超级宝典
2、博客:vs2012中OpenGL配置
3、计算机图像学基础
5.代码
// DiffuseLight.cpp
// OpenGL SuperBible
// Demonstrates simple diffuse lighting
// Program by Richard S. Wright Jr.
#include
#include
#include
#include
#include
#include
#include
#ifdef __APPLE__
#include
#else
#define FREEGLUT_STATIC
#include
#endif
GLFrame viewFrame;
GLFrustum viewFrustum; GLTriangleBatch sphereBatch;
//GLBatch sphereBatch; GLMatrixStack modelViewMatrix; GLMatrixStack projectionMatrix;
GLGeometryTransform transformPipeline; GLShaderManager shaderManager;
GLuint ADSLightShader;
GLint locAmbient;
GLint locDiffuse;
GLint locSpecular;
GLint locLight;
GLint locMVP;
GLint locMV;
GLint locNM;
GLint lightOnOff = 0;
//points
static const float vertex_list[][3] = {
-0.5f, -1.5f, -0.5f,
0.5f, -1.5f, -0.5f,
0.5f, -0.5f, -0.5f,
-0.5f, -0.5f, -0.5f,
-0.5f, -1.5f, 0.5f,
0.5f, -1.5f, 0.5f,
0.5f, -0.5f, 0.5f,
-0.5f, -0.5f, 0.5f,
};
//points connect
static const GLint index_list[][4] = {
{0, 1, 2, 3},
{3, 2, 6, 7},
{4, 5, 6, 7},
{0, 1, 5, 4},
{1, 5, 6, 2},
{0, 4, 7, 3}
};
// draw cube
void DrawCube(void)
{
int i,j;
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_QUADS);
for(i=0; i<6; ++i)
{
for(j=0; j<4; ++j)
{
glVertex3fv(vertex_list[index_list[i][j]]);
}
}
glEnd();
}
void SetupRC(void)
{
// Background
glClearColor(0.0f, 1.0f, 0.0f, 1.0f );
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
shaderManager.InitializeStockShaders();
//viewFrame.MoveForward(4.0f);
// Make the sphere
gltMakeSphere(sphereBatch, 0.5f, 26, 13);
ADSLightShader = shaderManager.LoadShaderPairWithAttributes("ADSGouraud.vp", "ADSGouraud.fp", 2, GLT_ATTRIBUTE_VERTEX, "vVertex",
GLT_ATTRIBUTE_NORMAL, "vNormal");
locAmbient = glGetUniformLocation(ADSLightShader, "ambientColor");
locDiffuse = glGetUniformLocation(ADSLightShader, "diffuseColor");
locSpecular = glGetUniformLocation(ADSLightShader, "specularColor");
locLight = glGetUniformLocation(ADSLightShader, "vLightPosition");
locMVP = glGetUniformLocation(ADSLightShader, "mvpMatrix");
locMV = glGetUniformLocation(ADSLightShader, "mvMatrix");
locNM = glGetUniformLocation(ADSLightShader, "normalMatrix");
}
// Cleanup
void ShutdownRC(void)
{
}
void RenderScene(void)
{
static CStopWatch rotTimer;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
modelViewMatrix.PushMatrix(viewFrame);
//modelViewMatrix.Rotate(rotTimer.GetElapsedSeconds() * 10.0f, 0.0f, 1.0f, 0.0f);
GLfloat vEyeLight[] = { -100.0f, 100.0f, 100.0f };
GLfloat vAmbientColor[] = { 0.1f, 0.1f, 0.1f, 1.0f };
GLfloat vDiffuseColor[] = { 0.0f, 0.0f, 1.0f, 1.0f };
GLfloat vSpecularColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
glUseProgram(ADSLightShader);
if(lightOnOff == 1)
glUniform4fv(locAmbient, 1, vAmbientColor);
if(lightOnOff == 2)
glUniform4fv(locDiffuse, 1, vDiffuseColor);
if(lightOnOff == 3)
glUniform4fv(locSpecular, 1, vSpecularColor);
glUniform3fv(locLight, 1, vEyeLight);
glUniformMatrix4fv(locMVP, 1, GL_FALSE, transformPipeline.GetModelViewProjectionMatrix());
glUniformMatrix4fv(locMV, 1, GL_FALSE, transformPipeline.GetModelViewMatrix());
glUniformMatrix3fv(locNM, 1, GL_FALSE, transformPipeline.GetNormalMatrix());
sphereBatch.Draw();
glColor3f(1.0, 1.0, 0.0);
glRectf(-1.0,-1.0,1.0,1.0);
GLfloat j = -3.0;
for(int i=0;i<=30;i++)
{
glBegin(GL_LINES);
glVertex2f(j,-3.0f);
glVertex2f(j,3.0f);
glEnd();
glBegin(GL_LINES);
glVertex2f(-3.0f,j);
glVertex2f(3.0f,j);
glEnd();
j = j + 0.2;
}
DrawCube();
modelViewMatrix.PopMatrix();
glutSwapBuffers();
glutPostRedisplay();
}
void ChangeSize(int w, int h)
{
// Prevent a divide by zero
if(h == 0)
h = 1;
// Set Viewport to window dimensions
glViewport(0, 0, w, h);
viewFrustum.SetPerspective(35.0f, float(w)/float(h), 1.0f, 100.0f);
projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);
}
void SpecialKeys(int key, int x, int y)
{
GLfloat stepSize = 0.1f;
GLfloat initx = 0.0;
GLfloat inity = 0.0;
if(key == GLUT_KEY_UP)
inity += stepSize;
if(key == GLUT_KEY_DOWN)
inity -= stepSize;
if(key == GLUT_KEY_LEFT)
initx -= stepSize;
if(key == GLUT_KEY_RIGHT)
initx += stepSize;
viewFrame.TranslateWorld(initx,inity,0);
if(key == GLUT_KEY_HOME)
viewFrame.RotateWorld(m3dDegToRad(-5.0), 1.0f, 0.0f, 0.0f);
if(key == GLUT_KEY_END)
viewFrame.RotateWorld(m3dDegToRad(5.0), 1.0f, 0.0f, 0.0f);
if(key == GLUT_KEY_INSERT)
viewFrame.RotateWorld(m3dDegToRad(-5.0), 0.0f, 1.0f, 0.0f);
if(key == GLUT_KEY_PAGE_UP)
viewFrame.RotateWorld(m3dDegToRad(5.0), 0.0f, 1.0f, 0.0f);
if(key == GLUT_KEY_F1)
viewFrame.MoveForward(1.0f);
if(key == GLUT_KEY_F2)
viewFrame.MoveForward(-1.0f);
glutPostRedisplay();
}
void right_menu(int id)
{
switch(id)
{
case 0:
lightOnOff = 0;
break;
case 1:
lightOnOff = 1;
break;
case 2:
lightOnOff = 2;
break;
case 3:
lightOnOff = 3;
break;
default:
break;
}
SetupRC();
glutPostRedisplay();
}
///////////////////////////////////////////////////////////////////////////////
int main(int argc, char* argv[])
{
gltSetWorkingDirectory(argv[0]);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
glutInitWindowSize(800, 600);
glutCreateWindow("ADS Lighting, Gouraud Shading");
glutReshapeFunc(ChangeSize);
glutDisplayFunc(RenderScene);
glutSpecialFunc(SpecialKeys);
glutCreateMenu(right_menu);
glutAddMenuEntry("off",0);
glutAddMenuEntry("ambient",1);
glutAddMenuEntry("diffuse",2);
glutAddMenuEntry("specular",3);
glutAttachMenu(GLUT_RIGHT_BUTTON);
GLenum err = glewInit();
if (GLEW_OK != err) {
fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
return 1;
}
SetupRC();
glutMainLoop();
ShutdownRC();
return 0;
}
.vp
#version 130
// Incoming per vertex... position and normal
in vec4 vVertex;
in vec3 vNormal;
// Set per batch
uniform vec4 ambientColor;
uniform vec4 diffuseColor;
uniform vec4 specularColor;
uniform vec3 vLightPosition;
uniform mat4 mvpMatrix;
uniform mat4 mvMatrix;
uniform mat3 normalMatrix;
// Color to fragment program
smooth out vec4 vVaryingColor;
void main(void)
{
// Get surface normal in eye coordinates
vec3 vEyeNormal = normalMatrix * vNormal;
// Get vertex position in eye coordinates
vec4 vPosition4 = mvMatrix * vVertex;
vec3 vPosition3 = vPosition4.xyz / vPosition4.w;
// Get vector to light source
vec3 vLightDir = normalize(vLightPosition - vPosition3);
// Dot product gives us diffuse intensity
float diff = max(0.0, dot(vEyeNormal, vLightDir));
// Multiply intensity by diffuse color, force alpha to 1.0 vVaryingColor = diff * diffuseColor;
// Add in ambient light
vVaryingColor += ambientColor;
// Specular Light
vec3 vReflection = normalize(reflect(-vLightDir, vEyeNormal)); float spec = max(0.0, dot(vEyeNormal, vReflection));
if(diff != 0) {
float fSpec = pow(spec, 128.0);
vVaryingColor.rgb += vec3(fSpec, fSpec, fSpec);
}
// Don't forget to transform the geometry!
gl_Position = mvpMatrix * vVertex;
}
.fp
#version 130
out vec4 vFragColor;
smooth in vec4 vVaryingColor;
void main(void)
{
vFragColor = vVaryingColor;
}