
Создание 2d игры на C# при помощи OpenGL
игра двухмерная (вид сверху).
игрок управляет работом.
нижняя часть робота - передвигается по 8 направлениям (север, сереро-запад и тд).
верхняя часть робота - вышка. она вращается вокруг центра робота.
за вращение отвечает позиция мыши. куда курсор туда и направлена вышка.
сейчас вместо нижней части работа ездит квадрат.
как можно поместить в него рисунок робота?[spoiler]
пытаюсь так:
<pre class="prettyprint">
// текстурный объект
public uint mGlTextureObject = 0;
// индефекатор текстуры
public int imageId = 0;
public Form1()
{
InitializeComponent();
AnT.InitializeContexts();
}
private void Form1_Load(object sender, EventArgs e)
{
Glut.glutInit();
Glut.glutInitDisplayMode(Glut.GLUT_RGB | Glut.GLUT_DOUBLE);
Il.ilInit();
Il.ilEnable(Il.IL_ORIGIN_SET);
Gl.glClearColor(255, 255, 255, 1);
Gl.glViewport(0, 0, AnT.Width, AnT.Height);
Gl.glMatrixMode(Gl.GL_PROJECTION);
Gl.glLoadIdentity();
Glu.gluOrtho2D(0.0, AnT.Width, 0.0, AnT.Height);
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();
//Gl.glEnable(Gl.GL_DEPTH_TEST);
//Gl.glEnable(Gl.GL_LIGHTING);
//Gl.glEnable(Gl.GL_LIGHT0);
Il.ilGenImages(1, out imageId);
Il.ilBindImage(imageId);
if (Il.ilLoadImage("1.jpg"))
{
int width = Il.ilGetInteger(Il.IL_IMAGE_WIDTH);
int height = Il.ilGetInteger(Il.IL_IMAGE_HEIGHT);
int bitspp = Il.ilGetInteger(Il.IL_IMAGE_BITS_PER_PIXEL);
switch (bitspp)
{
case 24:
mGlTextureObject = MakeGlTexture(Gl.GL_RGB, Il.ilGetData(), width, height);
break;
case 32:
mGlTextureObject = MakeGlTexture(Gl.GL_RGBA, Il.ilGetData(), width, height);
break;
}
Il.ilDeleteImages(1, ref imageId);
RenderTimer.Start();
Thread thP = new Thread(deystvie);
thP.Start();
}
else
{
Application.Exit();
}
}
private static uint MakeGlTexture(int Format, IntPtr pixels, int w, int h)
{
// индетефекатор текстурного объекта
uint texObject;
// генерируем текстурный объект
Gl.glGenTextures(1, out texObject);
// устанавливаем режим упаковки пикселей
Gl.glPixelStorei(Gl.GL_UNPACK_ALIGNMENT, 1);
// создаем привязку к только что созданной текстуре
Gl.glBindTexture(Gl.GL_TEXTURE_2D, texObject);
// устанавливаем режим фильтрации и повторения текстуры
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_REPEAT);
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_REPEAT);
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.glTexEnvf(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_MODE, Gl.GL_REPLACE);
// создаем RGB или RGBA текстуру
switch (Format)
{
case Gl.GL_RGB:
Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGB, w, h, 0, Gl.GL_RGB, Gl.GL_UNSIGNED_BYTE, pixels);
break;
case Gl.GL_RGBA:
Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA, w, h, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, pixels);
break;
}
// возвращаем индетефекатор текстурного объекта
return texObject;
}
public bool bUp = false;
public bool bRight = false;
public bool bDown = false;
public bool bLeft = false;
public static int Nap = 0;
private void RenderTimer_Tick(object sender, EventArgs e)
{
Draw();
}
private void Draw()
{
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);
//Gl.glClearColor(255, 255, 255, 1);
Gl.glColor3f(255, 0, 0);
Gl.glLoadIdentity();
Gl.glEnable(Gl.GL_TEXTURE_2D);
Gl.glBindTexture(Gl.GL_TEXTURE_2D, mGlTextureObject);
Gl.glPushMatrix();
Gl.glBegin(Gl.GL_QUADS);
Gl.glVertex2d(player.posX - player.width / 2, player.posY - player.height / 2);
Gl.glTexCoord2f(0, 0);
Gl.glVertex2d(player.posX - player.width / 2, player.posY + player.height / 2);
Gl.glTexCoord2f(0, 1);
Gl.glVertex2d(player.posX + player.width / 2, player.posY + player.height / 2);
Gl.glTexCoord2f(1, 1);
Gl.glVertex2d(player.posX + player.width / 2, player.posY - player.height / 2);
Gl.glTexCoord2f(1, 0);
Gl.glEnd();
//Gl.glFlush();
Gl.glPopMatrix();
Gl.glDisable(Gl.GL_TEXTURE_2D);
AnT.Invalidate();
}
static Robots player = new Robots();
</pre>

