ece report csp-02-003 opengl programming –dialog …lgh/ecetechnicalreports/csp... · 2006. 6....

35
ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG BASED AND MATLAB INTERFACE Laurence.G.Hassebrook Daniel Lau VeeraGanesh Yalla Geethavani Goli Signal and Image Processing Laboratory Department of Electrical Engineering University of Kentucky 12/20/2002

Upload: others

Post on 20-Mar-2021

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

ECE REPORT CSP-02-003

OpenGL PROGRAMMING –DIALOG BASED AND MATLAB INTERFACE

Laurence.G.Hassebrook Daniel Lau

VeeraGanesh Yalla Geethavani Goli

Signal and Image Processing Laboratory Department of Electrical Engineering

University of Kentucky

12/20/2002

Page 2: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

2

ABSTRACT

The report describes the integration of OpenGL and Microsoft Foundation Class

(MFC) features. OpenGL is a powerful tool to create 3-D graphics in any programming

language. It only needs a set of library files to be included to create graphics in any

language. The MFC has many existing classes to create graphics. A simple application to

draw a cube in a dialog box with slider control is explained step by step. A small section

on the use of Matlab to create a user interface is included. The Matlab function calls itself

recursively without the use of global variables.

KEYWORDS OpenGL, Microsoft Foundation Class (MFC), rendering context

1. INTRODUCTION

OpenGL® stands for “Open Graphics Library”. OpenGL is an operating system and

hardware platform independent graphics library, which is used to draw/create interactive

3D graphics. OpenGL is in itself not a programming language like C, C++ or any other

language. It can be called API - Application Program Interface. It is easily portable and

very efficient. Its library consists of some 250 to 300 commands, which are used to

create graphics.

As mentioned before, OpenGL is a hardware independent platform. In order to

incorporate these features, commands to perform windowing tasks and to accept user

inputs are not included in OpenGL. So, according to the hardware being used, one should

use the particular windowing system that supports it.

In the same way, OpenGL does not include high-level commands to model complex 3D

objects. All the OpenGL graphics models should be built using geometric primitives-

points, lines and polygons. All primitives are a group of one or more vertices.

OpenGL® is a registered trademark of Silicon Graphics Inc.

Page 3: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

3

OpenGL library GL.lib does not include high level commands but libraries like GLU

(OpenGL Utility) and GLUT (OpenGL Utility Toolkit) can be built on top of OpenGL.

These additional libraries are built to serve some special purposes which OpenGL library,

GL.lib does not offer. For example, GLU has quadrics routines that create some of the

same three dimensional such as a sphere, cylinder, cone etc. GLUT includes several

routines that create more complicated three-dimensional objects such as a sphere, a torus,

and a teapot. OpenGL and GLUT together simply open windows, detecting input and so

on.

Most implementations of OpenGL have a similar order of operations, a series of

processing stages called the OpenGL rendering pipeline. This ordering is not a strict rule

of how OpenGL is implemented but provides a reliable guide for predicting what

OpenGL will do.

2. A simplified version of the OpenGL pipeline

Fig 1: simplified version of the OpenGL pipeline

As an application makes OpenGL API function calls, the commands are placed in a

command buffer. This buffer eventually fills with commands, vertex data, texture data,

and so on. When the buffer is flushed, either programmatically or by driver’s design, the

commands and data are passed to the next stage in the pipeline.

OpenGL Command Buffer

Transform And Lighting

Rasterization

Frame Buffer

OpenGL API calls

Page 4: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

4

Vertex data is usually transformed and lit initially. To make it simple, “Transform and

lighting” is a mathematically intensive stage where points used to describe an object’s

geometry are recalculated for the given object’s location and orientation. Lighting

calculations are performed as well to indicate how brightly the colors should be at each

vertex.

After this stage, the data is fed to the rasterization portion of the pipeline. The rasterizer

actually creates the color image from the geometric, color and texture data. The image is

then placed in the frame buffer. The frame buffer is the memory of the graphics display

device, which means the image is displayed on the screen. This is a brief overview of

how 3D graphics rendering is done.

3. Overview of Device Contexts, Rendering Contexts, and Pixel Formats

Windows by itself has a 2D graphics API called the GDI-graphics device interface. A

window is rectangular area of the screen where an application displays data and looks for

mouse clicks. In order to use OpenGL calls in a windows program, one need to:

1) Get a device context for the rendering location.

2) Select and set a pixel format for the device context.

3) Create a rendering context (RC) associated with the device context.

4) Draw using OpenGL commands.

5) Release the RC.

6) Release the DC.

To understand these steps, one needs to have a clear knowledge about DC and RC.

3.1 Device Context (DC)

GDI-windows original 2D graphics interface is capable of drawing to the screen, to

memory, to printers, or to any other device that provides a GDI interface layer and that

can process GDI calls.

All GDI calls are passed through a DC (a rendering handle to the selected device such as

screen, printer etc.) and it does the rendering. One advantage of DC is that a DC created

for the screen, does rendering on the screen, then it switches to a printer DC and renders

