Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Программирование игр, графики и искусственного интеллекта > С чего начать - C# + OpenGL


Автор: bc0der 15.4.2007, 17:40
Подскажите пожалуйста как написать хоть самую простую OpenGL программу на C# ? Скачал библиотеку Tao . Дайте пожалуйста примеры , кто писал проги ( самые простые ) .

Автор: WERITAS 16.4.2007, 22:54
ИМХО неудачный выбор языка для работы с графикой. C# - скриптовый язык, и на нем одном хорошее графическое приложение не построишь

Автор: $tatic 16.4.2007, 23:04
На сайте библиотеки http://cs-sdl.sourceforge.net есть порты примеров NeHe для связки SDL.NET + Tao.GL на C#.

Цитата(WERITAS @  16.4.2007,  23:54 Найти цитируемый пост)
C# - скриптовый язык

C# - не скриптовый язык.

Цитата(WERITAS @  16.4.2007,  23:54 Найти цитируемый пост)
на нем одном хорошее графическое приложение не построишь

Ни на чем не основанное заключение. C# свободно справляется и не с такими задачами.

Автор: arilou 17.4.2007, 20:56
WERITAS, 
$tatic, 


M
arilou
Главное, во флейм не сорвитесь

Автор: nerezus 18.4.2007, 16:17
Цитата
C# - скриптовый язык, и на нем одном хорошее графическое приложение не построишь
 Прежде, чем что-то ляпнуть, надо думать, головой.


arilou, $tatic, И вообще мне кажется, что это тролль, см. причины изменения его репутации.

Автор: RWander 12.9.2007, 18:07
Цитата(nerezus @  18.4.2007,  18:17 Найти цитируемый пост)
И вообще мне кажется, что это тролль

 smile

Добавлено через 8 минут и 39 секунд
Цитата(bc0der @  15.4.2007,  19:40 Найти цитируемый пост)
Подскажите пожалуйста как написать хоть самую простую OpenGL программу на C# ?


подключи opengl32.dll и glu32.dll к своему проекту и импортируй те функции, которые тебе необходимы

например:
Код

        [DllImport("opengl32.dll")]   public static extern void glBegin(uint mode);
        [DllImport("opengl32.dll")]   public static extern void gEnd();
        ....


ЗЫ: в списке юсингов необходимо прописать:
Код

using System.Runtime.InteropServices;


хотя, по-моему, tao framework использовать лучше - геморою меньше будет.

Добавлено через 10 минут и 6 секунд
или сразу переходи на XNA framework

Автор: NightmareZ 21.9.2007, 18:55
Цитата(bc0der @  15.4.2007,  17:40 Найти цитируемый пост)
Дайте пожалуйста примеры , кто писал проги ( самые простые ) .


Код

using System;
using Tao.Platform.Windows;
using Tao.OpenGl;
using System.Runtime.InteropServices;

namespace MyFramework
{
    public class RenderException : ApplicationException 
    {
        public RenderException(string s) : base(s) { }
    }

    public class Render: IDisposable
    {
        private IntPtr Handle = IntPtr.Zero;
        private IntPtr dc = IntPtr.Zero;
        private IntPtr hrc = IntPtr.Zero;

        public Render(IntPtr Handle)
        {
            this.Handle = Handle;
            if (Handle == IntPtr.Zero)
            {
                throw new RenderException("Invalid window handle!");
            }

            dc = User.GetDC(Handle);
            if (dc == IntPtr.Zero)
            {
                throw new RenderException("Can't get device context!");
            }

            var pfd = new Gdi.PIXELFORMATDESCRIPTOR();
            pfd.dwFlags = Gdi.PFD_SUPPORT_OPENGL |
                Gdi.PFD_DRAW_TO_WINDOW |
                Gdi.PFD_DOUBLEBUFFER;
            pfd.nVersion = 1;
            pfd.nSize = (short)Marshal.SizeOf(pfd);

            var PixelFormat = Gdi.ChoosePixelFormat(dc, ref pfd);
            if (PixelFormat == 0)
            {
                throw new RenderException("Can't choose pixel format!");
            }

            if (!Gdi.SetPixelFormat(dc, PixelFormat, ref pfd))
            {
                throw new RenderException("Can't set pixel format!");
            }

            hrc = Wgl.wglCreateContext(dc);
            if (hrc == IntPtr.Zero)
            {
                throw new RenderException("Can't create rendering context!");
            }

            if (!Wgl.wglMakeCurrent(dc, hrc))
            {
                throw new RenderException("Can't set current rendering context!");
            }
        }

