Перейти к содержимому
Compvision.ru
mrgloom

минимальный проэкт mfc+opengl+opencv

Recommended Posts

где можно посмотреть минимальный проэкт mfc+opengl+opencv для вывода картинки?

или хотя бы кто нибудь может расписать по шагам как его сделать.

интересуют следующие вопросы:

opencv используется только как загрузчик изображений, потом это дело надо как то преобразовать в форму понятную для opengl.

а чтобы вывести это дело через mfc надо как то встроить в него opengl и вообще на что это должно выводится на picture control или прямо в окно, например можно mfc типа scrollview чтобы вывести несколько картинок в разные места?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А не лучше для этого DevIL использовать(для загрузки картинок)?

Он и преобразование их в текстуры поддерживает.

Кстати, в последних версиях OpenCV есть поддержка OpenGL и текстур. Правда я её не использовал пока.

OpenGl - без разницы куда выводиться, лишь бы контекст устройства был, дальше назначаем на него контекст рендеринга.

Кусок из Buildera, для студии не должно сильно отличаться, контекст и в Африке контекст.


//---------------------------------------------------------------------------
void __fastcall TPanel3D::Init3D(void)
{
TColor Col=clBtnFace;
float R=0.75;
float G=0.75;
float B=0.75;
hdc = GetDC(Handle); // получаем описатель контекста
SetPixelFormatDescriptor(); // установка формата пикселей
hrc = wglCreateLayerContext(hdc,0); // создаем контекст OpenGL
if(hrc == NULL) // если не получилось
ShowMessage("Не удалось создать контекст OpenGL.");
if(wglMakeCurrent(hdc, hrc) == false) // Делаем его текущим
ShowMessage("Не удалось сделать контекст текущим.");
glEnable(GL_DEPTH_TEST); // Включен тест глубины
glDisable(GL_CULL_FACE); // Включен режим отображения только одой стороны
glEnable(GL_NORMALIZE); // Нормализация нормалей
glClearColor(R, G, B, 1.0f); // Цвет очистки экрана
SetupLighting(); // Установка освещения
SetSize(size);// размеры коробки под изображение
Started=true;
BuildFonts();
}
//---------------------------------------------------------------------------
void __fastcall TPanel3D::SetPixelFormatDescriptor()
{
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
24,
0,0,0,0,0,0,
0,0,
0,0,0,0,0,
32,
0,
0,
PFD_MAIN_PLANE,
0,
0,0,
};
PixelFormat = ChoosePixelFormat(hdc, &pfd);
SetPixelFormat(hdc, PixelFormat, &pfd);
}
//---------------------------------------------------------------------------
void __fastcall TPanel3D::SetupLighting()
{
GLfloat MaterialAmbient[] = {0.5, 0.5, 0.5, 1.0};
GLfloat MaterialDiffuse[] = {1.0, 1.0, 1.0, 1.0};
GLfloat MaterialSpecular[] = {0.3, 0.3, .3, 0.3};
GLfloat MaterialShininess[] = {0.5};
GLfloat AmbientLightPosition[] = {100, 100,100, 1.0};
GLfloat LightAmbient[] = {0.5, 0.5, 0.5, 0.7};

glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, MaterialAmbient);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialDiffuse);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, MaterialSpecular);
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, MaterialShininess);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
glLightfv(GL_LIGHT0, GL_POSITION, AmbientLightPosition);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, LightAmbient);

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
glShadeModel(GL_SMOOTH);
if(CullFace){glEnable(GL_CULL_FACE);}
}
//---------------------------------------------------------------------------
void __fastcall TPanel3D::End3D(void)
{
KillFonts();
wglMakeCurrent(NULL, NULL);
wglDeleteContext(hrc);
ReleaseDC(Handle,hdc);
Started=false;
}
//---------------------------------------------------------------------------
[/code]

После этого OpenGL должен рисовать на этом контексте.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

не знаю как насчет Devil, просто удобно загружать и обрабатывать изображения в OpenCV, есть текущий старый проэкт на MFC+GDI хочется переписать на OpenGL, тем более хочется иметь минимальный проэкт для тестов opengl+opencv.

нашел проэкт под консоль без mfc

http://blog.damiles.com/2008/10/opencv-opengl/

проверил работает, правда с параметрами вывода картинки в opengl пока не разобрался.

//#include <windows.h>

#include <stdio.h>


#include <GL/glut.h>

#include <gl/GL.h>


#include <ctype.h>

#include "cv.h"

#include "highgui.h"


GLuint texture; //the array for our texture

IplImage *imagenText1;

GLfloat angle = 0.0;


//The IplImage to OpenGl texture function