получается только красный квадрат
как в него поместить рисунок из файла?
игрок управляет работом.
нижняя часть робота - передвигается по 8 направлениям (север, сереро-запад и тд).
верхняя часть робота - вышка. она вращается вокруг центра робота.
за вращение отвечает позиция мыши. куда курсор туда и направлена вышка.
сейчас вместо нижней части работа ездит квадрат.
как можно поместить в него рисунок робота?[spoiler]
пытаюсь так:
<pre class="prettyprint">
// текстурный объект
public uint mGlTextureObject = 0;
// индефекатор текстуры
public int imageId = 0;
public Form1()
{
InitializeComponent();
AnT.InitializeContexts();
}
private void Form1_Load(object sender, EventArgs e)
{
Glut.glutInit();
Glut.glutInitDisplayMode(Glut.GLUT_RGB | Glut.GLUT_DOUBLE);
Il.ilInit();
Il.ilEnable(Il.IL_ORIGIN_SET);
Gl.glClearColor(255, 255, 255, 1);
Gl.glViewport(0, 0, AnT.Width, AnT.Height);
Gl.glMatrixMode(Gl.GL_PROJECTION);
Gl.glLoadIdentity();
Glu.gluOrtho2D(0.0, AnT.Width, 0.0, AnT.Height);
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();
//Gl.glEnable(Gl.GL_DEPTH_TEST);
//Gl.glEnable(Gl.GL_LIGHTING);
//Gl.glEnable(Gl.GL_LIGHT0);
Il.ilGenImages(1, out imageId);
Il.ilBindImage(imageId);
if (Il.ilLoadImage("1.jpg"))
{
int width = Il.ilGetInteger(Il.IL_IMAGE_WIDTH);
int height = Il.ilGetInteger(Il.IL_IMAGE_HEIGHT);
int bitspp = Il.ilGetInteger(Il.IL_IMAGE_BITS_PER_PIXEL);
switch (bitspp)
{
case 24:
mGlTextureObject = MakeGlTexture(Gl.GL_RGB, Il.ilGetData(), width, height);
break;
case 32:
mGlTextureObject = MakeGlTexture(Gl.GL_RGBA, Il.ilGetData(), width, height);
break;
}
Il.ilDeleteImages(1, ref imageId);
RenderTimer.Start();
Thread thP = new Thread(deystvie);
thP.Start();
}
else
{
Application.Exit();
}
}
private static uint MakeGlTexture(int Format, IntPtr pixels, int w, int h)
{
// индетефекатор текстурного объекта
uint texObject;
// генерируем текстурный объект
Gl.glGenTextures(1, out texObject);
// устанавливаем режим упаковки пикселей
Gl.glPixelStorei(Gl.GL_UNPACK_ALIGNMENT, 1);
// создаем привязку к только что созданной текстуре
Gl.glBindTexture(Gl.GL_TEXTURE_2D, texObject);
// устанавливаем режим фильтрации и повторения текстуры
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_REPEAT);
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_REPEAT);
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.glTexEnvf(Gl.GL_TEXTURE_ENV, Gl.GL_TEXTURE_ENV_MODE, Gl.GL_REPLACE);
// создаем RGB или RGBA текстуру
switch (Format)
{
case Gl.GL_RGB:
Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGB, w, h, 0, Gl.GL_RGB, Gl.GL_UNSIGNED_BYTE, pixels);
break;
case Gl.GL_RGBA:
Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA, w, h, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, pixels);
break;
}
// возвращаем индетефекатор текстурного объекта
return texObject;
}
public bool bUp = false;
public bool bRight = false;
public bool bDown = false;
public bool bLeft = false;
public static int Nap = 0;
private void RenderTimer_Tick(object sender, EventArgs e)
{
Draw();
}
private void Draw()
{
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);
//Gl.glClearColor(255, 255, 255, 1);
Gl.glColor3f(255, 0, 0);
Gl.glLoadIdentity();
Gl.glEnable(Gl.GL_TEXTURE_2D);
Gl.glBindTexture(Gl.GL_TEXTURE_2D, mGlTextureObject);
Gl.glPushMatrix();
Gl.glBegin(Gl.GL_QUADS);
Gl.glVertex2d(player.posX - player.width / 2, player.posY - player.height / 2);
Gl.glTexCoord2f(0, 0);
Gl.glVertex2d(player.posX - player.width / 2, player.posY + player.height / 2);
Gl.glTexCoord2f(0, 1);
Gl.glVertex2d(player.posX + player.width / 2, player.posY + player.height / 2);
Gl.glTexCoord2f(1, 1);
Gl.glVertex2d(player.posX + player.width / 2, player.posY - player.height / 2);
Gl.glTexCoord2f(1, 0);
Gl.glEnd();
//Gl.glFlush();
Gl.glPopMatrix();
Gl.glDisable(Gl.GL_TEXTURE_2D);
AnT.Invalidate();
}
static Robots player = new Robots();
</pre>