        ~Render()
        {
            Destructor();
        }

        private void Destructor()
        {
            if (hrc != IntPtr.Zero)
            {
                Wgl.wglMakeCurrent(IntPtr.Zero, IntPtr.Zero);
                Wgl.wglDeleteContext(hrc);
            }

            if (dc != IntPtr.Zero)
            {
                User.ReleaseDC(Handle, dc);
            }

            Handle = IntPtr.Zero;
        }

        public void Dispose()
        {
            GC.SuppressFinalize(this);
            Destructor();
        }

        public void Resize(int Width, int Height)
        {
            Width = Math.Abs(Width);
            Height = Math.Abs(Height);

            if (Width == 0)
            {
                Width = 1;
            }

            if (Height == 0)
            {
                Height = 1;
            }

            Gl.glViewport(0, 0, Width, Height);
            Gl.glMatrixMode(Gl.GL_PROJECTION);
            Gl.glLoadIdentity();
            Glu.gluPerspective(45, (double)Width / (double)Height, 1, 1000);
            Gl.glMatrixMode(Gl.GL_MODELVIEW);
            Gl.glLoadIdentity();
        }

        public void BeginScene()
        {
            Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
        }

        public void EndScene()
        {
            Gdi.SwapBuffers(dc);
        }
    }
}


Код

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;
using MakarovFramework;

namespace MyProject
{
    public partial class Form1 : Form
    {
        private Render render = null;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            render = new Render(Handle);
            render.Resize(Width, Height);
            
        }

        private void Form1_Click(object sender, EventArgs e)
        {
            if (render != null)
            {
                render.BeginScene();

                render.EndScene();
            }
        }

        private void Form1_ResizeEnd(object sender, EventArgs e)
        {
            if (render != null)
            {
                render.Resize(Width, Height);
            }
        }
    }
}

Автор: RWander 22.9.2007, 12:09
NightmareZ, хороший пример +1
есть еще одна очень хорошая http://www.rsdn.ru/article/files/dotnet/OpenGLBase.xml?print по использованию OpenGL в .NET

Автор: arilou 22.9.2007, 19:32
NightmareZ, тока вместо финалайзера надо использовать реализацию IDisposable

Автор: NightmareZ 24.9.2007, 20:46
Цитата(arilou @  22.9.2007,  19:32 Найти цитируемый пост)
NightmareZ, тока вместо финалайзера надо использовать реализацию IDisposable

Дык, как бы, оно и используется.

Автор: RWander 24.9.2007, 20:57
Цитата(NightmareZ @  21.9.2007,  20:55 Найти цитируемый пост)
 var pfd = new Gdi.PIXELFORMATDESCRIPTOR();

а что за "var"? у меня выдает ошибку, говорит пространство имен или тип не найден.

Автор: RWander 24.9.2007, 21:25
а и еще, как с помощью Tao Framework работать с текстурами? есть ли какой-нибудь аналог функции auxDIBImageLoad(char* file) для загрузки текстуры из файла?

Автор: NightmareZ 24.9.2007, 22:43
Цитата(RWander @ 24.9.2007,  20:57)
Цитата(NightmareZ @  21.9.2007,  20:55 Найти цитируемый пост)
 var pfd = new Gdi.PIXELFORMATDESCRIPTOR();

а что за "var"? у меня выдает ошибку, говорит пространство имен или тип не найден.

Юз да Visual Studio 2008. Это C#3.

Просто чтоб не писать
Код

Gdi.PIXELFORMATDESCRIPTOR pfd = new Gdi.PIXELFORMATDESCRIPTOR();

пишем
Код

var pfd = new Gdi.PIXELFORMATDESCRIPTOR();

и тип переменной pfd определяется сам.

Цитата(RWander @ 24.9.2007,  21:25)
а и еще, как с помощью Tao Framework работать с текстурами? есть ли какой-нибудь аналог функции auxDIBImageLoad(char* file) для загрузки текстуры из файла?

