Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Got an OpenGL question i would like to have answered to see into which direction i would need to research.

Here's the basic setup:

I'm, for now, trying to display a grid consisting of cubes. There's not much i can do about reducing the number of elements here, since each cube can have a number of appearances and adjacent cubes rarely share the same appearance.

Here's a few examples.

The maximum number of cubes is 768x768x96 (width x length x height). Right now i have a very simplicistic method for doing it in immediate mode. (The images up there are from another dude though and right now i'm not entirely sure as to how he does it.)

My question here is: What would be the method to do this with that gives the most performance?

Adbot
ADBOT LOVES YOU

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Would be 32x32x1 chunks then, as i want to be able to slice layers off the top 1 by 1 so one can easily see what's going on inside the mountain.

In any case, thanks a lot! You really showed me something i missed. :) (Was simply having one big texture previously, with the world being sub-divided in 16x16x1 chunks and the texture being applied by moving it around based on offsets.)

Can i get some more info on what the advantages/disadvantages of display list vs. vbo are?

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
I originally started to write a 3d visualizer for maps from dwarf fortress in Perl. Some other dude however was also working on it, only he did it in C++ and was a bit faster than i was, so i completely forgot about the 3d part and concentrated on writing the part of the program that extracts the map from the memory of the running program.

Now i'm finding that the will to poke at this is flagging, since i can get out more info now, but i can't visualize it, since i don't have the source to his engine, nor am i really fluent in c++.

As such i'm looking to move forward and get done with implementing my 3d viewer in perl and would simply like to hear what a good way to get this done is, as i have only very BASIC experience with OpenGL.

This isn't really an engine, as it's mostly about viewing static content.

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

MasterSlowPoke posted:

don't give dwarf fortress graphics or I might get sucked into playing it forever

Oh god, you just gave me an idea. D:

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
I'm guessing i'm being dumb about something here. These cubes are all flush to each other:


Click here for the full 1271x936 image.


How can i stop the borders there from loving up?

Source code here if anyone wants to look: http://code.google.com/p/dwarvis/source/browse/trunk/livevis/dwarvis.pl
Relevant functions: cbRenderScene ourDrawCube ourInit

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Thanks guys, problems identified:

Had the front clipping plane FAR too close, because i dislike how things look when the camera clips through stuff and the front plane is too far away from it. That's irrelevant for this project though. :)

Additionally, the cubes are currently still rendered fully, which means that inside faces are still being rendered and confuse the depth buffer. Slated to be done later to keep the code simple for now.

Played around with glPolygonOffset too, but well, the results seemed REALLY random. :o

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Ok, one more odd question and i don't even know if you guys can actually help me there. The following happens on a two-core system under WinXP with Perl running the program.

I have it running fine and it generates 18 display lists at start.

As of now every display list starts with glBegin(GL_QUADS); and ends with glEnd();. The displaylists get then looped through in the render function. At this point the thing simply hums along and uses one core to render as is normal.
code:
prepare:
    for my $z (0..$zcount){
        glNewList($z, GL_COMPILE);
        glBegin(GL_QUADS);    # OK, let's start drawing our planer quads.
        **stuff**
        glEnd();    # All polygons have been drawn.
        glEndList();
    }

------------
render:
    for my $z (0..$zcount){
    glCallList($z);
    }

However when i take the begin and end out of the lists proper and put them in front and after the loop, it suddenly goes weird. The CPUs cores both go to 100%, all used by the Perl process and the framerate noticeably drops. It doesn't even matter whether the list calling loops is within begin/end or not. If it isn't it won't render, but the CPU will still freak out.
code:
prepare:
    for my $z (0..$zcount){
        glNewList($z, GL_COMPILE);
        **stuff**
        glEndList();
    }

------------
render:
    glBegin(GL_QUADS);    # OK, let's start drawing our planer quads.
    for my $z (0..$zcount){
        glCallList($z);
    }
    glEnd();    # All polygons have been drawn.

Any ideas?

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Um, they pretty much do the same thing:
code:
call list 1
  begin
    stuff
  end
call list 2
  begin
    stuff
  end
code:
begin
  call list 1
    stuff
  call list 2
    stuff
end
Both versions work and display stuff, but mysteriously the second one causes a single-threaded program to actually abuse two cores.

As for VBO: I've considered it, but well ... I can't be arsed to. I'd need to figure out how they work first (haven't seen a SIMPLE example tutorial yet) and then i'd have to figure out how to get them to work in Perl.

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Try checking the code yourself: http://code.google.com/p/dwarvis/source/browse/trunk/livevis/dwarvis.pl