Page 5: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

5

using the same commands. So, with the same rendering commands, but with a different

DC, printer will have the same the thing that was shown on the screen.

3.2 Rendering Context (RC)

Similarly, RC is the OpenGL equivalent of the GDI DC. An RC is the context through

which OpenGL calls are rendered to the device. To put it in simple words, a rendering

context is what links OpenGL calls to the DC. The DC connects the Window to the GDI

(Graphics Device Interface). The RC connects OpenGL to the DC.

3.3 Pixel Formats

Pixel Formats are the translation layer between OpenGL commands and the rendering

operation that a window performs. The selected pixel format describes such things as

how colors are displayed, the depth of field resolution.

There are four functions in windows OpenGL API that handles the pixel format. These

are:

1) ChoosePixelFormat() Obtains a device context’s pixel format that’s

the closest match to a pixel format template

that was provided by the user.

2) SetPixelFormat() Sets a DC’s current pixel format to the pixel format

index specified .

3) GetPixelFormat() Returns the pixel format index of a DC’s current

pixel format.

4) DescribePixelFormat() Given a DC and a pixel format index, fills a

PIXELFORMATDESCRIPTOR data structure

with the pixel format’s properties.

Page 6: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

6

3.3.1 Pixel Format Structure

The capabilities of an OpenGL window depend on the pixel format selected for the

OpenGL rendering window. Listed below are the properties of this format:

• Single or double buffering.

• RGBA or color indexing.

• Drawing to a window or bitmap.

• Support of GDI or OpenGL calls.

• Color depth (depth= number of bits).

• Z-axis depth.

• Stencil buffer.

• Visibility buffers.

In windows, these values are set for each OpenGL window, using a data structure called

the PIXELFORMATDESCRIPTOR. The pixel format has to be selected before the

OpenGL rendering context is created and once the pixel format is set for a rendering

context, it cannot be changed.

The exact values of the PIXELFORMATDESCRIPTOR that are supported depend on

1) The implementation of OpenGL that is running. 2) The current video mode Windows is running in. 3) Current video hardware installed. The structure of PIXELFORMATDESCRIPTOR is as follows: Typedef structtagPIXELFORMATDESCRIPTOR { WORD nSize; WORD nVersion; DWORD dwFlags; BYTE iPixelType; BYTE cColorBits; BYTE cRedbits; BYTE cRedShift; BYTE cGreenBits;

Page 7: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

7

BYTE cGreenShift; BYTE cBluebits; BYTE cBlueShift; BYTE cAlphaBits; BYTE cAlphaShift; BYTE cAccumBits; BYTE cAccumRedBits; BYTE cAccumGreenBits; BYTE cAccumBlueBits; BYTE cAccumAlphaBits; BYTE cDepthBits; BYTE cStencilBits; BYTE cAuxBuffers; BYTE iLayerType; BYTE bReserved; DWORD dwLayerMask; DWORD dwVisibleMask; DWORD dwDamageMask; } PIXELFORMATDESCRIPTOR, *PPIXELFORMATDESCRIPTOR, FAR *LPPIXELFORMATDESCRIPTOR; STRUCTURE ELEMENT DESCRIPTION nSize Specifies the size in bytes of the data structure and should be

set to sizeof(PIXELFORMATDESCRIPTOR). nVersion Specifies the version of the structure(and not the OpenGL

version). dwFlags Specifies a set of bit flags that specify properties

of the pixel buffer. The properties are generally not mutually exclusive; however, there are exceptions. The following constants are defined:

PFD_DOUBLEBUFFER:This is used when one needs double buffering. This flag is important if you want fast rendering, since you usually draw to the hidden, or "back," buffer , then swap it to the front. This flag and PFD_SUPPORT_GDI are mutually exclusive in the release 1.0 generic implementation. PFD_STEREO: This is used when one needs a steroscopic buffer. This flag is not supported in the release 1.0 generic implementation.

Page 8: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

8

PFD_DRAW_TO_WINDOW: We want to draw to a window or device, or for the device driver to support it. PFD_DRAW_TO_BITMAP:We want to draw to a memory bitmap or for the device driver to support it.

PFD_SUPPORT_GDI:We want to have a buffer that support GDI drawing. This flag and PFD_DOUBLEBUFFER are mutually exclusive in the release 1.0 generic implementation.

PFD_SUPPORT_OPENGL:We want to use OpenGL, or the device supports it.

PFD_GENERIC_FORMAT:The pixel format is supported by the generic implementation. If this bit is clear, this pixel format is supposed by a device driver or by hardware.

PFD_GENERIC_ACCELERATED: New with OpenGL 1.1, this flag is used with PFD_GENERIC_FORMAT to differentiate between the various driver types.

PFD_NEED_PALETTE: The buffer used RGBA pixels on a palette managed device. This means that a logical palette is required to achieve the best results. The colors in the palette are specified according to the values of the cRedBits, cRedShift, cGreenBits, cGreenShift, cBluebits, and cBlueShift members. The palette should be created and realized in the DC before calling wglMakeCurrent().

