• Content count

  • Joined

  • Last visited

Community Reputation

124 Neutral

About Niux

  • Rank
  1. Hi all I'm trying to do multiple passes with my fragment shader on a texture by using FBOs and render-to-texture technique. I have a texture (256x256) on a quard in the center of my window (1024x768) and I want to render that texture to my FBOs 2+ times. Problem is, when I do that the "normal" render-to-texture way, it is not only the texture but the entire scene that is rendered to the FBO. Is there anyway to only render my texture to the FBO? (So I keep size, scale, aspect ration (for the texture) etc. intact and not get the rest of the sceen rendered aswell?) Thanks, Niux
  2. Hey I'm new to both GL and Cg myself, but I'm playing around with the the same thing. The first thing I noticed was that you are setting the texture parameter before you bind the fragment program. I honestly don't know if it makes a difference, but though I would mention it. Also I see you've commented out the vertex shader which means you are using the fixed function pipeline vertex shader - again I'm not certain of this, but have you tried with you own vertex shader to be sure that the texture coordinates gets passed to the fragment program? (I think it should work that way you do it tho..) The Cg tutorials recommend that you use this line of code: // Allow cg Run-Time system to handle texture activation. cgGLSetManageTextureParameters(cgContext, true); Hope my guesses can be of some help :) -Niux
  3. And there we go - my image is correctly blured now :) Thanks again!
  4. Thanks for the swift reply! I'm aware of the seperate filter however I figured I'd get the blur working, before optimizing it :) The thing I'm particually interested in is how the TEXCOORD indexing/accessing/addressing (what's the term?) works (since I need to write several more filters after this one). You write, for the horizontal filter: sum += tex2D(bloom, float2(texCoord.x, texCoord.y - 4*bloomSize)) * 0.05; sum += tex2D(bloom, float2(texCoord.x, texCoord.y - 3*bloomSize)) * 0.09; sum += tex2D(bloom, float2(texCoord.x, texCoord.y - 2*bloomSize)) * 0.12; ... Or in general: tex2D(texture, float2(texCoord.x, texCoord.y +/- i * kernelSize)) * weight; As I said, I'm interested in how the offset to the y coordinate works, specifically the "i * kernelSize" part. I can't see why you are multiplying the kernel/bloom size on the i'th index? I guess my question could be "how does the texCoord datastructure look like?" Again, thanks for your help - I'm trying it now! However I still need to figure the other stuff out, can you help me with that?
  5. Hello I'm trying to implement a blur filter in a Cg fragment shader, however I'm still new to Cg, so I have a basic (I think) question: When bluring I need to sum a neighborhood of fragments - the question is, how do I access these neighbors in the texture. I'm duing it like this, but I'm not getting the correct effect: void FragmentMain( in vertexOut IN, uniform sampler2D texture, uniform sampler2D glowTexture, out float4 color : COLOR) { //Compute new fragment color value : Box Filter int kernelSize = 1; float weight = 1.0f / 9; float4 colorSum = float4(0.0f, 0.0f, 0.0f, 0.0f); int weightSum = 0; int dX, dY; float2 neighborCoord; for(dX = -kernelSize; dX <= kernelSize; dX++) { for(dY = -kernelSize; dY <= kernelSize; dY++) { neighborCoord = float2(IN.texCoord.x+dX, IN.texCoord.y+dY); colorSum += tex2D(glowTexture, neighborCoord) * weight; weightSum += weight; } } float4 newColor = colorSum / weightSum; color = newColor; //Result of blur }
  6. AI Learning Method

    Also, while your designing your algorithm on paper remember to define your datastructures and when doing so, try to think through the entire algorithm and how you plan to implement it in order to get a datastructure that supports your all your needs.
  7. Eclipse Build/Run issue

    Quote: The code runs just fine when I execute it within Eclipse, but the executable jar file consistently crashes. What could be causing this? The path to the file. I'm not completely sure about this, but - you are using relative paths right? The path to your .wld when running in eclipse is not the same as when executing the .jar. When running in eclipse the project executes from the root of your project folder: MyProject/res/models/*.wld You would then use the path "res/models/*.wld" in your code. However when running the .jar, the program executes from the path where you run java -jar ... At the same time, your .jar i probably has MyProject as root folder, thus the path your should be using is "MyProject/res/models/*.wld". As I said, I'm not completely sure about the last part, but the "can read the file in Eclipse, but not 'outside' Eclipse" is almost always a path problem.
  8. Okay - minor update. I found wrong radian/degree conversions, just as you said. The axis-angle matrix was fine though. I updated the code to remember the orientation of the fish and now orientation*relative rotation is uploaded to opengl. That fixed the scaling problems and every thing looks more correct now. Only thing is the orientation of the fish isn't right. When the program starts, the fish is a (4, 0, 0)T (facing positive Z) and begins to move towards (0, 0, 0)T. That works correctly - the fish rotates from facing positive Z to negative X. However when the fish gets to (0, 0, 0)T, it starts to move towards (5, 5, 5)T - this is where the orientation starts to be wrong. So I printed the matrices and axis/angles: //Fish is at (0, 0, 4) starts moving towards (0, 0, 0) new position: (0, 0, 0) //Find axis angle turn Axis: (0, -4, 0) //See below turn angle: 90 //axis-angle to rotation matrix relative rotation: | 6.12303e-17 -0 -1 | | 0 1 -0 | | 1 0 6.12303e-17 | // orientation = rotation * orientation - actually I haven't 2x checked this function EDIT: now I have, it's correct new orientation: | 6.12303e-17 0 -1 | | 0 1 0 | | 6.12303e-17 0 -1 | //Update heading to displacement.normalize() old heading: (0, 0, 1) new heading: (-1, 0, 0) //Fish is at (0, 0, 0) (facing negative X) starts moving towards (5, 5, 5) new position: (5, 5, 5) //Find axis angle turn Axis: (0, 5, -5) //See below turn angle: 54.7356 //axis-angle to rotation matrix relative rotation: | 0.57735 0.57735 0.57735 | | -0.57735 0.788675 -0.211325 | | -0.57735 -0.211325 0.788675 | // orientation = rotation * orientation new orientation: | 7.07027e-17 0.57735 -1.1547 | | -5.37597e-17 0.455342 0.877991 | | 1.88314e-17 -0.429558 -0.30755 | //Update heading to displacement.normalize() old heading: (-1, 0, 0) new heading: (0.57735, 0.57735, 0.5773 About the turn axis: I take the cross product between current heading (normalized) and the new displacement vector (newPosition - oldPosition) - NOT normalized. EDIT: I normalize the turnAxis vector before passing it to the axisAngleToRotationMatrix-function. If I don't, I get strange scale-transformations when applying the new orientation matrix. For comparison I staged an example of the fish moving from (0, 0, 0)T (facing positive Z) to (5, 5, 5)T as the first move, ie. with a correct orientation. new position: (5, 5, 5) turn Axis: (-5, 5, 0) turn angle: 54.7356 relative rotation: | 0.788675 -0.211325 0.57735 | | -0.211325 0.788675 0.57735 | | -0.57735 -0.57735 0.57735 | new orientation: | 0.788675 -0.211325 0.57735 | | -0.166667 0.833333 0.455342 | | -0.359117 -0.359117 -0.0188747 | old heading: (0, 0, 1) new heading: (0.57735, 0.57735, 0.57735) The turn axis' are different thus the relative rotation matrix is different. I'm still trying to figure out why the turnAxis is different, but I posted this since experienced eyes might be able to spot the error :) EDIT: Doh - of cause the turnAxis is different, then initial heading is different (negative X vs. positive Z) EDIT2: I did another test - keeping the fish axis-aligned: Facing: From: To: Result: Result facing: Expected facing: + Z (4, 0, 0) (4, 0, 0) Good - X - X - X (0, 0, 0) (0, 0, 4) Bad + X + Z + X (0, 0, 4) (0, 0, 0) Bad + Z - Z + Z (0, 0, 0) (0, 4, 0) Bad - Y + Y - Y (0, 4, 0) (0, 0, 0) Bad + Z - Y + Z (0, 0, 0) (0, 4, 0) Bad + Z + Y + Z (0, 4, 0) (0, 0, 0) Bad + Z - Y + Z (0, 0, 0) (0, 0, 4) Bad + Y + Z + Y (0, 0, 4) (0, 0, 0) Bad + Z - Z The matrix from the second step looks like this: |0 0 1| |0 1 -0| |-1 0 0| Applying that to the old heading vector (-1, 0, 0)T, gives the expected result (0, 0, 1)T. [Edited by - Niux on March 11, 2010 6:40:02 AM]
  9. Quote: Is what you're getting for an axis-angle rotation of (90, [0, -1, 0]), then your axis-angle-to-matrix function is wrong. Quote: Is what you're getting for an axis-angle rotation of (90, [0, -1, 0]), then your axis-angle-to-matrix function is wrong. Each of the basis vectors of the resulting matrix should be unit-length, more or less, which clearly isn't the case here; also, a 90-degree rotation should leave you with an 'axis-aligned' orientation, which leads me to believe that there's an incorrect or missing degrees<->radians conversion somewhere. Good, I'll look into these things. Quote: Is incorrect; the right-most column should be [0, 0, 0, 1]T, not [1, 1, 1, 1]T. Yes, sorry - I was just testing (1,1,1,1) to see the difference and forgot to set it back (when I wrote the post, I had (0,0,0,1) in mind) Quote: Lastly, it doesn't seem to me that you're using the computed rotation matrix correctly. Unless you're reading back the OpenGL modelview matrix somewhere, you shouldn't ever be uploading the relative rotation directly to OpenGL. Rather, you need to track the orientation of the fish yourself (using another matrix), update it each frame using the relative rotation matrix, orthogonalize it to prevent drift, and then upload that matrix to OpenGL when it's time to render. Okay - I've clearly misunderstood that part, and I can see the mistake now. Again, thanks alot!
  10. Okay, so the code should be clean now. Back to my problem. What I've done except for cleaning code, since the orientation algorithm/calculation still doesn't work, is to only use the rotation matrix (axis-angle matrix / Rodriques' rotation matrix, lefthanded). Now the rotation seems to work right this way, but my fish is scaled alot(!) in one axis and pancaked in another axis. Here's what happening: 1) Find crossProduct between current heading (initially (0,0,1)) and new displacement 2) Find rotation angle by: angle = sin-1(|v x w| / |v||w|) * (180 / M_PI) 3) Compose rotation matrix 4) Put rotation matrix on matrix stack Notice, I'm not updating the heading (heading = normalize(displacement)) - if I do so, the fish is obfuscated even more (scaled into a wired shape). I've taken a closer look at what I'm doing with the matrix stack (entire application): Method: Stack: Comment: glLoadIdentity(); [I, ] glPushMatrix(); [I, I] glTranslatef(...); [I, T] Translate fish to its position in R^3 glPushMatrix(); [I, T, T] glMultMatrix(...); [I, T, TR] Load the rotation matrix on the stack (*) glPuchMatrix(); [I, T, TR, ] glScalef(...); [I, T, TR, S] Adjust size of fish glRotatef(...); [I, T, TR, S, R] Rotate fish to face positive Z after drawing *) If i use glLoadMatrix(..); here, as I expected was the right thing, the fish ends up in the face of the camera? I looked at some actual angle,axis,rotation matrix values too see if they where the problem: (Fish is at (4, 0, 0) and starts moving towards (0, 0, 0)) turn Axis: (0, -1, 0) turn angle: 90 rotation matrix: | -25.6727 -0 -51.2222 | | 0 1 -0 | | 51.2222 0 -25.6727 | The axis and angle looks right to me - not sure about the matrix though. Here is the code for vector cross product: void crossProduct(Vector3& dest, Vector3& v1, Vector3& v2) { /* * a d bf - ce * b x e = cd - fa * c f ae - bd */ float a = v1.x; float b = v1.y; float c = v1.z; float d = v2.x; float e = v2.y; float f = v2.z; dest.x = (b*f) - (c*e); dest.y = (c*d) - (f*a); dest.z = (a*e) - (b*d); } Here is the code snippet for axis-angle calculations: Vector3 turnAxis; crossProduct(turnAxis, heading, displacement); //Find angle double angle = asin( turnAxis.length() / (heading.length() * displacement.length())); angle *= (180 / M_PI); turnAxis.normalize(); //Build axis-angle (rotation) matrix rotation = Matrix33( 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 ); axisAngleToRotation(rotation, turnAxis, angle); Here is the code for building the rotation matrix: void axisAngleToRotation(Matrix33& m, Vector3& v, GLfloat a) { GLfloat s = sin(a) * (180 / M_PI); GLfloat cplus = cos(a) * (180 / M_PI); GLfloat cminus = 1 - cplus; /* Rodrigues' rotation matrix, left handed, column major * (Given the vector = (x, y, z)) * * | c_plus + x^2 * c_minus x*y*c_minus - x*s x*z*c_minus + y*s | * | x*y*c_minus - z*s c_plus + b^2 * c_minus y*z*c_minus - x*s | * | x*z*c_minus - y*s y*z*c_minus + x*s c_plus + z^2 * c_minus | * * Where s = sin(angle), c_plus = cos(angle), c_minus = 1-c_plus */ m.a = cplus + (v.x*v.x) * cminus; m.b = v.x * v.y * cminus + v.z * s; m.c = v.x * v.z * cminus - v.y * s; m.d = v.x * v.y * cminus - v.z * s; m.e = cplus + (v.y * v.y) * cminus; m.f = v.y * v.z * cminus + v.x * s; m.g = v.x * v.z * cminus + v.y * s; m.h = v.y * v.z * cminus - v.x * s; m.i = cplus +(v.z * v.z) * cminus; } Here is the code for loading the matrix on the stack: GLfloat mat3[16]={ rotation.a, rotation.d, rotation.g, 1.0, rotation.b, rotation.e, rotation.h, 1.0, rotation.c, rotation.f, rotation.i, 1.0, 0.0, 0.0, 0.0, 1.0}; glMultTransposeMatrixf(mat3);
  11. Quote: Only if you don't initialize yourself in the initialization list: MyClass() : o(...) // <--- initialization list { // constructor body } Aha! And I can have an initialization list for every constructor? Can I use an argument to the constructor in the initialization list?
  12. Thanks for all the replies! Quote: Yes; that's what .push_back() is for. Maybe I should have bin more specific in my question, however what I wanted to find out, was whether .push_back() would only put the reference in the vector and not copy the object. Meaning when the Myclass t(...) would go out of scope and be deleted, the reference would be invalid. But I probably should have thought about it one extra time, before asking, since classes is a vector of MyClass and not MyClass references. Quote: However, do you really need to "do stuff with t" before putting it into the vector? What is "stuff" here? "Stuff" in this case is to initialize a member of MyClass with a random number. Now, this could be done in a constructor, but it is not really coherent with the class interface - using a setter method would be better in this case. Another question I have; When declaring members in the header file like this: class MyClass { public: MyClass(); virtual ~MyClass(); private: MyOtherClass o; }; I noticed that the default (MyOtherClass(void)) constructor is automatically called. I looked it up and it is an error not to initialise the object when declared, thus the automatic call to the default constructor. BUT what I want, and this is most likely a Java ting I shouldn't be doing in C++, is to just declare the member object (o), and later initialise it: o = MyOtherClass(...); The reason for initialising it later could be that the constructor arguments are not calculated when the header is loaded. So the question is what is the correct C++ way to do this ? Right now I just have a default constructor that does nothing and then later reassign the member variable.
  13. Hey all I'm in the process of learning C++ and I have a few questions about how to do some specific stuff the right way. 1. Which is the better solution and why? //somewhere an object is defined MyClass t = MyClass(...); //here's functions that operates on MyClass void doStuffWithTable1(MyClass* t) { ... ... } // OR void doStuffWithTable2(MyClass& t) { ... ... } 2. Will this work? Why not and how to do it right? //foo.h ... std:vector<MyClass> classes; ... //foo.cpp ... Foo::Foo() { for(int i = 0; i < n; i++) { MyClass t(...); //do stuff with t classes.push_back(t); } } ... Will classes after this for-loop, contain n instances of MyClass?
  14. Quote:Just out of curiosity, is it part of the assignment that the program be written in C++? Or is the choice of language up to you? Part of the assignment. However I don't mind - should be able to write C/C++ before I get a BS in CS - unfortunately, my university has Java as the official language of choice. Quote:Matrix44* matrix = new Matrix44(...); Instead, you would just write this: Matrix44 matrix(...); Yes - I picked up a copy of 'The C++ Programming Language' and started reading up. The code now looks like this: /* * Fish.h * * Created on: Mar 8, 2010 * Author: Mark */ class Fish { public: Fish(); Fish(TriangleMesh* model); void calculateNewTrajectory(Vector3* newPosition, float speed); void preFrame(double time); void draw(); virtual ~Fish(); private: void init(); void drawFishModel(); void drawFish(); TriangleMesh* model; Vector3 position; Vector3 stopPosition; Vector3 startPosition; Vector3 displacement; double travelTime; double startTime; bool trajectorySet; bool avoidState; bool withModel; }; /* * Fish.cpp * * Created on: Mar 8, 2010 * Author: Mark */ #include "h.h" using namespace std; Fish::Fish() { withModel = false; init(); } Fish::Fish(TriangleMesh* model) { this->model = model; withModel = true; init(); } void Fish::init() { position = Vector3(0.0, 0.0, 0.0); //Prevents read from uninitialised variables, if calculateNewTrajectory //has never bin called. trajectorySet = false; } /* Pre-calculate everything needed to move fish from A to B */ void Fish::calculateNewTrajectory(Vector3* newPosition, float speed) { //Find displacement vector (vector fish will swim along) subtractVectors(&displacement, newPosition, &position); stopPosition = *newPosition; //Copy vector startPosition = position; travelTime = displacement.length() / speed; startTime = Clock::getTime(); trajectorySet = true; } /* Move the fish if a trajectory is set */ void Fish::preFrame(double time) { if(trajectorySet) { //Check that the fish has somewhere to go double elapsedTime = time - startTime; if (elapsedTime > travelTime) { //Is the movement done? position = stopPosition; //Copy vector //If this movement was an 'avoid other fish' movement //exit the avoid state when movement is done if (avoidState) { avoidState = false; } } else { //If movement is not done, continue along displacement vector Vector3 currentDisplacement; //Calculate how far the fish have move until now, based on time scaleVector(&currentDisplacement, &displacement, elapsedTime / travelTime); //Update the fish' position addVectors(&position, &startPosition, &currentDisplacement); } } } /* Draw the fish and rotate to face in the direction of movement. * Also to basic fish animation. */ void Fish::draw() { //Rotate with respect to local coordinate system //Do the drawing glPushMatrix(); if (!withModel) { drawFish(); } else { drawFishModel(); } glPopMatrix(); } /* Draws a fish (sort of) if no model is used */ void Fish::drawFish() { glutWireSphere(0.5, 5, 5); } /* Draws a fish if a model is loaded */ void Fish::drawFishModel() { glBegin(GL_TRIANGLES); for (unsigned int i = 0; i < model->faces.size(); i++) { /* First Vertex */ glNormal3f( model->normals[model->faces[i].vn[0]].x, model->normals[model->faces[i].vn[0]].y, model->normals[model->faces[i].vn[0]].z ); glVertex3f( model->verts[model->faces[i].v[0]].x, model->verts[model->faces[i].v[0]].y, model->verts[model->faces[i].v[0]].z ); /* Second Vertex */ glNormal3f( model->normals[model->faces[i].vn[1]].x, model->normals[model->faces[i].vn[1]].y, model->normals[model->faces[i].vn[1]].z ); glVertex3f( model->verts[model->faces[i].v[1]].x, model->verts[model->faces[i].v[1]].y, model->verts[model->faces[i].v[1]].z ); /* Third Vertex */ glNormal3f( model->normals[model->faces[i].vn[2]].x, model->normals[model->faces[i].vn[2]].y, model->normals[model->faces[i].vn[2]].z ); glVertex3f( model->verts[model->faces[i].v[2]].x, model->verts[model->faces[i].v[2]].y, model->verts[model->faces[i].v[2]].z ); } glEnd(); } Fish::~Fish() { } My vector/matrix functions looks like this addVectors(&position, &startPosition, &currentDisplacement); ... ... void addVectors(Vector3* dest, Vector3* v1, Vector3* v2) { dest->x = v1->x+v2->x; dest->y = v1->y+v2->y; dest->z = v1->z+v2->z; } As you can see I'm not done with the rewriting yet. I'm not sure whether passing pointers to the addVectors function is the best practise (I guess v1 and v2 should be constant references)? The only other thing that uses pointers is the triangularMesh, but since the model is the same for all fish objects - and never changed - it seems like a waste of memory to load a model for each fish. Again, thanks for all the time your are spending on this - if I could rate you higher, I would. [Edited by - Niux on March 9, 2010 6:43:30 AM]
  15. Well, no :) This is for an introductory OpenGL class I'm taking, where we need to implement a Boids model in 3D. However, the cool thing is that a part of the project is to make it in 3D stereo (Avatar style). Plus we should be able to interact with the shoal of fish with a Wii-mote, so we get the 3D interaction feel. But maybe I'll make it a game - I mean, 3D stereo Wii-mote controlled fishing game sounds alright ;)