im trying to create flying 3d camera which can dynamically change it’s direction and can recognize if player presses many buttons in the same time. I made it, but there is a problem, when i press as example W + D all is ok, camera is moving, but if i start rotating camera , movement slows down , is there any easier way to make flying 3d camera which changes direction dynamically and can move even if i press multiple keys?
int main(int argc,char** argv){
bool quit = false;
SDL_Event e;
if(!init()){
printf("na");
}
else{
glUseProgram(programShader);
glm::vec3 cameraStep = glm::vec3(0.f,0.f,0.f);
unsigned int projectionLoc, viewLoc, modelLoc;
float movementSensitivity = 0.0005f, cameraSensitivity = 0.01f;
glm::mat4 projection = glm::mat4(1.f);
glm::mat4 view = glm::mat4(1.f);
glm::mat4 model = glm::mat4(1.f);
glm::vec3 cameraPos = glm::vec3(0.0,0.0,2.0);
glm::vec3 cameraUp = glm::vec3(0.0,1.f,0.0);
glm::vec3 cameraFront = glm::vec3(0.0,0.0,-1.f);
view = glm::lookAt(cameraPos,cameraPos + cameraFront, cameraUp);
projection = glm::perspective(glm::radians(45.f),1.f,0.1f,100.f);
projectionLoc = glGetUniformLocation(programShader,"projection");
viewLoc = glGetUniformLocation(programShader,"view");
modelLoc = glGetUniformLocation(programShader,"model");
// std::cout << projectionLoc << " " << viewLoc << " " << modelLoc << std::endl;
glUniformMatrix4fv(projectionLoc,1,GL_FALSE,glm::value_ptr(projection));
glUniformMatrix4fv(viewLoc,1,GL_FALSE,glm::value_ptr(view));
glUniformMatrix4fv(modelLoc,1,GL_FALSE,glm::value_ptr(model));
glBindVertexArray(VAOs[0]);
glBindTexture(GL_TEXTURE_2D,textures[0]);
float frameBasedCorrection, thisTicks = 0, previousTicks = 0;
glm::vec3 lastPosFrontSpeed, lastNegFrontSpeed, lastPosSideSpeed, lastNegSideSpeed;
int previousMouseX, previousMouseY;
float pitch = 0, yaw =-90;
while(!quit){
thisTicks = SDL_GetTicks();
frameBasedCorrection = thisTicks - previousTicks;
previousTicks = thisTicks;
float movementCorrection = movementSensitivity * frameBasedCorrection;
float cameraCorrection = cameraSensitivity * frameBasedCorrection;
while(SDL_PollEvent(&e)!=0){
if(e.type == SDL_QUIT){quit = true;}
else if(e.type == SDL_KEYDOWN && e.key.repeat == 0){
switch (e.key.keysym.sym){
case SDLK_w: lastPosFrontSpeed = cameraFront * movementCorrection;
cameraStep += lastPosFrontSpeed; break;
case SDLK_s: lastNegFrontSpeed = cameraFront * movementCorrection;
cameraStep -= lastNegFrontSpeed; break;
case SDLK_d: lastPosSideSpeed = glm::normalize(glm::cross(cameraFront, cameraUp)) * movementCorrection;
cameraStep += lastPosSideSpeed; break;
case SDLK_a: lastNegSideSpeed = glm::normalize(glm::cross(cameraFront, cameraUp)) * movementCorrection;
cameraStep -= lastNegSideSpeed; break;
}
}
else if(e.type == SDL_KEYDOWN && e.key.repeat > 0){
switch (e.key.keysym.sym){
case SDLK_w:
cameraStep -= lastPosFrontSpeed; lastPosFrontSpeed = cameraFront * movementCorrection;
cameraStep += lastPosFrontSpeed; break;
case SDLK_s:
cameraStep += lastNegFrontSpeed;lastNegFrontSpeed = cameraFront * movementCorrection;
cameraStep -= lastNegFrontSpeed; break;
case SDLK_d: cameraStep -= lastPosSideSpeed;
lastPosSideSpeed = glm::normalize(glm::cross(cameraFront, cameraUp)) * movementCorrection;
cameraStep += lastPosSideSpeed; break;
case SDLK_a: cameraStep += lastNegSideSpeed;
lastNegSideSpeed = glm::normalize(glm::cross(cameraFront, cameraUp)) * movementCorrection;
cameraStep -= lastNegSideSpeed; break;
}
}
else if(e.type == SDL_KEYUP && e.key.repeat == 0){
switch (e.key.keysym.sym){
case SDLK_w: cameraStep -= lastPosFrontSpeed; break;
case SDLK_s: cameraStep += lastNegFrontSpeed; break;
case SDLK_d: cameraStep -= lastPosSideSpeed; break;
case SDLK_a: cameraStep += lastNegSideSpeed; break;
}
}
else if(e.type == SDL_MOUSEMOTION){
int thisMouseX, thisMouseY;
SDL_GetMouseState(&thisMouseX,&thisMouseY);
if(thisMouseX > previousMouseX){
if(thisMouseX - previousMouseX < 200){
yaw += 1.f * cameraCorrection * (thisMouseX - previousMouseX);
}else{yaw += 1.f * cameraCorrection * (100);}
}
if(thisMouseX < previousMouseX ){
if(previousMouseX - thisMouseX < 200){
yaw -= 1.f * cameraCorrection * (previousMouseX - thisMouseX);
}else{yaw -= 1.f * cameraCorrection * 100;}
}
if(thisMouseY > previousMouseY && pitch > -80.f){
if(thisMouseY - previousMouseY < 100){
pitch -= 1.f * cameraCorrection * (thisMouseY-previousMouseY);
}else{pitch -= 1.f * cameraCorrection * 10.f;}
}
if(thisMouseY < previousMouseY && pitch < 80.f){
if(previousMouseY - thisMouseY < 100){
pitch+=1.f*cameraCorrection * (previousMouseY - thisMouseY);
}else{pitch+= 1.f* cameraCorrection * 10.f;}
}
previousMouseX = thisMouseX; previousMouseY = thisMouseY;
cameraFront = glm::vec3(cos(glm::radians(yaw)) * cos(glm::radians(pitch)),sin(glm::radians(pitch)),sin(glm::radians(yaw)) * cos(glm::radians(pitch)));
}
}
cameraPos += cameraStep ;
view = glm::lookAt(cameraPos,cameraPos + cameraFront, cameraUp);
glUniformMatrix4fv(viewLoc,1,GL_FALSE,glm::value_ptr(view));
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawElements(GL_TRIANGLES,36,GL_UNSIGNED_INT,0);
if(SDL_GetTicks() - thisTicks < ONE_FRAME_TIME){
SDL_Delay(ONE_FRAME_TIME- (SDL_GetTicks() - thisTicks));
}
SDL_GL_SwapWindow(gWindow);
}
}
}