Определена ли данная функция в Tao Framework - не знаю. Даже если нет - никто не мешает самому её описать и использовать.

Автор: RWander 25.9.2007, 10:26
 может хотя бы есть какой-нибуь пример по работе с текстурами в tao?

Автор: RWander 25.9.2007, 12:55
Попытался написать загрузку текстуры, вроде правильно, но не работает. Может кто подскажет, в чем проблема?
Код

            int[] texture = new int[1];  // Место для одной текстуры

           //получение массива байтов
            System.IO.Stream str = 
                new System.IO.FileStream(@"img.bmp", System.IO.FileMode.Open); 
            System.IO.BinaryReader br = 
                new System.IO.BinaryReader(str);
            byte[] img_bytes = br.ReadBytes((int)br.BaseStream.Length);
            str.Close();

            // Создание текстуры
            Gl.glGenTextures(1, texture);
            Gl.glBindTexture(Gl.GL_TEXTURE_2D, texture[0]);

            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.glPixelStorei(Gl.GL_UNPACK_ALIGNMENT, 1);
            Glu.gluBuild2DMipmaps(Gl.GL_TEXTURE_2D, Gl.GL_RGB, 57, 64, Gl.GL_RGB, Gl.GL_UNSIGNED_BYTE, img_bytes);

            //должен рисоваться текстурированный треугольник,
            //но вместо это рисуется белый треугольник.
            Gl.glBegin(Gl.GL_TRIANGLES);
            Gl.glTexCoord2f(1, 1); Gl.glVertex2f(1, 1);
            Gl.glTexCoord2f(0, 0); Gl.glVertex2f(0, 0);
            Gl.glTexCoord2f(0, 1); Gl.glVertex2f(0, 1);
            Gl.glEnd();


Автор: arilou 25.9.2007, 15:19
Цитата(NightmareZ @  24.9.2007,  20:46 Найти цитируемый пост)

Дык, как бы, оно и используется. 

Смутила реализация. Обычно делается так:

Код

class A : IDisposable
{
    bool _isDisposed = false;
   
    public void Dispose()
    {
          // dispose of unmanaged resources here
          _isDisposed = true;
     }

     ~A()
     {
          if(!_isDisposed)
               Dispose();
     }
}

Автор: NightmareZ 15.10.2007, 20:38
Цитата(arilou @ 25.9.2007,  15:19)
Цитата(NightmareZ @  24.9.2007,  20:46 Найти цитируемый пост)

Дык, как бы, оно и используется. 

Смутила реализация. Обычно делается так:

Код

class A : IDisposable
{
    bool _isDisposed = false;
   
    public void Dispose()
    {
          // dispose of unmanaged resources here
          _isDisposed = true;
     }

     ~A()
     {
          if(!_isDisposed)
               Dispose();
     }
}

У меня вместо _isDisposed идёт проверка, равны ли dc и hrc нулю, и, если не равны, то освобождаются. Вводить лишнюю переменную тут нет смысла.

Если же ещё больше придираться, то деструктор тут вообще нехорошо использовать. Потому что он скорее всего вызовется после того, как будет закрыто окно.... и вызовется ReleaseDC.... для dc, которого уже нет.

Наверное, стоит в конструктор передавать не Handle окна, а ссылку на экземпляр Form, чтоб класс рендера смог заюзать обработчик OnClosing формы для удаления dc как раз перед тем, как окно будет закрыто.

Автор: arilou 15.10.2007, 22:27
Цитата(NightmareZ @  15.10.2007,  20:38 Найти цитируемый пост)
и вызовется ReleaseDC.... для dc, которого уже нет.

это верно только для Windows Forms, т.к. там куча костылей сделана для того, чтобы не утекали GDI ресурсы.
Цитата(NightmareZ @  15.10.2007,  20:38 Найти цитируемый пост)
Наверное, стоит в конструктор передавать не Handle окна, а ссылку на экземпляр Form, чтоб класс рендера смог заюзать обработчик OnClosing формы для удаления dc как раз перед тем, как окно будет закрыто. 

А вот это верно! Так и надо, т.к. handle может меняться.

