Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Загружаю .bmp в Drawing::Bitmap, потом в текстуру, Как правильно это реализовать? 
V
    Опции темы
Arks
Дата 26.9.2006, 16:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 197
Регистрация: 7.5.2006
Где: Барнаул

Репутация: нет
Всего: нет



OpenGL.
Собственно, у меня реализовано следующим образом:
Код

bool LoadTextureFromFile(System::String *filename, UInt32 &Texture, Int32 TextureQuality)
{
    //BITMAP_FILE_PTR bmp = new BITMAP_FILE;
    System::Drawing::Bitmap *bmp = new System::Drawing::Bitmap(filename);
    UInt32 pxls[] = __gc new UInt32[bmp->Height*bmp->Width*3];
    
    for(Int32 i=0; i<bmp->Height; i++)
        for(Int32 j=0; j<bmp->Width; j++)
        {
            // Мне нужен массив пикселей в формате GL_RGB
            Int32 clr = bmp->GetPixel(j,i).ToArgb();
            pxls[(i*bmp->Width+j)*3] = (clr >> 16) & 0xFF;
            pxls[(i*bmp->Width+j)*3+1] = (clr >> 8) & 0xFF;
            pxls[(i*bmp->Width+j)*3+2] = clr & 0xFF;
        }
    
    char *fn = (char*)Marshal::StringToHGlobalAnsi(filename).ToPointer();
    UInt32 __pin *pxl = &pxls[0];
    GLuint __pin *texture = &Texture;
    Marshal::FreeHGlobal((int)fn);
    glGenTextures(1,texture);
    glBindTexture(GL_TEXTURE_2D,Texture);
    glTexImage2D(GL_TEXTURE_2D,0,3,bmp->Width,bmp->Height,0,GL_RGB,GL_UNSIGNED_BYTE,pxl);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,TextureQuality);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,TextureQuality);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
    return true;
}


Похоже, что код работает неправильно. Где может быть ошибка? Или как более эффективно можно это реализовать?
PM MAIL ICQ Skype MSN   Вверх
mr.DUDA
Дата 26.9.2006, 16:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Разве в OpenGL нет функции, загружающей битмап ? Или хотя бы какую-нибудь библиотеку типа devIL поюзать.


--------------------
user posted image
PM MAIL WWW   Вверх
Arks
Дата 26.9.2006, 18:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 197
Регистрация: 7.5.2006
Где: Барнаул

Репутация: нет
Всего: нет



Нет. Да и мне потом понадобится другие форматы грузить. Мне сейчас хотя бы в любом формате бы сделать.
PM MAIL ICQ Skype MSN   Вверх
$tatic
Дата 26.9.2006, 21:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 28.1.2005

Репутация: 2
Всего: 22



А почему ты для этого используешь именно .NET. Может тебе правда лучше будет другую, более удобную графическую библу. Или же совсем перейти на .NET. Возможно помесь управляемого и неуправляемого кода и глючит.
PM MAIL   Вверх
mr.DUDA
Дата 26.9.2006, 21:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Не совсем понимаю, чем синтаксически указатель в C++/CLI отличается от ссылки на объект (и там и там используется * ), но можно залочить битмап (LockBits, с указанием формата пикселов) и работать с ним через указатель на буфер (адрес в BitmapData.Scan0) - так будет в десятки (если не больше) раз быстрее, чем через Get/SetPixel. И вместо StringToHGlobalAnsi можно юзать тот же буфер, что возвращает LockBits, кстати.


--------------------
user posted image
PM MAIL WWW   Вверх
Arks
Дата 28.9.2006, 13:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 197
Регистрация: 7.5.2006
Где: Барнаул

Репутация: нет
Всего: нет



Про LockBits спасибо. А как это для String сделать, он же вроде специализировано только для Bitmap сделан? А StringToHGlobalAnsi - это из мсдн, там написано так в char * переводить...
Ещё про LockBits. Битмап в .net хранится в формате ARGB, но в OpenGL такого формата нет! Что тут можно сделать?
И вообще тот код в принципе верен, или нет?

[quote]Не совсем понимаю, чем синтаксически указатель в C++/CLI отличается от ссылки на объект (и там и там используется * )[/qoute]
Ссылка (обозначение: &) - автоматически разименовываемый указатель.
PM MAIL ICQ Skype MSN   Вверх
Dmitriy_Donetsk
Дата 28.9.2006, 13:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 28.9.2006

Репутация: нет
Всего: нет



PM MAIL   Вверх
mr.DUDA
Дата 28.9.2006, 17:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Цитата(Arks @  28.9.2006,  13:16 Найти цитируемый пост)
А как это для String сделать, он же вроде специализировано только для Bitmap сделан? А StringToHGlobalAnsi - это из мсдн, там написано так в char * переводить...

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

Цитата(Dmitriy_Donetsk @  28.9.2006,  13:41 Найти цитируемый пост)
[email protected]

это к чему ?  smile 

Цитата(Arks @  28.9.2006,  13:16 Найти цитируемый пост)
Ссылка (обозначение: &) - автоматически разименовываемый указатель.

Это я знаю, с С++ знаком  smile

Другое имел ввиду:
Цитата
System::Drawing::Bitmap *bmp = new System::Drawing::Bitmap(filename);


Это что - ссылка ? Или указатель, как в обычном С++ ? Просто к примеру в шарпе указатель это указатель, а ссылка это ссылка. А в С++/CLI похоже понятия слегка слились, т.к. сказать про bmp что это указатель и например кастовать его в void*... хм-м... можно ли ?


