Jump to content
Compvision.ru
Sign in to follow this  
mrgloom

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

Recommended Posts

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

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

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

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

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

Share this post


Link to post
Share on other sites

А не лучше для этого 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 должен рисовать на этом контексте.

Share this post


Link to post
Share on other sites

не знаю как насчет 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?

Share this post


Link to post
Share on other sites

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

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

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

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

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

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

Share this post


Link to post
Share on other sites

да чего то не удалось запустить в 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();

	////_________________________________________________

}

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

Share this post


Link to post
Share on other sites

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

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

}

Share this post


Link to post
Share on other sites

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

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 и размерами изображения пока непонятно.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×