Advertisement Jump to content
  • Advertisement


  • Content Count

  • Joined

  • Last visited

Community Reputation

199 Neutral

About Rarosu

  • Rank

Personal Information

  • Interests
  1. Calling glFinish() after the first draw call seems to fix this problem. Obviously this is not ideal as it will block the execution until the draw call has finished, but it will at least fix the symptoms.
  2. @Glass_Knife Hah. It it a frightening thought to think how many hidden driver errors there are out there.   Updating the Intel driver to did not solve the problem unfortunately. The only solution I can see currently is revert to using glUniform* or create separate uniform buffer objects for each instance. Which sucks. If I find out anything else I'll update this thread.   - Rarosu
  3. Running this project on an Nvidia card instead yielded the expected results... Two boxes. Either Nvidia is lenient with whatever error I might be doing, or this Intel driver has some bug. I will look into updating my drivers and see if this fixes the problem.
  4. @beans222 I don't think that is the problem in this case, but to be safe, I have tried changing the uniform data to an array of 4 floats and will include it in the edit.
  5. Thanks for the reply, GlassKnife, I'll edit the original post with the code.   I have reduced the issue to where I know there is something going on with the uniform bindings. I have tried making a separate program, VBO and VAO for the second instance and the same problem occurs. When I make a separate uniform buffer object however and fill it with the same data, it works. That is, the difference between: glUseProgram(program); glBindVertexArray(vao); // Instance is rendered. uniform_buffer_data.offset = 1.3f; glBindBufferBase(GL_UNIFORM_BUFFER, UNIFORM_BINDING, uniform_buffer); glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(UniformBuffer), &uniform_buffer_data); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // This instance is also rendered. ubo_data2.offset = -0.4f; glBindBufferBase(GL_UNIFORM_BUFFER, UNIFORM_BINDING, ubo2); glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(UniformBuffer), &ubo_data2); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); And this: glUseProgram(program); glBindVertexArray(vao); // This instance is no longer visible. uniform_buffer_data.offset = 1.3f; glBindBufferBase(GL_UNIFORM_BUFFER, UNIFORM_BINDING, uniform_buffer); glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(UniformBuffer), &uniform_buffer_data); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // And only this one is rendered. uniform_buffer_data.offset = -0.4f; glBindBufferBase(GL_UNIFORM_BUFFER, UNIFORM_BINDING, uniform_buffer); glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(UniformBuffer), &uniform_buffer_data); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); As for checking the state, I am not sure what to look for in this scenario. I tried apitrace at your suggestion (which seems awesome) and the state looks fine to me; as I would expect it.
  6. Hello GameDev!   I am porting an OpenGL 4.4 application to OpenGL 3.1 to get it to run on my Intel HD Graphics 3000 card (on my laptop). So far, things have been going well, but I ran into a problem when rendering more than one instance using the same vertex buffer (just changing the uniform buffer between the draw calls). When I do this, only the last instance is rendered. The non-ported code did not exhibit this problem and I just cannot see what I might have done to cause it to fail.   I have managed to isolate the bug in a minimal sample: #include <SDL2/SDL.h> #include <GL/gl3w.h> #include <iostream> #include <string> const int OPENGL_MAJOR = 3; const int OPENGL_MINOR = 1; const int UNIFORM_BINDING = 1; const char* VERTEX_SOURCE = "#version 140 \n" " \n" "in vec2 in_position; \n" " \n" "layout(std140) uniform UniformBuffer \n" "{ \n" " vec4 offset; \n" "}; \n" " \n" "void main() \n" "{ \n" " gl_Position = vec4(in_position, 0.0f, 1.0f);\n" " gl_Position.x += offset.x; \n" "} \n"; const char* FRAGMENT_SOURCE = "#version 140 \n" " \n" "out vec4 out_color; \n" " \n" "void main() \n" "{ \n" " out_color = vec4(1.0f, 1.0f, 1.0f, 1.0f); \n" "} \n"; struct UniformBuffer { float offset[4]; }; SDL_Window* window = nullptr; SDL_GLContext glcontext = nullptr; unsigned int viewport_width = 800; unsigned int viewport_height = 600; bool running = true; GLuint vertexShader = 0; GLuint fragmentShader = 0; GLuint program = 0; GLuint position_vbo = 0; GLuint vao = 0; UniformBuffer uniform_buffer_data; GLuint uniform_buffer = 0; void initialize(); void loadResources(); GLuint compileShader(const char* source, GLuint type); void linkProgram(GLuint program); void run(); void handleEvents(); void render(); int main(int argc, char* argv[]) { initialize(); loadResources(); run(); return 0; } void initialize() { if (SDL_Init(0) != 0) { throw std::runtime_error("Failed to initialize SDL"); } window = SDL_CreateWindow("gl3", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, viewport_width, viewport_height, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); if (window == nullptr) { throw std::runtime_error("Failed to create SDL window"); } SDL_GLcontextFlag flags = SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG; #ifndef NDEBUG flags = (SDL_GLcontextFlag)(flags | SDL_GL_CONTEXT_DEBUG_FLAG); #endif SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, OPENGL_MAJOR); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, OPENGL_MINOR); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, flags); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 32); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 0); glcontext = SDL_GL_CreateContext(window); if (glcontext == nullptr) { throw std::runtime_error("Failed to create OpenGL context"); } if (gl3wInit() != 0) { throw std::runtime_error(std::string("Failed to initialize gl3w")); } if (gl3wIsSupported(OPENGL_MAJOR, OPENGL_MINOR) != 1) { throw std::runtime_error("OpenGL version not supported"); } glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glViewport(0, 0, viewport_width, viewport_height); SDL_GL_SetSwapInterval(1); } void loadResources() { // VBOs. float positions[] = { -0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, 0.5f }; glGenVertexArrays(1, &vao); glBindVertexArray(vao); glGenBuffers(1, &position_vbo); glBindBuffer(GL_ARRAY_BUFFER, position_vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 8, positions, GL_STATIC_DRAW); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(0); // Shaders. vertexShader = compileShader(VERTEX_SOURCE, GL_VERTEX_SHADER); fragmentShader = compileShader(FRAGMENT_SOURCE, GL_FRAGMENT_SHADER); program = glCreateProgram(); glAttachShader(program, vertexShader); glAttachShader(program, fragmentShader); linkProgram(program); glUniformBlockBinding(program, glGetUniformBlockIndex(program, "UniformBuffer"), UNIFORM_BINDING); // UBOs. uniform_buffer_data.offset[0] = 0.0f; uniform_buffer_data.offset[1] = 0.0f; uniform_buffer_data.offset[2] = 0.0f; uniform_buffer_data.offset[3] = 0.0f; glGenBuffers(1, &uniform_buffer); glBindBufferBase(GL_UNIFORM_BUFFER, UNIFORM_BINDING, uniform_buffer); glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformBuffer) * sizeof(float), &uniform_buffer_data, GL_DYNAMIC_DRAW); } GLuint compileShader(const char* source, GLuint type) { GLuint shader = glCreateShader(type); glShaderSource(shader, 1, &source, nullptr); glCompileShader(shader); GLint status; glGetShaderiv(shader, GL_COMPILE_STATUS, &status); if (status != GL_TRUE) { GLint logSize; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logSize); std::string log; if (logSize > 0) { int written; log.resize(logSize); glGetShaderInfoLog(shader, logSize, &written, &log[0]); } throw std::runtime_error("Failed to compile shader: " + log); } return shader; } void linkProgram(GLuint program) { glLinkProgram(program); GLint status; glGetProgramiv(program, GL_LINK_STATUS, &status); if (status != GL_TRUE) { GLint logSize; glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logSize); std::string log; if (logSize > 0) { int written; log.resize(logSize); glGetProgramInfoLog(program, logSize, &written, &log[0]); } throw std::runtime_error("Failed to link program: " + log); } } void run() { while (running) { handleEvents(); render(); } } void handleEvents() { SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_QUIT: { running = false; } break; case SDL_WINDOWEVENT: { switch (event.window.event) { case SDL_WINDOWEVENT_RESIZED: { viewport_width = event.window.data1; viewport_height = event.window.data2; glViewport(0, 0, viewport_width, viewport_height); } break; } } break; } } } void render() { glClear(GL_COLOR_BUFFER_BIT); glUseProgram(program); glBindVertexArray(vao); uniform_buffer_data.offset[0] = 1.3f; glBindBufferBase(GL_UNIFORM_BUFFER, UNIFORM_BINDING, uniform_buffer); glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(UniformBuffer) * sizeof(float), &uniform_buffer_data); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); uniform_buffer_data.offset[0] = -0.4f; glBindBufferBase(GL_UNIFORM_BUFFER, UNIFORM_BINDING, uniform_buffer); glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(UniformBuffer) * sizeof(float), &uniform_buffer_data); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); SDL_GL_SwapWindow(window); } I am using SDL2 and GL3W and I am working in Visual Studio 2013 on Windows 10. The biggest change when I ported was that I no longer could specify the uniform binding point in the shader, but had to use glUniformBlockBinding instead. Anyone familiar with this version of OpenGL who could tell me if I am doing something stupid?   Cheers! - Rarosu
  7. Thank you for the reply! I have encountered the Pacejka model before when researching, but it seemed like it was mostly used for more realistic simulations when I feel like there should be relatively simple model to get a car to lose grip when the traction exceeds the maximum friction. I might look into it again and actually implement it, but I am hesitant to complicate the model with magic equations before I have a working simple model. Additionally, I have also tried to keep track of the wheel spin and calculate the slip ratio before (as I believe is an input to the Pacejka formulas), but it always ended up being rather unstable as the traction could change pretty drastically for low slip ratios and cause the wheel spin to fluctuate.
  8. That makes intuitive sense to me, but I am not sure where it would fit in. No resources I have looked at has had an explicit opposing friction force (apart from rolling friction). It feels like the radius of the circle of traction would be smaller when the car starts to slide (making the maximum forward/backward traction and cornering forces smaller which makes it more difficult to correct the car trajectory). However, I need to check versus the circle to know whether I am sliding... So, either I am wrong in how I am detecting when the car starts to slide, or I will need a state that remains across frames.
  9. Hello all!   I have been working on a simple top-down 2D car simulator and have some questions to anyone who is experienced with this. The main problem I have is how to simulate a wheel losing grip. I have been reading Brian Beckman's series on racing and I understand that the tires have an adhesive limit and that the circle/ellipsis of traction can be used to know whether a wheel is gripping or not. Am I right to presume that the amount of traction on a tire needs to be capped to the circle? This is my per-frame code at the moment:   float speed = glm::length(velocity_local); // Calculate weight distribution. float weight = description.mass * G; float wheelbase = description.cg_to_front_axle + description.cg_to_back_axle; float front_weight = (description.cg_to_back_axle / wheelbase) * weight - (description.cg_height / wheelbase) * description.mass * acceleration_local.x; float rear_weight = (description.cg_to_front_axle / wheelbase) * weight + (description.cg_height / wheelbase) * description.mass * acceleration_local.x; // Assume the wheels are rolling and calculate the engine torque. float wheel_angular_velocity = velocity_local.x / description.wheel_radius; float transmission = description.gear_ratios[gear] * description.differential_ratio * description.transmission_efficiency; float engine_rpm = ANGULAR_VELOCITY_TO_RPM * wheel_angular_velocity * transmission; float engine_torque = throttle ? lerp_curve(description.torque_curve, engine_rpm) : 0.0f; // Simplified traction model - use the torque on the wheels. float drive_torque = engine_torque * transmission; float traction_force = drive_torque / description.wheel_radius; // Calculate the braking torque on the wheels. float braking_torque = reverse ? 3500 : 0; float braking_force = -braking_torque / description.wheel_radius * glm::sign(velocity_local.x); // Calculate the lateral slip angles and determine the lateral cornering force. float front_angular_velocity = car_angular_velocity * description.cg_to_front_axle; float rear_angular_velocity = -car_angular_velocity * description.cg_to_back_axle; float slip_angle_front = std::atan2(velocity_local.y + front_angular_velocity, std::abs(velocity_local.x)) - glm::sign(velocity_local.x) * steer_angle; float slip_angle_rear = std::atan2(velocity_local.y + rear_angular_velocity, std::abs(velocity_local.x)); float cornering_force_front = front_weight * -description.cornering_stiffness * slip_angle_front; float cornering_force_rear = rear_weight * -description.cornering_stiffness * slip_angle_rear; // The wheels have a limited maximal traction before they start to slide. float traction_circle_radius = 0.8; glm::vec2 front_total_traction = glm::vec2(0, cornering_force_front * std::cos(steer_angle)); glm::vec2 rear_total_traction = glm::vec2(traction_force + braking_force, cornering_force_rear); bool front_slipping = false; float front_total_traction_length = glm::length(front_total_traction); if (front_total_traction_length / front_weight >= traction_circle_radius) { front_total_traction /= front_total_traction_length; front_total_traction *= traction_circle_radius * front_weight; front_slipping = true; } bool rear_slipping = false; float rear_total_traction_length = glm::length(rear_total_traction); if (rear_total_traction_length / rear_weight >= traction_circle_radius) { rear_total_traction /= rear_total_traction_length; rear_total_traction *= traction_circle_radius * rear_weight; rear_slipping = true; } // Calculate the torque on the car body and integrate car yaw rate and orientation. float cornering_torque_front = front_total_traction.y * description.cg_to_front_axle; float cornering_torque_rear = rear_total_traction.y * description.cg_to_back_axle; float car_torque = std::cos(steer_angle) * cornering_torque_front - cornering_torque_rear; float car_angular_acceleration = car_torque / description.inertia; car_angular_velocity += car_angular_acceleration * dt; orientation += car_angular_velocity * dt; // Calculate the wind drag force on the car. Simplification that the area facing the velocity direction is the front. float area = description.height * 2.0f * description.halfwidth; float drag_multiplier = 0.5f * description.air_density * area * description.drag_coefficient; glm::vec2 drag_resistance = -drag_multiplier * speed * velocity_local; // Calculate the rolling friction force on the car. glm::vec2 rolling_resistance = glm::vec2(-description.wheel_rolling_friction * velocity_local.x, 0); // Sum the forces on the car's CG and integrate the velocity. glm::vec2 force = rear_total_traction + front_total_traction + drag_resistance + rolling_resistance; acceleration_local = force / description.mass; velocity_local += acceleration_local * dt; // Calculate the acceleration and velocity in world coordinates and integrate world position. float sn = std::sin(orientation); float cs = std::cos(orientation); acceleration.x = cs * acceleration_local.x - sn * acceleration_local.y; acceleration.y = sn * acceleration_local.x + cs * acceleration_local.y; velocity.x = cs * velocity_local.x - sn * velocity_local.y; velocity.y = sn * velocity_local.x + cs * velocity_local.y; position += velocity * dt;   This gets me a car that can accelerate and steer, however the tires never seem to lose grip the way I expect them to. I can move at 200 km/h and make a abrupt turn without spinning (the car simply moves in approximately the same arc as when going slow). Am I missing some step to simulate a sliding car apart from capping the traction?   Also, as a side question, is using the torque on the rear wheels as the forward traction force an acceptable approximation? I saw this being done in "on the envelope" calculations by Brian, ignoring slip ratios and wheel turn rate integration. However, I am not sure how correct this actually is.   Any input is appreciated!  
  10. Great info and links, Sean! I'll definitely have a read through them, it is more information than I've found previously and it's nice to get something substantial on the subject. I'm considering using WebSockets or something for the connection to the central web server, since it is already suitable for that purpose. WebRTC is the option I'm considering between the browsers when game state data needs to be distributed. I'll read up on the protocol and see what it can offer though, and try out some implementations and see what works and what doesn't.
  11. My plan is to make a co-op platformer/action game for a small group of people, so the cheating aspect is hopefully not too relevant in this case, even though I think it is possible to solve if one of the clients are acting server. My current idea is to use the server as a broker of kind. Let one of the clients (the host) create the game via a web form. The server will generate a random hash and send it back in the URL of the response. The host can send the URL to any player they wish to invite. A peer that connects with the URL will be matched by the server with the host that is associated with the given hash. The server will respond with the connection details to the host, and the peer can connect to the host. It /feels/ straightforward and I'm going to experiment with it, but I'm not sure if I'm on the right path here. I'm mostly looking to alleviate the web server of having to mirror all the game messages and instead only focusing on the whole setting up the connections. The latency of the game itself will be another challenge :D
  12. Hello! I've gotten interested in making multiplayer games using HTML5. I've looked into WebSockets via, but I was disappointed that all the communication seemed to have to go through the server. What I had been hoping for was to use the web server only as a kind of matchmaker and resource deliverer, and let the clients send the game state updates between each other (with the client that created the game acting as the game server). Without this kind of direct communication between the clients, it seems like the web server would get an unproportionate workload, especially with a couple of games running. I found that WebRTC could be used for peer to peer communication in browsers, but I haven't found much information on the subject. Has anyone used this for a game yet? Is there any proper documentation available? How realistic is it to implement peer-to-peer communication via the browser at the current date? :) I would love to hear the experiences of anyone else who has been developing multiplayer games for the web and what the common solutions are, if any.
  13. Hello, I'm getting a problem when creating an effect using the Effects11 framework: D3D11: ERROR: ID3D11Device::CreateVertexShader: Shader must be vs_4_0 or vs_4_1. Shader version provided: vs_5_0 [ STATE_CREATION ERROR #167: CREATEVERTEXSHADER_INVALIDSHADERTYPE ] First-chance exception at 0x000007fefde9cacd in WarSettlers.exe: Microsoft C++ exception: _com_error at memory location 0x0018e620.. D3D11: ERROR: ID3D11Device::CreatePixelShader: Shader must be ps_4_0 or ps_4_1. Shader version provided: ps_5_0 [ STATE_CREATION ERROR #193: CREATEPIXELSHADER_INVALIDSHADERTYPE ] First-chance exception at 0x000007fefde9cacd in WarSettlers.exe: Microsoft C++ exception: _com_error at memory location 0x0018e620.. So my card isn't supporting a shader version higher than 4.1. Fair enough. I can switch adapter and then it works fine. My problem is that D3DX11CreateEffectFromMemory from which these errors originate returns S_OK. And then the program breaks because it cannot find a bound vertex and pixel shader. I'd really like to be able to catch this and output a proper error to the user, so my question is if there is any way of detecting this? The code I use for compiling and creating an effect below: // Compile the effect ID3D10Blob* shader; ID3D10Blob* errors; HRESULT result = D3DX11CompileFromFile("Resources/Effects/BasicColor.fx", NULL, NULL, NULL, "fx_5_0", D3D10_SHADER_ENABLE_STRICTNESS | D3D10_SHADER_DEBUG, 0, NULL, &shader, &errors, NULL); if (FAILED(result)) { std::string errorMessage; if (errors != NULL) { errorMessage = static_cast(errors->GetBufferPointer()); } else { errorMessage = "Could not find effect file"; } throw DirectXErrorM(result, errorMessage); } result = D3DX11CreateEffectFromMemory(shader->GetBufferPointer(), shader->GetBufferSize(), 0, GetD3D().GetDevice().Resource(), &m_effect.Resource()); if (FAILED(result)) { throw DirectXErrorM(result, "Failed to create effect from compiled blob."); } Does anyone have any idea on how to check if the vertex- and pixel shader have been actually created by the effect?
  14. Rarosu

    [SFML] random number generator

    You probably do not want to seed the random number generator with GetElapsedTime(). This function will give you the time since the application has started, which should be approximately the same number every time. Instead, you could use: #include <iostream> #include <time> #include <SFML/System.hpp> int main(int argc, char**argv) { sf::Randomizer::SetSeed(time(NULL)); int _random = sf::Randomizer::Random(0,100); std::cout << _random << std::endl; return 0; } .. which would give you the number of seconds since 1970, and is always unique. Hope it helps, cheers!
  15. Hi, You should be able to solve this problem using the rule of cosine first and then the rule of sine. The rule of cosine can be used to get one of the angles, by knowing two sides, and then you can use the rule of sine to get the rest of them. Hope this helps and that you solve your problem. Cheers! - Rarosu
  • Advertisement

Important Information

By using, you agree to our community Guidelines, Terms of Use, and Privacy Policy. 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!