Проблема с C ++ OpenGL SDL - PullRequest
       20

Проблема с C ++ OpenGL SDL

3 голосов
/ 08 октября 2011

Я снова вернулся с, вероятно, маленькой проблемой, которую я не могу решить, пока предпринимаю свое приключение OpenGL / SDL.

Эта программа вызывает экран SDL 640x480px, но естьвнутри ничего нет, даже фон, он прозрачен для всего, что находится на экране позади него, и я должен признаться, я не уверен, хотя, возможно, это еще одна глупая ошибка.

#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>

SDL_Event event;

int main (int argc, char **argv)

{

bool quit = false;

init();
draw_square(0,0,0);

while (quit == false)

    {

        if( event.type == SDL_QUIT )

            {

                quit = true;

            }

    }

SDL_Quit();

return 0;

}

void init ()

{

SDL_Init(SDL_INIT_EVERYTHING);
SDL_SetVideoMode(640,480,32,SDL_OPENGL);
SDL_WM_SetCaption( "OpenGL Test", NULL );

glClearColor( 0, 0, 0, 0 );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( 0, 0 , 640 , 480, 0, 1 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();

}

void draw_square (int x, int y, int z)

{

glTranslatef(x,y,z);

glColor4f(1.0,1.0,1.0,1.0);

glBegin(GL_QUADS);

    glVertex3f(0, 0 ,0);
    glVertex3f(50,0 ,0);
    glVertex3f(50,50,0);
    glVertex3f(0, 50,0);

glEnd();

glPushMatrix();

}

Большое спасибо~ Майкл

Ответы [ 3 ]

4 голосов
/ 08 октября 2011

Вы не очищаете экран, несмотря на настройку чистого цвета.Вам нужен вызов как glClear (GL_COLOR_BUFFER_BIT);на самом деле выполнять очистку.

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

0 голосов
/ 08 октября 2011
#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>

SDL_Event event;

int main (int argc, char **argv)
{
    bool quit = false;

Вы должны действительно вызвать SDL_Init, а не делегировать его в какую-либо функцию инициализации.В противном случае somebode (вы?) Может измениться, когда init вызывается и прерывает вашу программу.Действительно, ваша основная функция - ваша функция инициализации.Создание окна должно происходить в функции с именем create_window или чем-то в этом роде.

    init();

Технически вызывающий draw_square, или любая функция рисования вне цикла событий вызывает проблемы.Эффект, который вы видите: Хорошо, что это происходит, если ваше окно становится видимым (изначально показано), но любые события, сообщающие программе, что содержимое должно быть обновлено, потому что они были перезаписаны, не имеют никакого эффекта.Всегда вызывайте функции рисования из цикла событий.Для статических отрисовок в ответ на события отрисовки, для анимированных сцен в секции ожидания.

    draw_square(0,0,0);

    while (quit == false) {
        if( event.type == SDL_QUIT ) {
            quit = true;
        }
    }

    SDL_Quit();

    return 0;
}

void init ()    
{

    SDL_Init(SDL_INIT_EVERYTHING);
    SDL_SetVideoMode(640,480,32,SDL_OPENGL);
    SDL_WM_SetCaption( "OpenGL Test", NULL );

Это наиболее распространенное заблуждение новичка, что OpenGL "инициализирован".Следующие вызовы предназначены для настройки сцены , то есть в начале функции рисования.

Вам также не хватает:

  • настройка области просмотра
  • фактически очищает сцену ( glClearColor только сообщает, какой цвет очистить при фактическом вызове очистки; технически он просто устанавливает некоторый "регистр", но не выполняется).

Так что их здесь не следует вызывать

    glClearColor( 0, 0, 0, 0 );
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    glOrtho( 0, 0 , 640 , 480, 0, 1 );
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
}

void draw_square (int x, int y, int z) {

    glTranslatef(x,y,z);

    glColor4f(1.0,1.0,1.0,1.0);

    glBegin(GL_QUADS);

        glVertex3f(0, 0 ,0);
        glVertex3f(50,0 ,0);
        glVertex3f(50,50,0);
        glVertex3f(0, 50,0);

    glEnd();

Следующая строка - это большой WTF ?!

    glPushMatrix();

Каждый стек матрицытолчок должен быть сбалансирован с помощью операции pop (glPopMatrix).Однако нажатие на матрицу имеет смысл, только если за ней следует какое-то преобразование.Что это не так.Если бы вы вызывали draw_square в цикле, вы бы исчерпали максимальную глубину стека матрицы в пределах от 32 до 128 итераций (более вероятно, при меньших числах).

}
0 голосов
/ 08 октября 2011

Вы передали 0 для альфы в вызове glClearColor . Попробуйте "1".

Это делает весь экран прозрачным. Я бы не ожидал, что это на самом деле сработает, но так приятно знать. :)

...