Помню как в 2010м году нашел на этом сайте классные уроки по C#+OpenGL и познакомился с интересными людьми, с которыми мы провели много времени в TeamSpeak и Skype, создавая игры. Я писал в блог какие-то школо-статьи с грамматическими ошибками и сообщество сайта оказывало поддержку: Isaer, Anvi и Bumblebee). Эти статьи даже сейчас не удалили:D.

В школьные времена было крайне интересно разрабатывать игры с нуля, разбираться в тонкостях игровых движков. Повзрослев, романтика пропала. Отличные игровые движки уже всё сделали за нас, писать свой движок не имеет смысла. Игровые студии нацелены на получение денег. Даже свои идеи начать разработку чего-то теперь проходят фильтр прибыльности.

Случайно найдя этот сайт, я удивился, как далеко со временем я ушел от гемдева. По окончанию школы я фрилансил в js/php, чтобы получать какие-то деньги, всё ещё думая о будущем в геймдеве. JavaScript открыл мне Canvas, WebRTC, WebGL. Я продолжал делать демки, а теперь эти технологии полностью вытеснили Flash. Позже в поисках серьёзной работы, я надеялся найти что-то в гемдеве и моим тестовым заданием было сделать однорукого бандита из казино:|. Тогда удалось найти оффер поперспективнее и я начал дальше углубляться в веб и бекенд. Окунулся в мир распределённых систем.

Некоторые мои друзья сейчас работают в геймдеве. Не знаю почему так происходит, но их работа - это постоянный стресс (вечные дедлайны и правки). Я чувствую, что судьба помогла мне найти лучший для себя путь.

Опыт с геймдевом стал хорошей базой: практика работы с языком программирования, структуры и алгоритмы, умение дебажить и танцевать с бубном (это вообще самый важный скилл).

С особой теплотой вспоминаю как в 2010 году мы пробовали создавать игры (https://esate.ru/blogs/Bumblebee/4065/). Спасибо сообществу Esate



Прокрастинатор приветствует!
Это первая статья из цикла по разработке мультиплатформенной игры на языке программирования C# с использованием библиотеки OpenTK, которая предоставляет простой доступ к OpenGL. Так же библиотека берет на себя работу с окнами приложения и, таким образом, упрощает нам жизнь при разработке не только под windows, но и linux и mac системы.
В дополнение к OpenTK мы будем использовать библиотеки Assimp.Net (порт библиотеки Assimp для С++) для загрузки трехмерных моделей, BEPUphysics для реализации физики и SixLabors для работы с двумерной графикой.

Для начала этого набора нам вполне хватит. Все библиотеки устанавливаются с помощью NuGet и, чуть позже, мы этого коснемся.
В качестве текстового редактора я буду использовать Visual Studio Code так как он доступен на всех целевых платформах, бесплатен и его функционала вполне достаточно.
Перед тем, как мы начнем, нужно установить SDK для работы с .Net Core. Сделать это можно по это ссылке: https://dotnet.microsoft.com/download Нас интересует LTS версия .Net Core и на момент написания статьи это 3.1. Выбираем ее и устанавливаем. После установки пишем в терминале dotnet и убеждаемся, что все установлено верно. Если же нет - решите вопрос и возвращайтесь к статье когда все будет в порядке.

Если вы, как и я, используете линукс, то быстрее и надежнее будет установить SDK через ваш пакетный менеджер, но убедитесь в том, что вы устанавливаете именно 3.1 версию.
Со вступлением покончено, можно приступать к самому интересному.
Что бы создать проект нужно проделать несколько простых действий.
Для начала, создадим папку, в которой будут храниться все файлы будущей игры.
Далее нужно выполнить команду, которая создаст каркас консольного приложения для нас.

dotnet new console

Если вы корректно установили .Net Core, то через несколько секунд программа сообщит вам, что файлы успешно созданы и можно переходить к следующему шагу.
Запускаем VS Code и открываем недавно созданную папку.



Скорее всего, IDE сама предложит установить все необходимое для комфортной работы, но если этого не произошло, то вам нужно вот это:
https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csharp

Следующая наша задача - установка библиотек из NuGet

Делается это довольно просто.
Переходим на сайт https://www.nuget.org/ и в строке поиска находим все необходимое.
Для упрощения вам жизни я просто опубликую команды, которые нужно ввести в консоли(которую можно вызвать прямо в VS Code):

dotnet add package OpenTK --version 4.6.7
dotnet add package BepuPhysics --version 2.3.0
dotnet add package AssimpNet --version 5.0.0-beta1
dotnet add package SixLabors.Fonts --version 1.0.0-beta15
dotnet add package SixLabors.ImageSharp --version 1.0.3

dotnet add package SixLabors.ImageSharp.Drawing --version 1.0.0-beta13

Версии библиотек актуальны на момент написания статьи. В будущем, когда мы будем обновлять библиотеки, на этом будет акцентировано дополнительное внимание
Хорошо. Еще одна настройка перед тем как мы начнем писать код, для того, что бы папка с ресурсами (assets) со всем ее содержимым копировалась при компиляции в папку с исполняемым файлом.
Откройте файл с расширением .csproj и вы найдете там тег ItemGroup. В него нужно добавить код, выделенный отступами.
<ItemGroup>

<Content Include="assets\**\*.*">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>

<PackageReference Include="AssimpNet" Version="5.0.0-beta1" />
<PackageReference Include="BepuPhysics" Version="2.3.0" />
<PackageReference Include="SixLabors.Fonts" Version="1.0.0-beta15" />
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.3" />
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta13" />
</ItemGroup>
Осталось только создать саму папку "assets" в корне нашего проекта и базовая инициализация на этом закончена.

Спасибо за внимание


В продолжение перевода с С++ на C#/OpenTk, привожу вторую и последнюю часть цикла уроков.
В прошлой заметке всё было усыпано скриншотами, о том как создать и настроить проект, а далее приводился лишь кусок кода. В этот раз будет по большей части код.
Основной момент, состоит в том, что вместо GLM из плюсового кода мы используем возможности OpenTk для работы с матрицами.

Код:
using System;
using System.Drawing;
using System.IO;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;

namespace openTk2
{
 public class GlShader : IDisposable
 {
 int ShaderProgram;
 int vertex_shader;
 int fragment_shader;
 
 private void ReleaseUnmanagedResources()
 {
 GL.UseProgram(0);
 GL.DeleteShader(vertex_shader);
 GL.DeleteShader(fragment_shader);
 GL.DeleteProgram(ShaderProgram);
 }
//Освобождение ресурсов шейдера
 public void Dispose()
 {
 ReleaseUnmanagedResources();
 GC.SuppressFinalize(this);
 }

 ~GlShader()
 {
 ReleaseUnmanagedResources();
 }

 public int loadFiles(string vertex_file_name, string fragment_file_name)
 {
 vertex_shader = loadSourcefile(vertex_file_name, ShaderType.VertexShader);
 fragment_shader = loadSourcefile(fragment_file_name, ShaderType.FragmentShader);

 linkProgram();

 return ShaderProgram;
 }

 private int loadSourcefile(string file_name, ShaderType type)
 {
 var source = File.ReadAllText(file_name);
 return compileSource(source, type);
 }

 public int load(string vertex_source, string fragment_source)
 {
 vertex_shader = compileSource(vertex_source, ShaderType.VertexShader);
 fragment_shader = compileSource(fragment_source, ShaderType.FragmentShader);

 linkProgram();
 return ShaderProgram;
 }

 private int compileSource(string source, ShaderType type)
 {
 //! Создаем фрагментный шейдер
 int shader = GL.CreateShader(type);
 //! Передаем исходный код
 GL.ShaderSource(shader, source);
 //! Компилируем шейдер
 GL.CompileShader(shader);
 return shader;
 }

 //! Функция печати лога шейдера
 private static void ShaderLog(string tag, int shader)
 {
 var infoLog = "";

 GL.GetShaderInfoLog(shader, out infoLog);

 if (infoLog.Length > 1)
 Console.WriteLine(tag + " InfoLog: " + infoLog + "\n\n\n");
 }

 private void linkProgram()
 {
 if (vertex_shader == 0 || fragment_shader == 0)
 {
 ShaderProgram = 0;
 return;
 }

 ShaderProgram = GL.CreateProgram();
 GL.AttachShader(ShaderProgram, vertex_shader);
 GL.AttachShader(ShaderProgram, fragment_shader);

 GL.LinkProgram(ShaderProgram);
 string log = GL.GetProgramInfoLog(ShaderProgram);
 if (string.IsNullOrEmpty(log) == false)
 Console.WriteLine(log);
 }

 public void use()
 {
 GL.UseProgram(ShaderProgram);
 }

 //---------------------------------------------------

 //! Attribute get
 public int getAttribLocation(string name)
 {
 int location = -1;
 location = GL.GetAttribLocation(ShaderProgram, name);
 if (location == -1)
 Console.WriteLine("Could not bind attribute {0}", name); 

 return location;
 }
 
 //! Attribute get
 public int getUniformLocation(string name)
 {
 int location = -1;
 location = GL.GetUniformLocation(ShaderProgram, name);
 if (location == -1)
 Console.WriteLine("Could not bind attribute {0}", name); 

 return location;
 }

 public void setUniform(int unifMatrix, Matrix4 matrixProjection)
 {
 GL.UniformMatrix4(unifMatrix, false, ref matrixProjection);
 }
 }

 class Game : GameWindow
 {
 private GlShader shader = new GlShader();

 //! ID атрибута вершин
 int Attrib_vertex;
 //! ID атрибута цветов
 int Attrib_color;
 //! ID юниформ матрицы проекции
 int Unif_matrix;
 //! ID Vertex Buffer Object
 int VBO_vertex;
 //! ID Vertex Buffer Object
 int VBO_color;
 //! ID VBO for element indices
 int VBO_element;

 //! Вершина
 public struct Vertex
 {
 public float x;
 public float y;
 public float z;
 };
 
 //! Количество индексов
 int Indices_count;
 //! Матрица проекции
 Matrix4 Matrix_projection;

 public Game()
 : base(640, 480, new GraphicsMode(new ColorFormat(32), 16), "Simple shaders on OpenTK!")
 {

 }

 protected override void OnLoad(EventArgs e)
 {
 base.OnLoad(e);

 GL.ClearColor(Color.Black);

 //! Инициализация
 initGL();
 initVBO();
 initShader();
 }

 protected override void OnUnload(EventArgs e)
 {
 base.OnUnload(e);

 //! Освобождение ресурсов
 freeVBO();
 shader.Dispose();
 }

 //! Функция печати лога шейдера
 static void ShaderLog(string tag, int shader)
 {
 string infoLog;

 GL.GetShaderInfoLog(shader, out infoLog);

 if (infoLog.Length > 1)
 Console.WriteLine(tag + " InfoLog: " + infoLog + "\n\n\n");
 }

 //! Проверка ошибок OpenGL, если есть то вывод в консоль тип ошибки
 static void CheckOpenGLerror()
 {
 ErrorCode errCode = GL.GetError();
 if (errCode != ErrorCode.NoError)
 {
 Console.WriteLine("OpenGl error! - {0}", errCode);
 Console.WriteLine(System.Environment.StackTrace);
 }
 }
 
 void initGL()
 {
 GL.ClearColor(0, 0, 0, 0);
 GL.Enable(EnableCap.DepthTest);
 }

 //! Инициализация шейдеров
 private void initShader()
 {
 //! Исходный код шейдеров
 const string vsSource = 
 @"attribute vec3 coord;
 attribute vec3 color;
 varying vec3 var_color;
 uniform mat4 matrix;
 void main() {
 gl_Position = matrix * vec4(coord, 1.0);
 var_color = color;
 }";
 const string fsSource = 
 @"varying vec3 var_color;
 void main() {
 gl_FragColor = vec4(var_color, 1.0);
 }";
 
 if(shader.load(vsSource, fsSource) == -1)
 {
 Console.WriteLine("error load shader");
 return;
 }
 
 CheckOpenGLerror();

 //! Вытягиваем ID атрибута из собранной программы 
 Attrib_vertex = shader.getAttribLocation("coord");
 
 CheckOpenGLerror();

 //! Вытягиваем ID юниформ
 Attrib_color = shader.getAttribLocation("color");
 
 CheckOpenGLerror();

 //! Вытягиваем ID юниформ матрицы проекции
 Unif_matrix = shader.getUniformLocation("matrix");

 CheckOpenGLerror();
 }

//! Инициализация VBO_vertex
 void initVBO()
 {
 //! Вершины куба
 Vertex [] vertices = { 
 new Vertex {x = -1.0f,y = -1.0f,z = -1.0f},
 new Vertex {x = 1.0f, y =-1.0f, z =-1.0f},
 new Vertex {x = 1.0f, y = 1.0f, z =-1.0f},
 new Vertex {x = -1.0f,y = 1.0f, z =-1.0f},
 new Vertex {x = -1.0f,y = -1.0f,z = 1.0f},
 new Vertex {x = 1.0f, y =-1.0f, z = 1.0f},
 new Vertex {x = 1.0f, y = 1.0f, z = 1.0f},
 new Vertex {x = -1.0f,y = 1.0f,z = 1.0f}
 };
 //! Цвета куба без альфа компонента(RGB)
 Vertex [] colors = { 
 new Vertex {x = 1.0f,y = 0.5f,z = 1.0f},
 new Vertex {x = 1.0f,y = 0.5f,z = 0.5f},
 new Vertex {x = 0.5f,y = 0.5f,z = 1.0f},
 new Vertex {x = 0.0f,y = 1.0f,z = 1.0f},
 new Vertex {x = 1.0f,y = 0.0f,z = 1.0f},
 new Vertex {x = 1.0f,y = 1.0f,z = 0.0f},
 new Vertex {x = 1.0f,y = 0.0f,z = 1.0f},
 new Vertex {x = 0.0f,y = 1.0f,z = 1.0f}
 };
 //! Индексы вершин, общие и для цветов
 uint [] indices = {
 0, 4, 5, 0, 5, 1,
 1, 5, 6, 1, 6, 2,
 2, 6, 7, 2, 7, 3,
 3, 7, 4, 3, 4, 0,
 4, 7, 6, 4, 6, 5,
 3, 0, 1, 3, 1, 2
 };

 // Создаем буфер для вершин
 GL.GenBuffers(1, out VBO_vertex);
 GL.BindBuffer(BufferTarget.ArrayBuffer, VBO_vertex);
 GL.BufferData(BufferTarget.ArrayBuffer, vertices.Length * Vector3.SizeInBytes, vertices, BufferUsageHint.StaticDraw);

 // Создаем буфер для цветов вершин
 GL.GenBuffers(1, out VBO_color);
 GL.BindBuffer(BufferTarget.ArrayBuffer, VBO_color);
 GL.BufferData(BufferTarget.ArrayBuffer, colors.Length * Vector3.SizeInBytes, colors, BufferUsageHint.StaticDraw);

 // Создаем буфер для индексов вершин
 GL.GenBuffers(1, out VBO_element);
 GL.BindBuffer(BufferTarget.ElementArrayBuffer, VBO_element);
 GL.BufferData(BufferTarget.ElementArrayBuffer, indices.Length * sizeof(int), indices, BufferUsageHint.StaticDraw);

 Indices_count = indices.Length;

 CheckOpenGLerror();
 }

 void freeVBO()
 {
 GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
 GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);
 
 GL.DeleteBuffers(1, ref VBO_element);
 GL.DeleteBuffers(1, ref VBO_element);
 GL.DeleteBuffers(1, ref VBO_color);
 }

 protected override void OnRenderFrame(FrameEventArgs e)
 {
 base.OnRenderFrame(e);

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

 //! Устанавливаем шейдерную программу текущей
 shader.use();
 //! Передаем матрицу в шейдер
 shader.setUniform(Unif_matrix, Matrix_projection);
 
 //! Подключаем буфер с индексами вершин общий для цветов и их вершин
 GL.BindBuffer(BufferTarget.ElementArrayBuffer, VBO_element);

 //! ВЕРШИНЫ
 //! Включаем массив атрибутов для вершин
 GL.EnableVertexAttribArray(Attrib_vertex);
 //! Подключаем VBO
 GL.BindBuffer(BufferTarget.ArrayBuffer, VBO_vertex);
 //! Указывая pointer 0 при подключенном буфере, мы указываем что данные в VBO
 GL.VertexAttribPointer(Attrib_vertex, 3, VertexAttribPointerType.Float, false, 0, 0);

 //! ЦВЕТА
 //! Включаем массив атрибутов для цветов
 GL.EnableVertexAttribArray(Attrib_color);
 GL.BindBuffer(BufferTarget.ArrayBuffer, VBO_color);
 GL.VertexAttribPointer(Attrib_color, 3, VertexAttribPointerType.Float, false, 0, 0);


 //! Передаем данные на видеокарту(рисуем)
 GL.DrawElements(BeginMode.Triangles, Indices_count, DrawElementsType.UnsignedInt, 0);

 //! Отключаем массив атрибутов
 GL.DisableVertexAttribArray(Attrib_vertex);

 //! Отключаем массив атрибутов
 GL.DisableVertexAttribArray(Attrib_color);

 CheckOpenGLerror();

 SwapBuffers();
 }

 protected override void OnResize(EventArgs e)
 {
 base.OnResize(e);

 GL.Viewport(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width, ClientRectangle.Height);

 var height = ClientRectangle.Height > 0 ? ClientRectangle.Height : 1;
 float aspectRatio = (float)ClientRectangle.Width/(float)height;

 Matrix_projection = Matrix4.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(45.0f), aspectRatio, 1.0f, 200.0f);
 
 // Перемещаем центр нашей оси координат для того чтобы увидеть куб
 Matrix_projection = Matrix4.Mult(Matrix4.CreateTranslation(new Vector3(0.0f, 0.0f, -10.0f)), Matrix_projection);
 // Поворачиваем ось координат(тоесть весь мир), чтобы развернуть отрисованное
 Matrix_projection = Matrix4.Mult(Matrix4.CreateFromAxisAngle(new Vector3(1.0f, 1.0f, 0.0f), MathHelper.DegreesToRadians(60.0f)), Matrix_projection);
 }
 }

 class Program
 {
 static void Main(string[] args)
 {
 var g = new Game();
 g.Run(30.0f);
 }
 }
}

