Скачиваний:
82
Добавлен:
16.07.2022
Размер:
1.8 Mб
Скачать
      1. Расчёт цены предлагаемого продукта

Данный проект разрабатывался «под заказ» конкретной компании, следовательно конечная цена проекта (Спрогр) рассчитывается по следующей формуле (прибыль заложим в размере 15% от стоимости разработки):

    1. Определение кода разрабатываемого программного изделия

Разработанный проект является разработкой по договору, следовательно, согласно классификации ОКПД 2 его можно отнести к

62.01.11.000 Услуги по проектированию и разработке информационных технологий для прикладных задач и тестированию программного обеспечения

Заключение

Целью данной работы являлась разработка библиотеки графических примитивов для упрощения разработки прикладных программ для операционной системы БагрОС-4000 в сфере авионики по заказу компании ПАО «Компания «Сухой». Библиотека абстрагирует работу со спецификацией OpenGL SC 1.0.1 при написании программ, давая разработчикам больше сконцентрироваться на проработке непосредственно интерфейса разрабатываемых приложений и других составляющих программного обеспечения.

Автором данного проекта был проведён анализ производительности различных способов отрисовки примитивов на целевой машине – МЦСТ «Эльбрус-401» под управлением ОС БагрОС-4000. По результатам данного анализа было выявлено, что снижение количества отправок данных на видеокарту, пусть и с увеличением объёма отправляемых данных, очень положительно сказывается на скорости отрисовки, что является ключевым фактором для работоспособности графических приложений.

Исходный код является собственностью ПАО «Компания «Сухой», по заказу которой был разработан данный проект.

Дальнейшее развитие продукта предполагает:

  • Оптимизацию внутреннего кода библиотеки;

  • Исправление «артефактов» изображения;

  • Реализация дополнительных методов и возможностей (например, сглаживание – antialiasing).

Список использованных источников

CITATION Обз18 \l 1033 : , [1],

CITATION ТЕХ20 \l 1049 : , [2],

CITATION ДАБ19 \l 1049 : , [3],

CITATION ИББ06 \l 1049 : , [4],

CITATION Кер15 \l 1049 : , [5],

CITATION The20 \l 1033 : , [6],

CITATION Ope20 \l 1033 : , [7],

CITATION Khr09 \l 1033 : , [8],

CITATION Har17 \l 1033 : , [9],

CITATION ПАО20 \l 1049 : , [10],

CITATION Фом14 \l 1049 : , [11],

CITATION Обз18 \l 1033 : , [1],

CITATION ТЕХ20 \l 1049 : , [2],

CITATION ДАБ19 \l 1049 : , [3],

CITATION ИББ06 \l 1049 : , [4],

CITATION Кер15 \l 1049 : , [5],

CITATION The20 \l 1033 : , [6],

CITATION Ope20 \l 1033 : , [7],

CITATION Khr09 \l 1033 : , [8],

CITATION Har17 \l 1033 : , [9],

CITATION ПАО20 \l 1049 : , [10],

CITATION Фом14 \l 1049 : , [11],

Приложение а Фрагменты исходного кода библиотеки

Файл InitValues.h

//

// Created by matgod on 17.04.2020.

//

#ifndef LIBTESTS_INITVALUES_H

#define LIBTESTS_INITVALUES_H

#include "lib.h"

#define PointsCount 400 // Размер буферов (количество вершин)

#define MinCirclePred 8

#define ColorCount 6

/*Цвет задаётся в формате RGBA своим шестнадцатеричным кодом*/

int32 Colors[ColorCount] = {

0xffffffff,

0xffff00ff,

0xff00ffff,

0xff0000ff,

0xffff00ff,

0xff00ffff,

};

#define FontCount 1

char* Fonts[FontCount] = {

"/usr/share/fonts/truetype/freefont/FreeSerif.ttf"

};

#define StippleCount 2

int16 Stipples[StippleCount][2] = {

{1, 0xffff},

{3, 0xaaaa}

};

// параметры отрисовки по умолчанию

#define XOffset 0

#define YOffset 0

#define AngleOffset 0

