# mako_5

Member

157

103 Neutral

• Rank
Member
1. ## Help Understanding Frustum Calculations

[font="Arial"]A and B are the right and up directions for the camera. A, B, and dir (the vector from eye to look) form a basis (three orthogonal axes), so B is not necessarily the Z-unit vector. You can use A and B with the eye coordinates to make pick rays. It really doesn't make sense to have a DrawFrustum() for the corners. After the perspective transform, the frustum corners will be the eight corners of the unit cube in clip coordinates. You might see the points drawn in the corners of the display for the near plane and further out for the far plane. See the "Stages of Vertex Transformation" [url="http://fly.cc.fer.hr/%7Eunreal/theredbook/chapter03.html"]http://fly.cc.fer.hr.../chapter03.html[/url] Normally, calculations are done [/font][font="Arial"]using the half angle of the field of view. The 360 simple compensates for not using a half FOV angle. A little clearer would be float ch = tanf(FOV * 0.5 * M_PI / 180.0);[/font]
2. ## Trouble with pick rays in OpenGL ES

Solved the problem. I've posted the correct code for anyone else trying to make pick rays. Multiplying by camera inverse transform takes to eye coordinates, but the pick ray needs to stay in world coordinates. Also, I mistook u for the camera's left vector, when it was the camera's right vector. The crucial error was that I also forgot the absolute value conversion in myintersectsPlane function: [code]bool intersectsPlane(const vec3 &planeNormal_, float planeConstant_) { return fabs(planeNormal_.dot(direction)) >= S4_RAY_PRECISION; }[/code] Real algorithm: [list=1][*]Take picked screen coordinates and convert to normalized device coordinates (-1,-1 to 1,1).[*]Use the frustum right and top bounds and the camera's left and up vectors (parallel to the view plane normal) to get an actual coordinate on the near plane.[*]Draw the ray from the camera's eye through this position.[/list] For making the pick ray: [code]ray3 S4Camera::makePickRay(int iScreenPixelX_, int iScreenPixelY_) { // n is away from the center... // u is right vector // Y-pixels are inverted; float pw = iScreenPixelX_; float ph = m_iFilmHeight - iScreenPixelY_; float x = 2 * pw / m_iFilmWidth - 1.0f; float y = 2 * ph / m_iFilmHeight - 1.0f; vec3 pickDirection = m_frustum.right*x*u + m_frustum.top*y*v + -m_frustum.near*n; ray3 pickRay(m_eye, pickDirection); return pickRay; } [/code] Here's how I'm making the camera transform: [code]void S4Camera::makeMatrix() { // n = viewplane normal // v = up // u = right n = m_eye - m_center; u = m_up.cross(n); v = n.cross(u); n.normalize(); u.normalize(); v.normalize(); mat4 &M = m_matrix; M[0] = u.x; M[4] = u.y; M[8] = u.z; M[12] = 0.0f; M[1] = v.x; M[5] = v.y; M[9] = v.z; M[13] = 0.0f; M[2] = n.x; M[6] = n.y; M[10] = n.z; M[14] = 0.0f; M[3] = 0.0f; M[7] = 0.0f; M[11] = 0.0f; M[15] = 1.0f; mat4 translation = mat4::translation(-m_eye); M *= translation; } [/code]
3. ## Trouble with pick rays in OpenGL ES

