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; }
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) { OpenGLColor grcolor(0xffdddddd); OpenGLColor cvcolor(0xff7470ff); OpenGLColor splinecolor(0xff000000); OpenGLColor outsidecolor(0.75f, 0.75f, 0.8f, 1); OpenGLColor insidecolor(1, 0.66f, 0.066f, 1); float world[16]; float view[16]; float proj[16]; float viewproj[16]; float pointsize[2] = { 10.0f / screenwidth, 10.0f / screenheight }; float grthickness[2] = { 1.5f / screenwidth, 1.5f / screenheight }; float cvthickness[2] = { 2.0f / screenwidth, 2.0f / screenheight }; float spthickness[2] = { 3.0f / screenwidth, 3.0f / screenheight }; float spviewport[] = { 0, 0, (float)screenwidth, (float)screenheight }; float eye[3] = { 5, 4, 15 }; float look[3] = { 5, 4, 5 }; float up[3] = { 0, 1, 0 }; float lightdir[4] = { 0, 1, 0, 0 }; float fwd[3]; float orient[2]; // play with ortho matrix instead of viewport (line thickness remains constant) ConvertToSplineViewport(spviewport[0], spviewport[1]); ConvertToSplineViewport(spviewport[2], spviewport[3]); GLMatrixIdentity(world); GLMatrixOrthoRH(proj, spviewport[0], spviewport[2], spviewport[1], spviewport[3], -1, 1); glViewport(0, 0, screenwidth, screenheight); glClearColor(1, 1, 1, 1); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glDisable(GL_DEPTH_TEST); renderlines->SetMatrix("matViewProj", proj); renderlines->SetMatrix("matWorld", world); renderlines->SetVector("color", &grcolor.r); renderlines->SetVector("lineThickness", grthickness); renderlines->Begin(); { supportlines->DrawSubset(0); renderlines->SetVector("color", &cvcolor.r); renderlines->SetVector("lineThickness", cvthickness); renderlines->CommitChanges(); supportlines->DrawSubset(1); if( hascompute ) { renderlines->SetVector("lineThickness", spthickness); renderlines->SetVector("color", &splinecolor.r); renderlines->CommitChanges(); curve->DrawSubset(0); } } renderlines->End(); renderpoints->SetMatrix("matViewProj", proj); renderpoints->SetMatrix("matWorld", world); renderpoints->SetVector("color", &cvcolor.r); renderpoints->SetVector("pointSize", pointsize); renderpoints->Begin(); { glBindVertexArray(supportlines->GetVertexLayout()); glDrawArrays(GL_POINTS, 44, numcontrolvertices); } renderpoints->End(); // render surface in a smaller viewport if( !fullscreen ) { glEnable(GL_SCISSOR_TEST); glScissor(screenwidth - surfvpwidth - 10, screenheight - surfvpheight - 10, surfvpwidth, surfvpheight); } glClearColor(0.0f, 0.125f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glDisable(GL_SCISSOR_TEST); glEnable(GL_DEPTH_TEST); if( fullscreen ) glViewport(0, 0, screenwidth, screenheight); else glViewport(screenwidth - surfvpwidth - 10, screenheight - surfvpheight - 10, surfvpwidth, surfvpheight); cameraangle.smooth(orient, alpha); GLVec3Subtract(fwd, look, eye); GLMatrixRotationYawPitchRoll(view, orient[0], orient[1], 0); GLVec3Transform(fwd, fwd, view); GLVec3Subtract(eye, look, fwd); GLMatrixPerspectiveRH(proj, M_PI / 3, 4.0f / 3.0f, 0.1f, 50.0f); GLMatrixLookAtRH(view, eye, look, up); GLMatrixMultiply(viewproj, view, proj); if( wireframe ) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glDisable(GL_CULL_FACE); if( hascompute ) { rendersurface->SetMatrix("matViewProj", viewproj); rendersurface->SetMatrix("matWorld", world); rendersurface->SetMatrix("matWorldInv", world); // its id rendersurface->SetVector("lightDir", lightdir); rendersurface->SetVector("eyePos", eye); rendersurface->SetVector("outsideColor", &outsidecolor.r); rendersurface->SetVector("insideColor", &insidecolor.r); rendersurface->SetInt("isWireMode", wireframe); rendersurface->Begin(); { surface->DrawSubset(0); } rendersurface->End(); } glEnable(GL_CULL_FACE); if( wireframe ) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // render text if( !fullscreen ) { glViewport(3, 0, 800, 130); glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); float xzplane[4] = { 0, 1, 0, -0.5f }; GLMatrixReflect(world, xzplane); basic2D->SetMatrix("matTexture", world); basic2D->SetInt("sampler0", 0); basic2D->Begin(); { glBindTexture(GL_TEXTURE_2D, text1); screenquad->Draw(); } basic2D->End(); glEnable(GL_DEPTH_TEST); glDisable(GL_BLEND); } #ifdef _DEBUG // check errors GLenum err = glGetError(); if( err != GL_NO_ERROR ) std::cout << "Error\n"; #endif SwapBuffers(hdc); mousedx = mousedy = 0; }