The display lists get constructed in ourInit by iterating over a 3-dimensional array and drawing cubes when appropiate. Cubes are drawn via the stuff contained in ourDrawCube. Down in cbRenderScene the display lists then get called.

Note that i know what you mean. When i leave out the begin/end things nothing gets rendered, but when i have them as noted above, it gets rendered either way. The only difference is the amount of CPU rape.

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Erm, and what about this?

"Only a subset of GL commands can be used between glBegin and glEnd. The commands are glVertex, glColor, glSecondaryColor, glIndex, glNormal, glFogCoord, glTexCoord, glMultiTexCoord, glVertexAttrib, glEvalCoord, glEvalPoint, glArrayElement, glMaterial, and glEdgeFlag. Also, it is acceptable to use glCallList or glCallLists to execute display lists that include only the preceding commands. If any other GL command is executed between glBegin and glEnd, the error flag is set and the command is ignored."

http://www.opengl.org/sdk/docs/man/xhtml/glBegin.xml

To elaborate on that: I had already suspected some incompatibility and done my share of googling. Every kind of documentation i ran across told me that it's a-ok as long as i only have vertex stuff in my display lists.


The threading thing is nice, now i only wish it could do that when it's not already massacring performance. :)

Mithaldu fucked around with this message at 06:09 on Sep 6, 2008

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Ooh, ok, yea, the optimization thing makes sense. Thanks. :)

As for the multithreading, i wouldn't know how. :/

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Been using windows xp + nvidia for ages and never saw anything like that in the driver settings, unless you're talking about prerendered images.

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Another question about OpenGL: As far as i can see it only offers a spot light source, which i'd have to put really far away to emulate a global directional light. Is there any direct way to make a global directional light in OpenGL?

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Ah, exactly what i was looking for, thanks. :)

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
I'm currently fiddling with more complex objects and i'm finding out that i cannot display them with all with QUADS anymore.

Currently i have the setup like this:
code:
Start display list
    Start GL_QUADS
        Loop through objects
    End GL_QUADS
End display list
Right now i'm thinking of doing this to the objects loops:
code:
Start Object
        Draw Quads
    End GL_QUADS
    Start GL_TRIANGLES
        Draw Triangles
    End GL_TRIANGLES
    Start GL_QUADS
End Object
Would the display lists get correctly optimized to take that into account or would it result in a performance loss, since there's roughly 265 objects per display list?

Or should i alternatively simply duplicate one vertex per quad in the same location with the same tex coords, so it looks like a triangle?

Mithaldu fucked around with this message at 15:16 on Sep 21, 2008

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
God, i just realized that quads or tris doesn't matter to the display list at all, since it only collapses into triangles internally anyhow.

Also: "and an additional vertex and index buffer" Huh?

Anyhow, the reason why i'm using quads is that the generation of the display lists also happens constantly in the background while new objects come into view and while the content of the data source changes. I'm hoping that using quads improves the generation performance there a bit, but right now i just plain don't know what the gently caress.

As for triangle-strips: I'd at most be using them for single quads anyhow, as i plan to use lighting and such and will need normals. Don't really see a method to do that easily.


Edit: Thanks guys, going with triangles is really the thing to do. As a test i inserted something that's a rather extreme case and it went absolutely smooth: http://www.veoh.com/videos/v16023678hb23TCjA
3D performance is perfectly fine and even with the switch from quads to tris, cache generation did not slow down noticeably.

Mithaldu fucked around with this message at 23:11 on Sep 24, 2008

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
A word ahead: I'm doing this in Perl, so i'm trying to keep stuff relatively simple. The more work i can shove off to OpenGL itself, the faster this thing becomes.

At any given time i'm rendering 45-180 display lists per frame. Additionally about 1-3 display lists gets remade roughly every second or so. Due to not being able to figure out a way how to thread the updates, i need to perform them inbetween frames. As such i try to keep them as few and fast as possible to avoid frame-rate hitching.

I'm not sure if VBOs give me any advantage there.

Additionally, I have no idea how VBOs work and I would need to figure out by trial and error how to get them working with the OpenGL interface i have. Which, i suspect, may be incomplete or buggy as well, since i can't get specular light reflection to work.

As for triangles, yea, i already switched everything around. Being able to sketch up the models in Wings 3D is a godsend.

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

Cross_ posted:

That's quite a bit. It might help to merge some of them if possible to avoid any overhead with state switching in between.
What kind of state switching to you mean?

Two things to keep in mind here: The data originates as (16x16)x(5-20) blocks. In the video above i am displaying a range of 3*3 blocks. One of the requirements for this application is the ability to slice off layers of the top at will to display the inside of the environment, since this is a digging/mountain-type stuff game.

