LINUX.ORG.RU

OpenGL/GLUT вывод простой картинки

 ,


1

2

Всем привет!

встала задача вывести картинку средствами OpenGL/GLUT без особого использования других библиотек. Не долго думая, получился вот такой код (который рисует белое окно):

#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

GLuint texId;
unsigned char *data;
uint32_t width, height;
void renderScene(void) {

    // Clear Color and Depth Buffers
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Reset transformations
    //glLoadIdentity();
    // Set the camera
    glBindTexture  (GL_TEXTURE_2D, texId); // Set as the current texture
    glTexImage2D   (GL_TEXTURE_2D, 0,GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glBegin(GL_QUADS);
        glTexCoord2d( 0.0,  1.0);   glVertex2d(-1.0, -1.0);
        glTexCoord2d( 0.0,  0.0);   glVertex2d(-1.0,  1.0);
        glTexCoord2d( 1.0,  0.0);   glVertex2d( 1.0,  1.0);
        glTexCoord2d( 1.0,  1.0);   glVertex2d( 1.0, -1.0);
    glEnd();

    glutSwapBuffers();
}

int main(int argc, char **argv) {

    const char* filename=argv[1];
    cv::Mat img = cv::imread(filename);
        width=img.cols;
        height=img.rows;
        data=(unsigned char *)img.data;
    // init GLUT and create window
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowPosition(100,100);
    glutInitWindowSize(320,320);
    glutCreateWindow("Lighthouse3D- GLUT Tutorial");

    // register callbacks
    glutDisplayFunc(renderScene);
    // glutReshapeFunc(renderScene);
    glutIdleFunc(renderScene);

    // enter GLUT event processing cycle
    glutMainLoop();

    return 1;
}

OpenCV здесь чисто для облегчения загрузки картинки и будет позже заменено. В последствии не планируется даже натягивать текстуру на что-то - просто вывод на экран. Вопрос знатокам - что здесь я забыл сделать для вывода картинки?

★★

Зачем это нужно делать каждый кадр?

    glTexImage2D   (GL_TEXTURE_2D, 0,GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

andreyu ★★★★★ ()

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

Как вы собираетесь выводить содержимое текстуры, не «натягивая» ее на что-либо?

А по теме, http://open.gl

andreyu ★★★★★ ()
Ответ на: комментарий от andreyu

Скажем так - мягко говоря, неочевидный мануал. Попробовал скомпилить sample-code отсюда (внизу страницы) - не вышло: мало того, что какие-то нестандартные библиотеки используются (sfml), так еще и код пришлось править. Попробую еще SFML на GLUT переделать, но хз, что выйдет из этого.

aido ★★ ()

glBegin

Зачем так в 2017 году делать?

O02eg ★★★★★ ()
Ответ на: комментарий от aido

Шейдерами, но тебе рано. По теме: glEnable(GL_TEXTURE_2D);

Dendy ★★★★★ ()
Ответ на: комментарий от Dendy

Это ж как надо упороться, чтобы тупую картинку шейдерами рисовать?

anonymous ()
Ответ на: комментарий от anonymous

Генерируй не тупую сразу на видеокарте.

anonymous ()
Ответ на: комментарий от aido

Скажем так - мягко говоря, неочевидный мануал.

Более чем очевидный и доступный для понимания. Разжевано все по шагам.

мало того, что какие-то нестандартные библиотеки используются (sfml)

Не более нестандартные, чем glut.

так еще и код пришлось править.

Что именно пришлось править?

andreyu ★★★★★ ()
Ответ на: комментарий от Dendy

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

А если хочется склеивать две и больше текстур стык-в-стык, то это лучше как рисовать?

aido ★★ ()
Ответ на: комментарий от aido

const char для шейдеров в самом начале.

Может const char* ? В любом случае это warning.

andreyu ★★★★★ ()
Ответ на: комментарий от aido

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

Вы все так же продолжаете грузить данные в текстуру каждый кадр?

А если хочется склеивать две и больше текстур стык-в-стык, то это лучше как рисовать?

clamp to edge.

andreyu ★★★★★ ()
Ответ на: комментарий от andreyu

Теперь так.

Ну точнее вместо GL_REPEAT в LOAD_TEXTURE - GL_CLAMP_TO_EDGE.

между glBegin и end - это то, как я хочу отображать текстуры. Совсем не гибкий способ, но иных пока не знаю=( Хотя в этом месте гибкость мне понадобится.

aido ★★ ()
Последнее исправление: aido (всего исправлений: 2)
Ответ на: комментарий от andreyu

Может const char* ? В любом случае это warning.

g++-4.9.2 сказал, что это ошибка и ему не понравилась буква R в начале строки и отсутствие переносов. Более высокую версию компилера не могу использовать из-за завязки одного из фреймворков на железо.

aido ★★ ()
Ответ на: комментарий от andreyu

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

aido ★★ ()
Ответ на: комментарий от aido

g++-4.9.2 сказал, что это ошибка

Вы уверены, что именно в отсутствии const ошибка?

и ему не понравилась буква R в начале строки и отсутствие переносов.

Ну так строоковые литералы появились в --std=c++11.

andreyu ★★★★★ ()
Ответ на: комментарий от aido

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

Любое изменение gl-стейта - это накладные расходы. Переключение текстуры - это изменение стейта. Если есть возможность использовать атлас, используйте его.

andreyu ★★★★★ ()
Ответ на: комментарий от andreyu

Я не говорил, что в отсутствие const.

В любом случае мы ушли далеко от основной темы. К тому же хочется это всё сделать на чистом Си.

aido ★★ ()
Ответ на: комментарий от aido

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

andreyu ★★★★★ ()
Ответ на: комментарий от andreyu

текстуры меняться будут. переключать состояние придется.

aido ★★ ()
Ответ на: комментарий от aido

Я не говорил, что в отсутствие const.

Значит я неправильно понял это.

К тому же хочется это всё сделать на чистом Си.

Да пожалуйста. Никто же не мешает.

andreyu ★★★★★ ()
Ответ на: комментарий от aido

Можно обновлять данные в текстуре без переключения текстур.

O02eg ★★★★★ ()
Ответ на: комментарий от O02eg

Можно обновлять данные в текстуре без переключения текстур.

Это может оказаться дороже переключения текстур. Но ТС так и не пояснил задачу.

andreyu ★★★★★ ()
Ответ на: комментарий от andreyu

Ок. Конкретная задача: используя только GL, GLU, GLUT, gcc-4.9.2 написать прогу, которая выводила бы несколько картинок в разном разрешении (высота одинаковая, ширина разная) стык-в-стык друг с другом. Картинки меняются часто (раз 10-20 в секунду) и имеют FullHD разрешение. В будущем их надо будет еще нарезать прямо на видеокарте. В какую сторону копать? Шейдеры, атласы, массивы текстур? Пока что у меня основной вопрос - как отобразить N текстур в разном разрешении стык-в-стык и сделать это по возможности гибко (количество текстур варьируется)?

aido ★★ ()
Ответ на: комментарий от aido

Картинки меняются часто (раз 10-20 в секунду) и имеют FullHD разрешение.

Создать текстуры размером с fullhd фрейм. Отправлять в видеокарту только те данные, которые будут видны на экране.
Используя shared context можно обновлять данные текстур в отдельном потоке.

Пока что у меня основной вопрос - как отобразить N текстур в разном разрешении стык-в-стык и сделать это по возможности гибко (количество текстур варьируется)?

Ответ тот же - clamp to edge.

andreyu ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.