#define CirclePred 8

#define Color 0

#define EdgingColor 0

#define LineWidth 0

#define EdgingWidth 0

#define LineType 0

#define Font 0

#define FontSize 40

#define Character 0

#define TAlign TEXTALIGN_LEFT

#define GMode GRAPHMODE_PAINT

#define MMode MaskModeWithoutMask

struct GraphFlags GraphicFlags = {0, 0, 0,

0, 0, 0, 0};

#endif //LIBTESTS_INITVALUES_H

Файл lib.h

//

// Created by matgod on 06.04.2020.

//

#ifndef TESTS_LIB_H

#define TESTS_LIB_H

#include <GL/gl.h>

#include <stdlib.h>

// Переопределения типов

typedef char int8;

typedef unsigned char uint8;

typedef short int16;

typedef unsigned short uint16;

typedef int int32;

typedef unsigned int uint32;

typedef float float32;

typedef double float64;

typedef wchar_t char_un;

typedef wchar_t char_mb;

// Структуры вершин

struct VERTEX {

int32 x, y;

};

struct Vertex {

int32 x, y;

};

// Выравнивание текста

enum TEXTALIGN {

TEXTALIGN_LEFT,

TEXTALIGN_CENTER,

TEXTALIGN_RIGHT

};

// Режимы маскирования

enum GRAPHMODE {

GRAPHMODE_PAINT,

GRAPHMODE_PAINT_MASK,

GRAPHMODE_PAINT_INVERSMASK,

GRAPHMODE_MAKE_NEW_MASK,

GRAPHMODE_MAKE_MASK,

GRAPHMODE_MAKE_SLICE

};

// OpenGL-сглаживание, заливка и обводка

enum GRAPHICFLAGS {

GF_SMOOTH_POINT,

GF_SMOOTH_LINE,

GF_SMOOTH_POLYGON,

GF_FILLING,

GF_EDGING_POINT,

GF_EDGING_LINE,

GF_EDGING_POLYGON

};

// Выравнивание текста

enum TextAlign {

TextAlignLeft,

TextAlignCenter,

TextAlignRight

};

// OpenGL-сглаживание, заливка и обводка

enum GraphMode {

GraphModeSmooth,

GraphModeFilling,

GraphModeEdging

};

// Режимы маскирования

enum MaskMode {

MaskModeWithoutMask,

MaskModeWithMask,

MaskModeWithInverseMask,

MaskModeNewMask,

MaskModeAddMask,

MaskModeCutMusk,

MaskModeClipLine,

MaskModeClipRect

};

// Стороны отсечения секущей линией

enum ClipSide {

ClipSideLeft,

ClipSideRight,

ClipSideTop,

ClipSideBottom

};

// Флаги режимов отрисовки

struct GraphFlags{

int8 GF_SMOOTH_POINT,

GF_SMOOTH_LINE,

GF_SMOOTH_POLYGON,

GF_FILLING,

GF_EDGING_POINT,

GF_EDGING_LINE,

GF_EDGING_POLYGON;

};

// Управляющие функции

void gfInit(int32 windowWidth, int32 windowHeight);

void gfSetRelativeOffset(int32 dx, int32 dy);

void gfSetAbsoluteOffset(float32 dx, float32 dy);

void gfGetAbsoluteOffset(float32* dx, float32* dy);

void gfSetRelativeAngle(float32 ang);

void gfSetAbsoluteAngle(float32 ang);

void gfCirclePred(int32 idx);

void gfColor(int32 idx);

#define gfSetColorIndex gfColor

void gfEdgingColor(int32 idx);

#define gfSetEdgingColorIndex gfEdgingColor

void gfLineWidth(int32 idx);

#define gfSetWidthIndex gfLineWidth

void gfEdgingWidth(int32 idx);

#define gfSetEdgingWidthIndex gfEdgingWidth

void gfLineType(int32 idx);

#define gfSetLineTypeIndex gfLineType

void gfFontSize(int32 size);

void gfFont(int32 idx);

#define gfSetFontIndex gfFont

void gfCharacter(int32 idx);