So i can only combine display lists on the 2D layer, which either means making the caching mechanism and general data->display chain a hell of a lot more complicated by assigning one cache to multiple blocks; or i could simply have the center block in each case cache enough data to display the blocks around it at once, which would make the memory use explode.

Honestly though, right now i'm really happy with the performance of this thing and i'm not even optimizing much.

Cross_ posted:

Also to repeat what was said above: use tri_strips_ if you can. They reduce the vertex data sent to card by up to 30% compared to triangle lists.
Even when doing so means i'm missing out on optimization by stripping out roughly 2000 triangles per display list?

sex offendin Link posted:

VBOs would be an advantage for anything that's generated exactly once and never modified for the entire session. For any element that might be frequently rebuilt, they're a wash or worse.
Thank you! That's the kind of information i need in order to decide whether researching a subject is worth my time.

Also, thanks in general to any of you guys throwing stuff at me here. Even if i can't use all of it, it's hard to find brains off which i can bounce ideas regarding this.

Mithaldu fucked around with this message at 23:13 on Sep 24, 2008

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

magicalblender posted:

Also, am I crazy, or has the page for glutKeyboardUpFunc disappeared from the Opengl documentation? I could swear I was looking at it a couple weeks ago, but it isn't there now.
That's part of FreeGLUT: http://docs.taoframework.com/Tao.FreeGlut/Tao.FreeGlut.Glut.glutKeyboardUpFunc.html

Now i need to see if i can compile OpenGL 0.57.0 in ActivePerl CPAN. :/

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Depends on your graphics card. Mine (Quadro NVS 140M) just displays it as normal. Others, like a 5 year old ATI, show black polygons that are above everything in the z-buffer.

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
The accum stuff is pretty nifty. brian, if you need more info, here's a pretty good read on it: http://www.cse.msu.edu/~cse872/tutorial5.html

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Due to finally being able to compile OpenGL 0.57 in CPAN, i have now access to a workable example of vertex arrays in Perl. If i look at this correctly, it means that it can draw a single triangle in exactly one call, as opposed to the 6 needed in immediate mode. This would mean a massive speed-up since Perl has a horrible penalty on sub calls.

However i'll still need to use display lists, since 180 calls per frame is a lot nicer than 46000.

What are good practices when combining display lists and vertex arrays and what should i pay attention to?

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

Hubis posted:

there are no real concerns with combining them, as vertex arrays are very commonly used and self-contained.
Except for when you try to include glXxxPointer calls in the display list. It works fine for glVertexPointer only, but when you try to put normals and texture coords in there too, it blows up. :D Luckily that shouldn't be too much of a problem as it only forces me to do some refactoring that i should've done a while ago already. (Construct display lists for all the basic elements and then make the big ones by calling the basic lists instead of constructing the big lists by drawing them all in immediate mode.)

Hubis posted:

Just don't go overwriting buffers the driver is still using and you should be ok.
Not using vertex buffers, since these seem to crash in perl510. If you're not talking about those, please enlighten me. :)

Hubis posted:

Also, I'm still confused as to why you're issuing only one triangle at a time -- are you really completely changing state every draw?
That was just me being completely new about vertex arrays. The sample code does this:
code:
for ( my $i = 0 ; $i < scalar(@indices) ; $i += 4 ) {
    glDrawArrays( GL_QUADS, $i, 4 );
}
I honestly have no idea though why he does that, when
code:
glDrawArrays( GL_QUADS, 0, scalar(@indices)+1 );
works perfectly fine too. :iiam: Although i have an inkling that he is a bit confused about what DrawArrays does, since his normals array only had 6 normals, corresponding to the amount of quads, instead of 24, which would be the number of vertices.

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Got a question about z-fighting issues. I'm rendering layers of roughly 80*80 objects, with roughly 20-40 layers stacked atop each other at any time. There is no computationally non-expensive way to cut out invisible geometry that i am aware of, so i pretty much have to render everything at all times. This leads to the z-buffer getting filled up pretty fast, resulting in rather ugly occasions of polys clipping through other polys.

I've already restricted the near and far clipping planes as much as possible so the geometry has the full z-buffer to play with.

Would it help the clipping issues to render the geometry (when looking at it from the top) by cycling through the z-layers bottom-up, drawing everything in them and calling glClear( GL_DEPTH_BUFFER_BIT ); inbetween every z-layer? If so, would it also help to do a full reset of the projection like this, or would that be unnecessary extra work?
code:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
    
//snip calculation of clipping planes
    
gluPerspective( $cam_angle, $width / $height, $dist_min, $dist_max );