Этим кодом можно заменить код из прошлой заметки, он должен компилироваться также хорошо.
C# вариант класса для шейдеров реализует интерфейс IDisposable для правильного освобождения ресурсов шейдерной программы. Освобождение происходит по событию выгрузки класса Game OnUnload.
Для трансформации и поворота матриц применяются методы из класса Matrix4, которые есть в OpenTk.

Результат работы:


Впрочем он должен быть такой же, как в оригинальном плюсовом коде.

Ссылка на оригинал.


Когда-то я ознакомился с уроком "Простой шейдер на GLSL", и это вдохновило на изучение шейдеров в OpenGL и сам современный OpenGL в частности. В основном я работаю с C# поэтому после ознакомления с кодом на C++ и его сборкой, приступил к переводу его в С#. Эта заметка как раз о том, как перенести код из урока на C#. Для доступа к OpenGL будет использоваться современная версия враппера OpenTK.

И так сперва создадим консольный проект на C#:


Подключим OpenTk через nuget





если не нашло OpenTk то нужно включить репоизоторий в настройках:


Используем следующий код:


using System;
using System.Drawing;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;

namespace openTk1
{
 class Game : GameWindow
 {

 //! Переменные с индентификаторами ID
 //! ID шейдерной программы
 int Program;
 //! ID атрибута
 int Attrib_vertex;
 //! ID юниформ переменной цвета
 int Unif_color;
 //! ID Vertex Buffer Object
 int VBO;

 //! Вершина
 struct Vertex
 {
 public float x;
 public float y;
 };

 public Game()
 : base(640, 480, new GraphicsMode(new ColorFormat(32), 16), "Simple shaders on OpenTK!")
 {

 }

 protected override void OnLoad(EventArgs e)
 {
 base.OnLoad(e);

 GL.ClearColor(Color.Black);

 //! Инициализация
 InitVBO();
 InitShader();
 }

 protected override void OnUnload(EventArgs e)
 {
 base.OnUnload(e);

 //! Освобождение ресурсов
 FreeShader();
 FreeVBO();
 }

 //! Функция печати лога шейдера
 static void ShaderLog(string tag, int shader)
 {
 string infoLog;

 GL.GetShaderInfoLog(shader, out infoLog);

 if (infoLog.Length > 1)
 Console.WriteLine(tag + " InfoLog: " + infoLog + "\n\n\n");
 }

 //! Проверка ошибок OpenGL, если есть то вывод в консоль тип ошибки
 static void CheckOpenGLerror()
 {
 ErrorCode errCode = GL.GetError();
 if (errCode != ErrorCode.NoError)
 Console.WriteLine("OpenGl error! - {0}", errCode);
 }

 private void InitShader()
 {
 //! Исходный код шейдеров
 const string vsSource = @"attribute vec2 coord;
 void main() {
 gl_Position = vec4(coord, 0.0, 1.0);
 };";
 const string fsSource = @"uniform vec4 color;
 void main() {
 gl_FragColor = color;
 }";

 //! Переменные для хранения идентификаторов шейдеров
 int vShader, fShader;

 //! Создаем вершинный шейдер
 vShader = GL.CreateShader(ShaderType.VertexShader);
 //! Передаем исходный код
 GL.ShaderSource(vShader, vsSource);
 //! Компилируем шейдер
 GL.CompileShader(vShader);

 ShaderLog("vertex shader", vShader);

 //! Создаем фрагментный шейдер
 fShader = GL.CreateShader(ShaderType.FragmentShader);
 //! Передаем исходный код
 GL.ShaderSource(fShader, fsSource);
 //! Компилируем шейдер
 GL.CompileShader(fShader);

 ShaderLog("fragment shader", fShader);

 //! Создаем программу и прикрепляем шейдеры к ней
 Program = GL.CreateProgram();
 GL.AttachShader(Program, vShader);
 GL.AttachShader(Program, fShader);

 //! Линкуем шейдерную программу
 GL.LinkProgram(Program);

 //Единственное, что не перевел на OpenTK:
 //! Проверяем статус сборки 
 //int link_ok;
 //GL.GetProgramiv(Program, GL_LINK_STATUS, &link_ok);
 //if(!link_ok)
 //{
 // std::cout << "error attach shaders \n";
 // return;
 //}

 //! Вытягиваем ID атрибута из собранной программы 
 const string attr_name = "coord";
 Attrib_vertex = GL.GetAttribLocation(Program, attr_name);
 if (Attrib_vertex == -1)
 {
 Console.WriteLine("could not bind attrib {0}", attr_name);
 return;
 }
 //! Вытягиваем ID юниформ
 const string unif_name = "color";
 Unif_color = GL.GetUniformLocation(Program, unif_name);
 if (Unif_color == -1)
 {
 Console.WriteLine("could not bind uniform {0}", unif_name);
 return;
 }

 CheckOpenGLerror();
 }

 //! Инициализация VBO
 void InitVBO()
 {
 GL.GenBuffers(1, out VBO);
 GL.BindBuffer(BufferTarget.ArrayBuffer, VBO);
 //! Вершины нашего треугольника
 Vertex[] triangle =
 {
 new Vertex {x = -1.0f, y = -1.0f},
 new Vertex {x = 0.0f, y = 1.0f},
 new Vertex {x = 1.0f, y = -1.0f}
 };
 //! Передаем вершины в буфер, 8 - количество байт в структуре 4 байта на 1 float, их у нас 2
 GL.BufferData(BufferTarget.ArrayBuffer, triangle.Length * 8, triangle, BufferUsageHint.StaticDraw);

 CheckOpenGLerror();
 }

 //! Освобождение шейдеров
 void FreeShader()
 {
 //! Передавая ноль, мы отключаем шейдрную программу
 GL.UseProgram(0);
 //! Удаляем шейдерную программу
 GL.DeleteProgram(Program);
 }

 //! Освобождение шейдеров
 void FreeVBO()
 {
 GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
 GL.DeleteBuffers(1, ref VBO);
 }

 protected override void OnRenderFrame(FrameEventArgs e)
 {
 base.OnRenderFrame(e);

 GL.Clear(ClearBufferMask.ColorBufferBit);
 //! Устанавливаем шейдерную программу текущей
 GL.UseProgram(Program);

 //! Передаем юниформ в шейдер
 GL.Uniform4(Unif_color, 1.0f, 0.0f, 0.0f, 1.0f);

 //! Включаем массив атрибутов
 GL.EnableVertexAttribArray(Attrib_vertex);
 //! Подключаем VBO
 GL.BindBuffer(BufferTarget.ArrayBuffer, VBO);
 //! Указывая pointer 0 при подключенном буфере, мы указываем что данные в VBO
 GL.VertexAttribPointer(Attrib_vertex, 2, VertexAttribPointerType.Float, false, 0, 0);
 //! Отключаем VBO
 GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
 //! Передаем данные на видеокарту(рисуем)
 GL.DrawArrays(PrimitiveType.Triangles, 0, 3); // 3 вершины

 //! Отключаем массив атрибутов
 GL.DisableVertexAttribArray(Attrib_vertex);

 //! Отключаем шейдерную программу
 GL.UseProgram(0);

 SwapBuffers();
 }

 protected override void OnResize(EventArgs e)
 {
 base.OnResize(e);

 GL.Viewport(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width, ClientRectangle.Height);
 }
 }

 class Program
 {
 static void Main(string[] args)
 {
 var g = new Game(); //Создание окна
 g.Run(30.0f);
 }
 }
}

 

Также нужно добавить System.Drawing:




Код хорошо описан в оригинальной статье, тут он делает тоже самое, структуру кода старался оставить такой же, так что проблем с пониманием быть не должно.

Результат работы программы:



Надеюсь заметка окажется полезной. Ошибки орфографии и оформления прошу слать в личку.


Привет всем читателям портала esate.ru.

В данной статье я постараюсь затронуть максимальное количество факторов, которые могут так или иначе повлиять на работоспособность написанного вами клиент-серверного приложения.

Несколько слов по статье.
Приложение, котрое мы напишем в ходе статьи, будет работать по следующему принципу:
Подключение -> Обработка данных -> Отключение.
Другими словами, клиент не будет постоянно подключен к серверу. Напротив, соединение будет происходить только при необходимости.
Данный способ не эффективен в условиях постоянного обмена данными, но, в достаточной мере, эффективен для решения задачи, которая будет перед ним поставленна на текущий момент.
Забегая немного вперед, могу сказать, что неше клиент-серверное приложение будет обмениваться файлами.

Я старался оттестировать приложение по-максимуму, но всегда есть вариант, что что-то пойдет не так. В таком случае буду рад вашим комментариям.

Если тема вам интересна - добро пожаловать под кат!

Это было небольшое вступление, а теперь перейдем к теории.
Теории будет не мало, но, поверьте, если вы хотите действительно понять, как на самом деле работает ваше клиент-серверное приложение – вы должны изучить тему достаточно глубоко и для начала поговорим о протоколах передачи данных по сети, а конкретнее о TCP.

Transmission Control Protocol (TCP, протокол управления передачей)
TCP - один из основных протоколов передачи данных интернета, предназначенный для управления передачей данных. Сети и подсети, в которых совместно используются протоколы TCP и IP, называются сетями TCP/IP.
В стеке протоколов IP TCP выполняет функции протокола транспортного уровня модели OSI.
Механизм TCP предоставляет поток данных с предварительной установкой соединения, осуществляет повторный запрос данных в случае потери данных и устраняет дублирование при получении двух копий одного пакета, гарантируя тем самым, в отличие от UDP, целостность передаваемых данных и уведомление отправителя о результатах передачи.
Реализации TCP обычно встроены в ядра ОС. Существуют реализации TCP, работающие в пространстве пользователя.
Когда осуществляется передача от компьютера к компьютеру через Интернет, TCP работает на верхнем уровне между двумя конечными системами, например, браузером и веб-сервером. TCP осуществляет надежную передачу потока байтов от одной программы на некотором компьютере к другой программе на другом компьютере (например, программы для электронной почты, для обмена файлами). TCP контролирует длину сообщения, скорость обмена сообщениями, сетевой трафик.