PFD_NEED_SYSTEM_PALETTE: Flag used by OpenGL hardware that supports only one palette. To use hardware accelerations in such hardware, the hardware palette had to be in a fixed order in RGBA mode or match the logical palette in color-index-mode. In the release 1.0 generic implementation the PFD_NEED_PALETTE flag doesn't have such a requirement. That is, if only PFD_NEED_PALETTE is set, the logical-to-system palette mapping is performed by the system. However, if PFD_NEED_SYSTEM_PALETTE is set, you

Page 9: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

9

should take over the system palette in your program by calling SetSystemPaletteUse () to force a one-to-one logical-to-system palette mapping. If your OpenGL hardware supports multiple hardware palettes and the device driver can allocate spare hardware palettes for OpenGL, then this flag may not be set. If a format requires PFD_NEED_SYSTEM_PALETTE but your program ignores it because it doesn't want to mess up the desktop colors, it won't get maximum performance but should still work. The PFD_NEED_SYSTEM_PALETTE flag isn't needed if the OpenGL hardware supports multiple hardware palettes and the driver can allocate spare hardware palettes and the driver can allcate spare hardware palettes for OpenGL.The generic pixel formats don't have this flag set.

PFD_SWAP_COPY: Not found in the original Windows NT 3.5 implementation. This is an advanced flag that depends on your OpenGL implementation and its extensions. If this flag is specified, it's a hint that you want the back buffer copied to the front buffer when the buffers are swapped. This is different from the default behaviour, whereby the back buffer becomes undefined when the buffers are swapped. The contents of the back buffer are not affected. Also see the next flag.

PFD_SWAP_EXCHANGE: Not found in the original Windows NT 3.5 implementation. This is an advanced flag that depends flag that depends on your OpenGL implementation and its extensions. If this flag is specified, it is a hint that you want the back buffer exchanged with the front buffer when the buffers are swapped. This is different from the default behaviour, whereby the back buffer becomes undefined when buffers are swapped. The contents of the back buffer are swapped with the front buffer. PFD_DOUBLEBUFFER_DONTCARE: Used only when calling the ChoosePixelFormat() function. This means to ignore single or double buffering when selecting a match for a format you've set up.

PFD_DOUBLEDONTCARE: Used only when calling the ChoosePixelFormat() function. This means to ignore the stereo flag when selecting a match for a format you've set up.

iPixelType Specifies the color type of the pixel data. The following types

are defined: • PFD_TYPE_RGBA: The pixel color is specified as

RGBA values. Each pixel has four separate color

Page 10: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

10

components: red, green, blue and alpha. Each component value varies from 0.0 to 1.0.

• PFD_TYPE_COLORINDEX: The pixel color is specified in a lookup table. Each pixel uses a color index value to look up a palette value instead of an RGBA value. This setting is needed if the RGBA setting fails to render colors satisfactorily or if palette animation is to be performed.

cColorBits Specifies the number of color bit planes in each color

buffer. For RGBA mode it's the size in bits of the color buffer. This value doesn’t include the alpha bit planes. If current mode is "true color" mode (16 million colors, or 24-bit color), then the hardware supports 8 bits per RGB color. So the value of cColorBits would be 24 bits (3*8=24). If the current mode is 256-color mode, the values for cColorBits will be never greater than 8 bits. Values will generally range from 4 to 32.For color-index mode it's the size of the color palette. Generally, RGBA mode is preferred over color-index mode. If color-index mode is used, one needs to set up the palette.

cRedBits Specifies the number of red bit planes in each RGBA

color buffer. For example, a value of 3 indicates that 8(2^3) different intensities of red are available.

cRedShift Specifies the shift count for red bit planes in each

RGBA color buffer. That is, it's where the red bits can be found in the color buffer. The shifts for red, green, and blue will all be different. For example, in an 8-bit, 256 color mode, the last two bits in an 8-bit color value are usually the two blue bits. The blue shift value would then be six.

cGreenBits Specifies the number of green bit planes in each RGBA color buffer.

cGreenShift Specifies the shift count for green bit planes in each

RGBA color buffer. cBlueBits Specifies the number of blue bit planes in each RGBA

color buffer. cBlueShift Specifies the shift count for blue bit planes in each

RGBA color buffer.

Page 11: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

11

cAlphaBits Specifies the number of alpha bit planes in each RGBA

color buffer. The alpha bit planes are used to specify the opacity of a color. Alpha bit planes are not supported in the release 1.0 generic implementation.

cAlphaShift Specifies the shift count for alpha bit planes in each

RGBA color buffer.

cAccumBits Specifies the total number of bit planes in the accumulation buffer, which is used for accumulating images.