glMatrixMode(GL_MODELVIEW);

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Disabling the depth buffer is not an option, as the z-culling needs to be kept functional for each z-layer. Sounds like a pretty neat approach though. (Although i'm confused by what you mean with shading work.)

To make things a bit more visual, some screenshots. The first one shows a normal view. You are looking at 5x5 blocks of 16x16 units each. Each unit can be a number of terrain features, as well as a building (red) or a number of items (blue). Currently i'm rendering all items, even if that means they overlap each other, as sorting out already rendered ones causes a performance impact on the cpu side that slows poo poo down. As such, there's probably 3000-6000 items rendered there (visible and underground), all in all coming together to a fuckton of polys.



The landscape blocks are rendered as one display-list each, with the coordinates for all vertices pre-calculated. The buildings and items are rendered as individual 0,0,0-centered display lists that get moved into place by being wrapped in gltranslate commands.

Additionally, each block has not only the top-faces of each landscape unit rendered, but also the no/so/we/ea faces of the edge units, since leaving them out would leave holes in the geometry. These are the first problem factor that i noticed: When zooming in, the begin to clip through the top faces.

Additionally the red building blocks are rarely problems and manage, again when zoomed in, to clip through the top faces *entirely*. Lastly, when just doing screenshots, i noticed that sometimes the stones on the ground that are part of the landscape display lists clip through the blue items.

The dimensions are such that each landscape unit is exactly 1x1x1 units big, speaking in floating point vertex coordinates. (Would it maybe help if i increased that?) Currently the clipping planes are being done by defining a bounding box around all visible content (since it's a neat rectangle) and selecting the two points that are furthest and closest from the screen-plane, when projected along the camera vector and using their distances as parameters.

I am using gluLookAt, with the target being the turquoise wireframe. If the camera is moved towards the target or away from it the clipping planes get adjusted to match the distances. If the near plane falls under 1.0, i adjust it to stay at 1.0.

And that's where my problem comes in. Looking at it all from afar is good and works, but when i zoom in by moving the camera closer, this happens:



Note how the rocks in the bottom left corner clip in front of the blue things, which should be straigh above them. Also note the side-faces at the block edge clipping through the top faces in the line in the bottom-right quarter as well as in the top middle on the dark ground.

I mitigated it a bit by switching from zooming by moving the camera to zooming by changing the fov, but even that doesn't fix it completely (and things tend to jerk and jump around a lot when moving the camera):



:words:

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
It's not a clone, it's this: http://code.google.com/p/dwarvis/ :) If you have the game and a decently complex map you can try it out for yourself with the version that's for download there.

And thanks for explaining the shading thing, yeah, OpenGL-wise i have massive amounts of performance left, even on my rather dinky quadro 140 mobile. CPU is the big bottle-neck, which is why i don't bother to cut out invisible stuff.

Regarding your understanding of what i'm doing: Exactly, thanks for summarizing it so well. :)

As for your last paragraph: You're suddenly disregarding your previous understanding there. :D The traditional "it get's worse in the distance" is only true if the clip planes are fixed at, for example, 1 and 1000. However in my case the clip planes are mobile and can wander from "1-150" to "1001-1150", which makes the distance thing irrelevant.

My theory on why it happens when zoomed in is that OpenGL has an easier time mapping objects between "1001-1150" than between "1-150", which is why i tried to fix it with zooming by adjusting FoV. On the other hand, it might simply be that the problems are universal, but too small to show up when viewed from a normal distance. :iiam:

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

shodanjr_gr posted:

Are those "blue things" as well as the rocks spites (as in textures rendered on billboards)? If so, maybe you are rendering them right on top of each other (which would explain the z-fighting)...
Nah, they're bone fida models. You can see that in the video here: http://www.veoh.com/videos/v16314761MGwKDQR7 What's happening there is quite plain and simple OpenGL having problems keeping things straight. I'm also suspecting that i'm forcing it to keep the geometry at too accurate levels, as things tend to "jump around" when zoomed in and any kind of "detail" work happens behind the comma.

shodanjr_gr posted:

To improve performance, you can look into lots of things, including geometry instancing (you have TONS of similar looking geometry in those pictures) and various occlusion-culling techniques. Furthermore, you could easily save lots of display-list calls, if you created lists for larger block sizes as well (for instance, instead of just keeping 1x1 block size lists, make some 2x2, 3x3, etc etc lists and call them, based on the size of your areas).
As mentioned, i'm using Perl, so the most important performance aspects are those that allow me to reduce the number of function calls, since Perl has a horrible performance penalty on those. I'm pretty much already using what you mentioned. Every unique model is pre-rendered into a 0-centered display list, then the landscape is generated in 16x16x1 slices, consisting of [gltranslate, glcalllist, gltranslate], all saved in display lists, etc. etc. Overall performance is not an issue anyhow as things are moving pretty smooth. The only problem the current variant of the code has is that huge numbers of items slow it the gently caress down, as i'm not caching "dormant" items into displaylists yet, but that's already planned and not an issue that i'm concerned over.

shodanjr_gr posted:

I think that the Z accuracy of opengl only depends on the Zfar - Znear value, but i could be wrong...When you create your frame buffer, try using a larger accuracy depth component (32 bits for instance) to rule out Z-issues.
How would i do that in OpenGL? I've never seen an explicit option for that and from what i remember from older games (Giants: Citizen Kabuto) that pretty much depends on the display bit-depth. I think OpenGL actually uses the alpha channel for each pixel to store the depth value.

Relevant code is here if that'd help you point it out: http://code.google.com/p/dwarvis/source/browse/trunk/lifevis/Lifevis/Viewer.pm

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
I'm taking a naive approach, in a manner, yes. The script is built by iterative design in such a manner i got one thing working, then multiplied its application, then figured out ways to optimize it properly. Simply helps me keep the whole thing straight in my mind and also helps me when i need to refactor things. (Going from immediate mode to vertex arrays was pretty painless.) However, as the post above yours shows, i'm not entirely clueless in how to leverage basic OpenGL features. :)

Back to the z-planes. I guess i expressed myself badly. Let me quote the article you linked to make it more clear:

quote:

The OpenGL Reference Manual description for glFrustum() relates depth precision to the zNear and zFar clipping planes by saying that roughly log2(zFar/zNear) bits of precision are lost.
Now, let's look at this:
code:
[1, 150]     |     150/1 = 150    | 7.22881869049588    bits lost
[1, 75]      |      75/1 =  75    | 6.22881869049588    bits lost
[1000, 1150] | 1150/1000 =   1,15 | 0.20163386116965043 bits lost
That's what i meant earlier when i said that it may be easier for Opengl to distribute the data of the third case.

I should maybe mention that due to the high density of objects i'm rendering combined with the uniform distribution, i'm thinking that a more evenly distributed z-buffer would be advantageous, as compared to one that's logarithmically skewed to the front. I'm thinking this mostly because i never had much of a problem with z-clipping in the distance. If and when it clipped, it did so uniformly and affected everything i'm drawing equally.

I also want to say thanks for taking the time to help me think about this, i appreciate that very much as it's kinda hard to find people to throw these concepts at.

As for clamping to [1, 1000], it produces hilarious results:

as compared to:


That's the whole reason i started looking into this in the first place. :)

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

shodanjr_gr posted:

No, opengl uses a separate render-target sized buffer to store the depth information. The precision of that buffer is adjustable. Besides, imagine if OGL used the alpha channel to store depth info, how would you do alpha blending AND depth testing at the same time? :)
Ah, ok, guess i was being stupid there. :D

