Dreaded noob questions: OpenGL in a Cocoa App

5thPeriodProductions
Unregistered
 
Post: #1
The documentation on Apple's ADC reference site is a bit old in terms of implementing OpenGL in a Cocoa app. It assumes the use of ProjectBuilder and, as such, an older version of OS X. While I'm sure most of the information is revelant, I still have a question or two.

I'm using Xcode version 2.2.1 and Interface Builder version 2.5.3 on Mac OS X 10.4.6. (On a PPC Mac, if that even matters.)

If I want to add an NSOpenGLView do I have to make a custom subclass as in the example found on "Open GL Programming?"

And, I assume all the normal Cocoa interface elements can interact with said view? For example, a slider (NSSlider) to increase or decrease the number of divisions of a triangle (tessellation)?

I'm just getting started with OpenGL, and I'll be sticking to 2D until I'm comfortable with making the move to the wide world of 3D. So, bear with me and my silly questions... On the bright side, maybe this thread can help other newbies.
Quote this message in a reply
Moderator
Posts: 3,574
Joined: 2003.06
Post: #2
- Generally speaking, the older stuff that uses Project Builder works just fine with Xcode. The Interface Builder differences between versions usually aren't a big deal either, but as a developer you'll constantly be challenged to `keep up', so learning how to extrapolate is a good thing.

- You can hook Cocoa interface elements up to *anything*, so yes, you can use cocoa `whatever' to control OpenGL `whatever' -- easily.

- Don't worry about `sticking to 2D until...'. 3D and 2D are the same thing minus a dimension, it ain't that big a' deal. The only real difference is geometry. Not that I'm saying you should do it one way or another, but don't restrict yourself to one particular corner of the graphics galaxy just because you think that might help. Most of the documentation you will read for OpenGL will be written from the standpoint of 3D. It is just as easily used in 2D, but for whatever reason that is not obvious to beginners. What I'm saying is that it's good to keep your focus on 2D for whatever reason, but be sure to learn what 3D is about at least on a basic level along your way, don't go out of your way to avoid it.
Quote this message in a reply
5thPeriodProductions
Unregistered
 
Post: #3
Ah, thanks. I had no real intention of avoiding 3D, just putting it off 'til I had a grasp on OpenGL and GLUT in general.

My original post stems from reading through Chapter 2 of Edward Angel's Open GL: A Primer 2nd Edition (2005). In section 2.14.2 "Tessellation and Subdivision" there's some example code that I thought might be fun to tie in with Aqua interface elements as a sort of useless "look what can be done" app.

The window contains an OpenGL display area and two sliders. There's a triangle in the center of the OpenGL display. One slider subdivides/tessellates the triangle (but doesn't display all the inner triangles' edges). The second slider twists the triangle to make a curved object, so as you increase subdivision, the twisting gets smoother. The twist in the book makes a cool vortex-like shape. Having NO knowledge of calculus, I don't understand the whole idea of theta degrees, so I don't even have a clue where to start on making functions where the slider actually increases the amount of rotation that causes the twisting.

But, now, looking back through some of the example code, I'm a bit confused.

They have a function called triangle() that "takes three two-dimensional vertices and draws the resulting polygon"
Code:
void triangle(GLfloat *a, GLfloat *b, GLfloat *c)
{
  glBegin(GL_TRIANGLES);
  glVertex2fv(a);
  glVertex2fv(b);
  glVertex2fv(c);
  glEnd();
}

WHen calling triangle() and passing a, b, and c, I suppose that a, b, and c are defined elsewhere... Perhaps through user input.