--------------------
user posted image
PM MAIL WWW   Вверх
Arks
Дата 28.9.2006, 18:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 197
Регистрация: 7.5.2006
Где: Барнаул

Репутация: нет
Всего: нет



Понял, в связи с чем у тебя вопросы по строке. Я закоментированные строки вырезал. Раньше я преобразовывал String *filename в char *fn, чтобы передать неуправляемой функции, сейчас же эти преобразования, конечно, пустая трата ресурсов компа... (И строк в посте  smile  )

Цитата
Это что - ссылка ? Или указатель, как в обычном С++ ? Просто к примеру в шарпе указатель это указатель, а ссылка это ссылка. А в С++/CLI похоже понятия слегка слились, т.к. сказать про bmp что это указатель и например кастовать его в void*... хм-м... можно ли ?


В 2003ей Студии - да. Указатели и ссылки в ней такие же как и в обычном С++ (в 2005ой, по умолчанию, уже нет, но я не на ней пишу). Тут две проблемы с конвертом к void*:
1) Если к неуправляемому типу, то надо юзать __pin, да и не всегда и это выручает (пример строк, где только через Маршалинг).
2) Drawing::Bitmap - класс, так что там не только массив цветов в argb формате лежит...

Вообще, у меня сейчас появилась такая мысль: загружу тот же битмап таким же образом и отображу на форме 2мя способами. Сразу будет видно, тут ли собака зарыта.
Отпишусь, как сделаю.
PM MAIL ICQ Skype MSN   Вверх
Arks
Дата 15.10.2006, 12:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 197
Регистрация: 7.5.2006
Где: Барнаул

Репутация: нет
Всего: нет



Так, руки наконец-то дошли до этого...  smile 

Попробовал загружать один и тот же битмап двумя способами:
1) на PictureBox
2) в массив (в формат rgb), потом на форму рисовать. К сожалению не нашёл ничего похожего на DrawPoint или PutPixel... Так что записывал в другой битмап и на другой PictureBox.
Код

Form1(void)
        {
            InitializeComponent();
            bmp = new System::Drawing::Bitmap(S"bmp1.bmp");
            bmp1 = new System::Drawing::Bitmap(bmp->Width,bmp->Height);
            this->pictureBox1->Image = bmp;

            // Open bmp1 in RGB format
            UInt32 pxls[] = __gc new UInt32[bmp->Height*bmp->Width*3];
            width = bmp->Width;
            height = bmp->Height;
            for(Int32 i=0; i<bmp->Height; i++)
                for(Int32 j=0; j<bmp->Width; j++)
                {
                    
                    Int32 clr = bmp->GetPixel(j,i).ToArgb();
                    pxls[(i*bmp->Width+j)*3] = (clr >> 16) & 0xFF;
                    pxls[(i*bmp->Width+j)*3+1] = (clr >> 8) & 0xFF;
                    pxls[(i*bmp->Width+j)*3+2] = clr & 0xFF;
                }
            // Copy it into bmp
            for(Int32 i=0; i<height; i++)
                for(Int32 j=0; j<width; j++)
                {
                    bmp1->SetPixel(j,i,Color::FromArgb(pxls[(i*width+j)*3],pxls[(i*width+j)*3+1],pxls[(i*width+j)*3+2]));
                }
                this->pictureBox2->Image = bmp1;
        }

Обе картинки одинаковые. Но самое интерес smile ное происходит, когда я изменяю второй цикл:
Код

for(Int32 j=0; j<height; j++)
                for(Int32 i=0; i<width; i++)

Оба PictureBox'a всё равно отображают одну и ту же картинку. Т.е. никаких различий! Либо я совсем туп, либо студия там чего мутит сама...  smile   Но не должно же быть одинакого, когда считываешь наоборот всё!!!

Ну да ладно. Вернусь к месту, где всё это загружаю. В функции glTexImage2D я указал GL_UNSIGNED_BYTE, хотя массив pxls в unsigned int... Результат:
user posted image
Если же поменять на GL_UNSIGNED_INT, как и следовало бы по идее, то ничего не рисуется вообще  smile 
А должно быть так:
user posted image

П.С.: А DevIL, что ранее упоминался бесплатный?

Это сообщение отредактировал(а) Arks - 15.10.2006, 12:22
PM MAIL ICQ Skype MSN   Вверх
mr.DUDA
Дата 16.10.2006, 10:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Arks, что-то ты намутил с форматом цветов.

Цитата(Arks @  15.10.2006,  12:21 Найти цитируемый пост)
П.С.: А DevIL, что ранее упоминался бесплатный?

абсолютно бесплатный (лицензия GNU LGPL)
http://openil.sourceforge.net/
порт под .NET


--------------------
user posted image
PM MAIL WWW   Вверх
Arks
Дата 16.10.2006, 11:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 197
Регистрация: 7.5.2006
Где: Барнаул

Репутация: нет
Всего: нет



Спасибо большое.  smile
Попробую девилом сделать.
PM MAIL ICQ Skype MSN   Вверх
Arks
Дата 17.10.2006, 08:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 197
Регистрация: 7.5.2006
Где: Барнаул

Репутация: нет
Всего: нет



Всё ништяк. Правда, пришлось кучу багов в других местах также пофиксить smile , но всё работает
PM MAIL ICQ Skype MSN   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0524 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.