Это было определение из википедии. Звучит просто безупречно, не так ли?
Конечно же так, но когда я первые 10-15 раз пытался реализовать простейший обмен данными, то каждый раз сталкивался с одной и той же ситуацией – обмен данными отлично проходил в локальной сети, а во внешней сети успех передачи был совершенно не предсказуем и, судя по вопросам на различных интернет-площадках, с такой ситуацией сталкивался почти каждый.

Чаще всего, проблема связана именно с таким замечательным описанием протокола. Вам кажется, что достаточно просто выполнить функцию Write() или WriteAsync(), а на обратной стороне вызвать функцию Read() или ReadAsync() и задача выполнена, ведь обо всем остальном позаботится сам протокол, но это не так.
Точнее, не совсем так.

Протокол, конечно, выполнит все, что от него зависит (при правильной реализации), но сделает все это на своем уровне – на уровне протокола, а вы, в свою очередь отвечаете, как программист, за абсолютно все операции на уровне приложения и, если вы когда-либо считали, что вызова одной функции на стороне клиента и одной на стороне сервера достаточно для нормальной передачи данных по сети интернет, то забудьте об этом – это совсем не так.

На самом деле вам предстоит большая работа.

Для начала вы должны подготовить так называемый пакет для отправки.
Есть несколько способов формирования пакетов, но лично я использую один и об остальных, к сожалению, ничего рассказать не могу, но вы всегда можете отыскать их в сети.

Суть в том, что перед отправкой данных мы отправляем их длину, а уже после этого сами данные.
Плюс такого подхода в том, что таким образом можно отправлять как «простые», так и «сложные» пакеты. Под «сложными» я подразумеваю пакеты, которые содержат в себе другие пакеты.

Я предлагаю использовать для определения длины пакета Little-Endian Int32 (int в C#), который занимает четыре байта.
Важно!
Даже эти четыре байта могут не прийти к вам сразу!
Для формирования таких пакетов лучше реализовать отдельный класс, что позволит в некоторой степени снизить риск ошибки.
Вторая важная вещь для реализации – механизм приема данных.
Далее мы реализуем его рекурсивной функцией, а пока просто опишем задачу.

Представим ситуацию, мы ожидаем 4 байта от клиента.
Метод Read() вернул нам из потока некоторое количество байт (0, 1, 2, 3 или 4).
Далее мы проверяем соответствует ли ожидаемая длинна массива полученной.
Если так, то все здорово, но если нет – вызываем метод Read() и продолжаем дописывать массив и так столько раз, сколько потребуется.
Важно!
Эти действия нужно выполнять всегда, когда вы принимаете данные как на стороне сервера, так и на стороне клиента.
Лично я еще ни разу не сталкивался с проблемами при вызове метода Write() и поэтому оставляю его без дополнительных обработчиков, но буду рад вашим замечаниям в комментариях.

Один момент - важный.
До отправки данных и после их полного принятия мы можем позволить себе думать о пересылаемых данных, как о пакетах, но вы должны четко понимать, что как только вы передали данные на отправку – вы положили их в поток (NetworkStream) и, вплоть до полного их получения, вы работаете с потоком данных, а не с конкретным массивом. Это важно понять, ведь пока TCP делает свои магические вещи может случиться так, что поток на время прервется и вы, естественно, получите за один раз не все данные.

Второй момент – интересный.

Я не могу точно сказать, связанно следующее поведение с процессами операционной системы или с чем-то еще, но я лично сталкивался с проблемой, когда нужно принять, скажем, 1000 байт данных. Выделяем массив под него и начинаем в него записывать данные из потока. В примерно 80 процентах случаев сервер не мог принять данные только из-за того, что система не успевала создать сам массив.

Третий момент - ознакомительный.
TCP построен таким образом, что после успешного соединения он будет считать соединение активным пока вы, практически, не сможете доказать ему обратное. По сути, если вы установили соединение и не будете передавать данные, перезагрузите роутер, то после его включения вы можете без проблем обменяться пакетами, а TCP будет думать, что ничего не произошло.

На этом блок с теорией закончится, но я настоятельно рекомендую вам почитать про TCP еще что-то.

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

РЕАЛИЗАЦИЯ СЕРВЕРНОЙ ЧАСТИ:

Создадим стандартный WinForm проект с одной формой с версией фреймворка, в моем случае, 4.6.1 и расставим на ней компоненты как на скриншоте ниже.

btnConnect будет запускать и останавливать сервер, а txtLog – отображать лог событий.
Далее по коду я не буду пояснять очевидные вещи, но постараюсь хорошо пояснить код, касающийся клиент-серверного приложения.
Начнем с реализации класса клиента.
Этот класс представляет из себя обертку над клиентом и хранит в себе данные, которые будут уникальны для каждого отдельного клиента.
В нашем случае - объект класса TcpClient, имя файла и прочее.
Все достаточно подробно откомментированно в коде.

Client.cs:
using System.Net.Sockets;
using System.Collections.Generic;

namespace EsateServer
{
 public class Client
 {
 // Статический список клиентов, подключенных в данный момент
 public static List<Client> CLIENTSLIST = new List<Client>();
 public static uint NEXT_ID
 {
 get
 {
 uint id = 1;
 while (CLIENTSLIST.Find(client => client.ID == id) != null) id++;
 return id;
 }
 }
 public TcpClient TCPClient = null;
 public uint ID = 0;
 public bool IS_CONNECTED = false;
 // Имя файла, полученного от клиента
 public string FILE_NAME = string.Empty;

 public Client(uint id, TcpClient tcpclient)
 {
 // Подключение
 ID = id;
 TCPClient = tcpclient;
 IS_CONNECTED = true;

 // Добавляем клиента в список текущих клиентов
 CLIENTSLIST.Add(this);
 }

 public void Disconnect()
 {
 // Отключение
 IS_CONNECTED = false;
 if (TCPClient != null)
 {
 TCPClient.Close();
 TCPClient = null;
 }

 // Убираем клиента из списка текущих клиентов
 CLIENTSLIST.Remove(this);
 }
 }
} 
Далее мы реализуем класс для работы с данными.
Данный класс будет принимать, паковать и отсылать данные.

DataWrapper.cs:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace EsateServer
{
 public static class DataWrapper
 {
 // Рекурсивный метод получения данных из потока
 private static async Task<bool> ReceiveDataLoop(Client client, byte[] buffer, int received = 0)
 {
 // Недополученные байты
 int difference = buffer.Length - received;
 // Смещение индекса
 int offset = buffer.Length - difference;
 try
 {
 // Полученные байты
 received += await client.TCPClient.GetStream().ReadAsync(buffer, offset, difference);
 }
 catch
 {
 // Если что-то пошло не так
 return false;
 }
 // Если получили не все байты
 if (received < buffer.Length)
 {
 // Продолжаем заполнять буффер
 return await ReceiveDataLoop(client, buffer, received);
 }
 else
 {
 // Все прошло успешно
 return true;
 }
 }

 public static async Task<byte[]> GetData(Client client)
 {
 byte[] buffer = new byte[4];
 // Получаем длинну имени
 if (!await ReceiveDataLoop(client, buffer)) return null;
 // Получаем имя
 buffer = new byte[Program.BytesToInt(buffer)];
 if (!await ReceiveDataLoop(client, buffer)) return null;
 client.FILE_NAME = Encoding.UTF8.GetString(buffer);
 // Получаем длинну файла
 buffer = new byte[4];
 if (!await ReceiveDataLoop(client, buffer)) return null;
 // Получаем файл
 buffer = new byte[Program.BytesToInt(buffer)];
 if (!await ReceiveDataLoop(client, buffer)) return null;

 // Возвращаем файл
 return buffer;
 }

 public static async Task SendData(Client client, byte[] data)
 {
 // Пишем данные в поток
 await client.TCPClient.GetStream().WriteAsync(data, 0, data.Length);
 }

 public static byte[] CreatePack(string filename, byte[] data)
 {
 // Создаем пакет для отправки
 List<byte> packList = new List<byte>();
 // Переводим строку в массив UTF8 байт
 byte[] name_bytes = Encoding.UTF8.GetBytes(filename);
 // Добавляем длинну строки
 packList.AddRange(BitConverter.GetBytes(name_bytes.Length));
 // Добавляем байты строки
 packList.AddRange(name_bytes);
 // Добавляем количество байт файла
 packList.AddRange(BitConverter.GetBytes(data.Length));
 // Добавляем байты файла
 packList.AddRange(data);

 // Возвращаем пакет для отправки
 return packList.ToArray();
 }
 }
}
Подготовки почти законченны.
Теперь перейдем к реализации класса сервера, который будет работать с созданными ранее классами.

EsateServer.cs:
using System;
using System.Net;
using System.Net.Sockets;

namespace EsateServer
{
 public class EsateServer
 {
 // Public variables
 public bool IS_RUNNING;
 // Private variables
 private static int PORT;
 private TcpListener TCPServer;

 // Constructor
 public EsateServer(int port = 1100)
 {
 PORT = port;
 IS_RUNNING = false;
 }

 //Public methods
 public void Start()
 {
 // Слушаем весь диапазон IP на заданном порту
 TCPServer = new TcpListener(IPAddress.Any, PORT);
 TCPServer.Start();
 IS_RUNNING = true;

 // Запускаем прослушивание клиентов
 AcceptClient();
 }
 public void Stop()
 {
 IS_RUNNING = false;

 try
 {
 while (Client.CLIENTSLIST.Count > 0)
 {
 Client.CLIENTSLIST[0].Disconnect();
 Client.CLIENTSLIST.RemoveAt(0);
 }
 }
 catch { }

 Client.CLIENTSLIST.Clear();
 TCPServer.Stop();
 }

 //Private methods
 private async void AcceptClient()
 {
 // Пока сервер запущен
 while (IS_RUNNING)
 {
 try
 {
 // Принимаем клиента
 TcpClient TCPClient = await TCPServer.AcceptTcpClientAsync();
 // Создаем экземпляр клиента
 var client = new Client(Client.NEXT_ID, TCPClient);

 // Дожидаемся данных от клиента и пишем их в массив
 byte[] data = await DataWrapper.GetData(client);
 // Если данные пришли
 if (data != null)
 {
 // Отправляем полученные данные клиенту обратно
 await DataWrapper.SendData(client, DataWrapper.CreatePack(client.FILE_NAME, data));
 }
 else
 {
 // Если что-то пошло не так
 System.Windows.Forms.MessageBox.Show("Файл не получен!", "Внимание!", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning);
 }

 // Отключаем клиента
 client.Disconnect();
 }
 catch (ObjectDisposedException) { return; }
 catch (Exception) { return; }
 }
 }
 }
}
Отлично.
Осталось буквально несколько строк кода в классе MainForm.
Создадим и объявим объект класса EsateServer в конструкторе формы:
 private EsateServer server;

 public MainForm()
 {
 InitializeComponent();
 server = new EsateServer();
 }
Последнее, что касается сервера - обработчик нажатия btnConnect:
 private void btnConnect_Click(object sender, EventArgs e)
 {
 if (server.IS_RUNNING)
 {
 // Остановка сервера
 server.Stop();
 btnConnect.Text = "Запустить";
 txtLog.AppendText($"{DateTime.Now}: Сервер остановлен\r\n");
 }
 else
 {
 // Запуск сервера
 server.Start();
 btnConnect.Text = "Остановить";
 txtLog.AppendText($"{DateTime.Now}: Сервер запущен\r\n");
 }
 }
Код сервера закончен.
Как вы могли заметить - он очень прост и, скорее всего, отличается от вашего только наличием метода ReceiveDataLoop().
Вы вольны расширять данный код и улучшать, но пусть это будет заданием для самостоятельно выполнения.
Могу посоветовать вам реализовать систему флагов, которыми обмениваются клиент и сервер и построить весь диалог на их основе.

РЕАЛИЗАЦИЯ КЛИЕНТСКОЙ ЧАСТИ:

...


Всем привет.

После установки на windows 10 visual studio 2015, в списке элементов панели управления нет элемента simpleOpenGLControl. Но элемента не будет в списке .NET Framework Components.



Проблема легко решается: в окне Choose Toolbox Items (Окно "выбор элементов панели управления" из урока по ссылке выше) на вкладке .NET Framework Components выбираем  Browse и переходим в  C:\Program Files (x86)\TaoFramework\bin. Выбираем Tao.Platform.Windows.dll



Затем фильтруем по слову simple (как на рисунке ниже) и выбираем нашедшийся компонент.

 



Доброго времени суток.

Это четвертая часть цикла статей "Разработка OpenGL приложения под Android".

Предыдущие статьи:
Разработка OpenGL приложения под Android. Часть 0. Введение.
Разработка OpenGL приложения под Android. Часть 1. Знакомство.
Разработка OpenGL приложения под Android. Часть 2. Матрицы.

Сегодня мы будем работать с освещением.
Это очень важная тема, умение работать с основами освещения пригодится Вам в большинстве Ваших собственных проектов.

Здесь может возникнуть вопрос зачем что-то менять, если по умолчанию в OpenGL уже выставлен источник света и мы и без того видим наши объекты.

Дело в том, что выставленный по умолчанию свет нельзя редактировать: изменять его цвет, насыщенность, положение и другие параметры. Но самое главное это то, что он всего один. Если Вам, к примеру, понадобится еще свет от ламп или фонарика, то стандартное освещение уже не поможет.

Читать подробнее...

OGLPart3.7z ( 2.65 МБ)






Доброго времени суток.

Это третья часть цикла статей "Разработка OpenGL приложения под Android".

Предыдущие статьи:
Разработка OpenGL приложения под Android. Часть 0. Введение.
Разработка OpenGL приложения под Android. Часть 1. Знакомство.

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

Как пишут во всех уроках и статьях на данную тему, скажу Вам, что, действительно, необходимости знать все свойства матриц у Вас нет, но их понимание способствовало бы скорейшему усвоению всех процессов OpenGL. С помощью матриц происходят смещение, поворот и прочие искажения пространства.

В OpenGL 1.0(именно эту версию мы пока используем) есть три типа матриц: GL_MODELVIEW, GL_PROJECTION и GL_TEXTURE.
Остановимся на каждой из них немного подробнее.

Читать подробнее...

OGLPart2.7z ( 2.65 МБ)







Доброго времени суток.

Это вторая часть цикла статей "Разработка OpenGL приложения под Android".

Первую часть можно найти здесь: Разработка OpenGL приложения под Android. Часть 0. Введение.

Начнем с того, что сегодня самый лучший день для того, чтобы написать свое первое приложение для android. Если у Вас что-то не получалось до этого момента - будьте уверены, сегодня все получится!

И так. Вы установили новейшую версию Android Studio и все необходимые компоненты для работы с Android 4.4? Немного пощупали, изучили основные принципы работы в данной IDE и готовы покорять мир 3D графики? Отлично! Тогда приступим к работе.
  • В первую очередь создадим проект и назовем его OGLPart1.
Вы можете назвать его как угодно, но мне так будет удобнее. Уроков будет много и что бы не запутаться в них я буду нумеровать проекты эквивалентно статьям. Здесь все просто. Все, что от Вас требуется это указать имя проекта, папку для его хранения и минимальную поддерживаемую версию android. Стандартная процедура.

Читать подробнее...

OGLPart1.7z ( 2.64 МБ)


- подсветка кода в черновиках в блогах
- вырезка лишних BB кодов в почтовых уведомлениях с форума (сейчас CENTER только добавлен)
- ездят кнопки  + косяки верстки в редактировании блоговых постов / черновиках
- пустой правый блок у неавториз пользователей в блогах


@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_main);
} 
йцу