#define gfSetSymbolIndex gfCharacter

void gfTextAlign(enum TEXTALIGN align);

void gfEnable(enum GRAPHICFLAGS flag);

void gfDisable(enum GRAPHICFLAGS flag);

void gfSetGraphMode(enum GraphMode mode, int32 enable);

void gfEndDrawing();

// Функции отрисовки примитивов

void gfPoint(int32 x, int32 y);

#define gfDrawPoint gfPoint

void gfLine(int32 x1, int32 y1, int32 x2, int32 y2);

#define gfDrawLine gfLine

void gfPolyline(struct VERTEX const *pv, int32 count);

#define gfDrawPolyline gfPolyline

void gfArc(int32 x, int32 y, int32 radius, float32 startAngle, float32 sweepAngle);

#define gfDrawArc gfArc

void gfBezier(struct VERTEX const *pv, int32 count, int32 edges);

#define gfDrawBezier gfBezier

void gfCircle(int32 x, int32 y, int32 radius);

#define gfDrawCircle gfCircle

void gfPartialCircle(int32 x, int32 y, int32 radius, float32 startAngle, float32 sweepAngle);

#define gfDrawPartialCircle gfPartialCircle

void gfRing(int32 x, int32 y, int32 innerRadius, int32 outerRadius);

#define gfDrawRing gfRing

void gfPartialRing(int32 x, int32 y, int32 innerRadius, int32 outerRadius, float32 startAngle, float32 sweepAngle);

#define gfDrawPartialRing gfPartialRing

void gfRect(int32 x1, int32 y1, int32 x2, int32 y2);

#define gfDrawRect gfRect

void gfPolygonFan(struct VERTEX const *pv, int32 count);

#define gfDrawPolygonFan gfPolygonFan

void gfPolygonStrip(struct VERTEX const *pv, int32 count);

#define gfDrawPolygonStrip gfPolygonStrip

void gfEllipse(int32 x, int32 y, int32 a, int32 b);

#define gfDrawEllipse gfEllipse

void gfText(int32 x, int32 y, float32 angle, int8 const *text);

void gfDrawTextA(int32 x, int32 y, float32 angle, char_mb const *text); /* multi-byte */

void gfDrawTextW(int32 x, int32 y, float32 angle, char_un const *text); /* unicode */

void gfSymbol(int32 x, int32 y);

#define gfDrawSymbol gfSymbol

// Функции маскирования

void gfPopMask(int32 id);

void gfPushMask(int32 id);

void gfPopTransform(int32 id);

void gfPushTransform(int32 id);

void gfSetClipLineParam(enum ClipSide side, int32 coord);

void gfSetClipRectParam(int32 left, int32 bottom, int32 right, int32 top);

void gfGraphicMode(enum GRAPHMODE mode);

void gfSetMaskMode(enum MaskMode mode);

// Математические функции

float32 mfLn(float32 val);

float32 mfLg(float32 val);

float32 mfSin(float32 val);

float32 mfSinr(float32 val);

float32 mfSinh(float32 val);

float32 mfSinhr(float32 val);

float32 mfCos(float32 val);

float32 mfCosr(float32 val);

float32 mfCosh(float32 val);

float32 mfCoshr(float32 val);

float32 mfTg(float32 val);

float32 mfTgr(float32 val);

float32 mfTgh(float32 val);

float32 mfTghr(float32 val);

float32 mfArcsin(float32 val);

float32 mfArccos(float32 val);

float32 mfArctg(float32 val);

float32 mfArcsinr(float32 val);

float32 mfArccosr(float32 val);

float32 mfArctgr(float32 val);

float32 mfArctg2r(float32 y, float32 x);

float32 mfSqrt(float32 val);

float32 mfExp(float32 val);

float32 mfCeil(float32 val);

float32 mfFloor(float32 val);

float32 mfPow(float32 val1, float32 val2);

float32 mfFabs(float32 val);

int32 mfAbs(int32 val);

float64 mfFmod(float64 val1, float64 val2);

void sfStrncpy(int8 *dst, int8 const *src, int32 count);