shodanjr_gr posted:

If you arent using FBOs, use FBOs. Its one of the features of OpenGL that ive grown to ADORE ever since i learned about it.
I'm not, since I have no idea what they are and what they do. I mentioned it earlier in the thread, but this is the first OpenGL app i'm doing and everything i'm using i'm literally learning as i go along. Could you maybe explain in plain english and shortly what they are and why i should be using them? :)

shodanjr_gr posted:

Also, why are you using Perl?
For the above reason. Hilariously fast prototyping that allows me to concentrate on learning what i'm dealing with instead of worrying about arcane intricacies of C++ memory handling. Aside from that it also allows me to keep everything Public Domain and increases the chance of someone coming after me and picking it up in case i ever decide to drop it.

shodanjr_gr posted:

fakedit: but as its been said already, i find it unlikely that these are depth precision issues. Its more likely that you have forgotten some sort of Z-test flag off at a point inside your rendering code...
Well, as far as i'm aware these are all relevant bits:
code:
# called once at the start
sub initialize_opengl {
    [snip]
    glClearDepth(1.0);
    glDepthFunc(GL_LESS);
    [snip]
}

# called once at the start and whenever the window is resized or the camera moved
sub resize_scene {
    [snip]

    glViewport( 0, 0, $width, $height );
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    [snip]

    gluPerspective( $cam_angle, $width / $height, $dist_min, $dist_max );
    glMatrixMode(GL_MODELVIEW);

    [snip]
}

