Визуализировать красный прямоугольник поверх 2D-текстуры в OpenGL.

Я много искал на этом сайте, но не мог точно найти, в чем именно моя проблема. В большинстве подобных задач использовалась консоль и библиотека Glut. Но так как я новичок в OpenGL и MFC и начал с комбинации MFC, они не смогли мне сильно помочь.

Я настраиваю класс COpenGLcontrol здесь, в codeguru для моих личных целей. Вот полный адаптированный курс, но если вы не заинтересованы в его загрузке, нет проблем, я объясню части, которые связаны. Это может занять некоторое время, поэтому я надеюсь, что вы будете терпеливы!

Прежде всего, я должен сказать вам, что моя цель рисования такого прямоугольника состоит в том, что я хочу создать два экземпляра класса в своей программе. введите описание изображения здесь
в меньшем окне изображение всегда будет в режиме zoom extent, но в большем во-первых, у пользователя есть возможность выполнять различные навигационные задачи. Таким образом, каждый раз, когда, например, изображение панорамируется или масштабируется, функция OnDraw большего экземпляра the extent rectangle будет вычисляться и передаваться в меньшее окно и отображаться там, чтобы показать, где мы находимся на таком большом изображении в целом.

Я выполнил следующие действия:
Изменение стека матрицы проекций и имитация 2D-сцены

void COpenGLControl::OnSize(UINT nType, int cx, int cy)
{
wglMakeCurrent(hdc, hrc);
CWnd::OnSize(nType, cx, cy);

if (0 >= cx || 0 >= cy || nType == SIZE_MINIMIZED) return;
oglWindowWidth = cx;
oglWindowHeight = cy;
// Map the OpenGL coordinates.
glViewport(0, 0, oglWindowWidth, oglWindowHeight);

// Projection view
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Set our current view perspective
glOrtho(-oglWindowWidth/2, oglWindowWidth/2, -oglWindowHeight/2,oglWindowHeight/2, 1, -1);
// Model view
glMatrixMode(GL_MODELVIEW);
wglMakeCurrent(NULL, NULL);
}  

Изменение стека матрицы представления модели и настройка камеры (кажется, что мы смотрим в отрицательное направление оси Z)

void COpenGLControl::OnDraw(CDC *pDC)
{
// TODO: Camera controls
wglMakeCurrent(hdc,hrc);
glLoadIdentity();
gluLookAt(0,0,1,0,0,0,0,1,0);
glTranslatef(m_fPosX, m_fPosY, 0.0f);
glScalef(m_fZoom,m_fZoom,1.0);
setViewRectangle();
if (WantToDrawRectangle)
    DrawRectangleOnTopOfTexture();
wglMakeCurrent(NULL, NULL);
}  

строка setViewRectangle() предназначена для вычисления vector<int>ViewRectangle одного из общедоступных данных-членов класса, и, если пользователь хочет, vector<int>RectangleToDraw другие общедоступные данные-члены будут использоваться для рисования прямоугольника. Это потому, что мы не хотим в большом окне рисовать такой прямоугольник, а в меньшем делаем. И меньший будет использовать данные большего.Но я еще не реализовал, как передавать эти данные в реальном времени между двумя экземплярами класса!
Так что пока просто для пробы класса, я установил начальное значение RectangleToDraw следующим образом, и поскольку окно представляет собой [0,0,573,543], установленное glOrtho, я думаю, что прямоугольник должен быть нарисован в центре, в верхней части текстуры. Но это не так.
в любом случае
Код для применения текстуры, которая будет вызываться в OnTimer

void COpenGLControl::oglDrawScene(void)
{
wglMakeCurrent(hdc, hrc);
float x0 = -ImageWidth/2; // top left corner of image
float y0 = ImageHeight/2;
float x1 = x0 + ImageWidth; // bottom right corner of image
float y1 = y0 - ImageHeight;

glBegin(GL_TRIANGLE_STRIP);
{
    glTexCoord2f(0,1);glVertex2f(x0, y1);
    glTexCoord2f(0,0);glVertex2f(x0, y0);
    glTexCoord2f(1,1);glVertex2f(x1, y1);
    glTexCoord2f(1,0);glVertex2f(x1, y0);
}
glEnd();
wglMakeCurrent(NULL, NULL);
}  

Код для вычисления ViewRectangle, который будет передан другому экземпляру класса

void COpenGLControl::setViewRectangle()
{
ViewRectangle.at(0) = m_fPosX - oglWindowWidth*m_fZoomInverse/2;
ViewRectangle.at(1) = m_fPosY - oglWindowHeight*m_fZoomInverse/2;
ViewRectangle.at(2) = m_fPosX + oglWindowWidth*m_fZoomInverse/2;
ViewRectangle.at(3) = m_fPosY + oglWindowHeight*m_fZoomInverse/2;
}  

Код для рисования прямоугольника поверх текстуры

void COpenGLControl::DrawRectangleOnTopOfTexture()
{
wglMakeCurrent(hdc, hrc);
glColor3f(1.0f,0.0f,0.0f);
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
glBegin(GL_QUADS);
   glVertex3f(RectangleToDraw.at(0),RectangleToDraw.at(1),0.5);
   glVertex3f(RectangleToDraw.at(0),RectangleToDraw.at(3),0.5);
   glVertex3f(RectangleToDraw.at(2),RectangleToDraw.at(3),0.5);
   glVertex3f(RectangleToDraw.at(2),RectangleToDraw.at(1),0.5);
glEnd();
SwapBuffers(hdc);
wglMakeCurrent(NULL, NULL);
}  

даже использование glVertex2f в приведенной выше функции не имеет никакого значения, и в обоих случаях я сталкиваюсь с:
введите описание изображения  здесь
Не путайте. Причина того, что в обоих окнах применяется неправильный рисунок, заключается в том, что я установил в конструкторе:

WantToDrawRectangle = true;  
RectangleToDraw.at(0) = -100;
RectangleToDraw.at(1) = -100;
RectangleToDraw.at(2) = 100;
RectangleToDraw.at(3) = 100;  

просто для того, чтобы попробовать нарисовать прямоугольник поверх текстуры. Наверняка после написания правильного кода я установлю их в истинный режим. Просто скажи мне

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


person Sepideh Abadpour    schedule 27.08.2013    source источник
comment
Какую версию OpenGL вы используете?   -  person evenex_code    schedule 28.08.2013


Ответы (1)


Поскольку edge flags устарели в современном OpenGL, я бы не стал использовать режим заливки многоугольников для рисования контуров. Если я правильно понимаю ваш снимок экрана, вы получаете линии на внутренних краях двух треугольников, используемых для рисования прямоугольника.

Вместо этого нарисуйте красный GL_LINE_LOOP, который использует 4 угла вашего прямоугольника... это предпочтительный метод по соображениям переносимости, поскольку GL_QUADS также устарел.

glColor3f     (1.0f, 0.0f, 0.0f);
glBegin       (GL_LINE_LOOP);
   glVertex3f (RectangleToDraw.at (0), RectangleToDraw.at (1), -1.0f);
   glVertex3f (RectangleToDraw.at (0), RectangleToDraw.at (3), -1.0f);
   glVertex3f (RectangleToDraw.at (2), RectangleToDraw.at (3), -1.0f);
   glVertex3f (RectangleToDraw.at (2), RectangleToDraw.at (1), -1.0f);
glEnd         ();

Кроме того, ваш скриншот, похоже, страдает от попытки текстурировать контур. Отключите GL_TEXTURE_2D, прежде чем рисовать линии.

person Andon M. Coleman    schedule 28.08.2013
comment
принял ваш совет, но нарисован только заполненный красный прямоугольник, больше, чем изображение при каждом увеличении. - person Sepideh Abadpour; 28.08.2013
comment
@sepideh: Это не имеет никакого смысла, вы использовали GL_LINE_LOOP? - person Andon M. Coleman; 28.08.2013
comment
да, кажется, я должен изучить библиотеку перенасыщения и сначала сделать рисунки, используя перенасыщение, а затем использовать свой опыт в этой программе! - person Sepideh Abadpour; 28.08.2013
comment
@sepideh: О, я думаю, что произошло то, что вы забыли установить glColor3f (...) обратно на что-то разумное (вероятно, 1.0f, 1.0f, 1.0f) и снова включить GL_TEXTURE_2D. Помните, что OpenGL — это довольно простой конечный автомат, у него есть раздражающее свойство использовать текущие состояния и связывать, а затем изменять. В устаревшем OpenGL всегда есть Attribute Stacks (например, glPushAttrib (...) и glPopAttrib (...)). - person Andon M. Coleman; 28.08.2013
comment
спасибо @Andone M.Coleman, но не могли бы вы немного объяснить мне, как здесь используются Attribute Stacks и что это такое? На самом деле Как мне изучить OpenGL, чтобы не путаться в деталях и задавать вопросы по каждой детали? - person Sepideh Abadpour; 28.08.2013
comment
@sepideh: Ну, в данный момент вы изучаете устаревший OpenGL, такие вещи, как glBegin (...), glEnable (GL_TEXTURE_2D) и т. Д., Все недействительны в современном OpenGL. Если вы хотите изучить современный OpenGL, arc Synthetic.org/gltut кажется довольно популярным. У него более высокая кривая обучения, потому что вы ничего не можете делать без шейдеров, и этот класс управления MFC OpenGL, который вы использовали, в конечном итоге придется переписать, чтобы получить основной контекст OpenGL. Но, наверное, лучше не изучать старый API, если можно этого избежать. - person Andon M. Coleman; 28.08.2013
comment
хорошо, спасибо @Andon M.Coleman Вы имеете в виду, что существуют более новые версии таких классов? На самом деле я и один из моих друзей соревнуемся в выполнении проекта, и мой друг нашел класс, который полностью реализует эту часть программы, но сколько бы я ни искал в Интернете, я просто нашел этот класс для рендеринга opengl в управлении MFC. - person Sepideh Abadpour; 28.08.2013
comment
давайте продолжим это обсуждение в чате - person Andon M. Coleman; 29.08.2013