Доброго времени суток.

Это первая статья из серии программирования 3D графики с использованием OpenGL в среде android приложений.

Я хотел бы начать с полезных ссылок, которые не раз пригодятся Вам при изучении данной темы.

Это Ваш главный ресурс и помощник. Именно здесь лучше всего получать информацию о принципах работы команд и пояснения по функциям и их аргументам. Вас немного может приостановить тот факт, что сайт практически весь на английском языке, но это можно превратить в плюс. Если взять себя в руки и начать переводить неясные Вам вещи, то материал будет усвоен в разы лучше, ведь Вы хорошо поработаете для его изучения. Возможно, получится подучить язык, а это никогда не будет лишним.

В общем и целом, я хотел бы привить Вам большую любовь к изучению документаций. Не важно чем Вы решите заняться в будущем - официальная документация, практически в любом случае, будет полезнее тех статей, что Вы найдете в сети.

Читать подробнее...



Доброго времени суток!
Мое имя в сети Freaky Brainstorm и я android разработчик в одной из частных компаний. Начинающий, совсем еще «зеленый» разработчик, но все когда-то с этого начинали.
Своими публикациями я хотел бы упростить жизнь некоторым людям, которые в связи со своей неопытностью, как и я столкнутся с проблемами, с которыми столкнулся я на пути android разработки.
Приложение над которым я работаю в данный момент очень связанно с 3D графикой и, скорее всего, основной упор в блоге будет сделан на OpenGL.
Я ни в коем случае, не утверждаю, что мои решения являются верными, и что поступать нужно именно таким образом который предлагаю я. Вовсе нет, здесь я просто описываю свое видение решения стоящих передо мной проблем программирования.


Если вы в первый раз открыли проект, скачав исходники с сайта и при попытки компиляции и запуска у вас вылетело исключение (щелкните на картинках для увеличения)




BadImageFormatException was unhandled
Была сделана попытка загрузить программу, имеющую неверный формат. (Исключение из HRESULT: 0x8007000B)

на строке Glut.glutInit(); (см рисунок выше), то вам необходимо в  в поле Platform установить x86 вместо значения Any CPU:








Затем снова откомпилируйте проект. Удачи! 8)


OpenTK:
http://sourceforge.net/projects/opentk/

OpenGL 4:
http://www.rastertek.com/


http://www.tutorialized.com/


https://support.google.com/webmasters/answer/189077?hl=ru
http://help.yandex.ru/webmaster/yandex-indexing/locale-pages.xml


https://7488ae8147aa4b6f0841d060194a8d7fa5c782f0.googledrive.com/host/0BzAso-3NQrbEQ0lkeWFHeVNfbGc/yandex_markers.htm


Центробежная сила)

В центре кругового игрового поля находятся объекты, которые растягивает в разные стороны с силой.
Нужно двигать их обратно, чтобы их не "засосало" за игровое поле. По пути они встречают препятствия, которые можно использовать, чтобы скапливать часть объектов в кучки, которые не могут уехать, и таким образом проще контролить процесс, чтобы объекты не уехали.

Периодически может появляться сила с одной из сторон, более сильная.

В этом же плане можно попробовать игру - где игровое поле немного изогнуто в центр и имеет несколько уровней (2-3) а мы бежим солдатом или катимся предметом - нужно быстро осозновать путь, как мы будем двигаться , уклоняяся от ловушек или встречных объектов.


Часто приходится вести отладочную информацию, чаще всего, в простых случаях это делается в консоль. Но гораздо чаще необходимо вести лог и в консоль, и в файл.
Поведаю Вам о простом классике логирования, который симулирует стандартные cout, cerr, используя шаблонную функцию-оператор <<. Расскажу о некоторых специфичных моментах с которыми столкнулся.

Читать подробнее...



Как известно Tao Framework, уже не развивается, и даже на его странице sourceforge, пишут: "возьмите OpenTK, как замену".
Но вот появился луч надежды на возрождение, Tao Framework.

Читать подробнее...



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

Читать подробнее...



Всем привет. С момента, когда я написал свою последнюю статью прошло ровно девять месяцев. За это время я успел поступить в универ и узнать много нового в области программирования, с чем спешу поделиться. Хочу запустить цикл статей о том, как написать он-лайн игру средствами .NET. Подробно расскажу о клиент-серверной архитектуры приложения, о организации двухстороннего клиента без использования сервера, и многое многое другое.

Я сразу хотел бы поинтересоваться у вас, чего вы ждете от прочтения всех статей в цикле: чему бы хотели научиться, и о чем рассказать подробней. Свои мысли излагайте в комментариях к топику.

Цикл обещает быть объемным а над первой статьей я уже работаю в свободное от учебы время (таки сессия на носу). В конце, да и в процессе создания цикла будем писать две простеньких 2D игрушки, которые будут на своем примере показывать, как можно использовать протокол TCP\IP в разработке игр. Так что ждите=)

Уже кое что готово:

Пишем он-лайн игру: Часть первая


Товарищи, делаю все как в уроке, но вылетает черный экран!!!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
// для работы с библиотекой OpenGL
using Tao.OpenGl;
// для работы с библиотекой FreeGLUT
using Tao.FreeGlut;
// для работы с элементом управления SimpleOpenGLControl
using Tao.Platform.Windows;

namespace laba1
{
public partial class Form1: Form
{
public Form1()
{
InitializeComponent();
AnT.InitializeContexts();
}

private void Form1_Load(object sender, EventArgs e)
{

// инициализация Glut
Glut.glutInit();
Glut.glutInitDisplayMode(Glut.GLUT_RGB | Glut.GLUT_DOUBLE | Glut.GLUT_DEPTH);

// очитка окна
Gl.glClearColor(255, 255, 255, 0);//выставление цвета основного

// установка порта вывода в соотвествии с размерами элемента anT
Gl.glViewport(0, 0, AnT.Width, AnT.Height);

// настройка проекции
Gl.glMatrixMode(Gl.GL_PROJECTION);
Gl.glLoadIdentity();
Glu.gluOrtho2D(0, 56 * AnT.Width / AnT.Height, 0, 56);
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);
Gl.glLoadIdentity();


???


Вы еще не используете VA? Тогда мы идем к вам!

Читать подробнее...



Выходят новые версии OpenGL. И все время, появляется информация, о том, что какие-то функции уже не рекомендуемые,а какие-то удалены. Фиксированный графический конвейер(ФГК) уходит, с новыми версиями OpenGL. Точнее он уже ушел, в OpenGL 3.3, core profile его уже нет. А, что же тогда приходит на смену традиционному, старому функционалу?!

Читать подробнее...



Всем привет, имеется проблема, при наложении текстуры и изменения её размера она ложится плиткой, пытаюсь поставить TEXTURE_NO_TILE в настройках текстуры, однако это не к чему не приводит.
Вот структура класса текстуры и меша
 [Flags]
    public enum Lib3dsTextureMapFlags
    {
        LIB3DS_TEXTURE_DECALE = 0x0001,
        LIB3DS_TEXTURE_MIRROR = 0x0002,
        LIB3DS_TEXTURE_NEGATE = 0x0008,
        LIB3DS_TEXTURE_NO_TILE = 0x0010,
        LIB3DS_TEXTURE_SUMMED_AREA = 0x0020,
        LIB3DS_TEXTURE_ALPHA_SOURCE = 0x0040,
        LIB3DS_TEXTURE_TINT = 0x0080,
        LIB3DS_TEXTURE_IGNORE_ALPHA = 0x0100,
        LIB3DS_TEXTURE_RGB_TINT = 0x0200
    }
 public class Lib3dsTextureMap
    {
        //public uint user_id;
        //public object user_ptr;
        public string name = "";
        public Lib3dsTextureMapFlags flags;
        public float percent;
        public float blur;
        public float[] scale = new float[2];
        public float[] offset = new float[2];
        public float rotation;
        public float[] tint_1 = new float[3];
        public float[] tint_2 = new float[3];
        public float[] tint_r = new float[3];
        public float[] tint_g = new float[3];
        public float[] tint_b = new float[3];
    }
public class Lib3dsMaterial
    {
        //public uint user_id;
        //public object user_ptr;
        public string name = "";                                  // Material name
        public float[] ambient = new float[3];    // Material ambient reflectivity
        public float[] diffuse = new float[3];    // Material diffuse reflectivity
        public float[] specular = new float[3];   // Material specular reflectivity
        public float shininess;                                 // Material specular exponent
        public float shin_strength;
        public bool use_blur;
        public float blur;
        public float transparency;
        public float falloff;
        public bool is_additive;
        public bool self_illum_flag;
        public float self_illum;
        public bool use_falloff;
        public int shading;
        public bool soften;
        public bool face_map;
        public bool two_sided;                  // Material visible from back
        public bool map_decal;
        public bool use_wire;
        public bool use_wire_abs;
        public float wire_size;
        public Lib3dsTextureMap texture1_map = new Lib3dsTextureMap();
        public Lib3dsTextureMap texture1_mask = new Lib3dsTextureMap();
        public Lib3dsTextureMap texture2_map = new Lib3dsTextureMap();
        public Lib3dsTextureMap texture2_mask = new Lib3dsTextureMap();
        public Lib3dsTextureMap opacity_map = new Lib3dsTextureMap();
        public Lib3dsTextureMap opacity_mask = new Lib3dsTextureMap();
        public Lib3dsTextureMap bump_map = new Lib3dsTextureMap();
        public Lib3dsTextureMap bump_mask = new Lib3dsTextureMap();
        public Lib3dsTextureMap specular_map = new Lib3dsTextureMap();
        public Lib3dsTextureMap specular_mask = new Lib3dsTextureMap();
        public Lib3dsTextureMap shininess_map = new Lib3dsTextureMap();
        public Lib3dsTextureMap shininess_mask = new Lib3dsTextureMap();
        public Lib3dsTextureMap self_illum_map = new Lib3dsTextureMap();
        public Lib3dsTextureMap self_illum_mask = new Lib3dsTextureMap();
        public Lib3dsTextureMap reflection_map = new Lib3dsTextureMap();
        public Lib3dsTextureMap reflection_mask = new Lib3dsTextureMap();
        public uint autorefl_map_flags;
        public int autorefl_map_anti_alias; // 0=None, 1=Low, 2=Medium, 3=High
        public int autorefl_map_size;
        public int autorefl_map_frame_step;
    }
 public class Lib3dsMesh
    {
        //public uint user_id;
        //public object user_ptr;
        public string name = "";                                  // Mesh name. Don't use more than 8 characters
        public Lib3dsObjectFlags object_flags;  // see Lib3dsObjectFlags
        public byte color;                                              // Index to editor palette [0..255]
        public float[,] matrix = new float[4, 4]; // Transformation matrix for mesh data
        public ushort nvertices;                                // Number of vertices in vertex array (max. 65535)
        public List<Lib3dsVertex> vertices;
        public List<Lib3dsTexturecoordinate> texcos;
        public List<ushort> vflags;
        public ushort nfaces;                                   // Number of faces in face array (max. 65535)
        public List<Lib3dsFace> faces;
        public string box_front = "";
        public string box_back = "";
        public string box_left = "";
        public string box_right = "";
        public string box_top = "";
        public string box_bottom = "";
        public Lib3dsMapType map_type;
        public float[] map_pos = new float[3];
        public float[,] map_matrix = new float[4, 4];
        public float map_scale;
        public float[] map_tile = new float[2];
        public float[] map_planar_size = new float[2];
        public float map_cylinder_height;
    }


Отрисовка текста в OpenGL, обычно нетривиальная задача, особенно для новичков. Стандартно эта задача сводится к рисованию прямоугольников с натянутой текстурой, на которой отображена та или иная буква. Располагая, которые, относительно друг, друга собираются в слова.
Когда-то, когда я еще учился в Академии, мы делали на ASP.NET капчу отрисовывая строки текста и линии в картинку. На C# это делается очень легко, встроенными методами класса Graphics. Им и воспользуемся для рисования нашего текста.
В этом посте я покажу очень примитивный и к сожалению не масштабируемый пример.=)

Читать подробнее...



Всем привет, есть такая проблема, нужно загруженную часть 3Д модели отрисовать в JPG файле. В принципи частично у меня это получилось, однако отрисовывается только часть модели (скорее всего она не под нужным углом повёрнута, как развернуть её я хз). Или я гдето как обычно натупил. Подскажите где ошибка, или как это можно иначе реализовать?

Читать подробнее...



Думаю практически все программисты(и не только) знают или хотя бы слышали, что такое freetype. Поэтому не будет долгих вступлении, копипаста информации с других ресурсов, о том, что такое freetype.

Читать подробнее...



Turbulenz WebGL Engine. Quake 4 в браузере

Видео

Движок Turbulenz

Turbulenz - игровой движок для социальных игр, использующий HTML 5, WebGL JavaScript. Его возможности позволяют делать захватающие реалтайм 3D игры, с физикой.

Читать подробнее...



Всем доброго времени суток, подскажите как отобразить текстуры  3d объекта, в окне SimpleOpenglControl


Всем привет, в общем проблема ясна из названия темы, в SimpleOpenGlControl не отображается модель.
Считывание 3д модели происходит библиотекой 3dslib
Вот код, может кто-то поймёт в чем дело  

Читать подробнее...



Убрать консольное окно(Windows, Visual Studio, C++)

У многих при использовании библиотек(glut, glfw) создающих окна и контекст OpenGL, возникает необходимость убрать консоль. Которая появляется вместе с запуском Вашего OpenGL приложения. Но многие не знают как это делается.
На самом деле здесь нет ничего сложного, повторив все описанные здесь действия, Вы добьетесь желаемого=)