# draws one frame
sub render_scene {
    [snip]
    glEnable(GL_DEPTH_TEST);

    glMatrixMode(GL_MODELVIEW);
    gluLookAt( $x_pos + $x_off, $y_pos + $y_off, $z_pos + $z_off, $x_pos, $y_pos, $z_pos, 0, 1, 0 );

    [snip]

    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    glColor3f( 0.75, 0.75, 0.75 );
        
    render_models();

    [snip]

    glLoadIdentity();
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();

    render_ui();

    glPopMatrix();
    glutSwapBuffers();
}
See anything missing?

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

shodanjr_gr posted:

Framebuffers
Alright, thanks for the explanation. I think glut already uses that internally when dealing with the backbuffer or something, but i'll be sure to try it out. :)

shodanjr_gr posted:

Oh well, whatever floats yer boat :P. I am terrible with C, but i havent had issues with coding OpenGL for it (although i mainly focus on shader development, so my C code rarely changes).
Let me put it like this: This thing needs to read the memory of another program byte-by-byte, continuously, update an internal represantation of that memory, render it and deal with user input. By the time i noticed how much of a pain it is to even do something simple as creating a 5-dimensional array of indeterminate size in C i decided i didn't want to bother with learning how to do that AND all the other crap when i can take a performance hit and just plain *do it*.

shodanjr_gr posted:

Out of curiousity, change the GL_LESS to GL_LEQUAL (i doubt it will change much though).
No noticeable change for the better. Might even have made it a bit worse.

shodanjr_gr posted:

Post your render_models(); code as well.
Nothing relevant in there imo. Lots of perl logic and looping through arrays, this when appropiate:

quote:


glColor3f($brightness, $brightness, $brightness);
glTranslatef( $x, $z, $y );

glBindTexture( GL_TEXTURE_2D, $texture_ID[creature] );
for my $part ( 0..$#{ $DRAW_MODEL{$model_name} } ) {
next if !defined $model_display_lists{$model_name}[$part];
glCallList($model_display_lists{$model_name}[$part]);
}
glTranslatef( -$x, -$z, -$y );
and at the end once this: glCallLists_p (@landscape_displaylists);


One thing i noticed: Is it normal that when z problems occur that one polygon that is orthogonal to another one pokes partly through it? When playing around with the clamped z-buffer i noticed that it sometimes looks as if the landscape-slices are not just drawing in the wrong order, but being shifted downwards by 0.1 units entirely.

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

OneEightHundred posted:

What are you using for the z-buffer that you're only getting 40 layers of precision? Make sure your nearplane isn't too close in particular.
Try scrolling up the page to see screenshots. :)

OneEightHundred posted:

As for a computationally-inexpensive way to occlude objects, try zoning them using occlusion queries. An occlusion query lets you know if and how much of some geometry is visible. Draw the world (occluders), then disable color/depth write and "draw" the bounding of a zone a bunch of objects could be contained in. Repeat for all zones. If the zone isn't visible, don't draw any objects fully contained in it.
That might actually work ... Do you maybe have some kind of example code for that? I should maybe elaborate on computationally inexpensive: Basically, anything that requires me to check each item on its own is useless, since it's faster for me to simply call a draw on it than to figure out whether it should be drawn. (Heck, the draw calls are even less expensive than for-looping over my item arrays.)

OneEightHundred posted:

For voxel-based stuff there's also octree occlusion, but I'm less familiar with that.
I thought about that too, but i'm only working with cubes at the smallest level here. Anything above that can only be sub-divided in 2d.

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

OneEightHundred posted:

Still not sure I understand where it's breaking down. What precision are you creating the depth buffer at?
No idea. As mentioned before, so far i'm using glut and whatever its basic settings are.

OneEightHundred posted:

If you're creating a complete 3D voxel grid, then you can draw it in order by just using the view axis. i.e. take the sign of each component of the view direction of the camera, and use that to determine which order to iterate through those components in the voxel array.
I'm not sure why you're talking about voxels now. I've never mentioned them and am rendering a 3d grid of even-sized objects which are either cubes or more complex objects that can fit inside cubes.

All in all i'm probably rendering ~20000 distinct objects with roughly 2-100 polys each, using display lists

When looking at that from some distance and clipping range settings [46.5098639640652, 145.702191155173] everything looks fine. When zooming in a bit, causing the clipping settings to change to [1, 107.441455160607] it all goes to hell.

OneEightHundred posted:

You can also squeeze more precision out by segmenting the world and doing multiple draw calls. This means that you'd chop your near/far range up into segments, draw anything visible in the farthest segment, clear your depth buffer, draw anything visible in the next-closest segment, repeat.
Yea, that's what i've been talking about above. :) However instead of segmenting it with vertical walls, i'll do that horizontal floors, metaphorically speaking. Reason for that being that the main problem i seem to be having is too many objects, which only horizontal seperation would do anything good for.