int loadTexture_Ipl(IplImage *image, GLuint *text) {


    if (image==NULL) return -1;


    glGenTextures(1, text);


	glBindTexture( GL_TEXTURE_2D, *text ); //bind the texture to it's array

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);


	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);


    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image->width, image->height,0, GL_BGR_EXT/*GL_BGR*/, GL_UNSIGNED_BYTE, image->imageData);

    return 0;


}


void plane (void) {

	glBindTexture( GL_TEXTURE_2D, texture ); //bind the texture

    glRotatef( angle, 1.0f, 1.0f, 1.0f );

    glBegin (GL_QUADS);

    glTexCoord2d(0.0,0.0); glVertex2d(-1.0,-1.0); //with our vertices we have to assign a texcoord

    glTexCoord2d(1.0,0.0); glVertex2d(+1.0,-1.0); //so that our texture has some points to draw to

    glTexCoord2d(1.0,1.0); glVertex2d(+1.0,+1.0);

    glTexCoord2d(0.0,1.0); glVertex2d(-1.0,+1.0);

    glEnd();


}


void display (void) {


	glClearColor (0.0,0.0,0.0,1.0);

    glClear (GL_COLOR_BUFFER_BIT);

    glLoadIdentity();  

    gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

    glEnable( GL_TEXTURE_2D ); //enable 2D texturing

    plane();

    glutSwapBuffers();

    angle =angle+0.01;

}


void FreeTexture( GLuint texture )

{

  glDeleteTextures( 1, &texture );

}


void reshape (int w, int h) {

    glViewport (0, 0, (GLsizei)w, (GLsizei)h);

    glMatrixMode (GL_PROJECTION);

    glLoadIdentity ();

    gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0);

    glMatrixMode (GL_MODELVIEW);

}


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

    glutInit (&argc, argv);

    glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE);

    glutInitWindowSize (500, 500);

    glutInitWindowPosition (100, 100);

    glutCreateWindow ("A basic OpenGL Window");

	glutDisplayFunc (display);

    glutIdleFunc (display);

    glutReshapeFunc (reshape);


	imagenText1=cvLoadImage("1.PNG");


	//The load iplimage to opengl texture

	loadTexture_Ipl( imagenText1, &texture ); 


	glutMainLoop ();


	//Free our texture

    FreeTexture( texture );


    return 0;

} 

я не очень понимаю, с этими контекстами, но ладно допустим что он один и тот же однотипный и его может использовать либо GDI либо OpenGL.

выводить как текстуру это стандартный прием?

если изображений много и мы скажем их загрузили в память(через OpenCV), то потом если мы их будем много раз повторно выводить, то как они хранится должны, я так предполагаю не как просто RAW RGB, а уже преобразованные в текстуры и лежать на видеокарте?

что если вывели допустим эти изображения и нам надо сверху еще вывести векторную графику? это можно выводить поверх или надо как то транслировать в текстуры на каждом шаге?

пока попробую создать проэкт scrollview и вывести туда пару картинок.

п.с. а как можно определить тип проэкта уже у существующего проэкта MFC?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Да, это стандартный способ вывод растровых изображений в openGL.

Да, изображения загружаются на видеокарту и затем выводятся по требованию.

Векторную графику можно выводить. Глубиной управляет Z координата (сцена все равно не плоская).

Формат текстур, обычный для OpenGL это RGBA.

Ваш кусок программы написан с использованием GLUT, он обеспечивает вспомогательные функции (цикл обработки сообщений), и это не очень то совместимо с оконным циклом. Так что придется использовать чистый OpenGL, без GLUT-овских функций (каллбэки разные).

Лучшей книгой по OpenGL считаю: opengl red book русская версия.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

да чего то не удалось запустить в mfc проэкте.

тут http://www.kencocomputers.com/tutorials/OpenGLLesson1.aspx как я понимаю просто по кнопке вызывается окно которое рисуется глутом, а нам надо чтобы опенжл рисовал внутри окна самого mfc.

ну тогда

у меня есть тестовый мфс проэкт там функция для отрисовки

void CtestView::OnDraw(CDC* /*pDC*/)