cAccumRedBits Specifies the number of red bit planes in the accumulation buffer. cAccumGreenBits Specifies the number of green bit planes in the accumulation buffer. cAccumAplhaBits Specifies the number of blue bit planes in the accumulation buffer. cDepthBits Specifies the number of bits of the depth (z-axis) buffer. Generally this value is 0, 16,24, or 32. cStencilBits Specifies the number of bits of the stencil buffer, which is used to restrict drawing to certain areas. cAuxBuffers Specifies the number of auxiliary buffers, which are not supported in the release 1.0 generic implementation. iLayerType Specifies the type of layer. The generic implementation

supports only the main plane, although the following values are defined:

• PFD_MAIN_PLANE: The layer is main plane. • PFD_OVERLAY_PLANE: The layer is the

overlay plane. • PFD_UNDERLAY_PLANE: The layer is the

underlay plane. bReserved Not used. Must be zero.

Page 12: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

12

dwLayerMask Obsolete in OpenGL 1.1 or later. Designated the layer mask, which is used in combination with the visible mask to see whether one layer overlays another.

dwVisibleMask Designates the visible mask, which is used in conjunction

with the layer mask to determine whether one layer overlays another. If the result of the bitwise-AND of the visible mask of a layer and the layer mask of a second layer is nonzero, the first layer overlays the second layer, and a transparent pixel value exists between the two layers. If the visible mask is 0, the layer is opaque.

dwDamageMask Obsolete in OpenGL 1.1 or later. Specified whether more

than one pixel format shares the same frame buffer. If the result of the bitwise AND of the damage masks between two pixel formats is nonzero, they share the same buffers.

3.4 WGL Rendering Contexts When an OpenGL window is created, the RC is created along with the pixel format, and each is held inside the class structure. Every OpenGL command is linked to a RC. A RC is what links OpenGL calls to a Windows window. In order to set up a connection between a RC and OpenGL calls, some routines are used. These are as follows: FUNCTIONS DESCRIPTION wglCreateContext() Creates a new OpenGL RC, suitable for drawing on the device

referenced by the DC provided. The RC has the same pixel format as the DC. An application should set the DC's pixel format before creating a RC.

wglMakeCurrent() Makes the specified RC the calling thread's current RC.

OpenGL calls made by the thread are then rendered on the device identified by the DC. If the RC specified is NULL, the function deselects the calling thread's current RC and releases the DC used by the RC. In this case the DC is ignored.

wglDeletecontext() Deletes the RC specified. It's an error to delete an RC that is

another thread's current RC. However, if an RC is the calling

Page 13: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

13

thread's current RC, the function makes the RC not current before deleting it.

wglGetCurrentContext() If the calling thread has a current RC, the function returns a

handle to that RC. Otherwise, NULL is returned. wglGetCurrent() If the calling thread has a current RC, the function returns a

handle to the DC associated with the RC by means of wglMakeCurrent(). Otherwise, NULL is returned.

The process of creating a RC from a DC is shown in the figure (2) below. The optimized approach is to get a DC first, then set the pixel format, create the RC, and make the RC current, all when a WM_CREATE is received. When the WM_PAINT calls are received (usually many WM_PAINT calls are received), only OPENGL calls have are to be performed, since RC is already created and selected. Finally, when the program is terminating, the RC is deselected and deleted, thereby releasing the DC.

Fig 2: DC/RC Handling

WINDOWS MESSAGE LOOP

WM_CREATE GET DC SET PIXELFORMAT CREATE RC FROM DC MAKE RC CURRENT USING DC

WM_PAINT MAKE OpenGL CALLS

WM_DESTROY MAKE RC NONCURRENT DELETE RC RELEASE DC

Page 14: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

14

4. Microsoft Foundation Class (MFC)

Any program, which uses OpenGL, requires a window to display the graphics. But as

OpenGL cannot handle windowing tasks by itself, MFC is used for windows 95/98/NT.

MFC window is a hybrid of C++ and Windows API calls. In effect, an MFC window

gives a C++ wrapper to a lot (but not all) of the Windows API, eliminating some of the

drudgery of writing a Windows application and providing some new services.

The Microsoft Foundation Class (MFC) Library is a collection of C++ classes

(generalized definitions used in object-oriented programming) that can be used in

building application programs. The classes in the MFC Library are written in the C++

programming language. The MFC Library saves a programmer time by providing code

that has already been written. It also provides an overall framework for developing the

application program.

There are MFC Library classes for all graphical user interface elements (windows,

frames, menus, tool bars, status bars, and so forth), for building interfaces to database, for

handling events such as messages from other applications, for handling keyboard and

mouse input and for creating ActiveX control.

OpenGL can be integrated with the MFC based graphic programs. The OpenGL output

can display in a portion of a Dialog box or a SDI (Single Document Interface) designed

using the MFC. The properties of the drawings so created using OpenGL can be

controlled by inserting additional Command buttons, Sliders etc. in the Dialog box or by

additional menu items in the SDI.

Page 15: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

15

5. Creating a Dialog based OpenGL application

The following sections (5.1 – 5.4) give the step by step procedure to create and execute a

MFC based OpenGL application program.

5.1 Creating the Project:

Press File

Press New

Select "Projects"

Select “MFC AppWizard (exe)” (Opens up the MFC application wizard.)