Читать подробнее...



Использование STL контейнера vector. Производительность vector-а
Использование контейнеров стандартной библиотеки C++, всегда обусловлено простотой и удобством, производительностью. Но как и всякий "инструмент" его нужно использовать правильно, ведь хороший и эффективный инструмент в неумелых руках может быть бесполезен или неэффективен. В этой небольшой статье, я поведаю, как его использовать максимально эфективно и какие проблемы, подводные камни могут возникнут при первом знакомстве.

Читать подробнее...



Привет всем!
Не могу никак разобраться с vertex array, либо не рисуется либо, если обращаться по элементо приводит вылету приложения. Причем приложение в debug сессии выдают ошибку обращение к не валидному участку памяти.

Подскажите, что я делаю не так.

Читать подробнее...



Тестирование производительности участка кода. Оценка производительности алгоритма

Иногда бывает необходимость протестировать алгоритм или часть кода, чтоб узнать "не здесь ли тормозит?". А использование профайлера слишком монструозно или не практично. Тогда можно замерить производительность участка кода, прямо в коде. Для этого есть много методов, и все они не без погрешностей.

Читать подробнее...



Всем привет!
Хотелось бы узнать, может кто сталкивался.
Мне нужно отсортировать 2D объекты от рисованных спрайтами на экране по строкам.

Читать подробнее...



Создадим скелет glfw приложения с полноэкранным сглаживанием.

Читать подробнее...



Всем добрый день.
Знает ли кто как в TaoFramework сделать сглаживание как в уроке 46 от NEHE?


Подскажите пожалуйста, есть ли прозрачность в OpenGl? Можно ли сделать кисть,  которая будет рисовать полу-прозрачными тонами?


Пожалуйста подскажите простую книгу или пособие по векторной алгебре.
С толкнулся с нюансами которые без пособии не разберу. Хочу полностью понять как перемножаются матрицы, и какие есть формулы для вычислений связанных с векторной алгеброй. Только, чтоб книга была для новичков в высшей математике или хоть написана простым изложением.=)


Доброго времени суток!!!
У меня такой вопрос. Задали смоделировать взлет ракеты, меня интересует, как можно загрузить модель в openGl и "привязать"  ее к классу, что бы в последствии, можно было вызывать обьект класса, и им манипулировать, необходимо с помошью клавиш управлять ей.  Больше меня интересует, то как привязать модель к классу. Если есть другие варианты, посоветуйте, или книги, где бы описывался этот процесс.


Нас пиарят, но в тоже время копирайтят, хоть и с указанием на источник.

http://www.big-dump.co.de/viewforum.php?f=75


Всем привет.

Сегодня разберем как программировать на самом лучшем эзотерическим языке программирования, а именно BrainFuck.

Читать подробнее...



Друзья, подскажите плиз в чем дело. Значит вот у меня в форме SimpleGLControl. При движении по нему мышью или нажатии клавиш клавиатуры начинается чередование предыдущего и текущего кадров. Можно ли как то побороть сий недуг?


Видео урок по созданию песочных часов в Blender. 1 часть
Для этого потребуется блендер выше 2.5 версии, рекомендую скачать самую новую 2.61

<object width="560" height="315"><param name="movie" value="http://www.youtube.com/v/II7aqKwKS8s?version=3&hl=ru_RU"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/II7aqKwKS8s?version=3&hl=ru_RU" type="application/x-shockwave-flash" width="560" height="315" allowscriptaccess="always" allowfullscreen="true"></embed></object>


В первой части описывается, процесс моделирования во втором уроке мы рассмотрим настройку материалов и света. Кому хоть чуток понравился ставьте плюс!
Это мой первый видео урок поэтому, пожалуйста не придирайтесь сильно, я  очень старался)  
Сразу меняйте качество видео, в стандартом ничего не разобрать.


Недавно на почту получил интересную новость, скоро компьютеры смогут реально видеть и "осознавать" происходящие =))))
Вот копия переведенного письма:

Читать подробнее...



Здравствуйте.

Как-то очень давно мне нужно было сделать в своей программе отправку отчета об ошибке мне на мыло.

В интернете и по сей день нету достойных примеров по решению данно задачи, и в тот же день я принялся писать библиотеку для отправки писем на мыло.

Читать подробнее...



Здравствуйте.Я новичок.Подскажите, кто знает как в этом уроке http://www.render.ru/books/show_book.php?book_id=414 двигать по высоте сегменты полигональной сетки (второй шаг, сразу после слов "Затем надо полученный объект преобразовать в полигональную сетку. После чего перейдите на подуровень Vertex и переместите 2 средних ряда вершин как у меня на рисунке"? А также, как выделять полигоны цельной выдавленной фигуры (следующий шаг) Буду очень признательна)))


Вот решил поделиться исходным кодом игрового движка который нажодится в глубокой стадии разработки.

Спасибо вашему сайту за загрузчик моделей ASE.

Дополняйте, оценевайте, неругайтесь.

Буду благодарен за помощь в развитии проекта.

Читать подробнее...



Ну что тут скажешь. Например нам нужно чтобы когда пользователь нажимал на ЛКМ был слышан выстрел.

Читать подробнее...



Так как еще плоховато ориентируюсь по сайту не обижайтесь на отсутствие скриншотов.

Итак, приступим:

Читать подробнее...



Какой игровой движок будет предпочтительнее?
Привет Всем!
Хотел узнать, какой игровой движок лучше изучать/использовать. Я знаю основы OpenGL вплоть до некоторых возможностей OpenGL 2.0 без шейдеров, написал пару очень простых игр, шахматы с немного недоделанным и туповатым ИИ, змейку, и типо астеройд. Писал на C++  используя GLUT или freeglut, GLEW, audiostate.
   Теперь хочу написать что нибудь посерьезнее и поинтереснее, но никак не могу решиться - изучать, и еще раз изучать API какого-то бесплатного движка.
 К примеру:     Run3, Delta3D, Unity, Crystal Space, clanlib, Cube 2...
Или же писать чисто по игре как делал раньше, на чистом GL. Или все таки написать примитивный движок для моих целей, конкретного жанра.
   Просто взглянув на референсы и екземплы(простые) движков я увидел, что там кода не на много меньше, чем я бы писал на чистом OGL. При том, что делает код не совсем ясно, и мне кажется,что я долго буду изучать любой двиг. И хотелось бы либо помучатся и изучить какой нить не плохой, халявный двиг, чтоб в преть им и пользоваться. Либо всетаки не мучатся с изучением не привычных вещей и продолжить изучать OGL и писать либо свой примитивный двиг, либо писать на чистом OGL для конкретных целей, жанра.
Сразу уточню, меня больше интересуют маленькие, простые игры, казуалки.
Хотелось бы продвинуться в игростроении, но какой путь избрать? Зависеть от движка, или же от собственных знаний?! И так ли двиг упрощает разработку простых игр???
Что можете подсказать?


Кто есть на сайте?
Где админ??!!
Кто хочет поддержать проект уроками?(даже если не может)
ЕСТЬ КТО ЖИВОЙ!?
Сайт мертв?


Кто хочет по участвовать в коллективном проекте??

Мы, группа энтузиастов, приглашаем Вас принять участие в создании стартового проекта однопользовательской, безбашанной игре с элементами экшена, стратегии, фантастики и Tower Defence! Под названием Tracks&Guns.
Eсли вы желаете принять участие для себя или же просто ради опыта, то можете попробовать попрактиковаться в 3D\\2D графике, программировании то мы с радостью приглашаем Вас в свою команду! У нас уже есть много собственных наработок, но мы всегда готовы для свежих идей!
Используемый движок Unity 3D.
Контактное лицо - Руслан.
Skype : Zionter.
E-mail : Ziont.2009@gmail.com


Подскажите, пожалуйста, как скачать готовый проект?


Честно говоря, впервые использую VBO и, возможно, поэтому не вижу причину ошибки. Лишь закомментировав glDrawElements, я не наблюдаю мерцаний на экране, иначе мерцает не только окно приложения, но и вся остальная область экрана, затем падает видеодрайвер. В чём может быть ошибка?

Код такой:

            Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
            Gl.glMatrixMode(Gl.GL_MODELVIEW);
            Gl.glLoadIdentity();

            Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, bufs[0]);
            Gl.glColorPointer(4, Gl.GL_FLOAT, 0, 0);
            
            Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, bufs[1]);
            Gl.glVertexPointer(3, Gl.GL_FLOAT, 0, 0);

            Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, bufs[2]);
            Gl.glNormalPointer(Gl.GL_FLOAT, 0, 0);

            Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, bufs[3]);

            Gl.glEnableClientState(Gl.GL_VERTEX_ARRAY);
            Gl.glEnableClientState(Gl.GL_COLOR_ARRAY);
            Gl.glEnableClientState(Gl.GL_NORMAL_ARRAY);

            Gl.glDrawElements(Gl.GL_TRIANGLES,   
            ElementData.Length,Gl.GL_UNSIGNED_INT, 0);//!!!!

            Gl.glDisableClientState(Gl.GL_VERTEX_ARRAY);
            Gl.glDisableClientState(Gl.GL_COLOR_ARRAY);
            Gl.glDisableClientState(Gl.GL_NORMAL_ARRAY);
            
            OpenGlControl.Invalidate();



Автор: Алексей Боресков
Название: Разработка и отладка шейдеров
Язык: Русский
Год: 2006
Формат: DJVU
Качество: высокое, 600 dpi

Читать подробнее...




Описание и оглавление
Формат: pdf
Тип: для ознакомления перед покупкой
Размер: ~ 6.2 Mb
Язык: Английский
Год 2005

Читать подробнее...



Воспроизведение звуковых файлов, в играх, и не только, с помощью простой и удобной библиотеки audiere (С++)
Звук в игре - одна из основных неотъемлемых составляющих, добавляющая реалистичности и играбельности. Поэтому, звук должен хотя бы присутствовать.
В этом топике я разберу базовый код, для воспроизведения звуковых файлов с помощью библиотеки audiere.

Читать подробнее...



API таймер Часть 2
А теперь мы подробнее разберем дополнительные возможности программирования
с использованием API таймера

Первая часть статьи находиться здесь

Читать подробнее...



Visual basic API timer
Организация игрового цикла с помощью Api таймера на Visual Basic.Net. Точность 1 мс.

Если взять встроенный таймер от Net, то он не дает разрешения срабатывания меньше чем 16 мс!
Да, еще у него разброс срабатывания может растянутся до 55 мс.
Связано это с тем, что у этого таймера низкий приоритет в системе. Например
если сработают другие события Windows, например события клавиатуры,
то система начинает обрабатывать сначала эти события, как более важные, а другие события оставляет на потом!

Читать подробнее...



Предисловие
   Сидел я и программировал разнообразную ерунду, а именно графические фильтры и все что с ними связано, на C#. И потихоньку учил С++. Потом решил я сравнить производительность C# и C++.В тесте будут принимать участие самые распространённые графические фильтры : негатив, сепия, корректировка яркости и контрастности. Написал основу на С++ для загрузки/сохранения изображений с использованием DevIL, и перевел коды фильтров с шарпа на C++. Хотя эта основа наверное далека от идеала.

Читать подробнее...



Эта тема перенесена сюда

http://www.esate.ru/blog/Visual_Basic_Net/320.html


Здравствуйте!
Хочу узнать, есть ли процедура, с помощью которой в OpenGl можно определить отображается полигон или вершина в данный момент на экране или нет?
Это мне нужно для определения проекции сцены на направление наблюдения. Или посоветуйте, если есть какой-то более простой способ.
Заранее спасибо!


Все привет!

Начал писать свою программку, и в самом начале столкнулся с проблемой.
В чем суть - есть сфера, она перемещается по экрану туда-сюда. Когда приложение запущено не в полноэкранном режиме, то все хорошо, но как только переходишь в full screen изображение как бы состоит из нескольких разных кадров, разрезанных по горизонтали и скрепленных вместе. При том, если вызвать диспетчер задач поверх приложения, то все опять работает нормально.
В чем может быть проблема?

Заранее спасибо!