получается только красный квадрат
как в него поместить рисунок из файла?
измени код отрисовки квадрата таким образом, чтобы сначала шли координаты текстуры, потом вершины (сейчас наоборот)
Gl.glTexCoord2f(0, 0);
Gl.glVertex2d(player.posX - player.width / 2, player.posY - player.height / 2);
Gl.glTexCoord2f(0, 1);
Gl.glVertex2d(player.posX - player.width / 2, player.posY + player.height / 2);
Gl.glTexCoord2f(1, 1);
Gl.glVertex2d(player.posX + player.width / 2, player.posY + player.height / 2);
Gl.glTexCoord2f(1, 0);
Gl.glVertex2d(player.posX + player.width / 2, player.posY - player.height / 2);
Gl.glEnd();
(команды с установкой текстурных координат перед командами установки вершин)?
Отрисовка так
Gl.glBegin(Gl.GL_QUADS);
Gl.glTexCoord2f(0, 0);
Gl.glVertex2d(0,0);
Gl.glTexCoord2f(0, 1);
Gl.glVertex2d(0, 355);
Gl.glTexCoord2f(1, 1);
Gl.glVertex2d(355, 355);
Gl.glTexCoord2f(1, 0);
Gl.glVertex2d(355,0);
Gl.glEnd();
все отрисовалось:
надо использовать картинки размерами кратными степени двойки (64х64,128х128).
нижняя часть работа нарисована.
как поверх неё рисовать верхнюю часть?
она имеет сложную структуру.
потом делаешь это все в фотошопе и рисуешь должно все получиться
там через косинусы синусы всякие
сейчас если найду то напишу (С++) я думаю не сложно будет переделать
float M_PI = 3.14159265
Gl.glBegin(Gl.GL_LINE);
for (int a = 0; a < 36; a++)
{
float x = cos(a * M_PI / 18);
float y = sin(a * M_PI / 18);
GL.glVertex2f(x + x, y + y);
x = 1 * cos((a + 1) * M_PI / 18);
y = 1 * sin((a + 1) * M_PI / 18);
GL.glVertex2f(x + x, y + y);
}
GL.glEnd();
ток не знаю библиотеку которая понимает косинусы и синусы
должно работать
if (tab_w[i].such)
{
Gl.glBindTexture(Gl.GL_TEXTURE_2D, textures[2]);
Gl.glBegin(Gl.GL_LINE_LOOP);
for (int j = 0; j < 180; j++)
{
double angle = 2 * Math.PI * j / 180;
Gl.glTexCoord2d((Math.Cos(angle) + 1) / 2, (Math.Sin(angle) + 1) / 2);
Gl.glVertex2d(tab_w[i].x + tab_w[i].width * Math.Cos(angle), tab_w[i].y + tab_w[i].width * Math.Sin(angle));
}
Gl.glEnd();
}
вместо GL_LINE_LOOP нужно использовать GL_POLYGON
private void Draw()
{
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);
Gl.glClearColor(0, 255, 0, 1);
Gl.glLoadIdentity();
Gl.glEnable(Gl.GL_TEXTURE_2D);
Gl.glPushMatrix();
Gl.glViewport(-player.posX+AnT.Width/2, -player.posY+AnT.Height/2, AnT.Width, AnT.Height);
камера движется за пользователем, но как только пользователь выезжает за первоночальный размер поля фигура исчезает.
как это исправить?
как карту сделать? как в стратегиях типа WarCraft
и еще класс Б, в нем массив объектов класса А и функции для обращения к ним (для перемещения, скрытия, отрисовки и т.д.)
+ отдельный класс для земной поверхности (ее лучше дробить на квадраты, и отрисовывать только те, которые видны из камеры.
{
Form1.Focus();
}
если не подводит память )