void FPSCamera::FitToBox(const OpenGLAABox& box) { float look[3]; GLVec3Set(look, -view[2], -view[6], -view[10]); GLVec3Add(look, position, look); GLFitToBox(Near, Far, position, look, box); }
void Render(float alpha, float elapsedtime) { float world[16]; float tmp[16]; float view[16]; float proj[16]; float viewproj[16]; float eye[3] = { 0, 0.3f, 8 }; float look[3] = { 0, 0.3f, 0 }; float up[3] = { 0, 1, 0 }; float clipplanes[2]; float orient[2]; cameraangle.smooth(orient, alpha); GLMatrixRotationAxis(view, orient[1], 1, 0, 0); GLMatrixRotationAxis(tmp, orient[0], 0, 1, 0); GLMatrixMultiply(view, view, tmp); GLVec3Transform(eye, eye, view); GLFitToBox(clipplanes[0], clipplanes[1], eye, look, scenebox); GLMatrixPerspectiveFovRH(proj, (60.0f * 3.14159f) / 180.f, (float)screenwidth / (float)screenheight, clipplanes[0], clipplanes[1]); GLMatrixLookAtRH(view, eye, look, up); GLMatrixMultiply(viewproj, view, proj); // STEP 1: initialize header pointer buffer glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glDisable(GL_DEPTH_TEST); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, headbuffer); init->SetInt("screenWidth", screenwidth); init->Begin(); { screenquad->Draw(); } init->End(); // STEP 2: collect transparent fragments into lists glBindTexture(GL_TEXTURE_2D, white); glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, counterbuffer); GLuint* counter = (GLuint*)glMapBuffer(GL_ATOMIC_COUNTER_BUFFER, GL_WRITE_ONLY); *counter = 0; glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER); glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, nodebuffer); glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, counterbuffer); collect->SetMatrix("matView", view); collect->SetMatrix("matProj", proj); collect->SetInt("screenWidth", screenwidth); collect->Begin(); { GLMatrixIdentity(world); for( int i = 0; i < numobjects; ++i ) { const SceneObject& obj = objects[i]; // scaling * rotation * translation GLMatrixScaling(tmp, obj.scale[0], obj.scale[1], obj.scale[2]); GLMatrixRotationAxis(world, obj.angle, 0, 1, 0); GLMatrixMultiply(world, tmp, world); GLMatrixTranslation(tmp, obj.position[0], obj.position[1], obj.position[2]); GLMatrixMultiply(world, world, tmp); collect->SetMatrix("matWorld", world); collect->SetVector("matAmbient", &obj.color.r); collect->CommitChanges(); if( obj.type == 0 ) box->DrawSubset(0); else if( obj.type == 1 ) dragon->DrawSubset(0); else if( obj.type == 2 ) buddha->DrawSubset(0); } } collect->End(); glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, 0); // STEP 3: render glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_SRC_ALPHA); render->SetInt("screenWidth", screenwidth); render->Begin(); { screenquad->Draw(); } render->End(); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, 0); glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST); #ifdef _DEBUG // check errors GLenum err = glGetError(); if( err != GL_NO_ERROR ) std::cout << "Error\n"; #endif SwapBuffers(hdc); mousedx = mousedy = 0; }
void Render(float alpha, float elapsedtime) { float tmp[16]; float texmat[16]; float view[16]; float viewinv[16]; float proj[16]; float viewproj[16]; float lightview[16]; float lightproj[16]; float lightviewproj[16]; float globalambient[4] = { 0.01f, 0.01f, 0.01f, 1.0f }; float moonlight[] = { -0.25f, 0.65f, -1, 0 }; float mooncolor[] = { 0.6f, 0.6f, 1, 1 }; float eye[3] = { 0, 0, 8 }; float look[3] = { 0, 0, 0 }; float up[3] = { 0, 1, 0 }; float screensize[2] = { (float)screenwidth, (float)screenheight }; float lightclip[2]; float clipplanes[2]; float orient[2]; // setup camera cameraangle.smooth(orient, alpha); GLMatrixRotationAxis(view, orient[1], 1, 0, 0); GLMatrixRotationAxis(tmp, orient[0], 0, 1, 0); GLMatrixMultiply(view, view, tmp); GLVec3Transform(eye, eye, view); GLFitToBox(clipplanes[0], clipplanes[1], eye, look, scenebox); GLMatrixPerspectiveFovRH(proj, (60.0f * 3.14159f) / 180.f, (float)screenwidth / (float)screenheight, clipplanes[0], clipplanes[1]); GLMatrixLookAtRH(view, eye, look, up); GLMatrixMultiply(viewproj, view, proj); // setup moonlight GLMatrixInverse(viewinv, view); GLVec3Transform(moonlight, moonlight, viewinv); GLVec3Normalize(moonlight, moonlight); // should be that value in view space (background is fix) // but let y stay in world space, so we see shadow moonlight[1] = 0.65f; GLMatrixViewVector(lightview, moonlight); GLFitToBox(lightproj, lightclip, lightview, scenebox); GLMatrixMultiply(lightviewproj, lightview, lightproj); // render shadow map glClearColor(0, 0, 0, 1); varianceshadow->SetMatrix("matViewProj", lightviewproj); varianceshadow->SetVector("clipPlanes", lightclip); shadowmap->Set(); { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); varianceshadow->Begin(); { RenderScene(varianceshadow); } varianceshadow->End(); } shadowmap->Unset(); // blur it float texelsize[] = { 1.0f / SHADOWMAP_SIZE, 1.0f / SHADOWMAP_SIZE }; glDepthMask(GL_FALSE); glBindTexture(GL_TEXTURE_2D, shadowmap->GetColorAttachment(0)); boxblur3x3->SetVector("texelSize", texelsize); blurredshadow->Set(); { boxblur3x3->Begin(); { screenquad->Draw(); } boxblur3x3->End(); } blurredshadow->Unset(); glDepthMask(GL_TRUE); // STEP 1: z pass ambient->SetMatrix("matViewProj", viewproj); ambient->SetVector("matAmbient", globalambient); framebuffer->Set(); { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); // draw background first glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); glBindTexture(GL_TEXTURE_2D, texture3); float scaledx = 1360.0f * (screenheight / 768.0f); float scale = screenwidth / scaledx; GLMatrixTranslation(tmp, -0.5f, 0, 0); GLMatrixScaling(texmat, scale, 1, 1); GLMatrixMultiply(texmat, tmp, texmat); GLMatrixTranslation(tmp, 0.5f, 0, 0); GLMatrixMultiply(texmat, texmat, tmp); GLMatrixRotationAxis(tmp, M_PI, 0, 0, 1); GLMatrixMultiply(texmat, texmat, tmp); basic2D->SetMatrix("matTexture", texmat); basic2D->Begin(); { screenquad->Draw(); } basic2D->End(); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); // then fill zbuffer ambient->Begin(); { RenderScene(ambient); } ambient->End(); } framebuffer->Unset(); // STEP 2: cull lights if( lightcull && timeout > DELAY ) { lightcull->SetFloat("alpha", alpha); lightcull->SetVector("clipPlanes", clipplanes); lightcull->SetVector("screenSize", screensize); lightcull->SetMatrix("matProj", proj); lightcull->SetMatrix("matView", view); lightcull->SetMatrix("matViewProj", viewproj); glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, counterbuffer); GLuint* counter = (GLuint*)glMapBuffer(GL_ATOMIC_COUNTER_BUFFER, GL_WRITE_ONLY); *counter = 0; glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, headbuffer); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, nodebuffer); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, lightbuffer); glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, counterbuffer); glBindTexture(GL_TEXTURE_2D, framebuffer->GetDepthAttachment()); lightcull->Begin(); { glDispatchCompute(workgroupsx, workgroupsy, 1); } lightcull->End(); glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, 0); glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0); glBindTexture(GL_TEXTURE_2D, 0); } // STEP 3: add some moonlight with shadow glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); glDepthMask(GL_FALSE); framebuffer->Set(); shadowedlight->SetMatrix("matViewProj", viewproj); shadowedlight->SetMatrix("lightViewProj", lightviewproj); shadowedlight->SetVector("eyePos", eye); shadowedlight->SetVector("lightPos", moonlight); shadowedlight->SetVector("lightColor", mooncolor); shadowedlight->SetVector("clipPlanes", lightclip); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, blurredshadow->GetColorAttachment(0)); glActiveTexture(GL_TEXTURE0); shadowedlight->Begin(); { RenderScene(shadowedlight); } shadowedlight->End(); // STEP 4: accumulate lighting if( lightaccum && timeout > DELAY ) { lightaccum->SetMatrix("matViewProj", viewproj); lightaccum->SetVector("eyePos", eye); lightaccum->SetFloat("alpha", alpha); lightaccum->SetInt("numTilesX", workgroupsx); lightaccum->Begin(); { RenderScene(lightaccum); } lightaccum->End(); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, 0); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, 0); } framebuffer->Unset(); glDisable(GL_BLEND); glDepthMask(GL_TRUE); // STEP 4: gamma correct glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glBindTexture(GL_TEXTURE_2D, framebuffer->GetColorAttachment(0)); gammacorrect->Begin(); { screenquad->Draw(); } gammacorrect->End(); #ifdef _DEBUG // check errors GLenum err = glGetError(); if( err != GL_NO_ERROR ) std::cout << "Error\n"; #endif SwapBuffers(hdc); mousedx = mousedy = 0; }