В рамках международной программы «Young creative entrepreneurs» Британский Совет в России и портал "Теории и практики" проводят конкурс для тех, кто работает в следующих областях:
- Разработка и продвижение интерактивных программ, компьютерных игр и приложений для ПК, мобильных устройств,  социальных сетей;
- Разработка социальных сетей, сайтов и онлайн платформ (кроме ресурсов, посвящённых исключительно музыке, моде или дизайну);
- Кинопроизводство, анимация, создание телепередач, работа со спецэффектами;
- Распространение и продажа мультимедийных товаров (телепередач, фильмов, анимации и др.);
- Профессиональные консультации и услуги по развитию и продвижению индустрии мультимедийных технологий.
Победитель поедет в профессиональный тур по Великобритании, в ходе которого посетит Лондонский фестиваль кинои конференцию Power to the Pixel.
Финалисты получат поощрительные призы от бизнес-академии RMA, школы Cinemotion_Labи языкового центра School#1.
Для участия в конкурсе необходимо заполнить заявку и отправить её на адрес Evgenia.Gerasimova@britishcouncil.ru  до 3 июля 2011г.

Жюри конкурса: представители Yota, RMA, Digital October, Greenfield Project, Cinemotion Lab, Cyberbrothers, Habrahabr.


Всем привет.
Сталкнулся с такой траблой: не хочет работать stencil. Вроде все правильно делаю.

Инициализация
private void InitGL()
       {
           float[] pos = { 3, 3, 3, 1 };
           float[] dir = { -1, -1, -1 };

           float[] mat_specular = { 1, 1, 1, 1 };

           Gl.glEnable(Gl.GL_DEPTH_TEST);

           Gl.glEnable(Gl.GL_COLOR_MATERIAL);

           Gl.glEnable(Gl.GL_LIGHTING);
           Gl.glEnable(Gl.GL_LIGHT0);

           Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_POSITION, pos);
           Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_SPOT_DIRECTION, dir);

           Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SPECULAR, mat_specular);
           Gl.glMaterialf(Gl.GL_FRONT, Gl.GL_SHININESS, 128.0f);

           Glut.glutInit();

           ResizeGL();    
       }


private void ResizeGL()
       {
           Gl.glViewport(0, 0, OGLC.Width, OGLC.Height);
           Gl.glMatrixMode(Gl.GL_PROJECTION);
           Gl.glLoadIdentity();
           Gl.glOrtho(-5, 5, -5, 5, 2, 12);
           
           Gl.glMatrixMode(Gl.GL_MODELVIEW);
       }


private void Display()
       {
           

           Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT | Gl.GL_STENCIL_BUFFER_BIT);
           Gl.glLoadIdentity();
           Glu.gluLookAt(0, 0, 5, 0, 0, 0, 0, 1, 0);

           // вращаем сцену
           Gl.glRotated(45, 1, 0, 0);
           Gl.glRotated(45, 0, 1, 0);
           Gl.glRotated(45, 0, 0, 1);

           // разрешаем тест трафарета
           Gl.glEnable(Gl.GL_STENCIL_TEST);

           // рисуем куб и заполняем буффер трафарета единицами
           // в том месте, где рисуется куб
           Gl.glStencilFunc(Gl.GL_ALWAYS, 1, 0);
           Gl.glStencilOp(Gl.GL_KEEP, Gl.GL_KEEP, Gl.GL_REPLACE);
           Glut.glutSolidCube(2.5);
           
           // заполняем буффер трафарета двойками
           // в том месте, где сфера закрывает куб
           Gl.glStencilFunc(Gl.GL_ALWAYS, 2, 0);
           Gl.glStencilOp(Gl.GL_KEEP, Gl.GL_KEEP, Gl.GL_REPLACE);
           Glut.glutSolidSphere(1.5, 20, 20);

           // очищаем буфферы цвета и глубины
           Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
           Gl.glStencilFunc(Gl.GL_EQUAL, 2, 255);
           Gl.glColor3d(1, 1, 1);
           Glut.glutSolidCube(2.5);

           OGLC.Invalidate();
       }

OGLC - сам элемент


Здравствуйте! Столкнулся с тем что на видеокартах Nvidia, после рисования точки(то есть после щелчка по окну и срабатывания функции рисования) точка повяляется на текущем кадре. Если щёлкаем ещё раз, то изображение появляется уже на пустом кадре... И так чередуется. На встроенной видеокарте Intel 946gz всё нормально. Причём на Geforce пробовал на разных и 9600 и 8600...

Вот сам проект, там щёлкаем на карандаш и пробуем нарисовать:
http://cid-2583f3fafd6afb42.skydrive.live.com/self.aspx/.SharedFavorites/dIIIplom.zip


Я установил Tao Framework и вижу 8Мб + 15Мб библиотек без которых ничего не будет работать. Подскажите пожалуйста сразу чтобы я мог оценить сколько весят отдельные части.

1) Сколько в среднем требуется Мб библиотек Tao чтобы написать 3D игру?
2) ...2D игру?
3) ...без звука?
4) ...без физики?
4) ...без шейдеров?


Возникла такая проблема с текстурами
DialogResult res = openFileDialog1.ShowDialog();
            
            // создаем изображение с индификатором imageId
            Il.ilGenImages(1, out imageId);
            // делаем изображение текущим
            Il.ilBindImage(imageId);
                      

            //загрузка изображения
            Il.ilLoadImage("123.jpg");

если убираю строку с открытием диалога файла, которая вообщем то ничего не должна делать, то текстура грузится не хочет, хотя так прекрасно грузится.
Как выйти из этого положения?


В одном SimpleOpenGlControl рисуется непосредственно 3d сцена, необходимо ещё один SimpleOpenGlControl для отрисовки в нём графика изменения некоторой величины . затруднительно рисовать график в том же окне . Сейчас получается ,что окно в котором будет отрисовываться сцена определяется последним вводом команды InitializeContexts

SimpleOpenGlControl GLCGraph,Vid;

GLCGraph.InitializeContexts();
Vid.InitializeContexts();

так отрисовка будет в окне Vid

Vid.InitializeContexts();
 GLCGraph.InitializeContexts();

так в GLCGraph

 Vid.InitializeContexts();
 GLCGraph.InitializeContexts();
 Vid.InitializeContexts();

так тоже сцена рисуется в Vid
причём одновременно в двух окнах хотябы одинаковое изображение рисоваться не хочет. Как сделать так чтобы вторая сцена рисовалась одновременно с первой ,только в другом SimpleOpenGlControl'е??


Всем-всем, добрый день!!!
Есть у меня одна простая задача, которая не решается почти год (не могу сказать, что я этим горжусь :)
Нужно нарисовать КРУГ так, чтобы центр был светлым, а ближе к краям цвет плавно изменялся вплоть до черного (Рис.1)

Рис.1 Окружность залитая монохромным градиентом

И все хорошо если круг такого же размера как и на Рис.1, но как только размер увеличивается или же уменьшается контраст между центром и краями, то выплывают самые некрасивые вещи...

Читать подробнее...



Указал режим дисплея RGBA:

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

Далее пишу:

Gl.glLineWidth(10);
Gl.glColor4f(1, 0, 0, 0.1f);
Gl.glBegin(Gl.GL_LINE_STRIP);
Gl.glVertex2d(lineX, 0);
Gl.glVertex2d(lineX, lineY - 0.5);
Gl.glEnd();
Gl.glBegin(Gl.GL_LINE_STRIP);
Gl.glVertex2d(0, lineY);
Gl.glVertex2d(lineX - 0.5, lineY);
Gl.glEnd();
Gl.glLineWidth(1);

В релузьтате все рисуется, но без альфа-канала((


Конкурс предложен пользователями сайта esate.ru

Условия участия:
Предоставить скриншоты вашего рабочего стола, на скриншотах должно быть:
         1. Рабочий стол
         2. Окно папки
         3. Браузер

Читать подробнее...



Всем привет. У меня возникла проблема. Необходимо вывести русский текст на экран. Никто не сталкивался с этим???


В моей проге, которую я пишу с помощью Tao, нужно рисовать 2D текст. Насколько я понял задача эта вовсе не тривиальная.

Необходимо чтобы я мог задавать шрифт, размер, цвет и язык вывода (мне нужна кириллица). То есть библиотека freeGlut здесь не подойдет (на сколько я понял из урока 5.4 там очень ограниченный набор шрифтов и невозможность использовать кириллицу). Вот тут и начались мои google мытарства. В итоге после многих часов поиска я не обнаружил ни одного внятного способа вывода текста в SimpleOpenGLControl.

Думаю каждому из нас это может понадобиться, поэтому надо основательно разобраться. Вот, например, в Tao есть FreeType. Но, как ей пользоваться? Ни толкового примера найдено не было...

Буду премного благодарен за разъяснение этого вопроса...


Всем привет. Мне опять нужна помощь))
Я столкнулся со следующей проблемой...я рисую сетку из прямоугольников, и на каждый меш накладываю текстуру...Если буду рисовать GL_QUAD_STRIP, то всё хорошо, но если просто GL_QUADS, то границы стаовятся видными.

Как мне исправить это??? Пробовал
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR);

Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_CLAMP_TO_EDGE);
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_CLAMP_TO_EDGE);

не помогло.


Всем привет. Я понимаю то это заезженная тема, но у меня есть проблема.....Вопрос следующий:
Мне нужно перевести координаты WinForm  в координаты GL....я это сделал, но есть косяк, а именно, узнаю координаты верхнего правого угла и правого нижнего угла:
Point3D P1 = ConvertP(new Point(AnT.Width, 0), Z);
Point3D P2 = ConvertP(new Point(AnT.Width, AnT.Height), Z);

где Z - радиус вектор (т.е. расстояние от начала координат до нашей точки). парадокс в том, что координаты p1.X != p2.X, и координаты p1.Y !=p2.Y....Расхождение по X небольшое (начинается с тысячных)....оно меня не волнует так как расхождение по Y (в сотых) т.е например p1.Y=3.508...., а p2.Y=3.538.....
В чем может быть проблема?

вот код:
public static Point3D ConvertP(Point p, double inZ)
        {
            Point3D P1, P2, Dir;
            double x, y, z;

            int vx = p.X, vy = AnTH - p.Y - 1;
            int[] viewport = new int[4];
            double[] projection = new double[16];
            double[] modelview = new double[16];
            Gl.glGetIntegerv(Gl.GL_VIEWPORT, viewport);
            Gl.glGetDoublev(Gl.GL_PROJECTION_MATRIX, projection);
            Gl.glGetDoublev(Gl.GL_MODELVIEW_MATRIX, modelview);
            int[] zz = new int[1];
            Gl.glReadPixels(vx, vy, 1, 1, Gl.GL_DEPTH_COMPONENT, Gl.GL_FLOAT, zz);
            Glu.gluUnProject(vx, vy, 0, modelview, projection, viewport, out x, out y, out z);
            P1 = new Point3D(x, y, z);
            Glu.gluUnProject(vx, vy, 1, modelview, projection, viewport, out x, out y, out z);
            P2 = new Point3D(x, y, z);
            Dir = new Point3D();
            Dir = P1 - P2;
            Dir.Normalize();

            Point3D A = new Point3D(0, 0, 2 * P1.Z + inZ);
            Point3D n = new Point3D(0, 0, -1);
            double t = n * (A - P1);
            Point3D P = P1 + t * Dir;
            double R = Math.Sqrt(P.X * P.X + P.Y * P.Y + P.Z * P.Z);
            double addz = 0;
            while (Math.Abs(R - inZ) > 0.00001)
            {
                double add= Math.Abs(R - inZ);
                if (R > inZ) addz -= add;
                else addz += add;
                A = new Point3D(0, 0, 2 * P1.Z + inZ + addz);
                n = new Point3D(0, 0, -1);
                t = n * (A - P1);
                P = P1 + t * Dir;
                R = Math.Sqrt(P.X * P.X + P.Y * P.Y + P.Z * P.Z);
            }
            return P;
        }

Ну а Point3D это вектор:
class Point3D
    {
        public double X, Y, Z;
        public Point3D()
        {
            this.X = 0;
            this.Y = 0;
            this.Z = 0;
        }
        public Point3D(double X, double Y, double Z)
        {
            this.X = X;
            this.Y = Y;
            this.Z = Z;
        }

        public void Normalize()
        {
            double Lenght = Math.Sqrt(X * X + Y * Y + Z * Z);
            this.X /= Lenght;
            this.Y /= Lenght;
            this.Z /= Lenght;
        }

        #region Перегрузка операторов
        public static Point3D operator +(Point3D P1, Point3D P2)
        {
            Point3D tmp = new Point3D();
            tmp.X = P1.X + P2.X;
            tmp.Y = P1.Y + P2.Y;
            tmp.Z = P1.Z + P2.Z;
            return tmp;
        }
        public static Point3D operator -(Point3D P1, Point3D P2)
        {
            Point3D tmp = new Point3D();
            tmp.X = P1.X - P2.X;
            tmp.Y = P1.Y - P2.Y;
            tmp.Z = P1.Z - P2.Z;
            return tmp;
        }
        public static double operator *(Point3D P1, Point3D P2)
        {
            return P1.X * P2.X + P1.Y * P2.Y + P1.Z * P2.Z;
        }
        public static Point3D operator *(double D, Point3D P)
        {

            Point3D tmp = new Point3D();
            tmp.X = P.X * D;
            tmp.Y = P.Y * D;
            tmp.Z = P.Z * D;
            return tmp;
        }
        #endregion
    }


Как сделать событие перетаскивание? Т.е уменя нарисован кубик, я нажимаю левую кнопку мыши и передвигаю мышь, то объект должен вращаться.

Что-то написал. Но почему-то сразу же выходит после запуска программы.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
// для работы с библиотекой OpenGL 
using Tao.OpenGl;
// для работы с библиотекой FreeGLUT 
using Tao.FreeGlut;
// для работы с элементом управления SimpleOpenGLControl 
using Tao.Platform.Windows;

namespace View3D
{
    public partial class Form1 : Form
    {
        int x, y;
        double AlphaX,AlphaY;
        bool MouseIsDown;
        public Form1()
        {
            AlphaX = 45;
            AlphaY = 45;
            
            InitializeComponent();
            AnT.InitializeContexts();

            Init();
            Draw();
            
            Gl.glFlush();
            AnT.Invalidate();
        }