void sfWcsncpy(char_un *dst, char_un const *src, int32 count);

int32 sfStrcmp(char_mb const *str1, char_mb const *str2);

int32 sfWcscmp(char_un const *str1, char_un const *str2);

char_mb *sfSnprintf(char_mb *dst, int32 limit, char_mb const *format, ... );

char_un *sfSwprintf(char_un *dst, int32 limit, char_un const *format, ... );

int32 sfAtoi(char_mb const *str);

int32 sfWtoi(char_un const *str);

uint32 sfAtoui(char_mb const *str);

uint32 sfWtoui(char_un const *str);

float32 sfAtof(char_mb const *str);

float32 sfWtof(char_un const *str);

#endif //TESTS_LIB_H

Фрагменты файла lib.c

Глобальные переменные (параметры библиотеки)

#define maskStackSize 256 // Размер стека масок

#define transformStackSize 256 // Размер стека трансформаций(линейный и угловой сдвиг)

struct Mask { // Стек масок

enum ClipSide side;

int32 coord, top, bot, left, right;

} maskStack[maskStackSize];

struct Transform { // Стек трансформаций

struct Vertex offset;

float32 angleOffset;

} transformStack[transformStackSize];

struct Vertexf { // структура точки с координатами типа float32

float32 x;

float32 y;

};

struct LineFormat { // Структура формата линии (толщина, шаблон, сглаживание)

int32 width;

int32 stipple;

int8 isSmooth;

};

// Буферы данных для отправки на ГП

float32 PolygonPoints[PointsCount][3];

float32 PolygonPointColors[PointsCount][4];

float32 LinePoints[PointsCount][3];

float32 LinePointColors[PointsCount][4];

int32 LineCount[PointsCount];

struct LineFormat lineFormat[PointsCount / 2] = {{1, 0, 0}};

int32 currentLineFormat = 0;

float32 TexturedPoints[PointsCount][3];

float32 TextureCoords[PointsCount][2];

float32 TexturedPointsColors[PointsCount][4];

GLuint TexturedPointsTexID[PointsCount / 4];

const int32 MaxTriangleCount = PointsCount / 3;

const int32 MaxLineCount = PointsCount / 2;

int32 DrawnTrianglesCount = 0;

// Текущие параметры отрисовки

int32 ww;

int32 wh;

struct Vertex offset = {XOffset, YOffset};

float32 angleOffset = AngleOffset;

int32 circlePred = CirclePred;

int32 color = Color;

int32 edgingColor = EdgingColor;

int32 lineWidth = LineWidth;

int32 edgingWidth = EdgingWidth;

int32 lineType = LineType;

int32 fontSize = FontSize;

int32 character = Character;

int32 currentMask = 0;

int32 currentDepth = 0;

int32 currentPolygonPoint = 0;

int32 currentLinePoint = 0;

int32 currentTexturedPoint = 0;

int32 currentTexturedFigure = 0;

char *fontTTF;

FT_Library freeTypeLib;

FT_Face fontFace;

enum TEXTALIGN textAlign;

struct GraphFlags graphicFlags;

struct {

enum ClipSide side;

int32 coord;

} clipLine = {ClipSideLeft, 0};

struct {

int32 top, left, bottom, right;

} clipRect = {0, 0, 0, 0};

Функции работы с буферами

void drawPolygons() {

glVertexPointer(3, GL_FLOAT, 0, PolygonPoints);

glColorPointer(4, GL_FLOAT, 0, PolygonPointColors);

glDrawArrays(GL_TRIANGLES, 0, currentPolygonPoint);

currentPolygonPoint = 0;

DrawnTrianglesCount = 0;

}

void drawLines() {

int i, drawnLines = 0;

glVertexPointer(3, GL_FLOAT, 0, LinePoints);

glColorPointer(3, GL_FLOAT, 0, LinePointColors);

for (i = 0; i <= currentLineFormat; ++i) {

if (lineFormat[i].isSmooth) {

glEnable(GL_LINE_SMOOTH);

} else {

glDisable(GL_LINE_SMOOTH);

}

glLineWidth(lineFormat[i].width);

glLineStipple(Stipples[lineFormat[i].stipple][0],

Stipples[lineFormat[i].stipple][1]);

glDrawArrays(GL_LINES, drawnLines, LineCount[i]);

drawnLines += LineCount[i];

LineCount[i] = 0;

}

currentLineFormat = 0;

currentLinePoint = 0;

}

