Jump to content
  • Advertisement


  • Content Count

  • Joined

  • Last visited

Community Reputation

145 Neutral

About Deckhead01

  • Rank

Personal Information

  • Interests

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Hey thanks for the response.
  2. I have the following setup in a GUI library I'm making (for fun). Ignore the colors and positions being integers, it's just to serve the purpose of illustration. Code: // Example program #include <iostream> #include <string> class Rect { public: virtual void Draw(const int position) const = 0; }; class ColorRect : public Rect { public: virtual void Draw(const int position) const override { /* does a draw */ } int color; }; class TextureRect : public Rect { public: virtual void Draw(const int position) const override { /* does a draw textured */ } int texture; }; class Widget { public: Rect* background; int position; virtual void Draw() const { background->Draw(position); } virtual void Update() { /* might do stuff */ } }; class Button : public Widget { public: virtual void Draw() const override { Widget::Draw(); border->Draw(position); } Rect* border; }; int main() { ColorRect redRect; redRect.color = 1; ColorRect blueRect; blueRect.color = 2; TextureRect textRect; textRect.texture = 1; Button b1; b1.border = &blueRect; b1.background = &redRect; b1.position = 1; Button b2; b2.border = &blueRect; b2.background = &textRect; b2.position = 2 while(true) { b1.Update(); b2.Update(); b1.Draw(); b2.Draw(); } } I think it should be obvious that the Rect class is a Flyweight that is used by multiple different objects at the same time. What I want to do now, for example, is have b1 animate it's border Rect. This animation should not affect the other Widget*s that use the same Rect*, i.e their animation needs to be paused, started and have a different "current frame". I'm hesitant to create an "Animated Rect" class or something, because then the only way to handle separate animation is for that class to hold a map of pointers to Widgets that are using it or something. In addition; I would also want to animate, for example, the position. Which means ideally the interface that you use to animate positions (which are specific to the object), is the same as the one used to animate the texture or color (which is shared amongst objects currently). Whatever it is that would hold the Animation state would need to hold a few things like frame_rate and probably time_since_updated or something. I just can't work out where to put it, or what to reorganise to fit in.
  3. Thanks a lot for your response.     Yes, after reading some more, I think what I meant was a "vortex", however     Yes, this is the sort of affect I want. So not really 3D, just 2D along the surface, but:     I'm not sure what you mean. I'm using a cubemap to texture my sphere. I have a 3D noise function. What I do is for each pixel in my cubemap, I work out it's x,y,z as though on a cube surface, I treat this as a direction from the center of the cube which I then change the magnitude of to be a unit distance. This new x,y,z coordinate is what I use to sample the noise function, this sample is stored in the original x,y,z coordinate. The end result is that once the texture is stretched over each hemisphere of my sphere, it's result is as though I cut away the corners of a volume cube of noise.   I hope that explanation makes sense.   Because, this is where I can't really comprehend how to now do my 2D spirals / vortexes around the face of the sphere. I imagine I would need to adjust the x,y,z coordinates AFTER projecting them to the surface of a sphere, otherwise they won't line up with each other? (like if one was on the edge of a cubemap face, I would get an angle if I "spiralled" before projecting). And due to the curve of the surface of the sphere, I need to be adjusting the way I do the spiralling so that it sucks in the noise towards the spirals center taking that curve of the sphere into account.   I think this means that my spirals/vortexes will need to be positioned in 3D space, not 2D space? Otherwise I won't be able work out where they are on my cubemap, considering that a spiral on the edge of a face needs to affect the neighbouring edge.   So as an example, if I had one big massive vortex, I need it to pull in everything from all over the sphere.   I know what I want, I just can't imagine how to do it...
  4. I have the following code which I based on this article http://www.geeks3d.com/20110428/shader-library-swirl-post-processing-filter-in-glsl/ that allows me to distort the coordinates of noise values before sampling my noise function.   It distorts it in a spiral/twirl and is great for generating something like a global cloud map (which is what I'm using it for). glm::vec2 tc = glm::vec2(position.x,position.y); for(const auto& spiral : spirals) { glm::vec2 spiralPosition = std::get<0>(spiral); float spiralRadius = std::get<1>(spiral); float spiralAngle = std::get<2>(spiral); tc -= spiralPosition; float distance = glm::length(tc); if(distance < spiralRadius) { float percent = (spiralRadius - distance) / spiralRadius; float theta = percent * percent * spiralAngle;// * 8.0; float s = std::sin(theta); float c = std::cos(theta); tc = glm::vec2(glm::dot(tc,glm::vec2(c,-s)),glm::dot(tc,glm::vec2(s,c))); } tc += spiralPosition; } return m_sourceModules[0]->GetValue(tc); The code is in C++ and relies on GLM but it doesn't matter, just what it's doing. The `spirals` container is a list of all my spirals (position, radius and angles).   What actually does the distorting is the inner if statement. Essentially, if the point I'm requesting a noise value for is within the radius of a spiral, it's distorted along the x and y depending on the distance from the spiral. So further away is distorted less.   I don't really know how this works. Just that it does. I have a vague understanding of cos and sin and how they relate to spherical coordinates. I understand that by using the dot product of my requested coordinates position and the sin and cos of the angle is what's producing the displacement.   What I would like to now do is extend this into 3 dimensions. The reason is that I'm generating cubemaps by sampling the surface of a sphere in a 3D noise function. In order to do this I believe I need to distort the z coordinate in a similar manner. Because if you imagine the surface of a sphere, I'm not sure how to ensure that the spiralling will produce a similar affect regardless of which "face" I'm sampling (negative z direction, positive y, negative x.... which way is it twisting?).   I have no idea how to do that.   I've tried to sort of hack away at it to now avail. I don't understand the math to begin with.   I kind of assume that displacing the z coordinate will mean that some noise is "sucked in" from the outside of the sphere and inside of the sphere, which is just fine. It will probably produce an interesting affect. The other way I guess it would work is somehow "shaping" the spiral to be in three dimensions, so that at the edges of the radius the spiral curves along with the sphere's surface, so I guess the z coordinate moves along the surface. This second way would probably reproduce the 2D affect along the sphere surface.
  5. Thanks a lot guys, I feel like a right idiot now; but I'm glad I learned this. I'm so used to C++ function overloading that the possibility of differently named functions didn't even enter my head.
  6. I love you. GL_DOUBLE was not supported.   My god. How is it even possible to know this stuff? Only GL_UNSIGNED_INT_10F_11F_11F_REV is mentioned in the docs as having support only in 4.4+
  7. Thanks for your reply Xycaleth. I've tried this, it as one of the first things I tried and didn't do anything.
  8. I've been trying to solve this for like 3 days and it's driving me bonkers. I've gotten my code down to the below. glDrawElements is segfaulting. I have assumed that it's from the indices but I look over it again and again and there's no problem. The segfault is happening is atio6axx.dll, which I assume means I've told OpenGL that one of my buffers is bigger than it actually is. But I check over it again and again and see no problem. I've used GLIntercept to verify that the segfault happens on the glDrawElements function. #include <exception> #include <iostream> #include <fstream> #include <sstream> #include <list> #include <string> #include <algorithm> #include <functional> #include <utilities.hpp> #include <GL/glew.h> #include <SDL2/sdl.h> #define GLM_FORCE_RADIANS #include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/type_ptr.hpp> #include <glm/gtx/transform.hpp> struct VertexData { GLdouble position[4]; GLfloat color[3]; GLfloat normal[3]; GLfloat tcoords[2]; }; int main(int argc, char* argv[]) { try { SDL_Window* window; SDL_GLContext context; if(SDL_Init(SDL_INIT_VIDEO) < 0) throw std::runtime_error("unable to initialise video"); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 4); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); window = SDL_CreateWindow("SpaceEngine", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 800, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN); if(!window) throw std::runtime_error("unable to create window"); context = SDL_GL_CreateContext(window); SDL_GL_SetSwapInterval(1); GLenum glewErr = glewInit(); if(glewErr != GLEW_OK) { SDL_GL_DeleteContext(context); SDL_DestroyWindow(window); SDL_Quit(); throw std::runtime_error(reinterpret_cast<const char*>(glewGetErrorString(glewErr))); } glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); std::vector<VertexData> vertices; std::vector<GLushort> indices; int rings = 200; int sectors = 200; float radius = 1.0; if(rings < 2) rings = 2; if(sectors < 2) sectors = 2; while(rings * sectors >= std::numeric_limits<GLushort>::max()) { rings /= 2; sectors /= 2; } const GLuint polyCountXPitch = rings+1; GLuint level = 0; for(GLuint p1 = 0; p1 < sectors-1; ++p1) { for(GLuint p2 = 0; p2 < rings-1; ++p2) { GLuint curr = level + p2; indices.push_back(curr + polyCountXPitch); indices.push_back(curr); indices.push_back(curr + 1); indices.push_back(curr + polyCountXPitch); indices.push_back(curr + 1); indices.push_back(curr + 1 + polyCountXPitch); } indices.push_back(level + rings - 1 + polyCountXPitch); indices.push_back(level + rings - 1); indices.push_back(level + rings); indices.push_back(level + rings - 1 + polyCountXPitch); indices.push_back(level + rings); indices.push_back(level + rings + polyCountXPitch); level += polyCountXPitch; } const GLuint polyCountSq = polyCountXPitch * sectors; //top point const GLuint polyCountSq1 = polyCountSq + 1; //bottom point const GLuint polyCountSqM1 = (sectors - 1) * polyCountXPitch; //last rows first index for(GLuint p2 = 0; p2 < rings - 1; ++p2) { indices.push_back(polyCountSq); indices.push_back(p2 + 1); indices.push_back(p2); indices.push_back(polyCountSqM1 + p2); indices.push_back(polyCountSqM1 + p2 + 1); indices.push_back(polyCountSq1); } indices.push_back(polyCountSq); indices.push_back(rings); indices.push_back(rings - 1); indices.push_back(polyCountSqM1 + rings - 1); indices.push_back(polyCountSqM1); indices.push_back(polyCountSq1); const GLdouble angleX = 2 * pi() / rings; const GLdouble angleY = pi() / sectors; GLuint i = 0; GLdouble axz; GLdouble ay = 0; vertices.resize(polyCountXPitch * sectors + 2); for(GLuint y = 0; y < sectors; ++y) { ay += angleY; const GLdouble sinay = std::sin(ay); axz = 0; for(GLuint xz = 0; xz < rings; ++xz) { const glm::vec3 pos((radius * std::cos(axz) * sinay),radius * std::cos(ay), radius * std::sin(axz) * sinay); glm::vec3 normal = pos; normal = glm::normalize(normal); GLuint tu = 0.5f; if(y == 0) { if(normal.y != -1.0f && normal.y != 1.0f) tu = std::acos(glm::clamp<GLdouble>(normal.x/sinay, -1.0f, 1.0f)) * 0.5 * (1.0f/pi()); if(normal.z < 0.0f) tu = 1 - tu; } else tu = vertices[i-polyCountXPitch].tcoords[0]; VertexData v; v.color[0] = 1; v.color[1] = 1; v.color[2] = 1; v.position[0] = pos.x; v.position[1] = pos.y; v.position[2] = pos.z; v.position[3] = 1.0f; v.normal[0] = normal.x; v.normal[1] = normal.y; v.normal[2] = normal.z; v.tcoords[0] = tu; v.tcoords[1] = ay * (1.0f/pi()); vertices.at(i) = v; ++i; axz += angleX; } vertices.at(i) = vertices.at(i - rings); vertices.at(i).tcoords[0] = 1.0f; ++i; } VertexData v; v.color[0] = 1; v.color[1] = 1; v.color[2] = 1; v.position[0] = 0; v.position[1] = radius; v.position[2] = 0; v.position[3] = 1.0f; v.normal[0] = 0; v.normal[1] = 1; v.normal[2] = 0; v.tcoords[0] = 0.5f; v.tcoords[1] = 0.0f; vertices.at(i) = v; ++i; v.position[1] = -radius; v.normal[1] = -1.0f; v.tcoords[1] = 1.0f; vertices.at(i) = v; GLuint vao; glGenVertexArrays(1,&vao); glBindVertexArray(vao); GLuint vbo; glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(struct VertexData) * vertices.size(), vertices.data(), GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 4, GL_DOUBLE, GL_FALSE, sizeof(struct VertexData), (const GLvoid*)offsetof(struct VertexData, position)); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(struct VertexData), (const GLvoid*)offsetof(struct VertexData, color)); glEnableVertexAttribArray(2); glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(struct VertexData), (const GLvoid*)offsetof(struct VertexData, normal)); glEnableVertexAttribArray(3); glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(struct VertexData), (const GLvoid*)offsetof(struct VertexData, tcoords)); GLuint ibo; glGenBuffers(1, &ibo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * indices.size(), indices.data(), GL_STATIC_DRAW); glBindVertexArray(0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); GLuint shader1,shader2; std::ifstream file("tutorial2.vert"); if(!file) throw std::runtime_error("The file tutorial2.vert was not opened"); else { std::string fileContents((std::istreambuf_iterator<char>(file)),std::istreambuf_iterator<char>()); shader1 = glCreateShader(GL_VERTEX_SHADER); std::string fail = "glCreateShader failed using " + GL_VERTEX_SHADER; if(!shader1) throw std::runtime_error(fail.c_str()); const GLchar* contents[1]; contents[0] = fileContents.c_str(); glShaderSource(shader1, 1, contents, NULL); glCompileShader(shader1); int compiled; glGetShaderiv(shader1, GL_COMPILE_STATUS, &compiled); if(compiled == 0) { int maxLength; glGetShaderiv(shader1, GL_INFO_LOG_LENGTH, &maxLength); char* vertexInfoLog = new char[maxLength]; glGetShaderInfoLog(shader1, maxLength, &maxLength, vertexInfoLog); throw std::runtime_error("Shader failed to compile:\n>\t" + std::string(vertexInfoLog)); } } std::ifstream file2("tutorial2.frag"); if(!file2) throw std::runtime_error("The file tutorial2.frag was not opened"); else { std::string fileContents((std::istreambuf_iterator<char>(file2)),std::istreambuf_iterator<char>()); shader2 = glCreateShader(GL_FRAGMENT_SHADER); std::string fail = "glCreateShader failed using " + GL_FRAGMENT_SHADER; if(!shader2) throw std::runtime_error(fail.c_str()); const GLchar* contents[1]; contents[0] = fileContents.c_str(); glShaderSource(shader2, 1, contents, NULL); glCompileShader(shader2); int compiled; glGetShaderiv(shader2, GL_COMPILE_STATUS, &compiled); if(compiled == 0) { int maxLength; glGetShaderiv(shader2, GL_INFO_LOG_LENGTH, &maxLength); char* vertexInfoLog = new char[maxLength]; glGetShaderInfoLog(shader2, maxLength, &maxLength, vertexInfoLog); throw std::runtime_error("Shader failed to compile:\n>\t" + std::string(vertexInfoLog)); } } GLuint program = glCreateProgram(); if(!program) throw std::runtime_error("glCreateProgram failed"); glAttachShader(program, shader1); glAttachShader(program, shader2); glBindAttribLocation(program, 0, "in_Position"); glBindAttribLocation(program, 1, "in_Color"); glBindAttribLocation(program, 2, "in_Normal"); glBindAttribLocation(program, 3, "in_UV"); glLinkProgram(program); int IsLinked; glGetProgramiv(program, GL_LINK_STATUS, (int *)&IsLinked); if(IsLinked == 0) { int maxLength; glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength); char* shaderProgramInfoLog = new char[maxLength]; glGetProgramInfoLog(program, maxLength, &maxLength, shaderProgramInfoLog); throw std::runtime_error("Program failed to link:\n>\t" + std::string(shaderProgramInfoLog) + ""); } glDetachShader(program, shader1); glDetachShader(program, shader2); bool done = false; while(!done) { SDL_Event event; while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_WINDOWEVENT: switch(event.window.event) { case SDL_WINDOWEVENT_CLOSE: done = true; break; } break; } } glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(program); glBindVertexArray(vao); //**** SEGFAULTS HERE *********/ glDrawElements(GL_TRIANGLES,indices.size(),GL_UNSIGNED_SHORT,0); glBindVertexArray(0); glUseProgram(0); SDL_GL_SwapWindow(window); } glUseProgram(0); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); glDeleteProgram(program); glDeleteBuffers(1, &vbo); glDeleteVertexArrays(1, &vao); SDL_GL_DeleteContext(context); SDL_DestroyWindow(window); SDL_Quit(); std::cout << "all good in the hood" << std::endl; } catch(const std::exception& e) { std::cout << "ERROR:\t" << e.what() << std::endl; } catch(...) { std::cout << "ERROR" << std::endl; } exit(EXIT_SUCCESS); } My Frag and vert shaders are inconsequential. I've also checked that the max and min values in the indices vectors are within the bounds of my vertices. This is such a beginner program that I'm assuming I've missed something incredibly simple, but I cannot see the problem. At this point I've tried every debugging technique I know.
  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!