        private void Init()
        {
            Glut.glutInit();
            Glut.glutInitDisplayMode(Glut.GLUT_RGB | Glut.GLUT_DOUBLE | Glut.GLUT_DEPTH);
            Gl.glClearColor(0, 0, 0, 1);
            Gl.glViewport(0, 0, AnT.Width, AnT.Height);
            Gl.glMatrixMode(Gl.GL_PROJECTION);
            Gl.glLoadIdentity();
            Glu.gluPerspective(45, (float)AnT.Width / (float)AnT.Height, 0.1, 200);
            Gl.glMatrixMode(Gl.GL_MODELVIEW);
            Gl.glLoadIdentity();
            Gl.glEnable(Gl.GL_DEPTH_TEST);
            Glu.gluLookAt(10, 10, 10, 0, 0, 0, 0, 0, 1); 
        }

        private void Draw()
        {
            Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
            Gl.glLoadIdentity();
            Gl.glColor3f(1, 1, 1);
            Gl.glPushMatrix();
            Gl.glTranslated(0, 0, -6);
            Gl.glRotated(AlphaX, 1, 0, 0);
            Gl.glRotated(AlphaY, 0, 1, 0);

            Glut.glutWireCube(2);
            Gl.glColor3f(1, 0, 0);

            DrawAxes(0.5);
            Gl.glPopMatrix();
        }
        private void DrawAxes(double Length)
        {
            Gl.glColor3f(1, 0, 0);
            Gl.glBegin(Gl.GL_LINES);
                Gl.glVertex3d(0,0,0);
                Gl.glVertex3d(Length, 0, 0);
            Gl.glEnd();
            Gl.glColor3f(0, 1, 0);
            Gl.glBegin(Gl.GL_LINES);
                Gl.glVertex3d(0, 0, 0);
                Gl.glVertex3d(0, Length, 0);
            Gl.glEnd();
            Gl.glColor3f(0, 0, 1);
            Gl.glBegin(Gl.GL_LINES);
                Gl.glVertex3d(0, 0, 0);
                Gl.glVertex3d(0, 0, Length);
            Gl.glEnd();
        }

        private void AnT_DragDrop(object sender, DragEventArgs e)
        {
            
        }

        private void AnT_MouseDown_1(object sender, MouseEventArgs e)
        {
            x = e.X;
            y = e.Y;
            MouseIsDown = true;
        }

        private void AnT_MouseUp_1(object sender, MouseEventArgs e)
        {
            MouseIsDown = false;
        }

        private void AnT_MouseMove_1(object sender, MouseEventArgs e)
        {
            if (MouseIsDown)
            {
                AlphaX += Convert.ToDouble(x - e.X);
                AlphaY += Convert.ToDouble(y - e.Y);
                x = e.X;
                y = e.Y;
                Init();
                Draw();
            }
        }
    }
}


Доброго времени суток.
Возникла потребность в создании генератора текстурных координат. Предположим, существует набор вершин произвольного трёхмерного объекта, сложной формы. Так при загрузке или создании подобного объекта, а быть может прямо во время его отрисовки, было бы здорово рассчитать текстурные координаты. Основной проблемой является определение коэффициента масштабирования.

Читать подробнее...



Задумал создать визуализатор.


Буду писать потихоньку. Надеюсь на помошь советами.

Пусть для начала будем считать что грид состит из кубов.
Создаем класс одного кубика
    class Cubic
    {
        public double x, y, z,size,r,g,b;
        public Cubic(double x, double y, double z)
        {

        }
        public void Draw()
        {
            Gl.glPushMatrix();
            Gl.glTranslated(x,y,z);
            Gl.glRotated(45, 1, 0, 1);
            Gl.glColor3d(r, g, b);
            Gl.glBegin(Gl.GL_POLYGON);
                Gl.glVertex3d(size, size, size);
                Gl.glVertex3d(-size, size, size);
                Gl.glVertex3d(-size, -size, size);
                Gl.glVertex3d(size, -size, size);
            Gl.glEnd();
            Gl.glBegin(Gl.GL_POLYGON);
                Gl.glVertex3d(size, size, -size);
                Gl.glVertex3d(size, -size, -size);
                Gl.glVertex3d(-size, -size, -size);
                Gl.glVertex3d(-size, size, -size);
            Gl.glEnd();
            Gl.glBegin(Gl.GL_POLYGON);
                Gl.glVertex3d(-size, size, size);
                Gl.glVertex3d(-size, size, -size);
                Gl.glVertex3d(-size, -size, -size);
                Gl.glVertex3d(-size, -size, size);
            Gl.glEnd();
            Gl.glBegin(Gl.GL_POLYGON);
                Gl.glVertex3d(size, size, size);
                Gl.glVertex3d(size, -size, size);
                Gl.glVertex3d(size, -size, -size);
                Gl.glVertex3d(size, size, -size);
            Gl.glEnd();
            Gl.glBegin(Gl.GL_POLYGON);
                Gl.glVertex3d(-size, size, -size);
                Gl.glVertex3d(-size, size, size);
                Gl.glVertex3d(size, size, size);
                Gl.glVertex3d(size, size, -size);
            Gl.glEnd();
            Gl.glBegin(Gl.GL_POLYGON);
                Gl.glVertex3d(-size, -size, -size);
                Gl.glVertex3d(size, -size, -size);
                Gl.glVertex3d(size, -size, size);
                Gl.glVertex3d(-size, -size, size);
            Gl.glEnd();
            Gl.glPopMatrix();
        }
    }


Есть сцена с несколькими сферами. Необходимо по клику на сфере менять ее цвет.
В 3D новичок и глубоко погружаться времени нету.
Наткнулся на статью: http://opengl.gamedev.ru/articles/?id=101
Переписал, получаю координаты отрезка.
Вопрос, что дальше с ними делать -как выделить сферу? Если можно с примерами:)


Заранее огромное спасибо!


Посоветуйте, пожалуйста, пару книг или ресурсов по OpenGL 3.0


Задача: Построить в одном проекте в двух разных simpleOpenGlControl две поверхности(например два цилиндра).

Делаю поверхности, если по отдельности то всё замечательно сроит, но вместе одну поверхность никак не хочет строить, заметил что не строит ту которая идет первая:

 
 public Form1()
        {
            InitializeComponent();
            simpleOpenGlControl1.InitializeContexts();//тут пусто
            simpleOpenGlControl2.InitializeContexts();//эту построит
            
        }

Читать подробнее...



Думаю, ознакомившись с первой частью этого цикла уроков, можно переходить на второй. И это опять перевод с gpwiki.org. Думаю, данный материал покажется вам полезным и разъяснит, из чего состоит графическое ядро! Случайно заметив его в интернете и узнав много нового, я решил поделится с вами этой ссылкой.

Читать подробнее...



У меня есть сетка. Как можно определять координаты при кликаньи мыши на одну из ячеек?


Есть ли одна процедура типа обратного вызова, такая чтоб там прописал, и перерисовывалось изображение?


Как сделать вот такую штуку
http://img3.imageshack.us/img3/1230/90289944.png
чтоб каждому значению соответствовало значение


В этом уроке разберем как установить IDE Code::Blocks, все необходимые нам библиотеки и скомпилировать проект.

Читать подробнее...



2.1 SystemCore - Application

Думаю из названия понятно, что в этом уроке будет рассматриваться системное ядро, а конкретнее его составляющая - приложение.

Читать подробнее...



1.0 Разбираем двиг

В этом уроке разберем основы двига, что это, зачем он нужен, что в него входит.

Читать подробнее...



0.0 Введение

Привет читателям моего блога, в этом блоге я собираюсь писать уроки по тому как сделать игровой движок.

Читать подробнее...



Скоро напишу урок по двигу, совсем еще толком не знаю про что там буду писать, но буду писать =)) что нить на ходу придумаю, так что в ближайшее время ждите что нить прикольное


У меня есть 3d объект(танк), который загружен в OpenGL. Загружено отдельно башня и остальная часть. Подскажите пожалуйста как сделать так чтобы башня(с танка) поворачивалась в определенную точку в пространстве или подскажите как просчитать матрицу поворота?


У кого нибудь есть идеи как такое можно реализовать? Дерево , Трава Очень хочу такое сделать =)


Интересно как это реализовать? чтоб вторая камера снимала что-то, и то что снимает отображалось на текстуре в реал тайм?


Добрый день,

Чтобы скомпилировать проект, использующий опенжл необходимо:
1.Установить TAO Framework
2.Подключить библиотеки:
TAO.Freglut.dll
TAO.OpenGL.dll
TAO.Platforms.Windows
3.Скопировать в папку Windows:
freeglut.dll

Какже теперь запустить скомпилированный экзешник на другом компьютере? Желательно без установки TAO Framework

Большое спасибо


Попробовал использовать Glut.glutMainLoop(). До этого задаю
Glut.glutDisplayFunc(RenderScene);
Glut.glutReshapeFunc(ChangeSize);
Программа виснет.
Никто не сталкивался?


Камера.

В этом уроке мы научимся создавать класс - камера.
Для этого мы сначала попробуем разобраться с командой библиотеки Glu - GluLookAt. В нашем случаи Glu.gluLookAt.Она принимает три набора
аргументов, которые задают точку наблюдения, прицельную точку (точку, на которую
направлена камера) и направление, которое следует считать верхним.



Пример:
          Glu.gluLookAt(Position.x, Position.y, Position.z, //Позиция самой камеры
                        View.x, View.y, View.z,             //Куда смотрим
                        Up.x, Up.y, Up.z);                  //Верх камеры


Вроде бы все просто. Теперь создадим отдельный класс в нашем приложении - Camera. Сразу подключим пространства и создадим Vertex3D - структуру, где будут храниться X,Y,Z векторов.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Tao.FreeGlut;
using Tao.OpenGl;
using Tao.Platform.Windows;

namespace Engine
{
    class Camera
    {
        private struct Vector3D
        {
            public float x, y, z;
        };
    }
}

Читать подробнее...



Чтоб при разворачивании формы, размеры SimpleOpenGLСontrol менялись тоже?


Они описаны в gl.h. Как возможно подключить gl.h ?
#define GL_POINTS                         0x0000
#define GL_LINES                          0x0001
#define GL_LINE_LOOP                      0x0002
#define GL_LINE_STRIP                     0x0003
#define GL_TRIANGLES                      0x0004
#define GL_TRIANGLE_STRIP                 0x0005
#define GL_TRIANGLE_FAN                   0x0006
#define GL_QUADS                          0x0007
#define GL_QUAD_STRIP                     0x0008
#define GL_POLYGON                        0x0009
Можно в принципе цифры писать, но код будет не читабельный. Кто с этим сталкивался?


В этом уроке мы научимся изменять тон и гамму изображения. Для изменения тона будем использовать цветовую модель HSL.О ней я сейчас расскажу поподробней...

Читать подробнее...



Возможно не совсем корректно задан вопрос, я постараюсь разъяснить. Есть 3D объект, например чайник, я подношу мышку к носику, необходимо выделить носик, если к ручке то ручку и т.д.


И снова я) Создал новый класс, камера, вроде бы все окей, работаю через gluLookAt, крутит, вертит, перемещается, но не могу додумать как сделать стрэйф (движение камеры влево или вправо)

Объявляю:
CCamera cam = new CCamera();


В инициализации:
cam.Position_Camera(0, 5, -10, 0, 0, 0, 0, 1, 0);


В таймере:
            Glu.gluLookAt(cam.mPos.x, cam.mPos.y, cam.mPos.z,
                      cam.mView.x, cam.mView.y, cam.mView.z,
                      cam.mUp.x, cam.mUp.y, cam.mUp.z);

            Gl.glPushMatrix();
            //модели
            Gl.glPopMatrix();


Считываю клаву:
        private void AnT_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.W)
                cam.Move_Camera(0.03f);

            if (e.KeyCode == Keys.S)
                cam.Move_Camera(-0.03f);

            if (e.KeyCode == Keys.A)
                cam.Rotate_Position(0.03f, 0, 1, 0);

            if (e.KeyCode == Keys.D)
                cam.Rotate_Position(-0.03f, 0, 1, 0);

            label2.Text = e.KeyCode.ToString();
        }


Вот сам класс:
        public struct Vector3D
        {
            public float x, y, z;
        };

        class CCamera
        {
            public Vector3D mPos;
            public Vector3D mView;
            public Vector3D mUp;

            static float currentRotX;
            static float lastRotX;

            public void Rotate_Position(float angle, float x, float y, float z)
            {
                mPos.x = mPos.x - mView.x;
                mPos.y = mPos.y - mView.y;
                mPos.z = mPos.z - mView.z;

                Vector3D vVector = mPos;
                Vector3D AVector;

                float SinA = (float)Math.Sin(angle);
                float CosA = (float)Math.Cos(angle);

                // Найдем новую позицию X для вращаемой точки 
                AVector.x = (CosA + (1 - CosA) * x * x) * vVector.x;
                AVector.x += ((1 - CosA) * x * y - z * SinA) * vVector.y;
                AVector.x += ((1 - CosA) * x * z + y * SinA) * vVector.z;

                // Найдем позицию Y 
                AVector.y = ((1 - CosA) * x * y + z * SinA) * vVector.x;
                AVector.y += (CosA + (1 - CosA) * y * y) * vVector.y;
                AVector.y += ((1 - CosA) * y * z - x * SinA) * vVector.z;

                // И позицию Z 
                AVector.z = ((1 - CosA) * x * z - y * SinA) * vVector.x;
                AVector.z += ((1 - CosA) * y * z + x * SinA) * vVector.y;
                AVector.z += (CosA + (1 - CosA) * z * z) * vVector.z;

                mPos.x = mView.x + AVector.x;
                mPos.y = mView.y + AVector.y;
                mPos.z = mView.z + AVector.z;
            }

            public void Move_Camera(float speed)
            {
                Vector3D mmView;
                mmView.x = mView.x - mPos.x;
                mmView.y = mView.y - mPos.y;
                mmView.z = mView.z - mPos.z;

                Vector3D vVector = mmView;  // Get the view vector 

                // Двигаем камеру со скоростью speed
                mPos.x = mPos.x + vVector.x * speed;
                mPos.z = mPos.z + vVector.z * speed;
                mView.x = mView.x + vVector.x * speed;
                mView.z = mView.z + vVector.z * speed;
            }

            public void Move()
            {
                mPos.x = mPos.x + 1;
                mView.x = mView.x + 1;
            }

            public void Rotate_View(float speed)
            {
                Vector3D mmView;
                mmView.x = mView.x - mPos.x;
                mmView.y = mView.y - mPos.y;
                mmView.z = mView.z - mPos.z;

                Vector3D vVector = mmView;  // Получаем вектор View

                mView.z = (float)(mPos.z + Math.Sin(speed) * vVector.x + Math.Cos(speed) * vVector.z);
                mView.x = (float)(mPos.x + Math.Cos(speed) * vVector.x - Math.Sin(speed) * vVector.z);
            }

            public void Position_Camera(float pos_x, float pos_y, float pos_z,
                    float view_x, float view_y, float view_z,
                    float up_x, float up_y, float up_z)
            {
                mPos.x = pos_x;
                mPos.y = pos_y;
                mPos.z = pos_z;
                mView.x = view_x;
                mView.y = view_y;
                mView.z = view_z;
                mUp.x = up_x;
                mUp.y = up_y;
                mUp.z = up_z;
            }
        };

