Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ЛР3

.docx
Скачиваний:
12
Добавлен:
21.06.2021
Размер:
559.89 Кб
Скачать

МИНИСТЕРСТВО НАУКИ И ВЫСШЕГО ОБРАЗОВАНИЯ РОССИЙСКОЙ ФЕДЕРАЦИИ

федеральное государственное автономное образовательное учреждение высшего образования

«САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ АЭРОКОСМИЧЕСКОГО ПРИБОРОСТРОЕНИЯ»

КАФЕДРА № 53 «ИФОРМАЦИОННО-СЕТЕВЫХ ТЕХНОЛОГИЙ»

ОТЧЕТ ЗАЩИЩЕН С ОЦЕНКОЙ

ПРЕПОДАВАТЕЛЬ

Ассистент

В.А. Ушаков

должность, уч. степень, звание

подпись, дата

инициалы, фамилия

ОТЧЕТ О ЛАБОРАТОРНОЙ РАБОТЕ № 3

ЗНАКОМСТВО С Open GL

по курсу: КОМПЬЮТЕРНАЯ ГРАФИКА

РАБОТУ ВЫПОЛНИЛА

СТУДЕНТКА ГР. №

подпись, дата

инициалы, фамилия

Санкт-Петербург 2021

Цель работы

Изучение открытой графической библиотеки OpenGL: построить динамическую 3D-сцену на языке программирования высокого уровня, поддерживающего библиотеку OpenGL.

Задание

С использованием любого языка программирования высокого уровня (из числа изученных в ходе освоения ООП 09.03.02), поддерживающего библиотеку OpenGL, построить динамическую 3D сцену.

Листинг с кодом программы

using System;

using Tao.FreeGlut;

using OpenGL;

namespace Graf3