void drawTextures() {

if (currentTexturedFigure > 0) {

glEnable(GL_TEXTURE_2D);

glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glColorPointer(4, GL_FLOAT, 0, TexturedPointsColors);

glVertexPointer(3, GL_FLOAT, 0, TexturedPoints);

glTexCoordPointer(2, GL_FLOAT, 0, TextureCoords);

int i;

for (i = 0; i < currentTexturedFigure; ++i) {

glBindTexture(GL_TEXTURE_2D, TexturedPointsTexID[i]);

glDrawArrays(GL_TRIANGLE_STRIP, i * 4, 4);

}

glDeleteTextures(currentTexturedFigure, TexturedPointsTexID);

glDisable(GL_TEXTURE_2D);

glDisableClientState(GL_TEXTURE_COORD_ARRAY);

currentTexturedPoint = 0;

currentTexturedFigure = 0;

}

}

void drawAll() {

drawPolygons();

drawLines();

drawTextures();

}

void pushLine(struct Vertexf A, struct Vertexf B) {

if (currentLinePoint + 2 >= PointsCount) drawLines();

LinePoints[currentLinePoint][0] = A.x;

LinePoints[currentLinePoint][1] = A.y;

LinePoints[currentLinePoint][2] = currentDepth;

LinePoints[currentLinePoint + 1][0] = B.x;

LinePoints[currentLinePoint + 1][1] = B.y;

LinePoints[currentLinePoint + 1][2] = currentDepth;

LinePointColors[currentLinePoint][0] =

LinePointColors[currentLinePoint + 1][0] =

(float32) (((uint32)Colors[color] >> 24) % 256) / 255;

LinePointColors[currentLinePoint][1] =

LinePointColors[currentLinePoint + 1][1] =

(float32) (((uint32)Colors[color] >> 16) % 256) / 255;

LinePointColors[currentLinePoint][2] =

LinePointColors[currentLinePoint + 1][2] =

(float32) (((uint32)Colors[color] >> 8) % 256) / 255;

LinePointColors[currentLinePoint][3] =

LinePointColors[currentLinePoint + 1][3] =

(float32) ((uint32)Colors[color] % 256) / 255;

LineCount[currentLineFormat] += 2;

currentLinePoint += 2;

}

void pushTriangle(struct Vertexf A, struct Vertexf B, struct Vertexf C) {

if (DrawnTrianglesCount == MaxTriangleCount) drawPolygons();

PolygonPoints[currentPolygonPoint][0] = A.x;

PolygonPoints[currentPolygonPoint][1] = A.y;

PolygonPoints[currentPolygonPoint][2] = currentDepth;

PolygonPoints[currentPolygonPoint + 1][0] = B.x;

PolygonPoints[currentPolygonPoint + 1][1] = B.y;

PolygonPoints[currentPolygonPoint + 1][2] = currentDepth;

PolygonPoints[currentPolygonPoint + 2][0] = C.x;

PolygonPoints[currentPolygonPoint + 2][1] = C.y;

PolygonPoints[currentPolygonPoint + 2][2] = currentDepth;

PolygonPointColors[currentPolygonPoint][0] =

PolygonPointColors[currentPolygonPoint + 1][0] =

PolygonPointColors[currentPolygonPoint + 2][0] =

(float32) (((uint32) Colors[color] >> 24) % 256) / 255;

PolygonPointColors[currentPolygonPoint][1] =

PolygonPointColors[currentPolygonPoint + 1][1] =

PolygonPointColors[currentPolygonPoint + 2][1] =

(float32) (((uint32) Colors[color] >> 16) % 256) / 255;

PolygonPointColors[currentPolygonPoint][2] =

PolygonPointColors[currentPolygonPoint + 1][2] =

PolygonPointColors[currentPolygonPoint + 2][2] =

(float32) (((uint32) Colors[color] >> 8) % 256) / 255;

PolygonPointColors[currentPolygonPoint][3] =

PolygonPointColors[currentPolygonPoint + 1][3] =

PolygonPointColors[currentPolygonPoint + 2][3] =

(float32) ((uint32) Colors[color] % 256) / 255;

currentPolygonPoint += 3;

++DrawnTrianglesCount;

}