{

	//всякая инициализация  не проверял

        //___________________________________

	CtestDoc* pDoc = GetDocument();

	ASSERT_VALID(pDoc);

	if (!pDoc)

		return;


	HGLRC m_hglrc;

	PIXELFORMATDESCRIPTOR pfd;

	int iPixelFormat;

	CDC *pDC;

	pDC = this->GetDC();

	memset(&pfd, 0, sizeof(pfd));

	pfd.nSize = sizeof(pfd);

	pfd.nVersion = 1;

	pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;

	pfd.iPixelType = PFD_TYPE_RGBA;

	pfd.iLayerType = PFD_MAIN_PLANE;

	pfd.cDepthBits = 16;

	iPixelFormat = ChoosePixelFormat(pDC->m_hDC, &pfd);

	SetPixelFormat(pDC->m_hDC, iPixelFormat, &pfd);

	m_hglrc = wglCreateContext(pDC->m_hDC);

	wglMakeCurrent(pDC->m_hDC, m_hglrc);

	ReleaseDC(pDC);

//конец инициализации

//___________________________________


        //используем старую функцию и делаем из IplImage текстуру

        IplImage* img= cvLoadImage("1.PNG");

	//The load iplimage to opengl texture

	LoadTexture_Ipl( img, &texture ); 

	display(); //тут каким то образом надо отобразить текстуру

	//Free our texture

        FreeTexture( texture ); //вроде как не должны удалять и создавать текстуру при каждой отрисовке, а сделать это только в инициализации



//потом рисуем всякую геометрию для теста получается поверх всего

	////_________________________________________________

	//// TODO: add draw code for native data here

	//CRect clientRect;

	//GetClientRect(&clientRect);

	//glViewport(0, 0, clientRect.right, clientRect.bottom);  // точка наблюдения? или область для обновления?


	//glClearColor (0.25, 0.25, 0.45, 1.0);	// цвет фона

	//glClear (GL_COLOR_BUFFER_BIT);	// очистка буфера цвета


	//glPointSize (10);			// размер точек

	//glColor3f (1.0, 0.0, 0.5);		// текущий цвет примитивов

	//glBegin (GL_POINTS);

	//	glVertex2f (-1, -1);

	//	glVertex2f (-1, 1);

	//	glVertex2f (0, 0);

	//	glVertex2f (1, -1);

	//	glVertex2f (1, 1);

	//	glVertex2f (-0.5, -0.5);

	//	glVertex2f (-0.5, 0.5);

	//	glVertex2f (0.5, -0.5);

	//	glVertex2f (0.5, 0.5);

	//glEnd();

	//glBegin(GL_QUADS);

	//	glLineWidth(10);

	//	glColor3d(1,0,0);     // красный цвет

	//	glVertex3d(0,0,0); // первая линия

	//	glVertex3d(0,1,0);

	//	glVertex3d(1,1,0);

	//	glVertex3d(1,0,0);

	//glEnd();

	//glBegin(GL_LINES);  // странные координаты

	//	glEnable(GL_LINE_SMOOTH);

	//	glLineWidth(10);

	//	glColor3d(1,0,0);     // красный цвет

	//	glVertex3d(0,0,0); // первая линия

	//	glColor3d(0,1,0);     // зеленый

	//	glVertex3d(1,1,0);

	//	//glColor3d(0,1,0);     // зеленый

	//	//glVertex3d(-3,3.3,0); // вторая линия

	//	//glVertex3d(-4,3.4,0);

	//	glDisable(GL_LINE_SMOOTH);

	//glEnd();

	////_________________________________________________

}

вообщем осталось понять как выводить текстуру без глута и как рисуются линии и т.д. поверх всего?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

в проэкте который выводит сплайны так сделано, единственное что там не используются текстуры.

void CMFCSplineView::OnDraw(CDC* pDC)

{

	CMFCSplineDoc* pDoc = GetDocument();

	ASSERT_VALID(pDoc);


	// Make the rendering context current

	wglMakeCurrent(m_hDC,m_hRC);


	// Call to the rendering function

	MainRenderScene();


	// Swap our scene to the front

	SwapBuffers(m_hDC);


	// Allow other rendering contexts to co-exist

	wglMakeCurrent(m_hDC,NULL);


	// TODO: add draw code for native data here

}

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

все оказалось довольно просто

void DrawTexture(GLuint texture)

{

	glEnable(GL_TEXTURE_2D);

	glBindTexture(GL_TEXTURE_2D,texture);

	//Соответственно включают режим текстурирования и выбирают текстуру по номеру из тех, что лежат в буфере.

	glBegin(GL_QUADS);

	glTexCoord2d(0.0,0.0); glVertex2d(-1.0,-1.0); //with our vertices we have to assign a texcoord

    glTexCoord2d(1.0,0.0); glVertex2d(+1.0,-1.0); //so that our texture has some points to draw to

    glTexCoord2d(1.0,1.0); glVertex2d(+1.0,+1.0);

    glTexCoord2d(0.0,1.0); glVertex2d(-1.0,+1.0);

	glEnd();


	glDisable(GL_TEXTURE_2D);

}

но с координатами относительно окна MFC и размерами изображения пока непонятно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

просто надо ставить не +1 и -1, а 0 и размер контекста. И viewport настроить под это дело.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте учётную запись или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать учётную запись

Зарегистрируйтесь для создания учётной записи. Это просто!

Зарегистрировать учётную запись

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×