I'm using OpenGL ES and it looks like I need to write my own pick rays. I'm taking the pick ray and trying to intersect with the xz-plane. I'm not sure if I'm not making the pick ray correctly or doing the intersect test correctly, or both are messed up. I'd really appreciate anyone who would look at this. Please let me know if there is any more code you need to see. Here's my algorithm idea for making the pick ray: [list=1][*]Take picked screen coordinates and convert to normalized device coordinates (-1,-1 to 1,1)?.[*]Use the frustum right and top bounds and the camera's left and up vectors (parallel to the view plane normal) to get an actual coordinate on the near plane.[*]Draw the ray from the camera's eye through this position.[*]Multiply the ray by the inverse camera transform to convert to world coordinates.[/list] This is the test which doesn't work correctly [code]ray3 pickRay = camera.makePickRay(screenX, screenY); // Try to intersect with y-plane yIntersect = pickRay.intersectPlanePoint(vec3(0,1,0),0); [/code] For making the pick ray [code]ray3 S4Camera::makePickRay(int iScreenPixelX_, int iScreenPixelY_) { // n is away from the center... // u is left vector // Y-pixels are inverted; float pw = iScreenPixelX_; float ph = m_iFilmHeight - iScreenPixelY_; // Convert to NDC? // The screen dimensions are film dimensions float x = 2 * pw / m_iFilmWidth - 1.0f; float y = 2 * ph / m_iFilmHeight - 1.0f; // Convert to world coordinates vec3 pickDirection = -m_frustum.right*x*u + m_frustum.top*y*v + -m_frustum.near*n; ray3 pickRay(m_eye, pickDirection); // Multiply by inverse camera transform pickRay.multiply(m_matrix); return pickRay; } [/code] Here's how I'm making the camera transform: [code]void S4Camera::makeMatrix() { // n = viewplane normal // v = up // u = left n = m_eye - m_center; u = m_up.cross(n); v = n.cross(u); n.normalize(); u.normalize(); v.normalize(); mat4 &M = m_matrix; M[0] = u.x; M[4] = u.y; M[8] = u.z; M[12] = 0.0f; M[1] = v.x; M[5] = v.y; M[9] = v.z; M[13] = 0.0f; M[2] = n.x; M[6] = n.y; M[10] = n.z; M[14] = 0.0f; M[3] = 0.0f; M[7] = 0.0f; M[11] = 0.0f; M[15] = 1.0f; mat4 translation = mat4::translation(-m_eye); M *= translation; } [/code] How I'm doing ray multiplication: [code] void ray3::multiply(const mat4& transform_) { origin.multiplyAsPoint(transform_); // multiplies as (x,y,z,1) direction.multiplyAsVector(transform_); // multiplies as (x,y,z,0) }[/code] And how I'm doing plane testing: [code] vec3 intersectPlanePoint(const vec3 &planeNormal_, float planeConstant_) { assert(intersectsPlane(planeNormal_, planeConstant_)); float t = (-planeConstant_ - planeNormal_.dot(origin)) / (planeNormal_.dot(direction)); return at(t); } [/code]
4. ## DirectX 9 or SDL and OpenGL

As a note: NeHe has most of the tutorials listed in multiple languages and environments at the end of the tutorials. GameDev's tutorials Gamasutra Personally, I like books (a little old school). Doing examples from the OpenGL SuperBible is what is helping me learn, and QT tutorials online. Also, there's a lot of good open source code you can look into (I've been looking at the GL screensavers for xscreensaver in Linux). Be careful though: Don't just focus on learning function calls, but try to see the big picture in what you're doing (e.g. matrix stacks and how and why you use them, the theory behind how things work), because these can be applied if you switch to DirectX or another library later on.
5. ## DirectX 9 or SDL and OpenGL

I like OpenGL because it is an API standard which can be used with a variety of bindings. For example, in C++ you can use OpenGL with GLUT, QT, or SDL for handling events and the windowing side, and keep your OpenGL code consistent between the windowing APIs. Or, you can take your OpenGL code, and then change over to QTRuby and use bindings for OpenGL with that. Or, you can port it (relatively easily) to JOGL, the Java bindings for OpenGL and still keep most of the same skills (writing shaders, using vertex buffers, depth shadow maps). Also, your code is relatively portable between Linux, Windows, and Mac. A project I was working on recently for a class was using JOGL, using skills I learned with C++/QT/OpenGL, being developed on my Linux machine and my group partners Windows machine.
6. ## OpenGL problem understanding why camera isnt working

Inside the drawCar() function you switch to modelview matrix and then load the identity. According to your comments you want to rotate the modelview matrix, which you're doing, except that call to loadIdentity() effectively erases it.
7. ## KeyPress Event

You might also want to look into QT, or wxWidgets.
8. ## Stretch a texture.

Try: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Repeat on X axis glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); // Stretch on Y axis Then texture coordinates are clamped between 0 and 1 on the x axis, and for example, going from 0 to 2 on the y axis will repeat the texture 2 times in the y direction.
9. ## matrix rotate and transform vectors.

It looks like they're storing a rotation in the matrix and then transforming the vector by that matrix (by multiplying the vector by the matrix). This is code in a project of mine which does essentially the same thing. Think of it as the vector being transformed by the matrix (instead of the other way around). // Gets the matrix transformation. gfx::m4r<GLfloat> trans; glGetFloatv(GL_MODELVIEW_MATRIX, *trans); gfx::v4r<GLfloat> vertex_normal( normal_array[i], normal_array[i+1], normal_array[i+2], 0); vertex_normal.rotate(trans); // Rotates the vector using the matrix. // Essentially vertex_normal = vertex_normal * rotation_part_of_transform_matrix
10. ## My Matrix class. How well is it implemented?

You're off to a good start, but you need to add some direction to it. What will your matrix class be used for? For example: I use my matrix with OpenGL,... so it uses a fixed size (4x4). OpenGL also uses a 4x4 column major ordering, so it only needs one fixed size array, which you don't need to dynamically allocate, which is slow if you do it a bunch of times, since you know it's size. Column major ordering is first four indexes are the first column, the second four indexes are the second column, etc. My code's not entirely great, so take what you think is useful. I only add the things I need at the time, it keeps me on track with what I'm working. I don't need the operator+ or operator- because in homogenous coordinates these are done by doing matrix multiplications. // Vector template <typename T> class v4r; /** 4x4 matrix. Matrix in homogenous coordinates. * Uses column-major ordering. */ template<typename T> class m4r { public: /** Makes identity matrix. */ m4r() { for(int i=0; i<=15; i++) data[i] = 0; data[0] = 1; data[5] = 1; data[10] = 1; data[15] = 1; } /** Matrix from copy of array data. */ m4r(T* arr) { set(arr); } /** Multiply matrix by constant. */ m4r<T>& operator*=(const T& t) { // Unrolled for speed. Ugly, but efficient. data[0] = data[0]*t; data[1] = data[1]*t; data[2] = data[2]*t; data[3] = data[3]*t; data[4] = data[4]*t; data[5] = data[5]*t; data[6] = data[6]*t; data[7] = data[7]*t; data[8] = data[8]*t; data[9] = data[9]*t; data[10] = data[10]*t; data[11] = data[11]*t; data[12] = data[12]*t; data[13] = data[13]*t; data[14] = data[14]*t; data[15] = data[15]*t; return *this; } void set(T* arr) { data[0] = arr[0]; data[1] = arr[1]; data[2] = arr[2]; data[3] = arr[3]; data[4] = arr[4]; data[5] = arr[5]; data[6] = arr[6]; data[7] = arr[7]; data[8] = arr[8]; data[9] = arr[9]; data[10] = arr[10]; data[11] = arr[11]; data[12] = arr[12]; data[13] = arr[13]; data[14] = arr[14]; data[15] = arr[15]; } /** Divide matrix by constant. */ m4r<T>& operator/=(const T& t) { assert(t != 0); T u = 1.0 / t; (*this) *= u; return *this; } /** Pointer to internal array. */ T* operator*() { return data; } bool operator==(const m4r& m) { for(unsigned int i=0; i<16; i++) { if(m.data[i] != data[i]) return false; } return true; } bool operator!=(const m4r& m) { return !(*this == m); } protected: /** Prevents use of copy constructor. */ m4r(const m4r& m){} friend class v4r<T>; template <typename U> friend std::ostream& operator<<(std::ostream& out, const m4r<U>& m); private: T data[16]; }; #include <iomanip> template <typename U> std::ostream& operator<<(std::ostream& out, const m4r<U>& m) { for(int i=0; i<4; i++) { for(int j=0; j<4; j++) { int next = i + j*4; out << std::setw(20) << m.data[next] << ' '; } out << std::endl; } return out; } Note how I added operator*(), this lets me do something like this to initialize the matrix through OpenGL. m4r<GLfloat> trans; glGetFloatv(GL_MODELVIEW_MATRIX, *trans); What are you going to be using the matrix class for?
11. ## Unity Community Driven Art, and Music

I've seen on Pure volume how people can post music and was wondering if anyone had any experience in working with musicians and/or artists (2D/3D) for putting any projects together. Also, could anyone recommend any sites where we could look for upcoming artists in particular, so we could get some of their art "out there", and also working with a game on a more personal/interactive level, like on a team?
12. ## SDL and VC++ Express: entry point

Quote:Original post by Firebrand ...snip... - started with the Empty project template. Someone suggested using the console application template, and even though it seemed a bit odd for a SDL app I tried it. It did not work for me. Basically, the program doesn't know where to begin. (It's not seeing/using the int main(...) for some reason). Did you start with just the Win32 App empty project, or just an empty project? Also, make sure that there isn't any extra struff that the new project Wizard tried to be "helpful" with. Here might be of help. Otherwise, check to see that sdlmain.lib and sdl.lib were properly added to the path, and change to just a "Multithreaded DLL" (not debug). I'm currently working on an SDL project of my own in C++ (using MS Visual Studio) and I've been trying things to see if I can duplicate the error. Not been successful so far, but I've still a couple more things to try.
13. ## SDL and VC++ Express: entry point

Can you post what you have for source. (Just so we can see...it might help)