|
Chapter 7
|
7.4 MFC-приложение - MFC AppWizardЭтот тип приложения обладаетя всеми достоинствами и недостаками WinAPI-приложения, рассмотренного выше, так как MFC - это библиотека классов С++, т.е. надстройка над WinAPI. Кто-нибудь, конечно, скажет, что приложение на плюсах немеренно большое, работает медленно и MFC для ленивых. В общем, тут у каждого свое мнение. Каждый по-своему прав. Тем не менее, я считаю, что для каждой задачи требуется свой инструмент. Где-то лучше использовать MFC, где-то WinAPI. Кричать, что первое или второе является незаменимым средством на все случаи жизни было бы неверным. У MFC есть свои особенности, отнести которые к достоинствам или недостаткам однозначно нельзя. В зависимости от решаемой задачи они идут в плюс или минус. Согласитесь,что глупо забивать сапожный гвоздь кувалдой или же скобу сапожным молотком. Создаем проект:
В CMFCView объявите закрытую(private) переменную hGLRC типа HGLRC. Там же объявите функцию int SetWindowPixelFormat(HDC) и открытую(public) функцию display. Вот, что должно получиться:
class CMFCView : public CView
{
private:
CClientDC *pdc;
HGLRC hGLRC;
int SetWindowPixelFormat(HDC);
public:
void display();
...
Вставьте код этой функции в файл MFCView.cpp. Код возьмите из предыдущего раздела. Отредактируйте функцию CMFCView::PreCretaeWindow следующим образом: BOOL CMFCView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
cs.style |= (WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
return CView::PreCreateWindow(cs);
}
Добавьте также функцию display сюда:
void CMFCView::display()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glTranslated(0.01,0,0);
glColor3d(1,0,0);
auxSolidSphere( 1 );
glFinish();
SwapBuffers(wglGetCurrentDC());
}
Теперь запустите View->Class Wizard и добавьте обработчик WM_CREATE,WM_DESTROY
и WM_SIZE в класс CMFCView. Отредактируйте их следующим образом:
int CMFCView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
pdc = new CClientDC(this);
if(SetWindowPixelFormat(pdc->m_hDC)==FALSE)
return -1;
hGLRC = wglCreateContext(pdc->m_hDC);
if(hGLRC == NULL)
return -1;
if(wglMakeCurrent(pdc->m_hDC, hGLRC)==FALSE)
return -1;
glEnable(GL_ALPHA_TEST);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
float pos[4] = {3,3,3,1};
float dir[3] = {-1,-1,-1};
glLightfv(GL_LIGHT0, GL_POSITION, pos);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, dir);
return 0;
}
void CMFCView::OnDestroy()
{
if(wglGetCurrentContext()!=NULL)
wglMakeCurrent(NULL, NULL) ;
if(hGLRC!=NULL)
{
wglDeleteContext(hGLRC);
hGLRC = NULL;
}
delete pdc;
CView::OnDestroy();
}
void CMFCView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
glViewport(0,0,cx,cy);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho(-5,5, -5,5, 2,12);
gluLookAt( 0,0,5, 0,0,0, 0,1,0 );
glMatrixMode( GL_MODELVIEW );
}
Пояснения смотри в предыдущих разделах. В StdAfx.h включите заголовочные
файлы, после строчки #include <afxext.h>
#include <gl/gl.h> #include <gl/glu.h> #include <gl/glaux.h>Запустите еще раз Class Wizard и добавьте функцию OnIdle в класс CMFCApp. Эта функция вызывается всякий раз, когда очередь сообщений окна пуста. Отредактируйте ее: BOOL CMFCApp::OnIdle(LONG lCount)
{
( (CMFCView*) ((CMainFrame*)m_pMainWnd)->GetActiveView() )->display();
return 1;//CWinApp::OnIdle(lCount);
}
![]() Исходный файл смотрите здесь. Исполняемый файл здесь. |
7.5 Java-апплеты - Magician Library
Достоинством данного типа приложения, конечно же, является переносимость(
для тех платформ, для которых существует плагин)
и незаменимое средство для web-программирования. Вы можете украсить свой
web-сервер апплетами с трехмерной графикой. К вашим услугам все возможности
OpenGL и объектно-ориентированного программирования. Недостатком является
сложность программирования на языке Java. За короткое время(три
месяца) работы с этим языком на меня свалилось очень много элементарых
проблем: отсутствие форматированного ввода/вывода, непонятное поведение
апплета - в разных броузерах по-разному; устаревшие методы, которые одним
компилятором воспринимались нормально, а другой выдавал предупреждение,
и прочие мелкие проблемы. Вообще, писать java-приложения, т.е. самостоятельные
программы, я бы не советовал. Воспользуйтесь альтернативой - OpenGL Auxilary
Library, рассмотренной в самом начале этой главы. Если же вам необходимо
переносимое приложение, то возьмите его из примеров к Magician Library.
Для java-апплетов - программ, исполняющихся в web-броузерах, альтернативы
нет. Поэтому я и рассматриваю здесь программирование апплетов. У этого типа приложений
имеются очень серьезные недостатки. Для запуска апплетов требуется плагин. Работают
такие апплеты крайне нестабильно, во всяком случае на момент времени июнь 1999 года было много проблем.
Сейчас вышла еще одна библиотека OpenGL для работы с java-апплетами, она называется
GL4Java. Далее я ее рассмотрю.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import com.hermetica.magician.*;
import com.hermetica.util3d.*;
public class template extends Applet implements GLEventListener
{
private CoreGL gl_ = new CoreGL();
private CoreGLU glu_ = new CoreGLU();
private GLComponent glc = null;
FrameRateComponent frc = new FrameRateComponent();
final int width = 400;
public void init()
{
glc = (GLComponent)GLDrawableFactory.createGLComponent(width, width);
add( "Center", glc );
/** Setup the context capabilities */
GLCapabilities cap = glc.getContext().getCapabilities();
cap.setDepthBits(12);
cap.setPixelType(GLCapabilities.RGBA);
cap.setColourBits(24);
cap.setRedBits(1);
cap.setDoubleBuffered(GLCapabilities.DOUBLEBUFFER);
frc.setSummaryOnly(true);
/** Register the GLEventListener with the GLComponent */
glc.addGLEventListener(this);
/** Initialize the component */
glc.initialize();
glc.start();
setSize(width,width);
}
public int getWidth() {
return width;
}
public int getHeight() {
return width;
}
/** Initialization stuff */
public void initialize( GLDrawable component )
{
float pos[] = {3,3,3,1};
float dir[] = {-1,-1,-1};
gl_.glClearColor( 1.0f, 1.0f, 0.796875f, 1.0f );
gl_.glShadeModel( GL.GL_SMOOTH );
gl_.glEnable(GL.GL_ALPHA_TEST);
gl_.glEnable(GL.GL_DEPTH_TEST);
gl_.glEnable(GL.GL_COLOR_MATERIAL);
gl_.glEnable(GL.GL_LIGHTING);
gl_.glEnable(GL.GL_LIGHT0);
gl_.glEnable(GL.GL_BLEND);
gl_.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
gl_.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, pos);
gl_.glLightfv(GL.GL_LIGHT0, GL.GL_SPOT_DIRECTION, dir);
}
/** Handles viewport resizing */
public void reshape( GLDrawable component, int x, int y,
int width, int height)
{
/** Setup the viewport */
gl_.glViewport( component, x, y, width, height);
gl_.glMatrixMode( GL.GL_PROJECTION );
gl_.glLoadIdentity();
gl_.glOrtho(-5,5,-5,5,2,12);
glu_.gluLookAt( 0,0,5, 0,0,0, 0,1,0 );
gl_.glMatrixMode( GL.GL_MODELVIEW );
}
public void display( GLDrawable component )
{
frc.startSample();
gl_.glClear( GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT );
gl_.glTranslated(0.01,0,0);
gl_.glColor3d(1,0,0);
shapes.solidSphere(0.6, 16, 16);
frc.stopSample();
}
public void stop()
{
if(glc.isRunning())
glc.suspend();
}
public void start()
{
if(glc.isRunning())
glc.resume();
}
public void destroy()
{
glc.destroy();
}
public GL getGL()
{
return gl_;
}
}
![]() Исходный файл смотрите здесь. Исполняемый файл здесь. 7.6 Java-апплеты GL4Java7.7 Linux-приложение - Mesa Library7.8 Упражнение:"Переносим игру Arcanoid"Перенесите во все, указанные здесь приложения, игру Arcanoid.
|
| Размещение рекламы на сайте ITSoft. |