А как стрейф сделать не пойму( может кто знает?


Что-то я запутался, есть у меня класс Objects, определяю его как массив
Objects[] mObject = new Objects[999];

объявляю переменную,

intcreatedObjects; 


чтоб узнать сколько объектов создал и по этой переменной создавать цикл, потом прицепляю к кнопке создания нового объекта

Читать подробнее...



Загрузка трехмерных моделей

Для загрузки из файла трехмерных объектов (Meshs) в OpenGl , нет встроенных решений. Так, как OpenGL- это кросс-платформенная библиотека, которая была написана для вывода графики, а не для работы с файловой системой, потоками....

Поэтому хочу поведать, как грузить удобный, и простой для понимания загрузки, DirectX-совский .X файл. Мы будем использовать связку C# + Tao.Framework, поэтому желательно почитать пару уроков, как ее использовать.

Читать подробнее...



И снова добрый вечер) в этот раз проблема является производительности, неизвестно по каким причинам, при более 1 объекта (простейшего, к прим. куб) в сцене, увеличивается нагрузка на цп. Вот рисую 10 текстурированных кубиков и тормозит очень сильно =(

Читать подробнее...



В этом уроке мы научимся изменять яркость и контрастность изображения.

Пара изображений для примера.

Оригинал


Контрастность + 35

Читать подробнее...



Всем привет! В этом уроке я расскажу, как создать негатив и сепию.

Пример изображения после обработки:



Читать подробнее...



Добрый день, хочу реализовать с помощью OpenGL (Tao Framework) программу которая б создавала атомы в пространстве по указанным координатам (как бы кристаллическую решетку) и можно было манипулировать этими объектами (вращать, передвигать), также надо это сделать компонентом, чтоб можно было просто в другие проекты вставлять, и все это нужно для моего универа. Суть проблемы в том, что вроде все правильно, а работает с глюками. Создает атомы, по координатам, вращает, но через несколько поворотов/созданий, исчезают все атомы кроме первого созданного атома, я пока не понимаю почему так происходит. Работаю без таймера, графика рисуется и обновляется по событию (к примеру кнопки вращения или добавления нового атома).

Читать подробнее...



Читая умные книжки я обнаружил, что там говорится о первом. А именно Gl.glTranslate(), Gl.glRotate(), Gl.glScale() изменяют именно сам объект, а за обзор на него (а точнее - на всю сцену) ответственна функция Glu.gluLookAt(). Потому что первые три преобразуют видовую матрицу, домножая её на соответствующую матрицу преобразований (автоматически внутри этих функций), а потом уже при визуализации координаты каждой точки домножаются на модернизированную видовую матрицу, поэтому эти функции изменяют положение, поворот и масштаб объектов, рисуемых при использовании модернизированной ими видовой матрицы. Glu.gluLookAt() - определяет именно положение камеры наблюдателя: первые три параметра - координаты точки наблюдения (КАМЕРЫ), вторые - центр сцены ВСЕЙ, которая будет проецироваться в центр области вывода, а третие - задают вектор положительного направления оси "У" у ВСЕЙ сцены при проецировании. Таким образом эта команда как бы совершает преобразование всех объектов сцены в целом. Её целесообразно использовать до определения и преобразования всех объектов сцены, пока видовая матрица единичная.

Какие мысли? Просто в уроках OpenGl+C# написано наоборот, вот я и задался вопросом)))


Есть быстрый и удобный способ проиграть видео в прям на форме, с помощью COM элемента Windows Media Player.
Не будет терять лишнее время и приступим сразу к делу.

Читать подробнее...



Всем доброе утро, скажите, почему при зацикливании какого-либо куска кода, ответственного за отрисовку изображение не выводится на экран ? Вот, во всех уроках используется таймер, который в некоторые промежутки времени вызывает функцию отрисовки и это работает.  Но  

Читать подробнее...



Есть ф-ия 2 порядка(3д кривая) надо как то её отобразить С помощью каких методов можно сделать такое?




надо чтобы цилиндр крутился не в начале его основания как показано на присунке а) , а надо чтобы он вращался в центре как показано в b).
Для это надо как то сдвинуть точку отсчета.
Не подскажите как это сделать лучше?


читаю уроки по тао фреймворку. Там есть замечательная ф-ия для отключения освещения. То ест 3-х мерный объект становиться черным пятном. Скажите как можно управлять светом, для искажения этого пятна? То есть есть разное освещение линейное или рассеивающее. Тут какое применяется?
зс


Здравствуйте! не могли бы вы мне помочь. Заранее спасибо за помощь.
Я имею цилиндр.



сначало он под 90 градусов, затем меняю градус относительно х оси. Как видите он изменил форму.

Мне надо определить расстояние 2 картинке(там знак вопроса стоит).
Причем цилиндр- это простая фигура. А может быть вместо него сложная(конус+ цилидр или ещё как -нибудь). Но у них будет всегда точка А и Б - верхняя и нижняя. И между ними надо расстояние определить. Своего рода это проекции(тем более если освещение выключить то будет черная фигура), то есть надо размеры проекции определить. Не знаю понятно ли я выразился, если что переспросите ,если что-то не понятно сказал.


Мне надо как то нарисовать патрон
http://img-fotki.yandex.ru/get/17/glock-23.2/0_c876_e515f3de_XL

как видите у них верхняя часть как конус только  боковые ребра его не прямые линии, а кривые. То есть надо нарисовать как бы выпуклый конус. Как в 3d максе его так деформировать?


можно ли как то распечатать содержимое simpleopenglcontrol?

можно ли как то сохранить содержимое simpleopenglcontrol в фаил?


вот тут сетка
http://www.esate.ru/page/risovanie-grafikov-v-C-sharp-OpenGL
хочу подобную сделать.

            // стартуем отрисовку в режиме визуализации точек 
            // объединяемых в линии (GL_LINE_STRIP) 
            Gl.glBegin(Gl.GL_LINE_STRIP);

            // рисуем начальную точку 
           // Gl.glVertex2d(GrapValuesArray[0, 0], GrapValuesArray[0, 1]);

            // проходим по массиву с координатами вычисленных точек 
            for (int ax = 0; ax < 5; ax++)
            {
                for (int ay = 0; ay < 5; ay++){
                // передаем в OpenGL информацию о вершине, участвующей в построении линий 
                    Gl.glVertex2d(ax , ay );
            }

            }

            // завершаем режим рисования 
            Gl.glEnd();


Делаю так, по логике он должен нарисовать квадрат.
glVertex2d рисует же точку? Но почему то получается такое:

что не так делаю?


Возможно вопрос дурацкий, но я сообразить не могу.
Вот есть цилиндр. Мы его строим так:

void glutSolidCylinder   (    GLdouble    radius,
GLdouble    height,
GLint    slices,
GLint    stacks
)    
    
Draw a solid cylinder.

Parameters:
radius    Radius of the cylinder.
height    Z height.
slices    Divisions around z axis.
stacks    Divisions along z axis.

radius это радиус. height высота. 2 других параметра не совсем ясно зачем. Если дословно переводить ,то деление вокруг оси z и деление вдоль оси z.

Нашел в уроке про трансформации
Glut.glutSolidCylinder(1,2,32,32);

1,2  это что в пикселях? Как бы это же не реально. Мне надо как-то понять сколько пикселей высота и радиус у него.

спасибо


читаю http://www.esate.ru/page/initsializatsiya-opengl-v-c-sharp

И немного решил поиграться с
            Gl.glRotated(antX, antY, antZ, 0);


немного не понимаю как она крутиться. Запутался.

Скажите как грамотно модернизировать
// обработчик кнопки "визуализировать" 
private void button1_Click(object sender, EventArgs e)
{
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);

Gl.glLoadIdentity();
Gl.glColor3f(1.0f, 0, 0);

Gl.glPushMatrix();
Gl.glTranslated(0,0,-6);
Gl.glRotated(45, 1, 1, 0);

// рисуем сферу с помощью библиотеки FreeGLUT 
Glut.glutWireSphere(2, 32, 32);

Gl.glPopMatrix();
Gl.glFlush();
AnT.Invalidate();
}


чтобы ещё рисовались оси (xyz).
Спасибо


Предположим у вас на форме есть кнопка. По её нажатию строиться сложная фигура ,н-р чайник.

Есть 2-ая кнопка. По её нажатию надо нарисовать проекцию этой сложной фигуры.
Не подскажите как?


Никогда не программировала в 3D. В основном базы данных в Visual Studio. Тут приходит начальник и говорит. Хочу такую программу: ща опишу, как смогу.
Значит, есть у меня предположим палуба на корабле, определенного размера. На нее можно загрузить груз определенного размера и веса. Так вот он хочет к примеру ввести высоту, ширину и вес груза, получить фигуру по введенным данным, покрутить ее во все стороны и поставить ее на палубу, ухватив мышкой. Ну и таким образом заставить всю палубу. Не могу понять, с чего начать. Могу ли я реализовать всю эту красоту в Visual Studio. Знаю C#,VB. Заранее спасибо


Компьютерная графика

Как известно, компьютерная графика - это не только OpenGL API. Это еще и множество математических алгоритмов, описывающих поведение света, законы его преломления, методы оптимизации трехмерных сцен, поиска невидимых поверхностей и т.д.







Читать подробнее...



Здравствуйте, поробовал переделать программу из руководства по программированию без корректной реакции на изменение размеров окна, но на экран ничего не выводится : он даже не очищается в заданный цвет. В чем может быть проблема ?

Читать подробнее...



В графическом программирование материалы занимают достаточно важную роль. Материал может рассеивать, отражать и излучать свет.

В этом уроке вы можете узнать основы работы с освещением в OpenGL.

Читать подробнее...



Урок 2. Основы освещения в OpenGL
Ну вот наконец-то и пришел 2 урок =). Задержался он немного, так как были проблемы с жестким диском и с инетом. Но вот вышел второй урок =). В этом уроке я раскажу про освещение.

Читать подробнее...



Всем добрый день!
Вопрос состоит в следующем: нужно узнать реальные размеры (РР) нарисованного на экране (скажем диаметр сферы), как это сделать?

Читать подробнее...



Здравствуйте, участники блога "Новые уроки OpenGL"!
И других блогов (прим. ред. :)

Данный топик создан для тех кто трудится над новыми уроками и, конечно же, для тех кто ожидает выхода *Новинок!  Предлагается в комментариях этого топика размещать названия публикуемых уроков и уроков, которые планируется разработать для публикации в данном блоге. Также по-возможности просьба указывать примерное время выхода новой публикации и суть урока в виде тезисов.

Читать подробнее...





Что мы узнаем в этом уроке
В данном небольшом уроке речь пойдет о работе Ваших приложений, которые используют ТАО, в полноэкранном или как его еще называют игровом режиме.

Читать подробнее...



Цикл  уроков по программированию OpenGL в Linux.Примечаниев первом уроке не будем расматривать CodeBlocks и SDL, но подготовим все до следующих уроковЧасть 0.1 - немного об Linux.<b>

Читать подробнее...



Доброго времени суток!
С OpenGL разбираюсь около года. Всегда появляется одна и та же проблема - при большом количестве рисуемых объектов происходит ну просто МХАТовская пауза. Искал выход в дисплейных списках и массивах вершин, но как с ними нормально работать так и не понял.

Читать подробнее...



Меня давно интересовало, как сделать туман в C# OpenGL. Я видел много статей по созданию тумана, но все они были написаны для С++. Изучая разности синтаксиса C# OpenGL и C++ OpenGL, я догадался, как сделать туман в шарпе.


Читать подробнее...



Уроки предназначены для тех, кто уже хорошо разбирается в C#.    В основном искусственный интеллект (ИИ) сложен из операторов выбора. Основная задача интеллекта, это чаще всего поиск пути. И именно в этом уроке мы поговорим об этом.

Читать подробнее...



Приветствую всех!!!
Итак начну.

Есть такое предложение коллективного создания игр используя допустим знания полученные на сайте. Совместная разработка идеи игр. Совместное распределение ролей!!!
Коментарии преветствуются (что зачем как и нужно ли)

Забыл добавить - если кто согласен или заинтересован - пишите в комментах да и тд


Необходимо создать меш из готового набора точек. Я делал это под DX, но как сделать в GL не имею понятия, кто реализовывал или кто знает как это сделать, подскажите плиз. Заранее спасибо :)


игра двухмерная (вид сверху).

игрок управляет работом.
нижняя часть робота - передвигается по 8 направлениям (север, сереро-запад и тд).
верхняя часть робота - вышка. она вращается вокруг центра робота.
за вращение отвечает позиция мыши. куда курсор туда и направлена вышка.
сейчас вместо нижней части работа ездит квадрат.
как можно поместить в него рисунок робота?

Читать подробнее...



^