View Full Version : Weird OpenGL texture problem
I am running across some very strange behavior with opengl textures.
I have recently discovered that the textures from my objects dont show up at times, lately no textures show up.
Today, I have recompiled everything with and without altivec support, and the textures now show up in the altivec build, but not in the other one??? The only code which could possible be related to this is the altivec instructions, but they are only used in the vector code, and it seems correct, except for the textures not showing up. It is not like bad texture coords are generated (the textures are set to wrap), but the textures don't show up.
And, this does not explain why the textures didnt show up until now, but now suddenly do again in the altivec build only.
So, does anybody know what could influence opengl to do this? I am checking for gl errors while loading the textures, etc, and reading the errors every frame, but nothing.
This is really driving me nuts, as I cannot find any apparent error.
henryj
2003.04.27, 07:17 PM
Could be a lot of things. OSX doesn't handle multiple contexts very well at the moment. If your screen saver kicks in while running an ogl app your will sometimes loose all your textures.
Also big (>1024) textures can silently fail to load.
I have textures ranging from 8x8 to 512x512. The texture loading is reported to be ok, as far as I can tell. no GL errors. I do have a TV viewer running at times, which draws to opengl, but here comes the chaos:
I have 2 test apps: one called physicstest, the other graphicstest. The physicstestapp is the one with the problems, at the moment. It basically does the same as the other graphicstest (which works perfectly fine), displaying a bunch of opengl primitives.
ackk. I am gonna need a strait jacket here. Now, after I ran the said graphicstestapp, running the physicstestapp shows the textures!!! This is totally insane. And apparently, no other opengl apps are affected by this crap, only mine. The textures in the two apps are totally unrelated, the console output from texture generation and display shows no hints of any difference.
I should note that as an experiment, I replaced GL_TEXTURE_2D by the RECTANGLE_EXT version, which broke my app (it was fine in the morning). Seeing this i replaced it by GL_TEXTURE_2D again. All the calls needing this parameter are in a single file, yet simply putting the code back did not fix it, as would be expected.
OpenGL is giving me a lot of crap these days. In the beginning of the project, lighting would only work when a single dot was drawn to screen before all else, but this bug vanished, without me fixing it. Now this sht.
To my knowledge, I am following all the damn specs for opengl, setting up views, etc. Why is this happening? And this was happening sporadically since 10.2.1, when I started the project.
I am really getting frustrated by this, it keeps too much time away from getting useful stuff done.
just a little more insanity: while the altivec version seems fixed, the non-altivec version is still broken. Yet I feel no pain in my foot. But I am considering putting a hammer on my desk, maybe it will bring this machine to raison again. :wacko:
OpenGL profiler reports the same for both flavors of the app, no errors either.
henryj
2003.04.27, 08:13 PM
I suggest you take a day off. All will become clear.
kberg
2003.04.28, 12:19 AM
I understand your frustration with textures. I had a rather major problem with texture objects under GL and ATi's radeon drivers, where my textures would randomly get corrupted somewhere, somehow... This was a particularily horrible and frustrating problem, as I poured over my code literally hundreds of times looking for anything at all that could be causing this... I found that running my app after being logged in for a long time (a couple days or more) or using mipmaps would greatly increase the probability of this corruption. Worse, this problem persisted across several OS updates (10.2.1 all the way up to 10.2.5). I eventually found my fix by generating my bitmap fonts after loading all my textures?! Any textures loaded after creating bitmap fonts could possibly be corrupted. Well, whatever works I guess...
Well, last night, I did a reboot, then ran that app again. that time, only the G3 version would display the textures, the G4 wouldnt.
This morning, both were miraculously working. Now, since my other apps based on the framework do not seem to display this behavior, I suspect I am not initializing something correctly, hence the random texturing mishap.
Yet, I checked my code, and I cant find any forgotten variables.
Oh well, I will move on, leave this as one of the mysteries of apple engineering.
Bossa Nova
2003.04.28, 01:12 PM
Whoa Dooog.
Your starting to make my head hurt :).
Anyway, why not post your app. We can run it on different machines. See how it performs.
You've got some very strange bugs. I hope you figure it out. Its starting to annoy me (and its not even my project :wacko: )
designdb
2003.04.28, 06:39 PM
I've been having the same problem, but in a very simple system. I've been running the deep cocoa tutorials, and just bumped into a real stumbling block.
Tutorial 3 is the intro to textures, and tries to use JPGs. he notes that under Jaguar, JPG textures don't work well, but if you convert to BMPs, it shoudl work fine.
The JPG textures display, but do not scale at all, causing them to tesselate along the upper edge of the cube face. the BMP textures do not display at all.
I am running 10.2.4. If I compile the Deep Cocoa sample code, I get the same effect. Anyone have any ideas?
James
OneSadCookie
2003.04.28, 06:48 PM
It's not an issue with the file format, so it must be an issue with his loader :)
I just use QuickTime: http://203.79.121.211/CVS/QTValuePak/
Well, I got more.
I am using Quicktime to load the textures, and I am 100 % sure it works because I use the same code for loading images for displacement maps, and that works all the time, so the image does get to memory, somehow.
Today, having nothing more annoying to do, I started coding a tank game. It is really simple right now, there are 4 cameras in a scene graph, plus a few boxes, one textured.
Now, there is no texture problem with this (but the other app is going haywire, still, and in a third I have just lost the ability to move objects with the mouse :???: ), but I am drawing boxes, and it seems like the face normals and directions somehow get inverted for some (!!!) of them, not all, not always, and only when viewed from certain cameras, disregarding the viewpoint.
I reached the point where debugging is of no help, so I am going back to the design, and extending the 70pgs of documentation I already have by more exact specs of how the different object involved in rendering should interact. Then I will try to implement it. Obviously, some really minor changes in the code are causing this unholy behavior, as 99% code in the 3 apps with the 3 different issues is the same, only a little setup here and there is different.
I doubt you are really interested in seeing what's happening. If I cannot solve this by next week, I will put together some binaries for all to enjoy. I will name it the Heisenberg collection.
I really do hate Heisenberg bugs.
henryj
2003.04.28, 11:36 PM
Like I said you should walk away from your computer for a couple of days. You are just thinking yourself into a deeper and deeper hole. It will all make sense after you have cleared the cobwebs from your mind.
Don't waste your time on design documents, it's pretty clear what you really need is unit tests.
Originally posted by henryj
...
Don't waste your time on design documents, it's pretty clear what you really need is unit tests.
What do you mean by unit tests?
OneSadCookie
2003.04.29, 06:10 PM
http://c2.com/cgi/wiki?UnitTest
henryj
2003.04.30, 02:26 AM
Here is an example from my font library that uses cppunit...
void testConstructor()
{
FTPoint point1;
CPPUNIT_ASSERT( point1.x == 0.0f);
CPPUNIT_ASSERT( point1.y == 0.0f);
CPPUNIT_ASSERT( point1.z == 0.0f);
FTPoint point2( 1.0f, 2.0f, 3.0f);
CPPUNIT_ASSERT( point2.x == 1.0f);
CPPUNIT_ASSERT( point2.y == 2.0f);
CPPUNIT_ASSERT( point2.z == 3.0f);
FT_Vector ftVector;
ftVector.x = 4;
ftVector.y = 23;
FTPoint point3( ftVector);
CPPUNIT_ASSERT( point3.x == 4.0f);
CPPUNIT_ASSERT( point3.y == 23.0f);
CPPUNIT_ASSERT( point3.z == 0.0f);
}
void testOperatorEqual()
{
FTPoint point1( 1.0f, 2.0f, 3.0f);
FTPoint point2( 1.0f, 2.0f, 3.0f);
FTPoint point3( -1.0f, 2.3f, 23.0f);
CPPUNIT_ASSERT( point1 == point1);
CPPUNIT_ASSERT( point1 == point2);
CPPUNIT_ASSERT( !(point1 == point3));
}
void testOperatorNotEqual()
{
FTPoint point1( 1.0f, 2.0f, 3.0f);
FTPoint point2( 1.0f, 2.0f, 3.0f);
FTPoint point3( -1.0f, 2.3f, 23.0f);
CPPUNIT_ASSERT( !(point1 != point1));
CPPUNIT_ASSERT( !(point1 != point2));
CPPUNIT_ASSERT( point1 != point3);
}
void testOperatorPlusEquals()
{
FTPoint point1( 1.0f, 2.0f, 3.0f);
FTPoint point2( -2.0f, 21.0f, 0.0f);
FTPoint point3( -1.0f, 23.0f, 3.0f);
point1 += point2;
CPPUNIT_ASSERT( point1 == point3);
}
What this tells me is that if I change the FTPoint code and my tests still pass then whetever uses this class will still work as before...
of if I change the FTPoint class and the tests fail, then I have an extremely simple piece of code to debug...
or, if I have something that doesn't work and it uses the FTPoint class and these tests pass, I know it's not this code causing the problem.
Check out FTGL if you want to see a test suite in action.
Unit tests and test first design is the most productive way to write code.
I think I get the idea, but it wont help me too much at this stage, since I don't even know what to test for, since I am not really sure what OpenGL expects that I am not doing.
Otherwise, I actually did use this technique when writing my matrix code. I wrote a cpp tool which I quickly ran when I made some changes to the code and verified that everything was Ok. Though I used console output to give meaningful error messages instead of simple assert.
OneSadCookie
2003.04.30, 05:35 PM
If you know what a function's supposed to be doing, then you know what to test for. As you write tests for functions, you'll gradually gain confidence that the error is not in those functions, so you'll narrow down where it could be. Once you've written enough tests, you'll either spot the error (and write a new test to make sure it doesn't happen again!), or a test will fail and you'll find the error that way.
henryj
2003.04.30, 06:24 PM
meaningful error messages instead of simple assert.
Here is some sample output from cppunit.
Running
.F....F.....F..F..F.......F..F.................... ......F....F.............
!!!FAILURES!!!
Test Results:
Run: 66 Failures: 9 Errors: 0
1) test: 10FTFontTest.testOpenFont (F) line: 71 ../test/FTFont-Test.cpp
expected: 1
but was: 6
2) test: 10FTFontTest.testSetFontSize (F) line: 113 ../test/FTFont-Test.cpp
expected: -14
but was: -15
3) test: 10FTBBoxTest.testGlyphConstructor (F) line: 49 ../test/FTBBox-Test.cpp
expected: 3
but was: 2
4) test: 10FTBBoxTest.testPlusEquals (F) line: 93 ../test/FTBBox-Test.cpp
expected: 3
but was: 2
5) test: 10FTSizeTest.testSetCharSize (F) line: 55 ../test/FTSize-Test.cpp
expected: -14
but was: -15
6) test: 16FTVectoriserTest.testGetOutline (F) line: 350 ../test/FTVectoriser-Test.cpp
expected: 29
but was: 28
7) test: 16FTVectoriserTest.testMakeMesh (F) line: 400 ../test/FTVectoriser-Test.cpp
expected: 29
but was: 28
8) test: 10FTFaceTest.testOpenFace (F) line: 34 ../test/FTFace-Test.cpp
"face1.Error() == 1"
9) test: 10FTFaceTest.testGetFontTable (F) line: 80 ../test/FTFace-Test.cpp
"testFace->FontTable( 'hmtx')"
UnitTests has exited with status 0.
Feanor
2003.05.01, 04:47 PM
Originally posted by henryj
Here is some sample output from cppunit
That's cool. I think it is hard to argue with your facts.
I like design, and recommend it for how to think about a problem, but I guess it is impossible to use design to isolate and fix bugs. I don't know if designs themselves can have bugs, but if so, the only way to find them would be to try to implement the design (in a computer program or some manual way). Design is a way to help think about the problem solution more clearly, to help improve algorithms and keep things organized so they are easier to understand.
I think that you can design a solution to a problem, but you cannot really design a program. You can implement a design by writing a program that adheres to it, but you have to make sure all the parts of the design are actually programmable, and then test those parts like you show. Design is inherent; I guess some people like to make it more explicit, while others don't want to waste the time.
henryj
2003.05.01, 07:24 PM
Wow Feanor...are you feeling alright? You're the last person I would have thought would come out on the side of no design.
Originally posted by Feanor
That's cool. I think it is hard to argue with your facts.
I like design, and recommend it for how to think about a problem, but I guess it is impossible to use design to isolate and fix bugs. I don't know if designs themselves can have bugs, but if so, the only way to find them would be to try to implement the design (in a computer program or some manual way). Design is a way to help think about the problem solution more clearly, to help improve algorithms and keep things organized so they are easier to understand.
I think that you can design a solution to a problem, but you cannot really design a program. You can implement a design by writing a program that adheres to it, but you have to make sure all the parts of the design are actually programmable, and then test those parts like you show. Design is inherent; I guess some people like to make it more explicit, while others don't want to waste the time.
To my shame, I have to admit that I have not used cppunit before, but I will give it a try.
I think the problem with unit testing is that it cannot test for really obscure bugs, which only appear at rare and/or extreme conditions. Furthermore, you need the rest of the bunch, such as functional tests.
The design should be a positive proof of the algorithm to be implemented, something which is quite tough to do by itself, but there is no way to test this with a limited number of test cases, typically. You have to make some assumptions about how something is implemented to be able to design tests which exploit potential weaknesses.
henryj
2003.05.01, 09:12 PM
To my shame, I have to admit that I have not used cppunit before, but I will give it a try.
You don't have to use cppunit. I use it because I find it useful and it has become second nature. There are alternatives or you can roll your own.
I think the problem with unit testing is that it cannot test for really obscure bugs, which only appear at rare and/or extreme conditions. Furthermore, you need the rest of the bunch, such as functional tests.
This is a common misconception. One of the best things about unit tests is it allows you to apply extreme conditions in a controlled environment. And it doesn't really matter if you miss a special case. When it does turn up it is a lot easier to simulate, debug and test in the 'clean room' of the unit test than in the production system with it's added complexity and noise as you have seen with your texture bug.
The design should be a positive proof of the algorithm to be implemented, something which is quite tough to do by itself, but there is no way to test this with a limited number of test cases, typically. You have to make some assumptions about how something is implemented to be able to design tests which exploit potential weaknesses
This is another misconception and an argument for test driven development. Most programming tasks involve calling a function with some arguments and getting a result back. This is true even of very complex algorithms. If you know the algorithm you should be able to predict the results from a given set of parameters. (If you don't know the algorithm well enough to predict the results you shouldn't be using it.) This being the case, you write the test first eg.
void testCompositeCurve()
{
FTContour contour( compositePoints, compositeTags, 18);
CPPUNIT_ASSERT( contour.PointCount() == 50);
}
This takes a known set of 18 bezier control points and produces a series of points on the curve. Independent (of the code) analysis says that there should be 50 points produced so that's what I test for. Simple. Then you write the code to produce the desired result.
Then you can write some boundary cases.
void testNullCurve()
{
FTContour contour( NULL, NULL, 0);
CPPUNIT_ASSERT( contour.PointCount() == 0);
}
As you get used to writing unit tests you realise that it is unnecessary to test every possible combination. You can apply the 'zero, one, infinity' rule and it doesn't matter anyway. Some tests are better than no tests.
Now there will be cases where it seems almost impossible to write a test. This can be because of...
a. A lazy programmer. Happens a lot. Sometimes the work to write the test is far more than writing the actual code. Do it anyway.
b. The code is a mess. In this case, rewrite your code. This is double win. Well tested, more understandable code.
c. Some technical hurdle. This almost never happens. So if you think this might be the case it's more likely a or b.
I did roll my own unit tests in the end. cppunit seemed a little bloated for any quick testing. I have reduced the overhead to 2 macros per test, and 1 per assertion, plus another one to give summarized results. No schmuck classes for testing.
Anyway, if you can tell me how I can test interaction with OpenGL rendering with a UNIT TEST, I will tell you how to travel faster than light ;) . This would be a functional test, IMHO, because it tests the interaction of different entities. Of course, I could check OpenGL state before and after the process to be tested, but if something goes wrong in between, I won't know, and maybe because I don't have enough design to know what I am supposed to be doing (assuming the other unit tests are all ok).
This is a common misconception. One of the best things about unit tests is it allows you to apply extreme conditions in a controlled environment. And it doesn't really matter if you miss a special case. When it does turn up it is a lot easier to simulate, debug and test in the 'clean room' of the unit test than in the production system with it's added complexity and noise as you have seen with your texture bug.
If your unit tests pass, but the code is still bad? You need to do some functional tests, to narrow done your weak spot, then re-do the unit tests (and the design) to test for it. You cannot solely rely on unit tests without looking outside your cleanroom. The unit tests are the most atomic tests you can possibly do, but you have to figure out what to test for. This should be in your design, but if the design is evolving with the code, the unit tests will change when you find bugs, if you can figure out the cause.
As you get used to writing unit tests you realise that it is unnecessary to test every possible combination. You can apply the 'zero, one, infinity' rule and it doesn't matter anyway. Some tests are better than no tests.
You have to find that zero and infinity first, only then you can test it. My problem is exactly that I don't know what's wrong, because the "informal" unit tests I have performed on seperate pieces of code seem correct.
Anyhow, it seems like a good idea to write unit tests for most things, so I will do that now instead of trying to find this GL bug. Maybe it is just a stupid typo somewhere, after all. With some tens of classes, and over 30k lines of code, it is quite likely.
Feanor
2003.05.01, 10:21 PM
Originally posted by henryj
Wow Feanor...are you feeling alright? You're the last person I would have thought would come out on the side of no design.
:blush:
Well who said "no design"? Sheesh. I still write requirements and overviews and build object graphs.
I do admit there's a definite limit. I guess I grew some more sense after some kind of experience accrual. Maybe I just levelled up? :D And there's that whole thing about code verifiability, or the theoretical lack thereof.
Feanor
2003.05.01, 10:31 PM
Originally posted by DoooG
I think the problem with unit testing is that it cannot test for really obscure bugs, which only appear at rare and/or extreme conditions. Furthermore, you need the rest of the bunch, such as functional tests.
This is not what I have been taught. Anyway, what is an "obscure" bug? Testing is meant to focus on edge conditions. If you know the input data as well as you should, you can formulate tests that check all the borderline cases, where bugs are more likely to occur, as well as typical cases. Or so I gather.
The design should be a positive proof of the algorithm to be implemented, something which is quite tough to do by itself, but there is no way to test this with a limited number of test cases, typically. You have to make some assumptions about how something is implemented to be able to design tests which exploit potential weaknesses.
Design can't prove anything, only account for things as a result of spending time thinking about the task. I guess if the problem you are working on is susceptible to mathematical proof (like by induction), you might be able to demonstrate that the design matches the algorithm, and hence is also correct, but that doesn't mean that the code will match the design.
Anyway, if you can tell me how I can test interaction with OpenGL rendering with a UNIT TEST, I will tell you how to travel faster than light..
Write a test harness that stands in for OpenGL and link to that instead. Then you can catch all of the data you are sending in and make sure it matches the specified parameters of the particular API call.
henryj
2003.05.02, 01:51 AM
DoooG...
Pretty much all of your concerns are unfounded and I know where you are coming from. I was a sceptic at first but once you get a taste for unit tests you will understand.
As for testing OpenGL, you answered that one yourself.
The unit tests are the most atomic tests you can possibly do
You test the specific bit you're interested not the whole system.
If there is something you don't know how to test, send it to me and I'll see if I can find some time to help.
Originally posted by henryj
DoooG...
Pretty much all of your concerns are unfounded and I know where you are coming from. I was a sceptic at first but once you get a taste for unit tests you will understand.
As for testing OpenGL, you answered that one yourself.
You test the specific bit you're interested not the whole system.
If there is something you don't know how to test, send it to me and I'll see if I can find some time to help.
Ummm, ok, I think I understand my misunderstanding. In this case, I just realized, I have made an acceptance/functional test by making the actual progam, and the test failed, since it does not display correctly. So the question is:
what if my unit tests are all correct, yet the overall result is bad?
I think the answer is that my unit tests are bad, and the design bug has to be found. Correct?
To get an object drawn on the screen, the interaction of 8 classes is required at a minimum, and as far as I can tell, the way for testing this is to make a little app that tries just that (just what I did). The computer won't be able to tell if the rendering is correct, so I have to do it.
henryj
2003.05.02, 11:01 PM
To get an object drawn on the screen, the interaction of 8 classes is required at a minimum, and as far as I can tell, the way for testing this is to make a little app that tries just that (just what I did).
Go back to your correct 'atomic' comment again.
Don't test the results of the interactions of those eight classes, test the individual classes in isolation. This is WAY easier from a coding point of view and easier to work out what to test.
Make sure your tests at least mirror what is going on in your system. Copy and paste the code into your tests
If all eight classes are well tested and correct then it's highly likely that the system will behave as expected.
If it doesn't then your logic (design) is wrong.
The computer won't be able to tell if the rendering is correct, so I have to do it.
You can grab a 'correct' frame and then write a test to compare this against. This assumes at some point you got your program to work.
vBulletin® v3.6.8, Copyright ©2000-2008, Jelsoft Enterprises Ltd.