The book then moves on to a recursive subdivision function (is it ok to call them methods?). It subdivides a single triangle m times and draws all the smaller triangles by the following code:
Code:
void divide_triangle(GLfloat a, GLfloat b, GLfloat c, int m)
{
  GLfloat v[3][2];
  int j;
  if(m>0)
  {
    for(j=0; j<2; j++) v[0][j] = (a[j] + b[j]/2;
    for(j=0; j<2; j++) v[1][j] = (a[j] + c[j]/2;
    for(j=0; j<2; j++) v[2][j] = (b[j] + c[j]/2;
    divide_triangle(a, v[0], v[1], m-1);
    divide_triangle(v[0], b, v[2], m-1);
    divide_triangle(v[1], v[2], c, m-1);
    divide_triangle(v[0], v[1], v[2], m-1);
  }
  else (triangle(a, b, c));
}

The display function that subdivides a triangle n times is:
Code:
void display(void)
{
  glClear(GL_COLOR_BUFFER_BIT);
  divide_triangle(v[0], v[1], v[2], n);
  glFlush();
}

Display is called in main() when it's passed as the argument for glutDisplayFunc(). (Right?)

Well, they also decide to include a global variable GLfloat v[3][2], but that also exists within divide_triangle(). No problems there?

I guess it also assumes you'll replace some of the variables with constants or provide further methods to give the variables values (such as the n that gets passed to divide_triangle() so it knows how many subdivisions to make).

So, the three GLfloats passed to divide_triangle aren't pointers to arrays, but you're passing arrays into the function as arguments? I get that a, b, and c are the vertices... But then what is the GLfloat v[3][2] for within the divide_triangle() function?

Perhaps this book was not the best choice for a beginner. Everything up to this section of the book made sense (that is, four-sided polygons). I do intend on checking out Interactive Computer Graphics: A Top-Down Approach with OpenGL, which is by the same author.

Hmm... Maybe a couple of comments in the code would've been nice... Grin
Quote this message in a reply
Moderator
Posts: 3,574
Joined: 2003.06
Post: #4
Sorry, it's way past my bedtime right now, so I really shouldn't even be answering this. But I'm an idiot so... First, I haven't seen anything of Ed Angel's since a little MacTech article like back in... 99? I am glad to hear he's still poking around with OpenGL since I heard great things about him back then even. He seemed to have a real nice attitude about it from what I remember, and that's back when most `real' graphics guys didn't dig the Mac. Not like that matters, but I'm babbling...

Second, those are an awful lot of questions to be shooting out at once! I'll try to hit some, and maybe someone else can take up the slack.

> My original post stems from reading through Chapter 2 of Edward Angel's Open GL: A Primer 2nd Edition (2005). In section 2.14.2 "Tessellation and Subdivision" there's some example code that I thought might be fun to tie in with Aqua interface elements as a sort of useless "look what can be done" app.

DO IT.


> Having NO knowledge of calculus, I don't understand the whole idea of theta degrees...

You do NOT need to know calculus, or be a math wiz to kick ass with computer graphics programming. Disclaimer: But without a solid background in linear algebra and basic calculus you will find it hard to read much of the technical literature out there on the subject, which often describes newer things you would *like* to do. I know that because I don't have a strong math background myself (I don't know calculus either) ;-) That won't stop you from learning how to do awesome things (like say normal mapping) but it's going to take double triple or quadruple effort, study, and experimentation to make it happen.

> ... I suppose that a, b, and c are defined elsewhere...

They were passed in as parameters to the function:

void triangle(GLfloat *a, GLfloat *b, GLfloat *c)

They would be defined somewhere else, perhaps the calling function, as:

GLFloat a[2], b[2], c[2];

Then:

a[0] = 1.0f; a[1] = 1.4f; b[0] = 5.0f;, etc...

> is it ok to call them methods?

Generally speaking, no -- not if you're programming in a procedural language like C. `Method' terminology is generally reserved for a class encapsulated function called in an object-oriented language like objective-C. You could probably get away with it in C++ without getting yelled at too much, but there are often different terms for different languages so I wouldn't try it myself ;-)

> Display is called in main() when it's passed as the argument for glutDisplayFunc(). (Right?)

No. Display is called from within GLUT when it's time for your app to draw a new frame, not when it's registered as the argument to glutDisplayFunc().

> Well, they also decide to include a global variable GLfloat v[3][2], but that also exists within divide_triangle(). No problems there?

I don't know. I'd have to see more of the code. But if it's declared in the global scope, and also in a function, technically the function (local scope) overrides the global scope. But that's bad form. I suspect something else is afoot. Heck, I don't even remember if that's legal in modern C standards...

> So, the three GLfloats passed to divide_triangle aren't pointers to arrays, but you're passing arrays into the function as arguments?

They *are* pointers to arrays. Arrays passed as parameters in C are pointers, you just don't see that. It's one of the finer, and more confusing, things to pick up about C. For instance, given:

int main(void)
{
int frick[24];

MyFunk(frick);
}

...

void MyFunk(int frick[])
{
}

is the same as

void MyFunk(int *frick)
{
}

> Perhaps this book was not the best choice for a beginner.

Just keep plugging away at it. You'll pick it up one way or another. I haven't read those books myself, but I can guarantee you if you keep going those won't be the only books you read on the subject, nor the only author...
Quote this message in a reply
Sage
Posts: 1,403
Joined: 2005.07
Post: #5
Please dont be like "im a stupid noob" no one cares about how good you are at programming and will be willing to help you whatever level you consider yourself.

Just ask the question you want an answer too.

Sir, e^iπ + 1 = 0, hence God exists; reply!
Quote this message in a reply
5thPeriodProductions
Unregistered
 
Post: #6
Haha. Sorry. I'll keep that in mind for the future... But I promise nothing! MUWA HA HA!

After a night's sleep I realize that GLfloat v[3][2] is really a traingle! 3 vertices with 2 coordinates (x and y). Woo...

But, I agree that having v[3][2] as a global and as a local within the divide_triangle() function is bad form.

No, I haven't plugged this code in to try running it. I thought I'd have a go at analyzing it to see how much of it I understand given my current level of skill with programming. And, like I said, quads weren't giving my brain any trouble.

I'll be working on this again tonight when I'll actually try compiling the code. And, yeah, I have to piece it together with some of the other example code in the chapter.

I swear I'll master pointers... I will! I must! : )
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Opengl/Cocoa text rendering tesil 15 17,247 Mar 20, 2012 11:16 AM
Last Post: OneSadCookie
  OpenGL ES2... many questions vunterslaush 39 24,825 Sep 5, 2011 09:21 AM
Last Post: ipeku
  OpenGL ES questions regarding 2D mixed with 3D jeonghyunhan 5 6,174 Jun 20, 2009 03:54 PM
Last Post: jeonghyunhan
  OpenGL: glRotate and some 3D questions. mikey 1 3,764 May 19, 2009 05:11 PM
Last Post: ThemsAllTook
  OpenGL Text Rendering (in Cocoa) daveh84 5 7,849 Feb 19, 2009 12:44 PM
Last Post: TomorrowPlusX