OneEightHundred posted:

You don't want to check each item, you want to check zones, and if the zone hull is culled, then everything in the zone is considered not visible. A zone would be a room, for example, and what you'd "draw" is a box for the bounds of the room.

I don't have example code, but it's asynchronous, it works by creating an occlusion query, drawing some stuff, ending the occlusion query, and then later when the card has the query finished, you can check how much it drew. You don't want to check immediately if you have other queries you can run.

By disabling depth/color write, it won't actually draw anything, but it will check the visibility of the polygons you're sending.

There's some trivial sample code here:
http://oss.sgi.com/projects/ogl-sample/registry/ARB/occlusion_query.txt
Yea, that's the kind of example i need, contains only the minimum requirements. To be honest, this method, if it works with the Perl OpenGL library, will actually help me a lot in solving another problem that's been sucking performance, so thanks a lot! :D

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Ah, i see. He's suggesting i do the job of the z-buffer in-code. Sadly that's not an option although i'll need to do it later on for objects with transparency. Reason for that not being an option is that it would massively increase the amount of work that Perl needs to do, which is what i'm trying to avoid. :)

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
I was tempted to post an image of a golf ball bucket here. But to be serious, I do not know what "range buckets" are. I can make vague guesses, which lead me to believe two things: Either you are talking about some technique that is completely unknown to me, or you're ignoring the display list structures i described in earlier posts around which i cannot work around. Color me confused.

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Pretty much a ghetto depth filter for pre-sorting then. Would actualls also work with my display lists, but i don't think it'd give me the granularity i'm aiming for.

I also jsut tried to get the occlusion stuff implemented, but ran into a few roadblocks, so i have a few questions: Is it possible to do the occlusion query stuff in another way than using glBeginQueryARB, etc? I know it's not very likely, but better to ask than to stay ignorant.

Secondly, there's a similar HP extension for that. Does it only work on special gfx cards or why would glGetBooleanv(GL_OCCLUSION_TEST_RESULT_HP, &result) return the error "Unknown param"?

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

OneEightHundred posted:

The point is that it'll let you get more resolution out of the depth buffer since you can adjust the near/farplane for each bucket.
I'm aware, just commenting that the z-layer seperation i mentioned before would give the depth buffer a good bit more of resolution, with nearly no computational overhead.

OneEightHundred posted:

No. What roadblocks are you running into?
glBeginQueryARB and associated commands are not yet implemented in the Perl OpenGL library. :)

OneEightHundred posted:

The HP extension stalls if you're running multiple queries and occlusion is all-or-nothing, and beyond that the only thing you need to do is create/destroy query objects once in a while so I'd recommend using the ARB one instead.
I know it's pretty horrible in comparison, but if i can get it to work, it just may suffice. Since it only relies on commands that are actually implemented already, it might work; unless it's hardware-specific.

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

OneEightHundred posted:

I'm pretty sure POGL will let you make core OpenGL 1.5 contexts,
No idea what that means.

OneEightHundred posted:

in which case everything will work the same except the occlusion query ARB functions are core, meaning they don't have "ARB" at the end.
As far as i am aware i can only use the functions that are defined in the .xs, compiled into the .dll and exported in the .pm. The only function with the word "query" in the name for which this is true is glpXQueryPointer.
I'm thinking about trying to see if they're easy enough to implement in the .xs and compile my own version, as well as mailing graphcomp about it, but i want to exhaust my options first.

OneEightHundred posted:

I see no reason it shouldn't, are you sure you're getting a context from the ICD and not the lovely stock Windows OpenGL implementation?
Again, i don't know what that means. Sorry. :/

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

OneEightHundred posted:

POGL definitely has a glBeginQuery binding in everything starting from the OpenGL 1.5 bindings and up.
Can you point out where you get that information from so i at least have a clue where to start looking? I mean, i'm looking at the source code for the module here, straight from CPAN, BEFORE compiling etc., and the only mentions of these functions are in the opengl includes files, but NOT in the perl files themselves.

OneEightHundred posted:

If you link against opengl32.lib then for whatever reason, the entry points (read: functions) you get are from the lovely stock Windows OpenGL library. You need to make sure that the project is set up to dynamically load the DLL and get the entrypoints with GetProcAddress, which will use the ICD version (a.k.a. the one that comes with your video drivers, which is fully-featured) instead.
Ah, alright. Thanks for the explanation. I'll be looking into that.

Edit: Looked into it. It loads "C:\Programme\Microsoft SDKs\Windows\v6.0A\Lib\OpenGL32.Lib". Tried removing that file to see if Makefile.PL can cope with that, but that only resulted in a broken build. Definitely thinking about trying to add the missing commands manually now.