Give the project name as say " DlgOgl” the same project name will be referred

to throughout the example. Give the location of the project and press ok.

5.2 Steps within MFC Wizard:

Step 1:

Select "Dialog Based" Press Next

Step 2:

Change the title for the dialog box if needed by specifying your title in

the “Please enter a title for your dialog” box. The title for the

application we designed was “OpenGl in a Dialog Box”. Leave the

default settings and Press Next.

Step 3:

Check “statically linked library”, leave the other default settings.

Press Next

Step 4:

Press Finish. Visual C++ responds by displaying the New Project Information window.

Step 5: Click OK button of the New project Information window.

Page 16: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

16

Based upon MFC wizard selections a dialog box is shown in the design window. To set the project configurations: From the Build menu select ‘set active configuration”, Visual C++. responds by displaying the default project configuration dialog box.

Select DlgOgl – Win32 Release in the Default Project Configuration dialog box, and then click the OK button.

The creation of project file and skeleton files of the DlgOgl program are completed. To add the needed libraries for open GL: From the Project menu select “Settings”, click the Link tab and enter the following in the Object/library modules box. opengl32.lib glu32.lib glut32.lib

5.3 Visual Design of the DlgOgl program To display the dialog box in the workspace design area if not already shown: Select Project Workspace from the View menu Select the ResourceView tab of the Project Workspace window. Expand the DlgOgl resources item Expand the Dialog item. Double-click the IDD_DLGOGL_DIALOG item.

Visual C++ responds by displaying the IDD_DLGOGL_DIALOG dialog box in design mode.)

Design the IDD_DLGOGL_DIALOG dialog box according to Table 1 .Delete the Ok button, Cancel button, and text in the IDD_DLGOGL_DIALOG dialog box.

Page 17: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

17

Table 1: The properties table of the IDD_DLGOGL_DIALOG dialog box Object Property Setting Dialog Box ID IDD_DLGOGL_DIALOG Caption OpenGL in a Dialog Box Font System, Size 10 (General tab) Minimize box Checked (Styles tab) Maximize box Checked (Styles tab) Push Button ID IDOK Caption &Quit Slider ID IDC_SLIDER Orientation Horizontal (Styles tab) Point Both (Styles tab) Picture Box ID IDC_OPENGLWIN Type Frame (General Tab) Visible Checked (General Tab) 5.3.1 Attaching Variable to the Slider: Step 1: Select ClassWizard from the View menu Visual C++ responds by displaying the MFC ClassWizard dialog box. Step 2:

Select the Member Variables tab of the MFC ClassWizard dialog box. (See figure 3)

Page 18: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

18

Fig 3: selecting ClassWizard’s Member Variables tab Step 3: Make sure that the Class name drop-down list box is set to CDlgOglDlg. Step 4:

Select IDC_SLIDER in the Object IDs list to attach a variable to the IDC_SLIDER, the slider control.

Step 5: Click the Add Variable button

Visual C++ responds by displaying the Add Member Variable dialog box (see figure 4)

Page 19: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

19

Fig 4: Add Member Variable dialog box

Step 6: Set the Add Member Variable dialog box as follows: Member Variable Name: m_clSlider Category: Value Variable type: CSliderCtrl Step 7: Click the OK button of the Add Member Variable dialog box. Step 8: Click the OK button of the MFC ClassWizard dialog box. 5.3.2 Adding the CGlView Class: The CGlView class will contain the OpenGL code. Step 1: Select ClassWizard from the View menu Visual C++ responds by displaying the MFC ClassWizard dialog box. Step 2: Click on the Add Class button and select “New”.

Visual C++ responds by displaying the New Class dialog box as shown in figure(5) below:

Page 20: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

20

Fig 5: New Class dialog box Step 3: Type the following Class information: Name: CglView (note: use lowercase ‘L’ in CglView) The GlView.cpp and Glview.h files will be automatically created. Base Class: choose generic CWnd Step 4: Click OK button on the New Class dialog box. Step 5: Click OK button on the MFC ClassWizard dialog box. 5.3.3 Adding Code to GlView.cpp file Step 1:

Open the GlView.cpp file from the project workspace menu by selecting the File View tab.

Step 2: Edit the CGlView::CGlView () { } function as follows:

Page 21: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

21

CGlView::CGlView (CWnd *pclWnd) { m_pclWnd = pclWnd; m_hWnd = pclWnd->m_hWnd; m_hDC = ::GetDC (m_hWnd); } Step 3: Add a new member function int CGlView::OnCreate() as follows:

o Click on the Class tab of the Project Workspace. o Select CGlView class from the DlgOgl classes. o Right Click the CGlView Class. o The following figure(6) shows the menu that pops up:

Fig 6: pop up menu

o Choose the Add Member Function option. o The figure(7) shows the Add Member Function dialog box.

Page 22: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

22

Fig 7: Add Member Function dialog box o Type the following:

Function type: int Function Declaration: OnCreate () Step 4: In a similar way, add the following functions to the GlView.cpp:

o BOOL CGlView::SetPixelformat(HDC hdc) Function type: BOOL Function Declaration: SetPixelformat(HDC hdc)

o GLvoid CGlView::ReSizeGLScene(GLsizei width, GLsizei height) Function type: GLvoid

Function Declaration: ReSizeGLScene (GLsizei width, GLsizei height)

o int CGlView::InitGL(GLvoid)

Function type: int Function Declaration: InitGL(GLvoid)

o int CGlView::DrawGLScene (GLint pos) Function type: int

Function Declaration: DrawGLScene (GLint pos) The code to be added to each member function is given in Appendix-1

Page 23: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

23

5.3.4 Adding Code to GlView.h file Step 1:

Open the GlView.h file from the project workspace menu by selecting the File View tab.

Step 2: Include the following header files under the //CGlView comment line #include <gl/gl.h> #include <gl/glu.h> #include <gl/glut.h> #include "math.h" Step 3: Add the following code to the GlView.h file after the #include declarations (some of the code already exists by default) class CGlView : public CWnd { // Construction public: CGlView(CWnd *pclWnd); // Attributes public: HDC m_hDC; // GDI Device Context HGLRC m_hglRC; // Rendering Context CWnd *m_pclWnd; HWND m_hWnd; // Operations public: BOOL SetPixelformat(HDC hdc); GLvoid ReSizeGLScene(GLsizei width, GLsizei height); int InitGL(GLvoid); int DrawGLScene(GLint pos); // Overrides ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CGlView) protected: //}}AFX_VIRTUAL // Implementation public: virtual ~CGlView(); // Generated message map functions protected: public: int OnCreate(); //{{AFX_MSG(CGlView) // afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); // afx_msg void OnSize(UINT nType, int cx, int cy);

Page 24: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

24

//}}AFX_MSG DECLARE_MESSAGE_MAP() }; 5.3.5 Adding Code to the DlgOglDlg.h file #include “GlView.h” (put at top)

CglView* m_pclGlView; (put under public, use lower case ‘L’ for m_pclGlView)

5.3.6 Adding Code to the DlgOglDlg.cpp file Step1:

Open the DlgOglDlg.cpp file from the project workspace menu by selecting the File View tab.

Step 2: Edit the BOOL CDlgOglDlg::OnInitDialog() function as follows (some of the code already exists by default) … … // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here m_clSlider.SetRange(0,360); m_clSlider.SetPageSize(60); m_clSlider.SetPos(180); CStatic *pclStatic = (CStatic *)GetDlgItem(IDC_OPENGLWIN); m_pclGlView = new CGlView(pclStatic); //OpenGL in Picture in a Dialog CPaintDC dc(this); // device context for painting HDC m_hDC; m_hDC = ::GetDC(this->m_hWnd); RECT rect; GetClientRect(&rect); int iWidth = -(rect.right - rect.left); int iHeight = rect.top - rect.bottom; m_pclGlView->OnCreate();

Page 25: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

25

m_pclGlView->ReSizeGLScene(iWidth, iHeight); m_pclGlView->InitGL(); m_pclGlView->DrawGLScene(0); return TRUE; // return TRUE unless you set the focus to a control … Step 3: Edit the BOOL CDlgOglDlg::OnPaint() function as follows: (some of the code already exists by default) … … … CDialog::OnPaint(); } // m_pclGlView->DrawGLScene(m_clSlider.GetPos()); // … … Step 4:

Add the OnHScroll( ) function to the DlgOglDlg.cpp program using the ClassWizard as follows:

o Select the Message Maps tab, make sure CDlgOglDlg in the object ID’s window is selected. In the messages window, select WM_HSCROLL.

o Click the Add Function button and then click the edit button to add the following code to the OnHScroll function.

The code fragment for the OnHScroll function is { m_pclGlView->DrawGLScene(m_clSlider.GetPos()); } Step 5:

Add the OnDestroy( ) function to the DlgOglDlg.cpp program using the ClassWizard as follows:

o Select the Message Maps tab and select WM_DESTROY under the messages window.

o Click the Add Function button and click OK.

The code fragment for the OnDestroy function is automatically created by the ClassWizard.

Page 26: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

26

5.4 Executing the Program: Step 1: Select the Build DlgOgl.Exe option from the Build menu. Step 2:

The application DlgOgl.exe can be executed by selecting Execute DlgOgl.Exe from the Build menu.

The following figure(8) shows the screenshot of the output obtained

Fig 8: Output

Page 27: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

27

6. Creation of Matlab Interface: MATLAB is a powerful programming language as well as an interactive computational environment. Files that contain code in the MATLAB language are called M-files. M-files are created using a text editor, and then used as any other MATLAB function or command. There are two kinds of M-files:

• Scripts, which do not accept input arguments or return output arguments. They operate on data in the workspace.

• Functions, which can accept input arguments and return output arguments. Internal variables are local to the function

6.1 Matlab Graphics:

6.1 .1 Handle Graphics: MATLAB provides a set of low-level functions that allow the creation and manipulation of lines, surfaces, and other graphics objects. This system is called Handle Graphics. 6.1.2 Graphics Objects: Graphics objects are the basic drawing primitives of MATLAB's Handle Graphics system. The objects are organized in a tree structured hierarchy. This reflects the interdependence of the graphics objects. For example, Line objects require Axes objects as a frame of reference. In turn, Axes objects exist only within Figure objects. 6.1.3 Graphics Objects: There are eleven kinds of Handle Graphics objects:

• The Root object is at the top of the hierarchy. It corresponds to the computer screen. MATLAB automatically creates the Root object at the beginning of a session.

• Figure objects are the windows on the root screen other than the Command window.

• Uicontrol objects are user interface controls that execute a function when users activate the object. These include pushbuttons, radio buttons, and sliders.

• Axes objects define a region in a figure window and orient their children within this region.

• Uimenu objects are user interface menus that reside at the top of the figure window.

Page 28: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

28

• Image objects are two-dimensional objects that MATLAB displays using the elements of a rectangular array as indices into a colormap.

• Line objects are the basic graphics primitive for most two-dimensional plots.

• Patch objects are filled polygons with edges. A single Patch can contain multiple faces, each colored independently with solid or interpolated colors.

• Surface objects are three-dimensional representations of matrix data created by plotting the value of the data as heights above the x-y plane.

• Text objects are character strings.

• Light objects define light sources that affect all objects within the Axes. A simple Matlab Graphics Interface function is described below. The program uses the Matlab Handle Graphics Objects described above. The advantage of this program is avoiding the use of global variables. The function is self supportive and does not need any external variables for its operation. This is only a template program and can be further extended to include several other features. The program explanation is done in the form of comment lines (in bold italics). 6.2 Function “MYGUI.m”: % Dr Daniel Lau's Menu Creation program % Declare the function MYGUI. The function has three input arguments str, arg1 & % arg2 function h=MYGUI (str,arg1,arg2) % % Check for the number of input arguments using nargin. If the number of input % arguments is less than one then set the str value to ‘INITIALIZE’. if (nargin < 1) str = 'INITIALIZE'; end % % Since there can be several cases based on the value of str, we use a switch-case % statement to evaluate the function based on the value of str. switch str % Case if value of str = ‘INTIALIZE’

Page 29: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

29

case 'INITIALIZE' I = rand(100,100); % generate a random number array of 100x100.Tthis is used % as a image for display purpose. h = figure('POSITION',[100 100 120 150],... 'Resize','of'); % creates a figure window with specified properties h(2) = axes('units','pixels',... 'position',[10,40,100,100]); % create axes based on the properties specified imshow(I); % display the array I as a 2D image h(3) = uicontrol('style','pushbutton',... 'units','pixels',... 'position',[10 10 100 20],... 'string','ROTATE',... 'callback','MYGUI(''BUTTON'');'); % creates a user interface control, a % pushbutton with caption % ‘ROTATE’ h(4) = uimenu('label','mymenu'); % create a user defined menu % ‘mymenu’ h(5) = uimenu(h(4),'label','option1'); % create a submenu in the %‘mymenu’ label it as ‘option1’ set(h(2),'userdata',I); % set the axes properties of axes to % I with handle h(2) set(h(1),'userdata',h); % set the figure properties % to the array h with handle h(1) return; % case if str = ‘BUTTON’, if the push button is pressed case 'BUTTON' h = get(gcf,'userdata'); % get userdata to handle of current % figure I = get(h(2),'userdata'); % get userdata with handle h(2) I= rot90(I); % rotate I by 90o and update axes(h(2)); % reset the axes

Page 30: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

30

imshow(I); % display the rotated I set(h(2),'userdata',I); % set the userdata property to current I % with handle h(2) return; end %

Page 31: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

31

Appendix –1 (GlView.cpp) ///////////////////////////////////////////////////////////////////////////// // CGlView message handlers int CGlView::OnCreate() { m_hDC = ::GetDC(this->m_hWnd); if(!SetPixelformat(m_hDC)) { ::MessageBox(::GetFocus(),"SetPixelformat Failed!","Error",MB_OK); return -1; } m_hglRC = wglCreateContext(m_hDC); int i= wglMakeCurrent(m_hDC,m_hglRC); InitGL(); return 0; } BOOL CGlView::SetPixelformat(HDC hdc) { PIXELFORMATDESCRIPTOR *ppfd; int pixelformat; PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd 1, // version number PFD_DRAW_TO_WINDOW | // support window PFD_SUPPORT_OPENGL | // support OpenGL PFD_GENERIC_FORMAT | PFD_DOUBLEBUFFER, // double buffered PFD_TYPE_RGBA, // RGBA type 24, // 24-bit color depth 0, 0, 0, 0, 0, 0, // color bits ignored 8, // no alpha buffer 0, // shift bit ignored 8, // no accumulation buffer 0, 0, 0, 0, // accum bits ignored 32, // 32-bit z-buffer 8, // no stencil buffer 8, // no auxiliary buffer PFD_MAIN_PLANE, // main layer 0, // reserved 0, 0, 0 // layer masks ignored };

Page 32: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

32

ppfd = &pfd; if ( (pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0 ) { ::MessageBox(NULL, "ChoosePixelFormat failed", "Error", MB_OK); return FALSE; } if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE) { ::MessageBox(NULL, "SetPixelFormat failed", "Error", MB_OK); return FALSE; } return TRUE; } GLvoid CGlView::ReSizeGLScene(GLsizei width, GLsizei height)// Resize And Initialize The GL Window { if (height==0) { height=1; } glViewport(0,0,width,height); // Reset The Current Viewport glMatrixMode(GL_PROJECTION); // Select The Projection Matrix glLoadIdentity(); // Reset The Projection Matrix // Calculate The Aspect Ratio Of The Window gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f); glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix glLoadIdentity(); // Reset The Modelview Matrix } int CGlView::InitGL(GLvoid) // All Setup For OpenGL Goes Here { // glClearColor(0.0f, 0.0f, 1.0f, 1.0f); // Black Background glClearDepth(1.0f); // Depth Buffer Setup glShadeModel(GL_SMOOTH); // Enable Smooth Shading glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); // Enables Depth Testing glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice

//Perspective calculations // return TRUE;

Page 33: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

33

} int CGlView::DrawGLScene(GLint pos) // The Drawing Space { GLfloat mat_specular[] = {0.0,0.0,0.0,1.0}; GLfloat mat_shininess[] = {128.0}; GLfloat light_position[] = {1.0,0.0,0.0,1.0}; glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glPushMatrix (); //glTranslatef (0.0, 0.0, -5.0); glPushMatrix (); // glRotated (0.0, 1.0, 0.0, 0.0); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); glLightfv(GL_LIGHT0, GL_POSITION, light_position); glTranslated (0.0, 0.0, -5.5); glEnable (GL_LIGHTING); // glPopMatrix (); // glTranslatef(0.0f,0.0f,-5.0f); // Move Into The Screen glRotatef((float)pos-180,0.0,1.0,0.0); //glRotatef(-54.73561f,1.0f,0.0f,0.0f); //glRotatef(45.0f,0.0f,1.0f,0.0f); glBegin(GL_QUADS); // Drawing Front glVertex3f( -1.0f, 1.0f, 1.0f); // Top Left glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Right glVertex3f( -1.0f,-1.0f, 1.0f); // Bottom Left glEnd(); glRotatef(90.0f, 0.0f, 1.0f, 0.0f); glBegin(GL_QUADS); // Drawing Right glVertex3f( -1.0f, 1.0f, 1.0f); // Top Left glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Right glVertex3f( -1.0f,-1.0f, 1.0f); // Bottom Left glEnd(); glRotatef(90.0f, 0.0f, 1.0f, 0.0f); glBegin(GL_QUADS); // Drawing Back glVertex3f( -1.0f, 1.0f, 1.0f); // Top Left glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Right glVertex3f( -1.0f,-1.0f, 1.0f); // Bottom Left glEnd(); glRotatef(90.0f, 0.0f, 1.0f, 0.0f); glBegin(GL_QUADS); // Drawing Left glVertex3f( -1.0f, 1.0f, 1.0f); // Top Left glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Right glVertex3f( -1.0f,-1.0f, 1.0f); // Bottom Left

Page 34: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

34

glEnd(); glRotatef(90.0f, 1.0f, 0.0f, 0.0f); glBegin(GL_QUADS); // Drawing Top glVertex3f( -1.0f, 1.0f, 1.0f); // Top Left glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Right glVertex3f( -1.0f,-1.0f, 1.0f); // Bottom Left glEnd(); glRotatef(180.0f, 1.0f, 0.0f, 0.0f); glBegin(GL_QUADS); // Drawing Bottom glVertex3f( -1.0f, 1.0f, 1.0f); // Top Left glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Right glVertex3f( -1.0f,-1.0f, 1.0f); // Bottom Left glEnd(); // glPopMatrix (); // SwapBuffers(m_hDC); return TRUE; }

Page 35: ECE REPORT CSP-02-003 OpenGL PROGRAMMING –DIALOG …lgh/ecetechnicalreports/csp... · 2006. 6. 30. · GDI-windows original 2D graphics interface is capable of drawing to the screen,

35

Bibliography

1) Ron Fosner, OpenGL programming for Windows 95 and Windows NT, Addison Wesley Developers press, 1997, ISBN 0-201-40709-4 2) Woo, Neider, Davis, Shreiner, OpenGL Programming Guide, Addison Wesley,

3rd edition, ISBN 0-201- 60458-2

3) Richard S.Wright, Jr., Michael Sweet, OpenGL SuperBible, Waite Group press, 2nd edition, ISBN 1-57169-164-2

4) Davis Chapman, Sam’s Teach yourself Visual C++ 6.0 in 21 days, SAMS, 1998, ISBN 0-672-31240-9