Автор: NightmareZ 15.10.2007, 23:38
Цитата(arilou @  15.10.2007,  22:27 Найти цитируемый пост)
это верно только для Windows Forms, т.к. там куча костылей сделана для того, чтобы не утекали GDI ресурсы.

Всмысле?


Цитата(arilou @  15.10.2007,  22:27 Найти цитируемый пост)
А вот это верно! Так и надо, т.к. handle может меняться.

Каким это образом может меняться handle окна?

Автор: arilou 16.10.2007, 09:02
Цитата(NightmareZ @  15.10.2007,  23:38 Найти цитируемый пост)
Всмысле?

В смысле, посмотри Reflector'ом что делает великолепный класс HandleCollector, вроде так называется. В Windows Forms для защиты от дурака (читай "программиста, не вызывающего Dispose у контролов и форм") есть примочка. Она сама освобождает хэндлы, если этого не сделать.

Цитата(NightmareZ @  15.10.2007,  23:38 Найти цитируемый пост)
Каким это образом может меняться handle окна? 

Про событие RecreatingWindowHandle не слышал? Если ты скрываешь окно, то насколько я помню, оно освобождает хэндл. 

ЗЫ. Это мы уже в оффтопике, если есть вопросы, пиши в ПМ.

Автор: galileopro 7.6.2009, 01:05
Помогите разобраться кто-нибудь
я попытался скомпилировать код NightmareZ и наткнулся на следующие ошибки

Error    1    The type or namespace name 'Tao' could not be found (are you missing a using directive or an assembly reference?)    C:\Documents and Settings\Admin\Мои документы\Visual Studio 2008\Projects\OpenGLforC\OpenGLforC\Form1.cs    

Error    2    The type or namespace name 'Tao' could not be found (are you missing a using directive or an assembly reference?)    C:\Documents and Settings\Admin\Мои документы\Visual Studio 2008\Projects\OpenGLforC\OpenGLforC\Form1.cs    

В чем тут дело?

Автор: RWander 7.6.2009, 12:35
скорее всего у тебя не установлен http://www.taoframework.com/downloads (нет необходмых dll-ок в GAC). 

Автор: galileopro 5.7.2009, 03:19
А вот вам еще одна реализация текстуры
Код
private void Coord(int number, double x, double y, double z)
        {
            string File;
            int size=16;
            File = "Texture"+number.ToString()+".bmp";
            byte[, ,] Bits = new byte[size, size, 3];
            Gl.glEnable(Gl.GL_TEXTURE_2D);
            Bitmap bitmap = new Bitmap(File);
            for (int i = 0; i <= size-1; i++)
                for (int j = 0; j <= size-1; j++)
                {
                    Bits[i, j, 0] = bitmap.GetPixel(i, j).R;
                    Bits[i, j, 1] = bitmap.GetPixel(i, j).G;
                    Bits[i, j, 2] = bitmap.GetPixel(i, j).B;
                }

            Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0,
                            Gl.GL_RGB, size, size, 0,
                            Gl.GL_RGB, Gl.GL_UNSIGNED_BYTE, @Bits);
            Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR);
            Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);

            Gl.glPushMatrix();
            Gl.glRotated(-90, 0, 0, 1);
            Gl.glTranslated(-1.0+y/450, -1.0+x/450, z/450);

            Gl.glBegin(Gl.GL_QUADS);

            Gl.glTexCoord2d(0.0, 1.0);
            Gl.glVertex2d(0, 1);

            Gl.glTexCoord2d(0.0f, 0.0f);
            Gl.glVertex2d(0, 0);

            Gl.glTexCoord2d(1.0, 0.0f);
            Gl.glVertex2d(1, 0);

            Gl.glTexCoord2d(1.0f, 1.0f);
            Gl.glVertex2d(1, 1);

            Gl.glEnd();
            Gl.glPopMatrix();
            Gl.glFlush();
        }


Автор: anvi 9.8.2009, 10:32
про работу c ogl в C# можно почитать здесь: http://esate.ru/page.php?where=yroki-OpenGL-c-sharp

правда там только заполняется ресурс и инфа для начинающих, но в принципе ее уже немало  smile 

Автор: RWander 9.8.2009, 10:49
anvi,  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)