Is there a good way to check whether glBeginQuery was executed correctly or am i gonna have to fly blind?

Mithaldu fucked around with this message at 07:29 on Nov 2, 2008

Mithaldu
Sep 25, 2007

Let's cuddle. :3:
Ah, i see what's going wrong now. You're looking at an older release. This is the most current and has a bunch of cruft removed: http://search.cpan.org/CPAN/authors/id/B/BF/BFREE/OpenGL-0.57.tar.gz

As for the file you were looking at there, i believe they weren't meant to reflect POGL, but only serve as documentation for the maintainer.

Also, Perl doesn't quite work that way. If you have visual studio express installed as well as ActivePerl, you can use the "Visual Studio 2008 Command Prompt" to run "perl Makefile.PL", which then generates the makefile like so: http://rafb.net/p/0x8xHQ38.html After that you do "nmake" and it generates the OpenGL.c file from the .xs file, which is then used to compile the dll. The .c file looks like this: http://www.mediafire.com/download.php?mttmnzzkto1

OneEightHundred posted:

Although realistically, if your program doesn't instantly crash from calling a bad entry point, it probably executed correctly.
That seems to happen. Build went fine, but the program exits without even as much as an error message when i try to call glGenQueries. (Chosen because i can copy/paste the glGenTextures entry for it.)

Edit: Narrowed it down a bit by inserting debug statements in the .c file. It crashes exactly when trying to call glGenQueries in the c part.

Also, poking at the perl process with Process Explorer shows it's using OpenGL32.DLL from the system32 directory. Would maybe replacing that with a more capable version work?

Edit2: Apparently i'd need to convince it to load nvoglnt.dll somehow. As i'm not too firm in c (beyond basic syntax and compiling stuff in visual studio), is there a simple way to edit the makefile/c file to make that happen?

Edit3: Nvm, got it. They apparently do both, link against the windows opengl library AND automatically load from the driver. Adding the following before the actual code section of the function in the .xs file made it work properly for this one function:
code:
INIT:
	loadProc(glGenQueries,"glGenQueries");
Now i only need to hope the rest of the functions will behave as well. :)

Also, thanks a lot for all the information you've given me. I doubt i would've gotten this far stumbling along on my own. :haw:

Edit4: I found out what the "Unknown param" i mentioned earlier means. In order to feed back data that is given by creating arrays, the xs code needs to allocate the memory for that. In order to allocate said memory it checks a function which has the size of the feedback array for different possible parameters stored. The HP occlusion testing feedback parameter was simply not listed there, so it doesn't know how much memory to allocate and bails out.

Edit5: All functions implemented and the occlusion queries are working now in the test implementation. I hope with that the hard part is over ...

Mithaldu fucked around with this message at 11:05 on Nov 2, 2008

Adbot
ADBOT LOVES YOU

Mithaldu
Sep 25, 2007

Let's cuddle. :3:

OneEightHundred posted:

Using LoadLibrary on opengl32.dll should do this automatically. I don't know why it works this way, all I know is that static-linking opengl32.lib is bad for your health.

You should try getting rid of whatever dependencies on the opengl32.lib it has, last thing you want to do is mix calls.
They're not using LoadLibrary at all and instead use wglGetProcAddress, which seems to be meant for loading nv/ati/hp/whatever extensions. No idea why they're doing it that way, but looking at MSDN it seems to be the way to go.

I actually think it's meant to be that way, since, uh, if you do it manually with LoadLibrary, you'd need to try for all possible driver dlls, and keep your code up-to-date as drivers change, right? If i'm wrong there, do you have example code for what's the "right way"?

OneEightHundred posted:

:hellyeah:
That's just me, but i believe i've also managed to make the syntax a bit nicer. :)
code:
# draw occluder

my @array = glGenQueries_p(1);
    
glDepthMask(GL_FALSE);
glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);

glBeginQuery(GL_SAMPLES_PASSED, $array[0]);
# draw occludee-shape
glEndQuery(GL_SAMPLES_PASSED);

glDepthMask(GL_TRUE);
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);

glFlush();

while( !glGetQueryObjectiv($array[0], GL_QUERY_RESULT_AVAILABLE) ) {}

if( glGetQueryObjectuiv($array[0], GL_QUERY_RESULT) > 0 ) {
# draw ocludee
}
Also, while i'm looking at it. What's the glFlush there good for?

Oh, and thanks again. The endorphine rush when you look at your code and realize "gently caress, it works" is always great. :haw:

Mithaldu fucked around with this message at 12:27 on Nov 2, 2008

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply