PDA

View Full Version : rotating a user-defined shape



mmsgl
12-07-2004, 05:48 AM
Hello,

This is my first attempt at using OpenGL.

Is it possible to define a shape by cross-section, and then rotate that, in the same way I have seen simple cubes rotated?

endash
12-07-2004, 09:20 AM
In short: Yes. Can you elaborate? It may be up to you to code a function to turn a cross-section into a "shape", but then you certainly can glRotate() it.

mmsgl
12-07-2004, 10:24 AM
There will be only a few standard shapes that I would require, and these are based on standard structural shapes produced by steel mills.

I had wanted to post a bitmap image of a sample, but I don't see how to do that on this board.

These cross-sections are pretty basic and would resemble an 'H', 'I', 'T', '0', etc.

Also, in re-reading my original post, I see that I didn't make it clear that I would require a 3D image to be generated from this "cross-section".

Is this also possible?

Aeluned
12-07-2004, 12:20 PM
your post still eludes me.
you have an image (2D representation) of the cross section and you want to extrapolate a 3D model representation of this cross-section?

there is a bit to be said if that's what your goal is, so I'll hold off on that.

but, as endash said, after you've got a 'shape' defined by vertices, rotating it is as easy as glRotatef().

mmsgl
12-08-2004, 04:37 AM
Originally posted by Aeluned:
your post still eludes me.
you have an image (2D representation) of the cross section and you want to extrapolate a 3D model representation of this cross-section?
Yes.

I was wanting to somehow mathematically define this "cross-section", have the "length" as a variable that can be adjusted at run-time, and have OpenGL do the rest.

The image below is the closest I could find to what I want to do.

The light green member is a "W" section that I would like to be able to generate and rotate.

http://www.nyacad.com/SS07TypConnWallBearing.htm

http://www.nyacad.com/SS07TypConnWallBearing.htm

Aeluned
12-08-2004, 06:24 AM
That looks like an "I" beam to me :p

Regardless...unfortunately as far as I know your task is not a trivial one. What you want to do is in the domain of computer vision and image processing. Techniques such as edge detection would be needed to extract the meaningful data in the image. The image you linked above is exceptionally tough because it contains perspective distortions (it's seen at an angle) and so determining what's going on is that much more difficult for a computer.

If all images were shown face on with a known color for the background it would simplify things a bit. You could more readily determine the type of cross section and at that point you can just assign a depth value to the object.

If at all possible, a data source specifying dimensions for the cross sections and the cross section type "I", "U", etc should be used. These are much more meaningful in building a computer model and then the task *would be* trivial. Can this be made available to you?

mmsgl
12-08-2004, 07:43 AM
Originally posted by Aeluned:
That looks like an "I" beam to me :p
Yes I agree :D
"I" beams have narrower flanges however, and although they used to be referred to as such, they are now called "S" beams - go figure :rolleyes:
The posted image is in fact a "W" beam for Wide Flange.

The image I linked is only to show what I was tring to generate; a simple 3D of the beam based on the cross-section which I was hoping to define "mathematically". I wasn't planning on using bitmaps, if I didn't have to.



If at all possible, a data source specifying dimensions for the cross sections and the cross section type "I", "U", etc should be used. These are much more meaningful in building a computer model and then the task *would be* trivial. Can this be made available to you?I in fact have tables that define the dimensions of every steel section produced.

These give, for the "W" shape for example, the width and thickness of the flange (horizontal component) and the height and thickness of the web (vertical component).

I was trying to start off very simplistic, and just see if I could generate just one 3D image (with arbitrary dimensions) and rotate that by moving the mouse.

Trouble is I don't know where to start, as all examples I find (and understand), use basic shapes(ie cubes, pyramids, etc.)

A push in the right direction, as to how to start, would be greatly appreciated.

Aeluned
12-08-2004, 08:28 AM
Ah, I see. Good.

The first thing to do is start with one of those examples you saw with a cube. You could grab this code from NeHe that creates an OpenGL window and sets up a perspective projection (setting up an OpenGL window is tedious)
http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=05.

Next, you need to come up with a mapping from the beam dimensions (specified in cm,inches,feet,or whatever the units may be) in real-world measurements to your worldspace coordinate system measurements. This part will involve some trial and error and will probably cause you some grief. For example, try adjusting the vertices of the cube in the application given some real world dimensions to turn it into the 'flange' part of the beam.

In its simplest form, you'll notice that the "W" beam you showed me before is made up of basically 3 cuboids, so it's a matter of drawing these 3 cuboids. In actuality though, the flange doesn't meet the web at a 90 degree angle, it curves...let's hold off on that because it makes things a bit more complicated.

as far as rotations are concerned:
there are many ways to do it. For simplicities sake, I'll mention the simplest way. This way doesn't give the most realistic 'feel' for rotation though.

declare 3 floats: rotationX,rotationY,rotationZ
all initially 0.

Assuming you know how to track how much the mouse has moved between mouse move messages (if you don't know how, i can explain)

each time the mouse moves, if the left mouse button is down track delta_X, delta_Y which is the amount the mouse has moved since the last mouse move.

if deltaX is negative decrement rotationY by some value - let's say 5 degrees (I've arbitrarily selected horizontal mouse movement for rotation about Y-axis - this is the standard though).
if deltaX is positive increment it.

rotation about X axis is analogous, swapping in horizontal mouse motion.

for Z rotation, you can check if the CTRL key is down as well as the left mouse button, if it is then rotate in Z.

then in your drawing code:


glLoadIdentity();
glRotate(rotationX,1,0,0);
glRotate(rotationY,0,1,0);
glRotate(rotationZ,0,0,1);
//draw your beam.
hope this stuff helps.

mmsgl
12-08-2004, 08:38 AM
OK thanks for your help thus far. :D

Now that I know it can be done, I will sit down and try to better understand the samples I had previously found, and the new one you have provided a link for.

I will probably be back with more questions as I get further into this (as I stated before, this will be my first go at using OpenGL).

mmsgl
12-08-2004, 06:53 PM
I managed to create one cuboid like so:

glBegin(GL_QUADS);

//top
glColor3f(0.0f,1.0f,0.0f); // green
glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right
glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left
glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom Left
glVertex3f( 1.0f, 1.0f, 1.0f); // Bottom Right
.
.
.
<5 more sides of this cuboid>

glEnd();And was successful in rotating that shape.

Now I have to do this 2 more times (ie 2 more cuboids) to represent my "I" shape?

Before I get to deep into this, I want to make sure I am going in the right direction.

Good so far?

Aeluned
12-09-2004, 07:17 AM
I think you're on the right track.

mmsgl
12-09-2004, 08:01 AM
OK.

Defining the three front faces that make up the cross-section is relatively easy.

I then have 3 rectangles X 6 faces per cube = 18 sides (faces) to define.

I just wanted to make sure there was no automatic way that OpenGL could generate all other faces of the cuboid since this cross-section was the same (continuous) from front to back. This obviously then would be much less work, with less chance of making errors.

P.S. This is kind of exciting! :D

Aeluned
12-09-2004, 08:22 AM
nope. no automatic face generation, you have to tough it out :)

