• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.

pinknation

Members
  • Content count

    34
  • Joined

  • Last visited

Community Reputation

126 Neutral

About pinknation

  • Rank
    Member
  1. So, I have a picture here that will help a lot with my question: [img]http://img690.imageshack.us/img690/6427/picturenw.jpg[/img] excuse the poor drawing if possible, anyways, the point here is that if I have a convex hull such as in Diagram 1, the teapot, and I slice on on that red line, from the top-down view, the slice points(otherwise the inverse of the plane) will look like that in 2D. is there any good triangulation algorithms which can a) support holes, and b) support edges/points seperated from each other creating sub polygons, but all within the same triangulation sweep; this is important, and any information would be great, I am capable of learning, but looking for something more open-source that i can try and understand better then a PDF, but anything will do
  2. To my above post which I cannot edit, I ment to say convert the 2D layers to radial, oh geeze I've been confusing those two a lot lately;
  3. try thinking more outside the box guys, unlimited detail isn't something that Bruce Dell found in some PDF file on rendering unlimited detail. He invented it, basically going against all other current techniques for rendering point data; My gist of all this, is that the entire world(not just individual models and objects in the world), are sliced into 2D layers, and converged into cartesian coordinates; these coordinates are then during run-time almost magically reverse transformed to their proper screen-space coordinates after already being sorted through some unknown function; Don't like that approach? We'll octree's have not been able to yeild those results in real-time either; So, lets try and take down the number of cycles, and complicated maths and leave it more simple, that's the only way he could process that much information in such a small amount of time. Accept it and move towards that; Computational Theory; I'd also say that ray-tracing is really not the answer here as he states Thinking outside the box might be an example of this based on the cartesian idea, that is the screen-space may not be nothing more then some normals right, and just like when righting a script to do reflection, and refraction, you're no more moving a few pixels in the direction of that normal. So lets transform our cartesian coordinates with some dot product to our screen-space normal; what might happen then? Magical reverse transformation of the exact "atom" we need for that point on the screen. Without a lot of cycles; Or math. This guy's been developing this thing for a long time, and deserves more respect for not having stuck to standards, and simply accepting the PDF's or Tutorials they find on GameDev as their ultimatum. He went around and beyond, I say you stop fighting it, and embrace it; Just because he hasn't decided to populate it yet, does not mean that it isn't there. Give him time to perfect it, and make some affiliations with physics companies, who can then compute on the GPU while all graphics processing is being done on the CPU. This type of co-proccessing is what is going to make next-gen games next-gen; Be patient;
  4. I am using glGetUniformLocation(); This is the exact code I'm using as far as my shaders go; int filehash(char* fname) { unsigned int hash = 0; while(*fname) { hash = ((hash<<1) + (hash>>7)*9 + (unsigned int)tolower((unsigned char)(*fname))); fname++; } return hash & 255; } class ShaderProperty { private: GLint myLocation; char *myName; public: ShaderProperty() { myLocation = 0; myName = 0; } ShaderProperty(GLuint programHandle, char* propertyName) { myLocation = glGetUniformLocation(programHandle, propertyName); printf("%d\n", myLocation); } void SetUniform1fv(int count, float *v) { glUniform1fv(myLocation, count, v); } void SetUniform2fv(int count, float *v) { glUniform2fv(myLocation, count, v); } void SetUniform3fv(int count, float *v) { glUniform3fv(myLocation, count, v); } void SetUniform4fv(int count, float *v) { glUniform4fv(myLocation, count, v); } void SetUniform1f(float v) { glUniform1f(myLocation, v); } void SetUniform2f(float v0, float v1) { glUniform2f(myLocation, v0, v1); } void SetUniform3f(float v0, float v1, float v2) { glUniform3f(myLocation, v0, v1, v2); } void SetUniform4f(float v0, float v1, float v2, float v3) { glUniform4f(myLocation, v0, v1, v2, v3); } char *GetName() { return myName; } }; class glShader { private: GLuint myProgram, myVertexShader, myFragmentShader; ShaderProperty *myProperties; public: static GLboolean IsSupported() { glewInit(); return glewIsSupported("GL_VERSION_2_0"); } glShader() { /* nothing to do */ } glShader(char *vert, char *frag) { myProperties = new ShaderProperty[255]; char *vs,*fs; myVertexShader = glCreateShader(GL_VERTEX_SHADER); myFragmentShader = glCreateShader(GL_FRAGMENT_SHADER); vs = textFileRead(vert); fs = textFileRead(frag); const char * vv = vs; const char * ff = fs; glShaderSource(myVertexShader, 1, &vv,NULL); glShaderSource(myFragmentShader, 1, &ff,NULL); free(vs); free(fs); glCompileShader(myVertexShader); glCompileShader(myFragmentShader); myProgram = glCreateProgram(); glAttachShader(myProgram, myVertexShader); glAttachShader(myProgram, myFragmentShader); glLinkProgram(myProgram); } ShaderProperty GetProperty(char *name) { int idx = filehash(name); if(myProperties[idx].GetName() != 0) myProperties[idx] = ShaderProperty(myProgram, name); return myProperties[idx]; } void Begin() { glUseProgram(myProgram); } void End() { glUseProgram(0); } void Dispose() { glDetachShader(myProgram, myVertexShader); glDetachShader(myProgram, myFragmentShader); glUseProgram(0); glLinkProgram(0); glDeleteShader(myVertexShader); glDeleteShader(myFragmentShader); glDeleteProgram(myProgram); delete [] myProperties; } }; and actually using those shaders during the rendernig process.. glPushMatrix(); //glEnable(GL_TEXTURE_2D); myShader.Begin(); myShader.GetProperty("time").SetUniform1f((time_ += .005f)); // draw water surface glBegin(GL_TRIANGLES); float rw = 1.f / wWidth; float rh = 1.f / wHeight; float rZ = .0f; for(int x = 0; x < wWidth; ++x) { for(int y = 0; y < wHeight; ++y) { float rx = (float)x; float ry = (float)y; // Top-Right glTexCoord2f(rw * rx, rw * ry); glVertex3f(rx + 0, rZ, ry + 0); glTexCoord2f((rw * rx) + rw, rw * ry); glVertex3f(rx + 1, rZ, ry + 0); glTexCoord2f((rw * rx) + rw, (rw * ry) + rh); glVertex3f(rx + 1, rZ, ry + 1); // Lower-Left glTexCoord2f(rw * rx, rw * ry); glVertex3f(rx + 0, rZ, ry + 0); glTexCoord2f(rw * rx, (rw * ry) + rh); glVertex3f(rx + 0, rZ, ry + 1); glTexCoord2f((rw * rx) + rw, (rw * ry) + rh); glVertex3f(rx + 1, rZ, ry + 1); } } glEnd(); myShader.End(); glDisable(GL_TEXTURE_2D); glPopMatrix(); [EDIT] well, LOL.. while looking at the code above(to make sure there were no errors while I copied/pasted) I noticed an error in my GetProperty() function, and fixed some logic.. ShaderProperty GetProperty(char *name) { int idx = filehash(name); if(myProperties[idx].GetName() == 0) myProperties[idx] = ShaderProperty(myProgram, name); return myProperties[idx]; } it was != 0, and is now == 0; before it set it everytime, and i think thats where it lost the original location, and replaced it with some NULL one ( or random ?); anyways, it works now.. hah!
  5. Vertex Shader: // wave functions /////////////////////// struct Wave { float freq; // 2*PI / wavelength float amp; // amplitude float phase; // speed * 2*PI / wavelength vec2 dir; }; #define NWAVES 2 Wave wave[NWAVES] = { { 1.0, 1.0, 0.5, vec2(-1, 0) }, { 2.0, 0.5, 1.3, vec2(-0.7, 0.7) } }; float evaluateWave(Wave w, vec2 pos, float t) { return w.amp * sin( dot(w.dir, pos)*w.freq + t*w.phase); } // derivative of wave function float evaluateWaveDeriv(Wave w, vec2 pos, float t) { return w.freq*w.amp * cos( dot(w.dir, pos)*w.freq + t*w.phase); } // sharp wave functions float evaluateWaveSharp(Wave w, vec2 pos, float t, float k) { return w.amp * pow(sin( dot(w.dir, pos)*w.freq + t*w.phase)* 0.5 + 0.5 , k); } float evaluateWaveDerivSharp(Wave w, vec2 pos, float t, float k) { return k*w.freq*w.amp * pow(sin( dot(w.dir, pos)*w.freq + t*w.phase)* 0.5 + 0.5 , k - 1) * cos( dot(w.dir, pos)*w.freq + t*w.phase); } uniform float time = .0; uniform float waveAmp = .15; uniform float waveFreq = .5; void main() { wave[0].freq = waveFreq; wave[0].amp = waveAmp; wave[1].freq = waveFreq*2.0; wave[1].amp = waveAmp*0.5; vec4 P = vec4(gl_Vertex); P.y = 0.0; float ddx = 0.0, ddy = 0.0; for(int i=0; i<NWAVES; i++) { P.y += evaluateWave(wave[i], P.xz, time); float deriv = evaluateWaveDeriv(wave[i], P.xz, time); ddx += deriv * wave[i].dir.x; ddy += deriv * wave[i].dir.y; } vec3 B = vec3(1, ddx, 0); vec3 T = vec3(0, ddy, 1); vec3 N = vec3(-ddx, 1, -ddy); gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; gl_TexCoord[1] = gl_TextureMatrix[0] * gl_MultiTexCoord0; gl_Position = gl_ModelViewProjectionMatrix * P; } Fragment Shader: sampler2D TextureUnit0; sampler2D TextureUnit1; float scale = 5.0; void main() { vec4 c1 = tex2D(TextureUnit0, gl_TexCoord[0].st * scale); gl_FragColor = c1; } If i was to change "gl_FragColor = c1;" in my fragment shader to "gl_FragColor = vec4(1, 0, 1, 1);" the waters' surface, as this shader simulates, will become animated, however, without changing that line to some hard-coded color(not obtaining the color from texture2D), it becomes frozen, and doesn't move. [Edited by - pinknation on January 27, 2010 1:00:59 PM]
  6. Hi there, I've been writing a "Particle Based Hydrodynamics" engine, in C++ using SSE for optimization.. SSE increased the speed a lot, but in the end things began to slow down do to O(N^N-1) collision detection, so I've decided to implement the kd-tree, so far I've been un-able to properly write the Nearest Neighbor search, and am beginning to have issues w/ kd-tree all together, because the wikipedia doesn't describe the proper way to 'balance' the tree(because none of my tree leafs should remain static, the tree should be re-balanced every frame, for optimization); I could do this the 'brute' way which starts from the root, and balances the tree.. just like I did to build it(using axis based median sorting); though that seemed like it maybe slow?? (of course it should still be faster then re-building the entire tree.. which im currently just doing every-frame LOL) I'm wondering if anyone knows of a better solution than kd-tree, and otherwise, if someone could help explain nearest neighbor search.. my current NN-search is like this: void find_neighbors(SSEBoundingSpheres &spheres, kdnode* node, kdnode *cnode, std::vector<int> &neighbors, float r, float min_dist = FLT_MAX) { if( node == 0 || cnode == 0 ) return; if(cnode->id != node->id) { float dir; if(node->axis == 0) dir = (spheres.position_x[node->id].m[0] - spheres.position_x[cnode->id].m[0]); else if(node->axis == 1) dir = (spheres.position_y[node->id].m[0] - spheres.position_y[cnode->id].m[0]); else if(node->axis == 2) dir = (spheres.position_z[node->id].m[0] - spheres.position_z[cnode->id].m[0]); if(dir < 0.0) { find_neighbors(spheres, node, cnode->left, neighbors, r); if(dir*dir<r) { neighbors.push_back(cnode->id); find_neighbors(spheres, node, cnode->right, neighbors, r); } } else { find_neighbors(spheres, node, cnode->right, neighbors, r); if(dir*dir<r) { neighbors.push_back(cnode->id); find_neighbors(spheres, node, cnode->left, neighbors, r); } } } } which is a recursive function, and doesn't appear to properly find all contacts.. actually the radius is greater than all the particles, so during the initial NN-Search I should see all of the particles as neighbors, but I don't.. ;_; thanks to anyone who can help resolve this. =]
  7. thanks again Flounder. <3 not 100% sure why I did that.. think I'm done w/ help for now, unless anyone can explain how to solve the collision issue..
  8. It's all good, thanks.. I'm just having issues now with particles colliding with one another, after the collision tests have completed. :[ I've been reading up on more collision detection & response, though I'm not understanding how to resolve this problem in an non-costly manner, like all that keeps coming to mind is 'BRUTE-FORCE BRUTE-FORCE BRUTE-FORCE'. ^_^
  9. yeah, understandable, I went ahead and listened to you guys: void BroadPhaseCollision() { grid->Refresh(particles, particles_length); for(int i = 0; i < grid->Width * grid->Height; ++i) { for(unsigned int j = 0; j < grid->m_grid[i].size(); ++j) { Particle p1 = particles[grid->m_grid[i][j]]; for(unsigned int k = j + 1; k < grid->m_grid[i].size(); ++k) { Particle p2 = particles[grid->m_grid[i][k]]; if(p1.id == p2.id) continue; float d_x = p2.p_x - p1.p_x; float d_y = p2.p_y - p1.p_y; float R = p1.radius + p2.radius; if(R * R > d_x * d_x + d_y * d_y) NarrowPhaseCollision(particles[grid->m_grid[i][j]], particles[grid->m_grid[i][k]]); } } } } its actually faster(at least its not as slow as it was before with 400 particles), though the collision itself is still acting funny.. I'll continue to try and figure that out :[ The problem is, that after the collisions are dealt with, more collisions are created, though its finished checking for collision, and continues to update the particles, resulting in a rather buggy Simulation.
  10. it shouldn't matter if I swept through cells, or particles.. because either way I'd loop through each particle, adding the cell loop, would simply add an extra loop. Edit: Would AABB method of collision detection be better? Currently I am using a Spatial Index Grid.. which I've seen used in SPH systems.
  11. @Flounder, thanks! I've resolved that, actually a noticeable speed-boost! Thanks, much! @Felix, you're right... that is exactly why! That's why I've included the collision detection, to avoid them becoming super close, however, during the Collision Detection Sweep, it pushes two colliding particles away from each other, and sometimes even pushes one of them, directly into another, causing it to 'shoot off'. That's what I was trying to explain in my original post, that I need a better method of Collision Detection, because my current solution doesn't solve each collision, before updating the physics. Edit: Oops, I've posted this twice.. ^_^' Sorry. I've read up on some collision response, and junk.. I've re-wrote my code(it's somewhat faster now), but there still seems to be some issues where they become to close, and shoot off.. My current code (for collisions detection) is: vector<int> FindContacts(Particle &particle) { vector<int> contacts = vector<int>(); vector<int> idxs = grid->GetNeighbourIndex(particle); for(unsigned int j = 0; j < idxs.size(); ++j) { int i = idxs[j]; if(particle.id == particles[i].id) continue; float d_x = particles[i].p_x - particle.p_x; float d_y = particles[i].p_y - particle.p_y; if(d_x * d_x + d_y * d_y < (particle.radius + particles[i].radius)*(particle.radius + particles[i].radius)) contacts.push_back(i); } return contacts; } void NarrowPhaseCollision(Particle &particle, Particle &particle2) { float friction = .5f; if(particle.id == particle2.id) return; float d_x = particle2.p_x - particle.p_x; float d_y = particle2.p_y - particle.p_y; float R = d_x * d_x + d_y * d_y; float totalRadius = particle.radius + particle2.radius; if(R < totalRadius * totalRadius) { R = sqrt(R); float radDiff = (totalRadius - R) * .5f; double nX = d_x / R; double nY = d_y / R; double a1 = DotProduct(particle.v_x, particle.v_y, nX, nY); double a2 = DotProduct(particle2.v_x, particle2.v_y, nX, nY); double optimisedP = (2.0 * (a1-a2)) / (particle.mass + particle2.mass); // force both particles out of one anothers radius particle.p_x -= radDiff; particle.p_y -= radDiff; particle2.p_x += radDiff; particle2.p_y += radDiff; // Reflect Velocities particle.v_x -= (optimisedP * particle2.mass * nX) * (1 - friction); particle.v_y -= (optimisedP * particle2.mass * nY) * (1 - friction); particle2.v_x += (optimisedP * particle.mass * nX) * (1 - friction); particle2.v_y += (optimisedP * particle.mass * nY) * (1 - friction); } } void BroadPhaseCollision() { for(int i = 0; i < particles_length; ++i) { vector<int> collisions = FindContacts(particles[i]); if(collisions.empty()) continue; for(unsigned int j = 0; j < collisions.size(); ++j) NarrowPhaseCollision(particles[i], particles[collisions[j]]); } } FindContacts() uses my Spatial Index Grid, to locate neighboring particles, which are checked for collisions, and then passes those which are colliding to the NarrowPhaseCollision(), which simply pushes the particles apart based on their radius, and uses a reflection velocity(with a friction constant), to push them farther apart.. This did manage to speed things up slightly, though its still not the best solution. My current order of action is: Add all forces to each particle individually(still time consuming) Update Particle Physics Start BroadPhaseCollision() Draw each particle Edit2: Unknown reason, though if instead of returning contacts as their IDs, but the actual Particle object itself, the particles never get 'too close', because they seem to constantly push one another, until they're no longer touching, however this seems to happen often, and so you notice what used to just be circular rotating clusters, is now becoming longer thinner lines. :P [Edited by - pinknation on August 18, 2009 3:46:11 AM]
  12. @Flounder, thanks! I've resolved that, actually a noticeable speed-boost! Thanks, much! @Felix, you're right... that is exactly why! That's why I've included the collision detection, to avoid them becoming super close, however, during the Collision Detection Sweep, it pushes two colliding particles away from each other, and sometimes even pushes one of them, directly into another, causing it to 'shoot off'. That's what I was trying to explain in my original post, that I need a better method of Collision Detection, because my current solution doesn't solve each collision, before updating the physics.
  13. uhm, Felix, your optimizations only made things buggy.. >.> @flounder: thanks, uhm, about the multiplying by .5f, that was just a quick way for me to add friction, so nevermind that :P; as for what you said about the sqrt thing.. that only made it buggy.. :S the 'buggy' that I refered to for both of you, was the particles began to vibrate, and/or not move
  14. Hi, my simulation is slowing down @ 200 particles, this mainly was because of the collision detection at first, where every particle, checked for collision against every other particle, meaning 200 * 199 iterations were processed each frame(along side the F = GMm/R^2 equation, which made it slower), I was able to speed this up, by implementing a spatial index grid.. which allowed me to only check for collision of neighboring particles(within the same grid cell), however the force calculations are still gathering a total(because that's most accurate.. perhaps I dont have to?) and so ending up w/ 200 * 199 iterations, still.. is there any way to speed up the math here, and any suggestions for other optimizations? " for(int i = 0; i < particles_length; ++i) { if(particle.id == particles[i].id) continue; float d_x = particles[i].p_x - particle.p_x; float d_y = particles[i].p_y - particle.p_y; float R = sqrt(d_x * d_x + d_y * d_y); float F = G * particle.mass * particles[i].mass / (R * R); if(R == 0.f || F == 0.f) continue; particle.f_x += d_x * F / R; particle.f_y += d_y * F / R; }" that adds the gravitation force of F = GMm/R^2. my collision code is: vector<int> idxs = grid->GetNeighbourIndex(particle); for(unsigned int j = 0; j < idxs.size(); ++j) { int i = idxs[j]; if(particle.id == particles[i].id) continue; double cNorm = atan2(particles[i].p_y - particle.p_y, particles[i].p_x - particle.p_x); double nX = cos(cNorm); double nY = sin(cNorm); double a1 = DotProduct(particle.v_x, particle.v_y, nX, nY); double a2 = DotProduct(particles[i].v_x, particles[i].v_y, nX, nY); double optimisedP = (2.0 * (a1-a2)) / (particle.mass + particles[i].mass); float d_x = particles[i].p_x - particle.p_x; float d_y = particles[i].p_y - particle.p_y; float R = sqrt(d_x * d_x + d_y * d_y); float totalRadius = particle.radius + particles[i].radius; if(R < totalRadius) { float radDiff = (totalRadius - R) * .5f; // force both particles out of one anothers radius particle.p_x -= radDiff; particle.p_y -= radDiff; particles[i].p_x += radDiff; particles[i].p_y += radDiff; // Reflect Velocities particle.v_x -= (optimisedP * particles[i].mass * nX) * .5f; particle.v_y -= (optimisedP * particles[i].mass * nY) * .5f; particles[i].v_x += (optimisedP * particle.mass * nX) * .5f; particles[i].v_y += (optimisedP * particle.mass * nY) * .5f; } } which I hope can also be optimized in some way.. (mostly took that code from somewhere on this site I think); Side-Question: I'm having one particular issue w/ collision detection, which is, it 'un-collides' all current collisions, though sometimes creates more 'collisions' before its unable to sweep it again, resulting in physics related issues(where the particles are to close, and blast off at some really high velocity), my order of computations is AddTotalForces, Update Particle, Collision Sweep.. any ideas how to fix this..? >.> unless I like had something recursive to constantly un-collide particles, until there are none colliding, I cannot think of any way to solve that.. so.. any suggestions here would help!
  15. Interesting suggestion, though I've checked, and they all seem to match accordingly. :) That's along the lines of what I'm thinking is causing the problem. :P The images are loaded from memory like this: Texture2D::Texture2D(void* buffer, int size) { Surface = IMG_Load_RW(SDL_RWFromMem(buffer, size), 1); if(Surface != NULL) { if(Surface->format->BytesPerPixel == 1) /* Looks like we're using a palette.. */ { SDL_Surface *converted = SDL_CreateRGBSurface(0, Surface->w, Surface->h, 32, RMASK, GMASK, BMASK, AMASK); SDL_LockSurface(Surface); for(int i = 0; i < (Surface->w * Surface->h); ++i) { SDL_Color color = Surface->format->palette->colors[*((Uint8 *)Surface->pixels + i)]; *((Uint32*)converted->pixels + i) = SDL_MapRGBA(converted->format, color.r, color.g, color.b, 255); } SDL_UnlockSurface(Surface); SDL_FreeSurface(Surface); Surface = converted; } GenerateTextureID(); } }