void pushEdgingTriangle(struct Vertexf A, struct Vertexf B, struct Vertexf C) {

if (DrawnTrianglesCount == MaxTriangleCount) drawPolygons();

PolygonPoints[currentPolygonPoint][0] = A.x;

PolygonPoints[currentPolygonPoint][1] = A.y;

PolygonPoints[currentPolygonPoint][2] = currentDepth - 0.5;

PolygonPoints[currentPolygonPoint + 1][0] = B.x;

PolygonPoints[currentPolygonPoint + 1][1] = B.y;

PolygonPoints[currentPolygonPoint + 1][2] = currentDepth - 0.5;

PolygonPoints[currentPolygonPoint + 2][0] = C.x;

PolygonPoints[currentPolygonPoint + 2][1] = C.y;

PolygonPoints[currentPolygonPoint + 2][2] = currentDepth - 0.5;

PolygonPointColors[currentPolygonPoint][0] =

PolygonPointColors[currentPolygonPoint + 1][0] =

PolygonPointColors[currentPolygonPoint + 2][0] =

(float32) (((uint32)Colors[edgingColor] >> 24) % 256) / 255;

PolygonPointColors[currentPolygonPoint][1] =

PolygonPointColors[currentPolygonPoint + 1][1] =

PolygonPointColors[currentPolygonPoint + 2][1] =

(float32) (((uint32) Colors[edgingColor] >> 16) % 256) / 255;

PolygonPointColors[currentPolygonPoint][2] =

PolygonPointColors[currentPolygonPoint + 1][2] =

PolygonPointColors[currentPolygonPoint + 2][2] =

(float32) (((uint32) Colors[edgingColor] >> 8) % 256) / 255;

PolygonPointColors[currentPolygonPoint][3] =

PolygonPointColors[currentPolygonPoint + 1][3] =

PolygonPointColors[currentPolygonPoint + 2][3] =

(float32) ((uint32) Colors[edgingColor] % 256) / 255;

currentPolygonPoint += 3;

++DrawnTrianglesCount;

}

