AzraelilMeraz

Member
  • Content count

    17
  • Joined

  • Last visited

Community Reputation

136 Neutral

About AzraelilMeraz

  • Rank
    Member
  1. [SOLVED] Hair simulation. Verlet/Constraints

    Nevermind... figured it out - there is nothing wrong with the algorithm - I just accidentally ran the constraint generation kernel every iteration...
  2. [SOLVED] Hair simulation. Verlet/Constraints

    I thought that maybe it's because of the parallel execution of the Distance constraints in the loop, so created a serialized version, where only one thread solves the constraints: [source lang="cpp"] barrier(CLK_LOCAL_MEM_FENCE); if(idl == 0) { for(int i = 0; i < dcIter; i++) { for(int i = 1; i < verticesPerHair; i++) { DistanceConstraint constraint = localconst[i]; distanceConstraint(localpos, constraint.id1 % verticesPerHair, constraint.id2 % verticesPerHair, constraint.d); } } } barrier(CLK_LOCAL_MEM_FENCE);[/source] This yielded the same results however :/. I've looked into several resources on the topic: [url="http://www.connellybarnes.com/documents/hair/#Verlet_Integration"]http://www.connellyb...let_Integration[/url] [url="http://dl.acm.org/citation.cfm?id=1837101.1837102"]http://dl.acm.org/ci...1837101.1837102[/url] [url="http://en.wikipedia.org/wiki/Verlet_integration"]http://en.wikipedia....let_integration[/url] [url="http://www.gamasutra.com/resource_guide/20030121/jacobson_pfv.htm"]http://www.gamasutra...acobson_pfv.htm[/url] But I see nothing on the issue at hand. I'm using 20 iterations for the constraints, but the same happens if I do 200 or 2000 - just at a slower rate!
  3. EDIT2: SOLVED, there is nothing wrong with the algorithm - I accidentally ran the constraint generation kernel every frame Hello! I've been toying with OpenGL and OpenCL trying to simulate Hair on the GPU. However I've run into issues that are not OpenGL/OpenCL specific - I seem to be incapable of writing a correct solving algorithm for distance constraints. I'm not sure where the issue is - maybe I'm generating the constraints incorrectly, maybe it's the solving. That's how I'm generating the constraints: [source lang="cpp"]// create constraints from original positions __kernel void buildConstraints(__global const float4* in, __global DistanceConstraint* out, const int verticesPerHair) { int id = get_global_id(0); if((id % verticesPerHair) != 0) { out[id].id1 = id-1; out[id].id2 = id; out[id].d = length(in[id-1]-in[id]); } else { out[id].id1 = id; out[id].id2 = id; out[id].d = 0; } }[/source] (id % verticesPerHair) != 0 means that the hair is a root. All but the root is constrained to the preceding vertex in the hair. The root is constrained to itself so it won't move Prior to constraining the vertices the verlet integration is computed on every vertex except the root: [source lang="cpp"] // verlet if(idl != 0) { float4 difference = localpos[idl] - oldpos[idx]; oldpos[idx] = localpos[idl]; localpos[idl] += (1-friction)*difference + force*pdt*pdt; }[/source] Then to satisfy the constraints I run fixed number of iterations of this code: [source lang="cpp"]barrier(CLK_LOCAL_MEM_FENCE); DistanceConstraint constraint = constraints[idx]; for(int i = 0; i < dcIter; i++) { if((idl%2) == 1) { distanceConstraint(localpos, constraint.id1 % verticesPerHair, constraint.id2 % verticesPerHair, constraint.d); } barrier(CLK_LOCAL_MEM_FENCE); if((idl%2) == 0) { distanceConstraint(localpos, constraint.id1 % verticesPerHair, constraint.id2 % verticesPerHair, constraint.d); } barrier(CLK_LOCAL_MEM_FENCE); } [/source] constraint is what was generated for this vertex in buildConstraints(). The barrier() function is there because the algorithm runs in parallel, so it solves the constraint for odd vertices then waits for all threads to complete and then solves the constraints for even vertices. the function distanceConstraint() looks like this: [source lang="cpp"] // satisfy distance constraints void distanceConstraint(__local HairVertex* pos, int idx1, int idx2, const float conDist) { // vector from vertex 1 to vertex 2 float4 difference = pos[idx2].position-pos[idx1].position; // By what amount move which vertex float2 cFactors = constraintFactors(idx1, idx2); // length of the vector between the vertices float len = length(difference); // distance the vertices must move towards each other float distance = len-conDist; // no corruption through div by zero len = max(len,1e-7f); // move pos[idx1].position += cFactors.x*distance/len*difference; pos[idx2].position += cFactors.y*distance/len*difference; }[/source] constraintFactors() returns factors that determine how to handle vertices depending on whether or not they are roots: [source lang="cpp"] // for given indices id1 and id2 return constraint factors float2 constraintFactors(int id1, int id2) { if(id1 != 0) { // first vertex is not a root if(id2 != 0) { // both vertices not a root return (float2)(0.5f, -0.5f); } else { // first vertex is not root, second is root return (float2)(0.0f, 0.0f); } } else { // first vertex is root if(id2 != 0) { // first vertex is root, second is not return (float2)(0.0f, -1.0f); } else { // both vertices are roots (shouldn't happen) return (float2)(0.0f, 0.0f); } } }[/source] I have looked through NVIDIAs DirectX implementation of the simulation (NVIDIAs SDK 11) and the only deviation from the constraint code was that when the first vertex is not root and the second is, the factors were (1.0f,0.0f). I am however not certain how the constraints were generated, so I predict that my mistake is somewhere there. The actual problem is that after a while the simulation goes full spaghetti mode... To be a bit more precise - the control vertices seem to move from the root towards the tip and the tip seems to move away in the direction the force is applied... Here's what it looks like in point mode: [url="http://sw-ores.de/projecthorizons/spaghetti.mkv"]http://sw-ores.de/pr...s/spaghetti.mkv[/url] I have no clue what I'm doing wrong [img]http://public.gamedev.net//public/style_emoticons/default/sad.png[/img]
  4. Oh I meant something different - if i have a texture coordinate of, for example, 3, then I get a repeated or clamped texture. What I want is to use short texture coordinates and to be able to adress texels which lie somewhere in the middle of the texture. Is this even possible with short as tex coord type?
  5. Flickering triangle

    Yep, I also set the near clipping plane to 1.0 because of another mesh which didn't render properly. Thank you for your help and for explaining why 1.0 for near plane is better. :)
  6. Flickering triangle

    gluPerspective( 60, // Field of view = 60 degrees static_cast<double>(WinXSize)/ static_cast<double>(WinYSize), // Window aspect (assumes square pixels) 0, // Near Z clipping plane 1000 // Far Z clippling plane ); and glClearDepth(1.0); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); Did I forget something? There's no difference between Debug/Release This doesn't happen with the Direct3D implementation of my Engine Edit: Hm - Just checked my Mesh exporting plugin - it didn't export normals properly. Though I don't see any connnection to a flickering triangle... [Edited by - AzraelilMeraz on October 10, 2008 3:37:12 PM]
  7. Flickering triangle

    Hello GameDev What is this? Thank you in advance
  8. Hi GameDev how do float and short texture coordinates relate to each other in OpenGL? It appears to me as if openGL tried to map the texture between 0 and 1. even with short. How do I change the range?
  9. [VBO] One big buffer for everything

    ?? I don't even use glDrawArrays :( edit: I hate those stupid mistakes :(: glTexCoordPointer(2, GL_FLOAT, 0, BUFFER_OFFSET(meshes[numMeshes].numVert*sizeof(AL_VertCol))); -> glTexCoordPointer(2, GL_FLOAT, 0, BUFFER_OFFSET(meshes[Id].numVert*sizeof(AL_VertCol))); [Edited by - AzraelilMeraz on October 6, 2008 2:40:37 PM]
  10. Hello GameDev I've got a simple but working 3D-Renderer based on VBOs. I've had a single Buffer for each vertex attribute before. Here's the code: rendering: void ALSAGE_OGL::drawMesh(int Id,AL_Vector pos,AL_Vector scale, int TexId) { glScalef(scale.x,scale.y,scale.z); glDisable(GL_LIGHTING); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); if(TexId != -1) glBindTexture(GL_TEXTURE_2D, textures[TexId].Name); if(lastMesh != Id) { glBindBuffer(GL_ARRAY_BUFFER,meshes[Id].VBO[2]); glColorPointer(4, GL_UNSIGNED_BYTE, 0,0); glBindBuffer(GL_ARRAY_BUFFER,meshes[Id].VBO[3]); glTexCoordPointer(2, GL_FLOAT, 0,0); glBindBuffer(GL_ARRAY_BUFFER,meshes[Id].VBO[4]); glNormalPointer(GL_FLOAT, 0,0); glBindBuffer(GL_ARRAY_BUFFER,meshes[Id].VBO[0]); glVertexPointer(3, GL_FLOAT, 0,0); lastMesh = Id; } glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,meshes[Id].VBO[1]); glDrawRangeElements(GL_TRIANGLES, 0,meshes[Id].numTris*3-1,meshes[Id].numTris*3, GL_UNSIGNED_INT,NULL); glBindTexture(GL_TEXTURE_2D, 0); glBindBuffer(GL_ARRAY_BUFFER,0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); } loading: int ALSAGE_OGL::loadMesh(AL_Char* filename) { AL_Mesh* mesh = new AL_Mesh; AL_byte nBufs = 5; mesh->loadFromFile(filename); meshes[numMeshes].numVert = mesh->vertCount(); meshes[numMeshes].numTris = mesh->TrisCount(); glGenBuffers(nBufs, meshes[numMeshes].VBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, meshes[numMeshes].VBO[1]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, meshes[numMeshes].numTris*sizeof(AL_Triangle), mesh->getTrianglePointer(), GL_STREAM_DRAW); glBindBuffer(GL_ARRAY_BUFFER, meshes[numMeshes].VBO[2]); glBufferData(GL_ARRAY_BUFFER, meshes[numMeshes].numVert*sizeof(AL_VertCol), mesh->getColorPointer(), GL_STREAM_DRAW); glBindBuffer(GL_ARRAY_BUFFER, meshes[numMeshes].VBO[3]); glBufferData(GL_ARRAY_BUFFER, meshes[numMeshes].numVert*sizeof(AL_VertTex), mesh->getUVCoordPointer(), GL_STREAM_DRAW); glBindBuffer(GL_ARRAY_BUFFER, meshes[numMeshes].VBO[4]); glBufferData(GL_ARRAY_BUFFER, meshes[numMeshes].numVert*sizeof(AL_VertNor), mesh->getNormalPointer(), GL_STREAM_DRAW); glBindBuffer(GL_ARRAY_BUFFER, meshes[numMeshes].VBO[0]); glBufferData(GL_ARRAY_BUFFER, meshes[numMeshes].numVert*sizeof(AL_VertCrd), mesh->getCoordPointer(), GL_STREAM_DRAW); numMeshes++; delete mesh; return numMeshes-1; } Now I want to pack those Buffers into one single Buffer for better performance. I dont want to use interleaved arrays, but packed arrays. first I did this: glBufferData(GL_ARRAY_BUFFER, meshes[numMeshes].numVert*sizeof(AL_VertTex), 0, GL_STREAM_DRAW); glBufferSubData(GL_ARRAY_BUFFER, 0, meshes[numMeshes].numVert*sizeof(AL_VertTex), mesh->getUVCoordPointer()); Everything is ok, it renders fine. Then I tried this: (lines 17-22 in loading): glBufferData(GL_ARRAY_BUFFER, meshes[numMeshes].numVert*(sizeof(AL_VertCol)+sizeof(AL_VertTex)), 0, GL_STREAM_DRAW); glBufferSubData(GL_ARRAY_BUFFER, 0, meshes[numMeshes].numVert*sizeof(AL_VertCol), mesh->getColorPointer()); /*glBindBuffer(GL_ARRAY_BUFFER, meshes[numMeshes].VBO[3]); glBufferData(GL_ARRAY_BUFFER, meshes[numMeshes].numVert*sizeof(AL_VertTex), 0, GL_STREAM_DRAW);*/ glBufferSubData(GL_ARRAY_BUFFER, meshes[numMeshes].numVert*sizeof(AL_VertCol), meshes[numMeshes].numVert*sizeof(AL_VertTex), mesh->getUVCoordPointer()); changing the lines 13-17 in rendering to this: glBindBuffer(GL_ARRAY_BUFFER,meshes[Id].VBO[2]); glColorPointer(4, GL_UNSIGNED_BYTE, 0,0); //glBindBuffer(GL_ARRAY_BUFFER,meshes[Id].VBO[3]); glTexCoordPointer(2, GL_FLOAT, 0, BUFFER_OFFSET(meshes[numMeshes].numVert*sizeof(AL_VertCol))); the result: http://b.imagehost.org/view/0899/bug.png the Textur Coordinates are completely off. So, what did I do wrong?
  11. OpenGL [Vista] SIGSEGV on glDrawRangeElements

    Thanks. Sorry for not thinking about something like this. Now I'll feel stupid for the rest of my life :DDD
  12. Hello GameDev! I have some code which runs perfectly on my Computer with Windows XP or Linux, but crashes on a notebook with Windows Vista. The crash occurs during the second call to glDrawRangeElements with the same buffers bound. I am notified by the debugger that the SIGSEGV signal comes from the ig4icd32.dll in the System32 folder, which looks like a video card driver dll to me. Is this some hardware or Vista issue, or is this crash possible due to unclean code? What could be wrong with my Buffers? The video card on my Computer is a NVIDIA GeForce FX5500 The Notebook has an integrated Intel GMA X3100 [EDIT] Commenting out glDrawRangeElements doesnt change anything - the Application SIGSEGVs in ig4icd32.dll on different OpenGL calls (This time glBindBuffer)[/EDIT] [Edited by - AzraelilMeraz on September 27, 2008 5:08:06 PM]
  13. Quote:Original post by idinev I've copy/pasted working code from a library of mine: http://pastebin.com/mc615750 (this file will stay up for a month) Kinda trying to make a good clean opensource library for OpenGL, that is as functional as DX10-SDK. Ah, use glEnableClientState(GL_VERTEX_ARRAY); at start of app, don't need to disable it imho. (as long as you'll be using only VBOs- as you should :P). Also, the type ILVBO was a handle-type with the ILI_VBO struct hidden in the .cpp file, just changed it here directly to *ILI_VBO for you to use the code directly Thank you for the code, but I have my own, working routines already :). I'll definitely look through your code, since it appears to make use of OpenGL in a more optimized way, but I'll stick to my code for now, because the machine where the programm must be able to run doesn't support OpenGL 2.0. Also, my real Problem lay only within my Blender exporting script.
  14. Quote:Original post by TheFlyingDutchman ... Last year I wrote an exporter for blender that exports vertices, normals and texture coordinates (multiple if necessary) in a format that could immediately be stored in vbo's. What I did when exporting a new vertex was check if another vertex with exactly the same normal and texture coordinates already exists in the buffer. Only if it found one that was exactly the same, the index created pointed to the existing vertex. Otherwise (for example: the vertex had an other normal or other texture coordinates) a new vertex with normals and texture coordinates was created in the buffer. That's exactly what I was thinking about, when I was reading your reply. Thank you very much :)