{

class Program

{

private static int width = 1280, height = 720;

private static ShaderProgram program;

private static VBO<Vector3> pyramid, cube, cubeNormals;

private static VBO<Vector3> pyramidColor;

private static VBO<Vector2> cubeUV;

private static VBO<uint> pyramidTriangles, cubeQuads;

private static Texture crateTexture;

private static System.Diagnostics.Stopwatch watch;

private static float xangle, yangle;

private static bool autoRotate, lighting = true, fullscreen = false;

private static bool left, right, up, down;

private static float angle;

static void Main(string[] args)

{

Glut.glutInit();

Glut.glutInitDisplayMode(Glut.GLUT_DOUBLE | Glut.GLUT_DEPTH);

Glut.glutInitWindowSize(width, height);

Glut.glutCreateWindow("My picture");

Glut.glutIdleFunc(OnRenderFrame);

Glut.glutDisplayFunc(OnDisplay);

Glut.glutKeyboardFunc(OnKeyboardDown);

Glut.glutKeyboardUpFunc(OnKeyboardUp);

Glut.glutCloseFunc(OnClose);

Glut.glutReshapeFunc(OnReshape);

Gl.Enable(EnableCap.DepthTest);

program = new ShaderProgram(VertexShader, FragmentShader);

program.Use();

program["projection_matrix"].SetValue(Matrix4.CreatePerspectiveFieldOfView(0.45f, (float)width / height, 0.1f, 1000f));

program["view_matrix"].SetValue(Matrix4.LookAt(new Vector3(3, 2, 17), new Vector3(0,-2,0), new Vector3(0, 1, 0)));

program["light_direction"].SetValue(new Vector3(0, 0, 1));

program["enable_lighting"].SetValue(lighting);

crateTexture = new Texture("crate.jpg");

pyramid = new VBO<Vector3>(new Vector3[] {

new Vector3(0, -2, 0), new Vector3(-1, -4, 1), new Vector3(1, -4, 1),

new Vector3(0, -2, 0), new Vector3(1, -4, 1), new Vector3(1, -4, -1), new Vector3(0, -2, 0), new Vector3(1, -4, -1), new Vector3(-1, -4, -1),

new Vector3(0, -2, 0), new Vector3(-1, -4, -1), new Vector3(-1, -4, 1) });

pyramidColor = new VBO<Vector3>(new Vector3[] {

new Vector3(1, 0, 0), new Vector3(0, 1, 0), new Vector3(0, 0, 1),

new Vector3(1, 0, 0), new Vector3(0, 0, 1), new Vector3(0, 1, 0),

new Vector3(1, 0, 0), new Vector3(0, 1, 0), new Vector3(0, 0, 1),

new Vector3(1, 0, 0), new Vector3(0, 0, 1), new Vector3(0, 1, 0) });

pyramidTriangles = new VBO<uint>(new uint[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }, BufferTarget.ElementArrayBuffer);

cube = new VBO<Vector3>(new Vector3[] {

new Vector3(1, 1, -1), new Vector3(-1, 1, -1), new Vector3(-1, 1, 1), new Vector3(1, 1, 1),

new Vector3(1, -1, 1), new Vector3(-1, -1, 1), new Vector3(-1, -1, -1), new Vector3(1, -1, -1),

new Vector3(1, 1, 1), new Vector3(-1, 1, 1), new Vector3(-1, -1, 1), new Vector3(1, -1, 1),

new Vector3(1, -1, -1), new Vector3(-1, -1, -1), new Vector3(-1, 1, -1), new Vector3(1, 1, -1),

new Vector3(-1, 1, 1), new Vector3(-1, 1, -1), new Vector3(-1, -1, -1), new Vector3(-1, -1, 1), new Vector3(1, 1, -1), new Vector3(1, 1, 1), new Vector3(1, -1, 1), new Vector3(1, -1, -1) });

cubeNormals = new VBO<Vector3>(new Vector3[] {

new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector3(0, 1, 0),

new Vector3(0, -1, 0), new Vector3(0, -1, 0), new Vector3(0, -1, 0), new Vector3(0, -1, 0),

new Vector3(0, 0, 1), new Vector3(0, 0, 1), new Vector3(0, 0, 1), new Vector3(0, 0, 1),

new Vector3(0, 0, -1), new Vector3(0, 0, -1), new Vector3(0, 0, -1), new Vector3(0, 0, -1),

new Vector3(-1, 0, 0), new Vector3(-1, 0, 0), new Vector3(-1, 0, 0), new Vector3(-1, 0, 0),

new Vector3(1, 0, 0), new Vector3(1, 0, 0), new Vector3(1, 0, 0), new Vector3(1, 0, 0) });

cubeUV = new VBO<Vector2>(new Vector2[] {

new Vector2(0, 0), new Vector2(1, 0), new Vector2(1, 1), new Vector2(0, 1),

new Vector2(0, 0), new Vector2(1, 0), new Vector2(1, 1), new Vector2(0, 1),

new Vector2(0, 0), new Vector2(1, 0), new Vector2(1, 1), new Vector2(0, 1),

new Vector2(0, 0), new Vector2(1, 0), new Vector2(1, 1), new Vector2(0, 1),

new Vector2(0, 0), new Vector2(1, 0), new Vector2(1, 1), new Vector2(0, 1),

new Vector2(0, 0), new Vector2(1, 0), new Vector2(1, 1), new Vector2(0, 1) });

cubeQuads = new VBO<uint>(new uint[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 }, BufferTarget.ElementArrayBuffer);

watch = System.Diagnostics.Stopwatch.StartNew();

Glut.glutMainLoop();

}

private static void OnClose()

{

pyramid.Dispose();

pyramidColor.Dispose();

pyramidTriangles.Dispose();

cube.Dispose();

cubeNormals.Dispose();

cubeUV.Dispose();

cubeQuads.Dispose();

crateTexture.Dispose();

program.DisposeChildren = true;

program.Dispose();

}

private static void OnDisplay()

{

}

private static void OnRenderFrame()

{

watch.Stop();

float deltaTime = (float)watch.ElapsedTicks / System.Diagnostics.Stopwatch.Frequency;

watch.Restart();

angle += deltaTime;

if (autoRotate)

{

xangle += deltaTime / 2;

yangle += deltaTime;

}

if (right) yangle += deltaTime;

if (left) yangle -= deltaTime;

if (up) xangle -= deltaTime;

if (down) xangle += deltaTime;

Gl.Viewport(0, 0, width, height);

Gl.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

Gl.UseProgram(program);

Gl.BindTexture(crateTexture);

program["model_matrix"].SetValue(Matrix4.CreateRotationY(angle) * Matrix4.CreateTranslation(new Vector3(-1.5f, 0, 0)));

Gl.BindBufferToShaderAttribute(pyramid, program, "vertexPosition");

Gl.BindBufferToShaderAttribute(pyramidColor, program, "vertexColor");

Gl.BindBuffer(pyramidTriangles);

Gl.DrawElements(BeginMode.Triangles, pyramidTriangles.Count, DrawElementsType.UnsignedInt, IntPtr.Zero);

program["model_matrix"].SetValue(Matrix4.CreateRotationY(yangle) * Matrix4.CreateRotationX(xangle));

program["enable_lighting"].SetValue(lighting);

Gl.BindBufferToShaderAttribute(cube, program, "vertexPosition");

Gl.BindBufferToShaderAttribute(cubeNormals, program, "vertexNormal");

Gl.BindBufferToShaderAttribute(cubeUV, program, "vertexUV");

Gl.BindBuffer(cubeQuads);

Gl.DrawElements(BeginMode.Quads, cubeQuads.Count, DrawElementsType.UnsignedInt, IntPtr.Zero);

Glut.glutSwapBuffers();

}

private static void OnReshape(int width, int height)

{

Program.width = width;

Program.height = height;

program.Use();

program["projection_matrix"].SetValue(Matrix4.CreatePerspectiveFieldOfView(0.45f, (float)width / height, 0.1f, 1000f));

}

private static void OnKeyboardDown(byte key, int x, int y)

{

if (key == 'w') up = true;

else if (key == 's') down = true;

else if (key == 'd') right = true;

else if (key == 'a') left = true;

else if (key == 27) Glut.glutLeaveMainLoop();

}

private static void OnKeyboardUp(byte key, int x, int y)

{

if (key == 'w') up = false;

else if (key == 's') down = false;

else if (key == 'd') right = false;

else if (key == 'a') left = false;

else if (key == ' ') autoRotate = !autoRotate;

else if (key == 'l') lighting = !lighting;

else if (key == 'f')

{

fullscreen = !fullscreen;

if (fullscreen) Glut.glutFullScreen();

else

{

Glut.glutPositionWindow(0, 0);

Glut.glutReshapeWindow(1280, 720);

}

}

}

public static string VertexShader = @"

#version 130

in vec3 vertexPosition;

in vec3 vertexNormal;

in vec2 vertexUV;

out vec3 normal;

out vec2 uv;

uniform mat4 projection_matrix;

uniform mat4 view_matrix;

uniform mat4 model_matrix;

void main(void)

{

normal = normalize((model_matrix * vec4(floor(vertexNormal), 0)).xyz);

uv = vertexUV;

gl_Position = projection_matrix * view_matrix * model_matrix * vec4(vertexPosition, 1);

}

";

public static string FragmentShader = @"

#version 130

uniform sampler2D texture;

uniform vec3 light_direction;

uniform bool enable_lighting;

in vec3 normal;

in vec2 uv;

out vec4 fragment;

void main(void)

{

float diffuse = max(dot(normal, light_direction), 0);

float ambient = 0.3;

float lighting = (enable_lighting ? max(diffuse, ambient) : 1);

fragment = lighting * texture2D(texture, uv);

}

";

}

}}

Экранные формы с результатами работы программы

На рисунках 1, 2 представлены скриншоты с результатами работы программы.

Рисунок 1 – результат работы программы с включенным освещением

Рисунок 2 – результат работы программы с выключенным освещением

Вывод

В ходе выполнения лабораторной работы была создана динамическая 3D-сцена на языке программирования высокого уровня, поддерживающего библиотеку OpenGL. Был реализован переход в полноэкранный режим, включение и выключение освещения, запуск и остановка вращения, а также управление направлением вращения с клавиатуры.

Соседние файлы в предмете Компьютерная Графика