void pushPolygonTriangle(struct Vertexf A, struct Vertexf B, struct Vertexf C) {

pushTriangle(A, B, C);

if (graphicFlags.GF_EDGING_POLYGON) {

struct Vertexf edging[6] = {{A.x - edgingWidth, A.y - edgingWidth},

{A.x - edgingWidth, A.y + edgingWidth},

{B.x - edgingWidth, B.y - edgingWidth},

{B.x - edgingWidth, B.y + edgingWidth},

{C.x - edgingWidth, C.y - edgingWidth},

{C.x - edgingWidth, C.y + edgingWidth}};

float32 buff;

float32 abAngle = A.x != B.x ? mfArctg((B.y - A.y) / (B.x - A.x)) :

(A.y <= B.y ? 90.f : -90.f);

float32 baAngle = abAngle + (abAngle < 0 ? 180.f : -180.f);

if (A.x > B.x) swapf(&abAngle, &baAngle);

float32 acAngle = A.x != C.x ? mfArctg((C.y - A.y) / (C.x - A.x)) :

(A.y <= C.y ? 90.f : -90.f);

float32 caAngle = acAngle + (acAngle < 0 ? 180.f : -180.f);

if (A.x > C.x) swapf(&acAngle, &caAngle);

if (((mfAbs(abAngle - acAngle) > 180) && (abAngle > acAngle)) ||

((mfAbs(abAngle - acAngle) < 180) && (abAngle < acAngle))) {

swapVertexf(&B, &C);

swapVertexf(&edging[2], &edging[4]);

swapVertexf(&edging[3], &edging[5]);

swapf(&abAngle, &acAngle);

swapf(&baAngle, &caAngle);

}

float32 bcAngle = B.x != C.x ? mfArctg((C.y - B.y) / (C.x - B.x)) :

(B.y <= C.y ? 90.f : -90.f);

float32 cbAngle = bcAngle + (bcAngle < 0 ? 180.f : -180.f);

if (B.x > C.x) swapf(&bcAngle, &cbAngle);

float32 aAngle = (abAngle + acAngle) / 2.f +

(mfAbs(abAngle - acAngle) > 180 ? 180.f : 0);

float32 bAngle = (baAngle + bcAngle) / 2.f +

(mfAbs(baAngle - bcAngle) > 180 ? 180.f : 0);

float32 cAngle = (caAngle + cbAngle) / 2.f +

(mfAbs(caAngle - cbAngle) > 180 ? 180.f : 0);

rotateAroundPoint(&edging[0].x, &edging[0].y, A.x, A.y, aAngle);

rotateAroundPoint(&edging[1].x, &edging[1].y, A.x, A.y, aAngle);

rotateAroundPoint(&edging[2].x, &edging[2].y, B.x, B.y, bAngle);

rotateAroundPoint(&edging[3].x, &edging[3].y, B.x, B.y, bAngle);

rotateAroundPoint(&edging[4].x, &edging[4].y, C.x, C.y, cAngle);

rotateAroundPoint(&edging[5].x, &edging[5].y, C.x, C.y, cAngle);

pushEdgingTriangle(edging[0], edging[1], A);

pushEdgingTriangle(edging[1], edging[2], A);

pushEdgingTriangle(edging[2], A, B);

pushEdgingTriangle(edging[2], edging[3], B);

pushEdgingTriangle(edging[3], edging[4], B);

pushEdgingTriangle(edging[4], B, C);

pushEdgingTriangle(edging[4], edging[5], C);

pushEdgingTriangle(edging[5], edging[0], C);

pushEdgingTriangle(edging[0], C, A);

}

}

void pushTexturedFigure(struct Vertexf *Coords, struct Vertexf *TexCoords, int32 count) {

int i;

for (i = 0; i < count; ++i) {

TexturedPoints[currentTexturedPoint][0] = Coords[i].x;

TexturedPoints[currentTexturedPoint][1] = Coords[i].y;

TexturedPoints[currentTexturedPoint][2] = currentDepth;

TextureCoords[currentTexturedPoint][0] = TexCoords[i].x;

TextureCoords[currentTexturedPoint][1] = TexCoords[i].y;

TexturedPointsColors[currentTexturedPoint][0] =

(float32) (((uint32)Colors[color] >> 24) % 256) / 255;

TexturedPointsColors[currentTexturedPoint][1] =

(float32) (((uint32) Colors[color] >> 16) % 256) / 255;

TexturedPointsColors[currentTexturedPoint][2] =

(float32) (((uint32) Colors[color] >> 8) % 256) / 255;

TexturedPointsColors[currentTexturedPoint][3] =

(float32) ((uint32) Colors[color] % 256) / 255;

++currentTexturedPoint;

}

++currentTexturedFigure;

}

Функция отрисовки линии