mmsgl
12-09-2004, 09:01 AM
OK :)

mmsgl
12-09-2004, 07:15 PM
Well I have a beam drawn :D

Looks pretty good, except that I have each face a different color. This is good for debugging as I can see each face clearly and watch what it does... I'll try to improve this later.

Rotation works, but not exactly as it should.

I'm sure it was working properly initially, but now it rotates in a giant arc. I think it might have something to do with me adding "zoom out" code. I had to do this because my beam is so big, it completely fills the window and the shape can not be seen.

Perhaps an explanation will help me in understanding why it is rotating as though it is "orbiting" around a distant point, rather than about it's own axis. Again, I am confused because I didn't change the rotation code, only added "zoom out" code.

def
12-10-2004, 07:45 AM
Rotation is always done around the center axis (0, 0, 0) coordinates. You propably translated our beam away from the world center instead of using the glScale function !?!

The automatic way you were looking for would be a function you have to write yourself. This is called an extrusion in most CAD applications.
Setup your vertices of the cross section in an array and write a function which generates QUADS between those vertices and the same set of vertices with a different z value (if the cross section is defined in the xy plane)

Given this function you would only need to supply the cross section and the length of the extrusion and the 3D faces would be created automatically. The next step would be to close the front and back of the beam...

Have fun

Aeluned
12-10-2004, 07:49 AM
This is happening because of the translation you've added to the modelview matrix. The origin of your object's local coordinate system changes after this translation (i.e. it is no longer at the same point as the world's origin). You need to translate the object back to the world origin, perform the rotation and then translate it back...this isn't necessary to achieve what you're trying to do; use glScale to scale the object up or down, like this:

//scales the object to 50% of its original size
glRotate();
glScalef(.5,.5,.5);
//draw object.

mmsgl
12-10-2004, 08:44 AM
def and Aeluned:

glScalef()

I wasn't aware of this function, so what I did was "zoom out" at startup and this explains why my face-on view appears as an isometric (fades to a vanishing point).

I will correct with the glScalef function.

def:
I understand the term "extrusion" as it applies in a manufacturing sense, so I underdstand exactly what you are getting at.

Do you know of any posted web samples that demonstrates this technique that you could refer me to?

all:
I think I should step back and familiarize myself with some OpenGL terms (modelview matrix, world origin, local coordinate system, etc) and concepts; I don't really understand these.

Is there a tutorial somewhere that explains this well somewhere (outside of code examples)?

I have looked a NeHe's site, but I get lost in all the code.

Using OpenGL is not trivial! :eek: (I might be in way over my head) :(

Aeluned
12-10-2004, 08:50 AM
This is a good read:
http://www.opengl.org/documentation/red_book_1.0/

mmsgl
12-10-2004, 09:11 AM
The OpenGL "Redbook" looks like exactly what I need.

Thanks! :)

def
12-10-2004, 10:03 AM
Actually there is a Library for doing Extrusions and other neat things in OpenGL. Its called GLE and you can find it here:
http://www.linas.org/gle/index.html

Writing your own simple extrusion function without capping would probably be easier than compiling and using the library, but it has some nice features.

:D Everybody should read the Red Book, and then the Blue Book. Mine is from 1993...

mmsgl
12-10-2004, 10:45 PM
OK I will try to write my own then.

Thanks!

mmsgl
12-11-2004, 10:57 AM
OK I have my CapAndExtrude function made and it works.

Changed "zoom out" to glScalef(.1,.1,.1); and this works great as my rotation now seems as though it is happening about the centroid (no "orbiting").

My initial display of my beam is face on, but still receeds to a vanishing point.

I think I want this initial presentation to be a true face-on view (showing cross-section only).

Any ideas as to why this is happening and how I can correct it?

def
12-12-2004, 01:27 PM
Originally posted by mmsgl:
My initial display of my beam is face on, but still receeds to a vanishing point.
Hmm, not sure what you are saying, but this could be because of no depth sorting (enable the depth buffer). The extruded faces seem to be drawn on top of the cap...
With depth enabled, the OpenGL renderer determines if a polygon is in front or behind another polygon.

Aeluned
12-13-2004, 06:40 AM
Just to clarify, depth testing works at the fragment level, which is much finer granularity than polygon level.

if you want to use depth testing:


glEnable(GL_DEPTH_TEST); //enable it
glDepthMask(GL_TRUE); //enable writing to depth buffer I'm not sure this is the problem though (you would have seen pretty bad artifacts without this).

Are you drawing your beam with its center at the center of the flange?

if you use the center of the flange as the center and render that at the world origin you should get a true cross section view (i.e. you won't see that the cross section has any depth).

perhaps you can have a toggle button that switches the render mode from 3D Perspective to a true cross-section view (where you set the depth of the flange and webs to 0).

mmsgl
12-13-2004, 07:09 AM
I have taken my origin (0,0,0) at the center of gravity of the 3D shape.

ie in the x-y plane, my origin is in the centre of the web both vertically and horizontally, and in the z direction it is half way down the length of the beam.

I think this correct because when I rotate it in any of the three directions there is no "wobble", but a rotation that seems natural.

I know this must be very confusing, because I am not using the correct terminology yet as I still don't know it.

If I understand you correctly however, this "receeding look" is because my shape has depth, and there is no way around this other than to make the depth = 0 if I want a true end view. I think I can do that.

I thought it might have something to do where the camera was positioned.

FireCat12
12-14-2004, 07:12 AM
It probably does have something to do with where the camera is positioned. If your object is positioned so that the direction extrusion is parallel to the cameras forward vector and the object has a flat front you should see a flat view.

For example a cube with data points
(-1,-1,1),
(1,-1,1),
(1,1,1),
(-1,1,1),
(-1,-1,-1),
(1,-1,-1),
(1,1,-1),
(-1,1,-1)

appears to be a square if viewed with the camera at
(0,0,3) looking along the vector (0,0,-1).

Aeluned
12-14-2004, 07:47 AM
Yeah, but the problem here is that he also has two 'webs' (is that the proper lingo mmsgl?) at both the top and bottom of the flange that are positioned not directly in front of the camera.

since the camera's 'forward' vector isn't perpendicular to the front faces of these objects you'll notice their depth.

mmsgl
12-14-2004, 12:00 PM
Yeah, but the problem here is that he also has two 'webs' (is that the proper lingo mmsgl?) at both the top and bottom of the flange that are positioned not directly in front of the camera.You have it backwards, there are two flanges (top & bottom horizontal members) and 1 web (vertical member) :D



since the camera's 'forward' vector isn't perpendicular to the front faces of these objects you'll notice their depth.I have been busy reading (and trying to absorb) some of the material in the "Redbook" you referenced me to.

Still not grasping camera's 'forward' vector so I could see if it somehow relates to:



If your object is positioned so that the direction extrusion is parallel to the cameras forward vector and the object has a flat front you should see a flat view.

Aeluned
12-14-2004, 12:08 PM
A camera's orientation is defined by 2 vectors:
the 'Look At' vector and the up vector.

The look at vector (referred to by FireCat as the 'forward' vector) is the vector that points straight out of the lens.

The up vector is used to define the orientation of the camera's object space coordinate system.

mmsgl
12-14-2004, 06:23 PM
OK almost solved! :D
I added a message box before this call:


...appears to be a square if viewed with the camera at
(0,0,3) looking along the vector (0,0,-1).When I originally put this code together it was cut & paste from a number of samples, and it is only now that I have to start adjusting settings etc, that I am actually learning the individual functions.

def
12-15-2004, 12:55 AM
It's important to know how the OpenGL "camera" or "eye" works.
This is my definition:
Since the camera has no geometric data (triangles, materials, etc.) it cannot be translated or rotated. In OpenGL the camera is always (!!!) at the center of the global coordinate system.
When people say, "position the camera at 2,1,-3", in OpenGL you really translate all the scene data to -2, -1, 3. The camera is not changed.
The GluLookAt function, for example, applies a rotation and a translation which will affect all the following geometric calls.
Without using GluLookAt() the camera is at 0,0,0 and is looking down the positiv z-axis.

The GluPerspective() or GluOrtho2D() functions affect the perspective view of the camera - like using the zoom on your photocamera.

mmsgl
12-17-2004, 05:09 PM
I've read up on the gluPerspective function and decided none of the parameters were causing this "receeding view".

I changed all the parameters anyways (individually) just in case, and other than changing the view angles, and distance from object, the "receeding view" remained.

I am posting my code in the hopes that someone can see what is happening and help me out.
(I've tried to figure it out myself, but I am honestly stuck)

The code below is complete and will build in an empty VC++ project.

edit
The code tags seems to have deleted all the blank lines between functions, etc.
It doesn't look this confusing in my code editor.


#include <windows.h> // must include this before GL/gl.h
#include <GL/gl.h> // OpenGL header file
#include <GL/glu.h> // OpenGL utilities header file
#include <stdio.h>

#pragma comment(lib, "opengl32.lib") // This is our basic software OpenGL library
#pragma comment(lib, "glu32.lib") // This is our glu32 library

enum
{
PAN = 1, // pan state bit
ROTATE, // rotate state bits
ZOOM // zoom state bit
};


HDC hDC; // device context
HPALETTE hPalette = 0; // custom palette (if needed)
GLfloat trans[3]; // current translation
GLfloat rot[2]; // current rotation
bool keys[256];
GLfloat zoom = 0.0f;


GLfloat Vertex[2][12];
GLfloat Length;

LONG WINAPI WindowProc(HWND, UINT, WPARAM, LPARAM);
HWND CreateOpenGLWindow(char* , int, int, int, int, BYTE, DWORD);
void init();
void display();
void reshape(int, int);
static void update(int, int, int, int, int);

static void GenerateCrossSection();
static void GenerateBeam3D();






int APIENTRY WinMain(HINSTANCE hCurrentInst, HINSTANCE hPreviousInst,
LPSTR lpszCmdLine, int nCmdShow)
{
HGLRC hRC; // opengl context
HWND hWnd; // window
MSG msg; // message
DWORD buffer = PFD_DOUBLEBUFFER; // buffering type
BYTE color = PFD_TYPE_RGBA; // color type

hWnd = CreateOpenGLWindow("OpenGL", 0, 0, 256, 256, color, buffer);
if (hWnd == NULL)
exit(1);

hDC = GetDC(hWnd);
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);

init();

ShowWindow(hWnd, nCmdShow);

while(GetMessage(&amp;msg, hWnd, 0, 0))
{
TranslateMessage(&amp;msg);
DispatchMessage(&amp;msg);
}

wglMakeCurrent(NULL, NULL);
ReleaseDC(hWnd,hDC);
wglDeleteContext(hRC);
DestroyWindow(hWnd);
if (hPalette) DeleteObject(hPalette);

return msg.wParam;
}

LONG WINAPI WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static PAINTSTRUCT ps;
static GLuint state = 0; // mouse state flag
static int omx, omy, mx, my;

switch(uMsg)
{
case WM_PAINT:
display();
BeginPaint(hWnd, &amp;ps);
EndPaint(hWnd, &amp;ps);
return 0;
case WM_CREATE:
GenerateCrossSection();
return 0;
case WM_SIZE:
reshape(LOWORD(lParam), HIWORD(lParam));
PostMessage(hWnd, WM_PAINT, 0, 0);
return 0;
case WM_CHAR:
switch (wParam)
{
case 27: // "ESC" key
PostQuitMessage(0); // Quit
break;
case 65: // "A" key
zoom +=0.05f; // Zoom In
PostMessage(hWnd, WM_PAINT, 0, 0);
break;
case 90: // "Z" key
zoom -=0.05f; // Zoom Out
PostMessage(hWnd, WM_PAINT, 0, 0);
break;
}
return 0;
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
SetCapture(hWnd);
mx = LOWORD(lParam);
my = HIWORD(lParam);
if (uMsg == WM_LBUTTONDOWN)
state |= PAN;
if (uMsg == WM_RBUTTONDOWN)
state |= ROTATE;
return 0;
case WM_LBUTTONUP:
case WM_RBUTTONUP:
ReleaseCapture();
state = 0;
return 0;
case WM_MOUSEMOVE:
if (state)
{
omx = mx;
omy = my;
mx = LOWORD(lParam);
my = HIWORD(lParam);
if(mx & 1 << 15) mx -= (1 << 16);
if(my & 1 << 15) my -= (1 << 16);
update(state, omx, mx, omy, my);
PostMessage(hWnd, WM_PAINT, 0, 0);
}
return 0;
case WM_PALETTECHANGED:
if (hWnd == (HWND)wParam)
break;
case WM_QUERYNEWPALETTE:
if (hPalette)
{
UnrealizeObject(hPalette);
SelectPalette(hDC, hPalette, FALSE);
RealizePalette(hDC);
return TRUE;
}
return FALSE;
case WM_CLOSE:
PostQuitMessage(0);
return 0;
}

return DefWindowProc(hWnd, uMsg, wParam, lParam);
}



HWND
CreateOpenGLWindow(char* title, int x, int y, int width, int height,
BYTE type, DWORD flags)
{
int n, pf;
HWND hWnd;
WNDCLASS wc;
LOGPALETTE* lpPal;
PIXELFORMATDESCRIPTOR pfd;
static HINSTANCE hInstance = 0;

if (!hInstance)
{
hInstance = GetModuleHandle(NULL);
wc.style = CS_OWNDC;
wc.lpfnWndProc = (WNDPROC)WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = "OpenGL";

if (!RegisterClass(&amp;wc))
{
MessageBox(NULL, "RegisterClass() failed: "
"Cannot register window class.", "Error", MB_OK);
return NULL;
}
}

hWnd = CreateWindow("OpenGL", title, WS_OVERLAPPEDWINDOW |
WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
x, y, width, height, NULL, NULL, hInstance, NULL);

if (hWnd == NULL)
{
MessageBox(NULL, "CreateWindow() failed: Cannot create a window.",
"Error", MB_OK);
return NULL;
}

hDC = GetDC(hWnd);

memset(&amp;pfd, 0, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | flags;
pfd.iPixelType = type;
pfd.cDepthBits = 32;
pfd.cColorBits = 32;

pf = ChoosePixelFormat(hDC, &amp;pfd);
if (pf == 0)
{
MessageBox(NULL, "ChoosePixelFormat() failed: "
"Cannot find a suitable pixel format.", "Error", MB_OK);
return 0;
}

if (SetPixelFormat(hDC, pf, &amp;pfd) == FALSE)
{
MessageBox(NULL, "SetPixelFormat() failed: "
"Cannot set format specified.", "Error", MB_OK);
return 0;
}

DescribePixelFormat(hDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &amp;pfd);

ReleaseDC(hWnd,hDC);
return hWnd;
}


void init()
{
glEnable(GL_DEPTH_TEST);
}

void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(trans[0], trans[1], trans[2]);
glRotatef(rot[0], 1.0f, 0.0f, 0.0f);
glRotatef(rot[1], 0.0f, 1.0f, 0.0f);
glScalef(.05,.05,.05); // scale to 5%
glTranslatef(0.0f, -0.0f, zoom);

GenerateBeam3D(); // my cap & extrude function

glPopMatrix();
glFlush();
SwapBuffers(hDC); // nop if singlebuffered
}

void reshape(int width, int height)
{

glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
MessageBox(NULL, "Pause!", "Debug", MB_OK);
gluPerspective(60.0, (float)width/height, 0.001, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -3.0f);
}


static void update(int state, int ox, int nx, int oy, int ny)
{
int dx = ox - nx;
int dy = ny - oy;

switch(state)
{
case PAN:
trans[0] -= dx / 100.0f;
trans[1] -= dy / 100.0f;
break;
case ROTATE:
rot[0] += (dy * 180.0f) / 500.0f;
rot[1] -= (dx * 180.0f) / 500.0f;
#define clamp(x) x = x > 360.0f ? x-360.0f : x < -360.0f ? x+=360.0f : x
clamp(rot[0]);
clamp(rot[1]);
break;
case ZOOM:
trans[2] -= (dx+dy) / 100.0f;
break;
}
}

static void GenerateCrossSection()
{
Length=20;

Vertex[0][ 0] = 7; Vertex[1][ 0] = 9;
Vertex[0][ 1] = -7; Vertex[1][ 1] = 9;
Vertex[0][ 2] = -7; Vertex[1][ 2] = 6;
Vertex[0][ 3] = -1; Vertex[1][ 3] = 6;
Vertex[0][ 4] = -1; Vertex[1][ 4] = -6;
Vertex[0][ 5] = -7; Vertex[1][ 5] = -6;
Vertex[0][ 6] = -7; Vertex[1][ 6] = -9;
Vertex[0][ 7] = 7; Vertex[1][ 7] = -9;
Vertex[0][ 8] = 7; Vertex[1][ 8] = -6;
Vertex[0][ 9] = 1; Vertex[1][ 9] = -6;
Vertex[0][10] = 1; Vertex[1][10] = 6;
Vertex[0][11] = 7; Vertex[1][11] = 6;
}

static void GenerateBeam3D()
{
glBegin(GL_QUADS);
//glBegin(GL_POLYGON);

// Cap

// front face
glColor3f(0.0f,1.0f,0.0f); // green
glVertex3f(Vertex[0][ 0],Vertex[1][ 0],(Length/2));
glVertex3f(Vertex[0][ 1],Vertex[1][ 1],(Length/2));
glVertex3f(Vertex[0][ 2],Vertex[1][ 2],(Length/2));
glVertex3f(Vertex[0][11],Vertex[1][11],(Length/2));
glVertex3f(Vertex[0][ 3],Vertex[1][ 3],(Length/2));
glVertex3f(Vertex[0][ 4],Vertex[1][ 4],(Length/2));
glVertex3f(Vertex[0][ 9],Vertex[1][ 9],(Length/2));
glVertex3f(Vertex[0][10],Vertex[1][10],(Length/2));
glVertex3f(Vertex[0][ 8],Vertex[1][ 8],(Length/2));
glVertex3f(Vertex[0][ 5],Vertex[1][ 5],(Length/2));
glVertex3f(Vertex[0][ 6],Vertex[1][ 6],(Length/2));
glVertex3f(Vertex[0][ 7],Vertex[1][ 7],(Length/2));

// back face
glColor3f(0.0f,1.0f,0.0f); // green
glVertex3f(Vertex[0][ 0],Vertex[1][ 0],-(Length/2));
glVertex3f(Vertex[0][ 1],Vertex[1][ 1],-(Length/2));
glVertex3f(Vertex[0][ 2],Vertex[1][ 2],-(Length/2));
glVertex3f(Vertex[0][11],Vertex[1][11],-(Length/2));
glVertex3f(Vertex[0][ 3],Vertex[1][ 3],-(Length/2));
glVertex3f(Vertex[0][ 4],Vertex[1][ 4],-(Length/2));
glVertex3f(Vertex[0][ 9],Vertex[1][ 9],-(Length/2));
glVertex3f(Vertex[0][10],Vertex[1][10],-(Length/2));
glVertex3f(Vertex[0][ 8],Vertex[1][ 8],-(Length/2));
glVertex3f(Vertex[0][ 5],Vertex[1][ 5],-(Length/2));
glVertex3f(Vertex[0][ 6],Vertex[1][ 6],-(Length/2));
glVertex3f(Vertex[0][ 7],Vertex[1][ 7],-(Length/2));

// extrude

// top flange outside
glColor3f(0.0f,0.0f,1.0f); // blue
glVertex3f(Vertex[0][ 0],Vertex[1][ 0], (Length/2));
glVertex3f(Vertex[0][ 0],Vertex[1][ 0],-(Length/2));
glVertex3f(Vertex[0][ 1],Vertex[1][ 1],-(Length/2));
glVertex3f(Vertex[0][ 1],Vertex[1][ 1], (Length/2));

// top flange left side
glColor3f(1.0f,1.0f,0.0f); // yellow
glVertex3f(Vertex[0][ 1],Vertex[1][ 1], (Length/2));
glVertex3f(Vertex[0][ 1],Vertex[1][ 1],-(Length/2));
glVertex3f(Vertex[0][ 2],Vertex[1][ 2],-(Length/2));
glVertex3f(Vertex[0][ 2],Vertex[1][ 2], (Length/2));

// top flange underside left
glColor3f(1.0f,0.0f,1.0f); // violet
glVertex3f(Vertex[0][ 2],Vertex[1][ 2], (Length/2));
glVertex3f(Vertex[0][ 2],Vertex[1][ 2],-(Length/2));
glVertex3f(Vertex[0][ 3],Vertex[1][ 3],-(Length/2));
glVertex3f(Vertex[0][ 3],Vertex[1][ 3], (Length/2));

// web left side
glColor3f(1.0f,0.5f,0.0f); // orange
glVertex3f(Vertex[0][ 3],Vertex[1][ 3], (Length/2));
glVertex3f(Vertex[0][ 3],Vertex[1][ 3],-(Length/2));
glVertex3f(Vertex[0][ 4],Vertex[1][ 4],-(Length/2));
glVertex3f(Vertex[0][ 4],Vertex[1][ 4], (Length/2));

// btm flange inside left
glColor3f(1.0f,0.0f,1.0f); // violet
glVertex3f(Vertex[0][ 4],Vertex[1][ 4], (Length/2));
glVertex3f(Vertex[0][ 4],Vertex[1][ 4],-(Length/2));
glVertex3f(Vertex[0][ 5],Vertex[1][ 5],-(Length/2));
glVertex3f(Vertex[0][ 5],Vertex[1][ 5], (Length/2));

// btm flange left side
glColor3f(1.0f,1.0f,0.0f); // yellow
glVertex3f(Vertex[0][ 5],Vertex[1][ 5], (Length/2));
glVertex3f(Vertex[0][ 5],Vertex[1][ 5],-(Length/2));
glVertex3f(Vertex[0][ 6],Vertex[1][ 6],-(Length/2));
glVertex3f(Vertex[0][ 6],Vertex[1][ 6], (Length/2));

// btm flange outside
glColor3f(0.0f,0.0f,1.0f); // blue
glVertex3f(Vertex[0][ 6],Vertex[1][ 6], (Length/2));
glVertex3f(Vertex[0][ 6],Vertex[1][ 6],-(Length/2));
glVertex3f(Vertex[0][ 7],Vertex[1][ 7],-(Length/2));
glVertex3f(Vertex[0][ 7],Vertex[1][ 7], (Length/2));

// btm flange right side
glColor3f(1.0f,1.0f,0.0f); // yellow
glVertex3f(Vertex[0][ 7],Vertex[1][ 7], (Length/2));
glVertex3f(Vertex[0][ 7],Vertex[1][ 7],-(Length/2));
glVertex3f(Vertex[0][ 8],Vertex[1][ 8],-(Length/2));
glVertex3f(Vertex[0][ 8],Vertex[1][ 8], (Length/2));

// btm flange inside right
glColor3f(1.0f,0.0f,1.0f); // violet
glVertex3f(Vertex[0][ 8],Vertex[1][ 8], (Length/2));
glVertex3f(Vertex[0][ 8],Vertex[1][ 8],-(Length/2));
glVertex3f(Vertex[0][ 9],Vertex[1][ 8],-(Length/2));
glVertex3f(Vertex[0][ 9],Vertex[1][ 9], (Length/2));

// web right side
glColor3f(1.0f,0.5f,0.0f); // orange
glVertex3f(Vertex[0][ 9],Vertex[1][ 9], (Length/2));
glVertex3f(Vertex[0][ 9],Vertex[1][ 9],-(Length/2));
glVertex3f(Vertex[0][10],Vertex[1][10],-(Length/2));
glVertex3f(Vertex[0][10],Vertex[1][10], (Length/2));

// top flange inside right
glColor3f(1.0f,0.0f,1.0f); // violet
glVertex3f(Vertex[0][10],Vertex[1][10], (Length/2));
glVertex3f(Vertex[0][10],Vertex[1][10],-(Length/2));
glVertex3f(Vertex[0][11],Vertex[1][11],-(Length/2));
glVertex3f(Vertex[0][11],Vertex[1][11], (Length/2));

// top flange right side
glColor3f(1.0f,1.0f,0.0f); // yellow
glVertex3f(Vertex[0][11],Vertex[1][11], (Length/2));
glVertex3f(Vertex[0][11],Vertex[1][11],-(Length/2));
glVertex3f(Vertex[0][ 0],Vertex[1][ 0],-(Length/2));
glVertex3f(Vertex[0][ 0],Vertex[1][ 0], (Length/2));

glEnd();
}

gmeed
12-17-2004, 05:35 PM
Originally posted by mmsgl:
I've read up on the gluPerspective function and decided none of the parameters were causing this "receeding view".Have you also looked at the gluOrtho2D function that def mentioned? The "receding" look you've described sounds exactly like perspective projection - the way we see things in the real world. To eliminate the perspective and get both ends of an extruded object to be the same size on the screen, use gluOrtho2D.

(I hope I didn't just jump into the middle of this thread and miss the point completely :p )

mmsgl
12-17-2004, 07:45 PM
No I haven't looked at gluOrtho2D function that both def and Aeluned suggested yet,
because I was trying to get gluPerspective to do the same thing as per FireCat12's post.

I will have to do as Aeluned suggested and add a toggle button that switches the render mode from 3D to 2D. I was hoping I could get it to, (as it is being rotated in the y-z plane) at 90 degree points (ie front, top, rear, bottom views), display true views (no recedding lines).
I don't think this would look natural though, plus I would have to somehow calculate when the rotation was at a 90 degree point.

And no you didn't miss the point, you understood exactly my problem. :)

gmeed
12-17-2004, 08:36 PM
Originally posted by mmsgl:
I was hoping I could get it to, (as it is being rotated in the y-z plane) at 90 degree points (ie front, top, rear, bottom views), display true views (no recedding lines).Now I'm not sure what look you're going for. What do you mean by "true" views? To me that means views like we have in the real world, where things do look smaller when they're farther away, but you don't want that.

Are you trying to do something like this picture (http://www.crowle.de/blender_tutorials/tut4_kaffee/Kaffee2.gif) , with ortho views from the top, side, etc to get accurate measurements, and another view to see what it really looks like in real life?

mmsgl
12-17-2004, 09:35 PM
I know, it's hard for me to choose the correct words to convey my meaning, especially because I don't know the proper OpenGL lingo.

I am using the wrong words when i say "true-view",
I should say "orthographic" view; so I would have
6 of these (front, top, rear, bottom, left-side, right-side), any other position of the object as it is rotated should be an isometric view.

The picture you referred me to, is much more sophisticated than my project, so it is hard for me to compare.

If you run my project, I think it will be clear where my problem is; the display opens with an orthographic front view (what I want), but only because I added a MessageBox to create a "pause" in the program execution. As soon as the MessageBox is dismissed, the display draws a front view again, but this time not orthographic anymore. When the right mouse button is held and the object it rotated I am getting the views as I want (isometric).

I appreciate your patience. :)

Overmind
12-18-2004, 06:33 AM
Yep, orthographic is the correct term ;)

For an orthographic projection you should use glOrtho instead of gluPerspective.

gluPerspective and glFrustum are for perspective rendering, glOrtho is for orthographic rendering. Don't use gluOrtho2D, it is used for 2D rendering...

mmsgl
12-18-2004, 09:33 PM
IT WORKS!!

glOrtho is what was required!

One small problem, the back end of a long "beam" is distorted.

I'm going to guess it has something to do with the setting of my far clipping plane.

I will investigate this.

Anyway, thanks for now!

gmeed
12-19-2004, 06:47 AM
Originally posted by mmsgl:
IT WORKS!!

glOrtho is what was required!

One small problem, the back end of a long "beam" is distorted.

I'm going to guess it has something to do with the setting of my far clipping plane.

I will investigate this.

Anyway, thanks for now!Alright!

But there's nothing you can do about the distortion. If the far end of the beam weren't distorted, it'd be smaller than the near end :p

mmsgl
12-19-2004, 12:42 PM
Maybe distortion is the wrong word; the far end was not parallel to the front end, and both near end and far end are identical (same cross-section). I was sure there was something wrong with the display of the far end.

I managed to fix this by adjusting the zFar parameter of glOrtho function.

I get lucky sometimes, as I don't understand why it fixes it.

The length of my beam is 200 units and this is my glOrtho code:

glOrtho(-5.0, 5.0, -5.0*(GLfloat)h/(GLfloat)w,5.0*(GLfloat)h/(GLfloat)w, -5.0, 50.0);I would have thought only a length of 55 units would have fit properly (50.0 - -5.0) :confused:

gmeed
12-19-2004, 08:29 PM
Originally posted by mmsgl:
I would have thought only a length of 55 units would have fit properly (50.0 - -5.0)Well, if you've still got this in your code: "glScalef(.05,.05,.05); // scale to 5%" ... .

Why don't you post a picture of the "distortion" problem.

mmsgl
12-19-2004, 08:32 PM
I don't see how to attach pictures or files using this board.

gmeed
12-19-2004, 09:22 PM
Originally posted by mmsgl:
I don't see how to attach pictures or files using this board.I haven't seen it done, either. You'd have to post a link.

mmsgl
12-20-2004, 03:59 AM
I don't know how to do that either; I only know how to post a link to a URL.

Oh well.

mmsgl
12-20-2004, 07:47 PM
Aeluned:

In one of your earlier posts you stated correctly that where the flange and web meet there is a radiused transition from one to the other, and that this could be addressed in the OpenGL representation of my "W" shape.

Could you explain now how this can be done?

(Once I finish this I can then move on to the next step in my project)

Aeluned
12-21-2004, 06:59 AM
Alright, what you need is 4 arcs to place at the meeting points where the web meets the flanges.
The arcs span PI/2.0 (or 90 degrees) and have a depth equal to that of the flanges, you'll also need caps at the end of the arcs to align with the surface and back face of the beam. This sort of stuff is always so much simpler to demonstrate on paper :(

There are two ways you can approach the problem:

Use OpenGL and procedurally generate the vertices needed to define these arcs (an alternative is to use OpenGL evaluators - glEvalMesh, glMap2f, etc... which will evaluate a Bezier surface patch given a set of control points). You may or may not need to dust off a trig and/or geometry book if taking this approach.

my suggestion is to forget everything above and get familiar with the very basics of a modeling software app (like 3D studio max). You can visually create a beam there (with a radial transition from the web to the flanges) and export it from there. Then load the model into your openGL app. There are libraries available for importing well known file extensions into an OpenGL app.

check out:
http://www.gametutorials.com/Tutorials/opengl/OpenGL_Pg4.htm

there are some object loaders there.

There's also 3DCafe.com. You'll see a 'free stuff' link toward the top; they have hundreds (maybe thousands) of 3D models there (you might find a beam if you're lucky).

mmsgl
12-21-2004, 05:42 PM
OK thanks!

I am going to go the OpenGL route,(probably your first option).

Wish me luck (I'll probably have questions in a few days :D )

mmsgl
12-22-2004, 06:53 PM
OK, I found a number of samples regarding producing circles in OpenGL, and they all work quite well.

When I try to incorprate into my project I am having a few minor difficulties (no errors, just no circle display).

I understand now the OpenGL concept that complex shapes are just a series of basic shapes (quads, triangles, etc) that combine to form the complex shape.

My beam is made up of three quads and now four quarter circles.

In my code which I had previously posted, I do this to define my 3 quads:

glBegin(GL_QUADS);
//define 3 quads (top flange, btm flange, web)
glVertex3f(Vertex[0][ 0],Vertex[1][ 0],(Length/2));
<additional glVertex3f calls here>
glEnd();The code I am using for the circle uses GL_POLYGON thus:
glBegin(GL_POLYGON);

In trying to combine quads and polygons, I did this:

glBegin(GL_QUADS);
//define 3 quads (top flange, btm flange, web)
glVertex3f(Vertex[0][ 0],Vertex[1][ 0],(Length/2));
<additional glVertex3f calls here>

//define a circle
glBegin(GL_POLYGON);
<circle code>
glEnd();
glEnd();In other words, I nested one glBegin/End block inside another.

Is this correct?

mmsgl
12-23-2004, 07:52 PM
Got the "caps" working for the 4 radiused flange to web transitions. :D

Now to figure out the "extrusions" for these.

Aeluned
12-27-2004, 11:10 AM
You can't nest glBegin/glEnd calls; You'll generate an error.

You'll need to render your arcs before or after the quads. As far as I can see, the order is of no consequence. depth writes and depth tests should produce proper results regardless of the render order.

mmsgl
12-27-2004, 09:25 PM
Yes, I found this out by trial and error.

I have the "radiused corner" almost working, but I need a little bit of help as the extruded portion is somewhat transparent instead of a solid color.

Here is what I came up with:
(Rotating with the right mouse button seems to work OK except that I am not getting a solid color.)

#include <windows.h> // must include this before GL/gl.h
#include <GL/gl.h> // OpenGL header file
#include <GL/glu.h> // OpenGL utilities header file
#include <stdio.h>
#include <math.h>

#pragma comment(lib, "opengl32.lib") // This is our basic software OpenGL library
#pragma comment(lib, "glu32.lib") // This is our glu32 library

enum
{
PAN = 1, // pan state bit
ROTATE, // rotate state bits
ZOOM // zoom state bit
};


HDC hDC; // device context
HPALETTE hPalette = 0; // custom palette (if needed)
GLfloat trans[3]; // current translation
GLfloat rot[2]; // current rotation
bool keys[256];
GLfloat zoom = 0.0f;



LONG WINAPI WindowProc(HWND, UINT, WPARAM, LPARAM);
HWND CreateOpenGLWindow(char* , int, int, int, int, BYTE, DWORD);
void init();
void display();
void reshape(int, int);
static void update(int, int, int, int, int);

static void drawRadiusedCorner();


int APIENTRY WinMain(HINSTANCE hCurrentInst, HINSTANCE hPreviousInst,
LPSTR lpszCmdLine, int nCmdShow)
{
HGLRC hRC; // opengl context
HWND hWnd; // window
MSG msg; // message
DWORD buffer = PFD_DOUBLEBUFFER; // buffering type
BYTE color = PFD_TYPE_RGBA; // color type

hWnd = CreateOpenGLWindow("OpenGL", 0, 0, 256, 256, color, buffer);
if (hWnd == NULL)
exit(1);

hDC = GetDC(hWnd);
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);

init();

ShowWindow(hWnd, nCmdShow);

while(GetMessage(&amp;msg, hWnd, 0, 0))
{
TranslateMessage(&amp;msg);
DispatchMessage(&amp;msg);
}

wglMakeCurrent(NULL, NULL);
ReleaseDC(hWnd,hDC);
wglDeleteContext(hRC);
DestroyWindow(hWnd);
if (hPalette) DeleteObject(hPalette);

return msg.wParam;
}

LONG WINAPI WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static PAINTSTRUCT ps;
static GLuint state = 0; // mouse state flag
static int omx, omy, mx, my;

switch(uMsg)
{
case WM_PAINT:
display();
BeginPaint(hWnd, &amp;ps);
EndPaint(hWnd, &amp;ps);
return 0;
case WM_SIZE:
reshape(LOWORD(lParam), HIWORD(lParam));
PostMessage(hWnd, WM_PAINT, 0, 0);
return 0;
case WM_CHAR:
switch (wParam)
{
case 27: // "ESC" key
PostQuitMessage(0); // Quit
break;
case 65: // "A" key
zoom +=0.05f; // Zoom In
PostMessage(hWnd, WM_PAINT, 0, 0);
break;
case 90: // "Z" key
zoom -=0.05f; // Zoom Out
PostMessage(hWnd, WM_PAINT, 0, 0);
break;
}
return 0;
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
SetCapture(hWnd);
mx = LOWORD(lParam);
my = HIWORD(lParam);
if (uMsg == WM_LBUTTONDOWN)
state |= PAN;
if (uMsg == WM_RBUTTONDOWN)
state |= ROTATE;
return 0;
case WM_LBUTTONUP:
case WM_RBUTTONUP:
ReleaseCapture();
state = 0;
return 0;
case WM_MOUSEMOVE:
if (state)
{
omx = mx;
omy = my;
mx = LOWORD(lParam);
my = HIWORD(lParam);
if(mx & 1 << 15) mx -= (1 << 16);
if(my & 1 << 15) my -= (1 << 16);
update(state, omx, mx, omy, my);
PostMessage(hWnd, WM_PAINT, 0, 0);
}
return 0;
case WM_PALETTECHANGED:
if (hWnd == (HWND)wParam)
break;
case WM_QUERYNEWPALETTE:
if (hPalette)
{
UnrealizeObject(hPalette);
SelectPalette(hDC, hPalette, FALSE);
RealizePalette(hDC);
return TRUE;
}
return FALSE;
case WM_CLOSE:
PostQuitMessage(0);
return 0;
}

return DefWindowProc(hWnd, uMsg, wParam, lParam);
}



HWND
CreateOpenGLWindow(char* title, int x, int y, int width, int height,
BYTE type, DWORD flags)
{
int n, pf;
HWND hWnd;
WNDCLASS wc;
LOGPALETTE* lpPal;
PIXELFORMATDESCRIPTOR pfd;
static HINSTANCE hInstance = 0;

if (!hInstance)
{
hInstance = GetModuleHandle(NULL);
wc.style = CS_OWNDC;
wc.lpfnWndProc = (WNDPROC)WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = "OpenGL";

if (!RegisterClass(&amp;wc))
{
MessageBox(NULL, "RegisterClass() failed: "
"Cannot register window class.", "Error", MB_OK);
return NULL;
}
}

hWnd = CreateWindow("OpenGL", title, WS_OVERLAPPEDWINDOW |
WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
x, y, width, height, NULL, NULL, hInstance, NULL);

if (hWnd == NULL)
{
MessageBox(NULL, "CreateWindow() failed: Cannot create a window.",
"Error", MB_OK);
return NULL;
}

hDC = GetDC(hWnd);

memset(&amp;pfd, 0, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | flags;
pfd.iPixelType = type;
pfd.cDepthBits = 32;
pfd.cColorBits = 32;

pf = ChoosePixelFormat(hDC, &amp;pfd);
if (pf == 0)
{
MessageBox(NULL, "ChoosePixelFormat() failed: "
"Cannot find a suitable pixel format.", "Error", MB_OK);
return 0;
}

if (SetPixelFormat(hDC, pf, &amp;pfd) == FALSE)
{
MessageBox(NULL, "SetPixelFormat() failed: "
"Cannot set format specified.", "Error", MB_OK);
return 0;
}

DescribePixelFormat(hDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &amp;pfd);

ReleaseDC(hWnd,hDC);
return hWnd;
}


void init()
{
glEnable(GL_DEPTH_TEST);
}

void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(trans[0], trans[1], trans[2]);
glRotatef(rot[0], 1.0f, 0.0f, 0.0f);
glRotatef(rot[1], 0.0f, 1.0f, 0.0f);
//glScalef(.05,.05,.05); // scale to 5%
glTranslatef(0.0f, -0.0f, zoom);

drawRadiusedCorner();

glPopMatrix();
glFlush();
SwapBuffers(hDC); // nop if singlebuffered
}

void reshape(int width, int height)
{

glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
MessageBox(NULL, "Pause!", "Debug", MB_OK);
//gluPerspective(60.0, (float)width/height, 0.001, 100.0);

//glOrtho ( left , right , bottom , top , zNear , zFar )
if (width <= height)
{
glOrtho(-5.0, 5.0, -5.0*(GLfloat)height/(GLfloat)width,
5.0*(GLfloat)height/(GLfloat)width, -5.0, 50.0);
}
else
{
glOrtho(-5.0*(GLfloat)width/(GLfloat)height,
5.0*(GLfloat)width/(GLfloat)height, -5.0, 5.0, -5.0, 50.0);
}



glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -3.0f);
}


static void update(int state, int ox, int nx, int oy, int ny)
{
int dx = ox - nx;
int dy = ny - oy;

switch(state)
{
case PAN:
trans[0] -= dx / 100.0f;
trans[1] -= dy / 100.0f;
break;
case ROTATE:
rot[0] += (dy * 180.0f) / 500.0f;
rot[1] -= (dx * 180.0f) / 500.0f;
#define clamp(x) x = x > 360.0f ? x-360.0f : x < -360.0f ? x+=360.0f : x
clamp(rot[0]);
clamp(rot[1]);
break;
case ZOOM:
trans[2] -= (dx+dy) / 100.0f;
break;
}
}


static void drawRadiusedCorner()
{
GLint i;
GLfloat cosine, sine;
GLfloat cosine2, sine2;

//front cap
glBegin(GL_POLYGON);
glColor3f(0.0f,1.0f,0.0f); // green
glVertex3f(1,1,1);
for(i=0;i<25;i++)
{
cosine=cos(i*2*3.14159/100.0);
sine=sin(i*2*3.14159/100.0);
glVertex3f(cosine,sine,1);
}
glEnd();

//rear cap
glBegin(GL_POLYGON);
glColor3f(0.0f,0.0f,1.0f); // blue
glVertex3f(1,1,-1);
for(i=0;i<25;i++)
{
cosine=cos(i*2*3.14159/100.0);
sine=sin(i*2*3.14159/100.0);
glVertex3f(cosine,sine,-1);
}
glEnd();

//extrusion
glBegin(GL_QUADS);
glColor3f(1.0f,1.0f,0.0f); // yellow
for(i=0;i<25;i=i+2)
{
cosine=cos(i*2*3.14159/100.0);
sine=sin(i*2*3.14159/100.0);
cosine2=cos((i+1)*2*3.14159/100.0);
sine2=sin((i+1)*2*3.14159/100.0);
glVertex3f(cosine,sine,1);
glVertex3f(cosine,sine,-1);
glVertex3f(cosine2,sine2,-1);
glVertex3f(cosine2,sine2,1);
}
glEnd();
}If anyone could spot my error, I would appreciate the help.

mmsgl
12-31-2004, 06:21 AM
I got the "radiused corner" working (caps and curved extrusion) and it looks good. :D

I need now to figure out how to position these
quarter circles in each of the four cartesian plane quadrants.

This should be trivial, but nothing I try works.

If anybody knows how to do this, and can save me hours of work, I'd appreciate some guidance.

Aeluned was right when he said I'd have to dust off some old trig books. :D

Aeluned
01-03-2005, 05:49 AM
There are two ways to position these rounded welds.

you can either explicitely define the vertices to match some set of the vertices on the beam OR you can position them using a series of:



glPushMatrix();
glRotate();
glTranslate();
glScale();
DrawWeld();
glPopMatrix();
you may not need some or all of the given transformations above, depending on where your weld arc is defined in world space.

It's difficult to give you definitive methods because I'm not sure exactly how you've implemented this.

mmsgl
01-03-2005, 04:01 PM
This is what I ended up doing:

void display()
{
glClear(GL_COLOR_BUFFER_BIT | L_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(trans[0], trans[1], trans[2]);
glRotatef(rot[0], 1.0f, 0.0f, 0.0f);
glRotatef(rot[1], 0.0f, 1.0f, 0.0f);
glScalef(.5,.5,.5);// scale to 50%
glTranslatef(0.0f, -0.0f, zoom);


drawRadiusedCornerQuadrant1(); //top left
drawRadiusedCornerQuadrant2(); //top right
drawRadiusedCornerQuadrant3(); //btm right
drawRadiusedCornerQuadrant4(); //btm left

glPopMatrix();
glFlush();
SwapBuffers(hDC);
}I needed a separate function for each of the 4 positions, as I couldn't figure out how to rotate the one generated figure in the other 3 positions.

I have these 4 corners in a separte project, and I now have to combine this in my existing "beam" code.

This is proving to be lots of work; still enjoying the challenge however.