void gfLine(int32 x1, int32 y1, int32 x2, int32 y2) {

rotateAndMovePoint(&x1, &y1);

rotateAndMovePoint(&x2, &y2);

if (x2 < x1) {

int temp = x2;

x2 = x1;

x1 = temp;

temp = y2;

y2 = y1;

y1 = temp;

}

float32 angle = x1 == x2 ? (y1 < y2 ? 90.f : -90.f) : mfArctg((float32)(y2 - y1) / (float32)(x2 - x1));

struct Vertexf leftTopEdg = {x1 - edgingWidth,

y1 + lineWidth / 2.f + edgingWidth},

leftBotEdg = {x1 - edgingWidth, y1 - lineWidth / 2.f - edgingWidth},

rightTopEdg = {x2 + edgingWidth, y2 + lineWidth / 2.f + edgingWidth},

rightBotEdg = {x2 + edgingWidth, y2 - lineWidth / 2.f - edgingWidth};

if(graphicFlags.GF_EDGING_LINE) {

float32 angleKoef = (x2 != x1) ? (float32)(y2 - y1) / (float32)(x2 - x1) : y2 > y1 ? 100000000.f : -100000000.f;

if(!graphicFlags.GF_SMOOTH_LINE) {

if (fabs(angleKoef) <= 1) {

leftTopEdg.x = x1 - edgingWidth;

leftTopEdg.y = angleKoef * leftTopEdg.x + y1 - angleKoef * x1 +

(edgingWidth + lineWidth / 2.f);

// top right

rightTopEdg.x = x2 + edgingWidth;

rightTopEdg.y = angleKoef * rightTopEdg.x + y2 - angleKoef * x2 +

(edgingWidth + lineWidth / 2.f);

// bot right

rightBotEdg.x = x2 + edgingWidth;

rightBotEdg.y = angleKoef * rightBotEdg.x + y2 - angleKoef * x2 –

(edgingWidth + lineWidth / 2.f);

// bot left

leftBotEdg.x = x1 - edgingWidth;

leftBotEdg.y = angleKoef * leftBotEdg.x + y1 - angleKoef * x1 –

(edgingWidth + lineWidth / 2.f);

} else {

if (y2 > y1) {

leftTopEdg.y = y1 - edgingWidth;

rightTopEdg.y = y2 + edgingWidth;

rightBotEdg.y = y2 + edgingWidth;

leftBotEdg.y = y1 - edgingWidth;

} else {

leftTopEdg.y = y1 + edgingWidth;

rightTopEdg.y = y2 - edgingWidth;

rightBotEdg.y = y2 - edgingWidth;

leftBotEdg.y = y1 + edgingWidth;

}

leftTopEdg.x = (1.f / angleKoef) * leftTopEdg.y + x1 –

(1.f / angleKoef) * y1 - (edgingWidth + lineWidth / 2.f);

rightTopEdg.x = (1.f / angleKoef) * rightTopEdg.y + x2 –

(1.f / angleKoef) * y2 - (edgingWidth + lineWidth / 2.f);

rightBotEdg.x = (1.f / angleKoef) * rightBotEdg.y + x2 –

(1.f / angleKoef) * y2 + (edgingWidth + lineWidth / 2.f);

leftBotEdg.x = (1.f / angleKoef) * leftBotEdg.y + x1 –

(1.f / angleKoef) * y1 + (edgingWidth + lineWidth / 2.f);

}

}

else {

leftTopEdg.x = x1 - edgingWidth;

leftTopEdg.y = y1 + lineWidth / 2.f + edgingWidth;

rotateAroundPoint(&leftTopEdg.x, &leftTopEdg.y, x1, y1,

mfArctg(angleKoef));

rightTopEdg.x = x2 + edgingWidth;

rightTopEdg.y = y2 + lineWidth / 2.f + edgingWidth;

rotateAroundPoint(&rightTopEdg.x, &rightTopEdg.y, x2, y2,

mfArctg(angleKoef));

rightBotEdg.x = x2 + edgingWidth;

rightBotEdg.y = y2 - lineWidth / 2.f - edgingWidth;

rotateAroundPoint(&rightBotEdg.x, &rightBotEdg.y, x2, y2,

mfArctg(angleKoef));

leftBotEdg.x = x1 - edgingWidth;

leftBotEdg.y = y1 - lineWidth / 2.f - edgingWidth;

rotateAroundPoint(&leftBotEdg.x, &leftBotEdg.y, x1, y1,

mfArctg(angleKoef));

}

}

struct Vertexf A = {x1, y1};

struct Vertexf B = {x2, y2};

if (graphicFlags.GF_EDGING_LINE) {

pushEdgingTriangle(rightBotEdg, leftTopEdg, rightTopEdg);

pushEdgingTriangle(leftTopEdg, rightBotEdg, leftBotEdg);

}

pushLine(A, B);

++currentDepth;

}