void Window1_Render(Win32Window* window, float alpha, float elapsedtime) { static float time = 0; float world[16]; time += elapsedtime; DrawingItem* drawingitem = window->GetDrawingItem(); DrawingLayer& bottomlayer = drawingitem->GetBottomLayer(); { NativeContext context = bottomlayer.GetContext(); float bigradius = 150; float smallradius = 80; float m2pi = 6.293185f; int segments = 16; GLMatrixRotationAxis(world, fmodf(time * 20.0f, 360.0f) * (3.14152f / 180.0f), 0, 0, 1); context.Clear(OpenGLColor(0.0f, 0.125f, 0.3f, 1.0f)); context.SetWorldTransform(world); context.MoveTo(0, bigradius); for( int i = 1; i <= segments; ++i ) { if( i % 2 == 1 ) { context.LineTo( sinf((m2pi / segments) * i) * smallradius, cosf((m2pi / segments) * i) * smallradius); } else { context.LineTo( sinf((m2pi / segments) * i) * bigradius, cosf((m2pi / segments) * i) * bigradius); } } } DrawingLayer& feedbacklayer = drawingitem->GetFeedbackLayer(); { NativeContext context = feedbacklayer.GetContext(); GLMatrixRotationAxis(world, -fmodf(time * 20.0f, 360.0f) * (3.14152f / 180.0f), 0, 0, 1); context.Clear(OpenGLColor(0, 0, 0, 0)); context.SetWorldTransform(world); context.SetColor(OpenGLColor(0, 1, 0, 1)); context.MoveTo(-120, 120); context.LineTo(120, 120); context.LineTo(120, -120); context.LineTo(-120, -120); context.LineTo(-120, 120); } drawingitem->RecomposeLayers(); }
void Render(float alpha, float elapsedtime) { static float time = 0; float lightpos[4] = { 6, 3, 10, 1 }; float eye[3] = { 0, 0, 3 }; float look[3] = { 0, 0, 0 }; float up[3] = { 0, 1, 0 }; float view[16]; float proj[16]; float world[16]; float viewproj[16]; float tmp1[16]; float tmp2[16]; glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); GLMatrixLookAtRH(view, eye, look, up); GLMatrixPerspectiveFovRH(proj, (60.0f * 3.14159f) / 180.f, (float)screenwidth / (float)screenheight, 0.1f, 100.0f); GLMatrixMultiply(viewproj, view, proj); //calculate world matrix GLMatrixIdentity(tmp2); tmp2[12] = -0.108f; // offset with bb center tmp2[13] = -0.7875f; // offset with bb center GLMatrixRotationAxis(tmp1, fmodf(time * 20.0f, 360.0f) * (3.14152f / 180.0f), 1, 0, 0); GLMatrixMultiply(world, tmp2, tmp1); GLMatrixRotationAxis(tmp2, fmodf(time * 20.0f, 360.0f) * (3.14152f / 180.0f), 0, 1, 0); GLMatrixMultiply(world, world, tmp2); // render time += elapsedtime; glUseProgram(program); glUniform4fv(uniform_eyePos, 1, eye); glUniform4fv(uniform_lightPos, 1, lightpos); glUniformMatrix4fv(uniform_matWorld, 1, false, world); glUniformMatrix4fv(uniform_matViewProj, 1, false, viewproj); { mesh->DrawSubset(0); } glUseProgram(0); // check errors GLenum err = glGetError(); if( err != GL_NO_ERROR ) std::cout << "Error\n"; SwapBuffers(hdc); }
void FPSCamera::GetViewVectors(float forward[3], float right[3], float up[3]) { float yaw[16]; float pitch[16]; // TODO: rollpitchyaw GLMatrixRotationAxis(yaw, anglecurve.curr[0], 0, 1, 0); GLMatrixRotationAxis(pitch, anglecurve.curr[1], 1, 0, 0); GLMatrixMultiply(view, yaw, pitch); GLVec3Set(forward, -view[2], -view[6], -view[10]); GLVec3Set(right, view[0], view[4], view[8]); GLVec3Set(up, view[1], view[5], view[9]); }
void Window2_Render(Win32Window* window, float alpha, float elapsedtime) { static float time = 0; float world[16]; time += elapsedtime; DrawingItem* drawingitem = window->GetDrawingItem(); DrawingLayer& bottomlayer = drawingitem->GetBottomLayer(); { NativeContext context = bottomlayer.GetContext(); GLMatrixRotationAxis(world, -fmodf(time * 20.0f, 360.0f) * (3.14152f / 180.0f), 0, 0, 1); context.Clear(OpenGLColor(0.0f, 0.125f, 0.3f, 1.0f)); context.SetWorldTransform(world); context.SetColor(OpenGLColor(1, 1, 1, 1)); context.MoveTo(-120, 120); context.LineTo(120, 120); context.LineTo(120, -120); context.LineTo(-120, -120); context.LineTo(-120, 120); } drawingitem->RecomposeLayers(); }
void FPSCamera::Animate(float alpha) { anglecurve.smooth(smoothedangles, alpha); body->GetInterpolatedPosition(position, alpha); position[1] += (1.8f - CAMERA_RADIUS); // recalculate view matrix float yaw[16]; float pitch[16]; // TODO: rollpitchyaw GLMatrixRotationAxis(yaw, smoothedangles[0], 0, 1, 0); GLMatrixRotationAxis(pitch, smoothedangles[1], 1, 0, 0); GLMatrixMultiply(view, yaw, pitch); view[12] = -(position[0] * view[0] + position[1] * view[4] + position[2] * view[8]); view[13] = -(position[0] * view[1] + position[1] * view[5] + position[2] * view[9]); view[14] = -(position[0] * view[2] + position[1] * view[6] + position[2] * view[10]); }
void RenderScene(OpenGLEffect* effect) { float world[16]; float worldinv[16]; float tmp[16]; GLMatrixIdentity(world); for( int i = 0; i < numobjects; ++i ) { const SceneObject& obj = objects[i]; 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); GLMatrixInverse(worldinv, world); effect->SetMatrix("matWorld", world); effect->SetMatrix("matWorldInv", worldinv); if( obj.type == 0 ) { float uv[] = { 2, 2, 0, 1 }; effect->SetVector("uv", uv); effect->CommitChanges(); glBindTexture(GL_TEXTURE_2D, texture1); box->DrawSubset(0); } else if( obj.type == 1 ) { float uv[] = { 1, 1, 0, 1 }; effect->SetVector("uv", uv); effect->CommitChanges(); glBindTexture(GL_TEXTURE_2D, texture2); teapot->DrawSubset(0); } } glBindTexture(GL_TEXTURE_2D, 0); }
void THREAD_Run() { float world[16]; float time = 0; while( true ) { if( !glwindow ) continue; DrawingItem* drawingitem = glwindow->GetDrawingItem(); DrawingLayer& feedbacklayer = drawingitem->GetFeedbackLayer(); { NativeContext context = feedbacklayer.GetContext(); float bigradius = 150; float smallradius = 80; float m2pi = 6.293185f; int segments = 16; GLMatrixRotationAxis(world, fmodf(time * 20.0f, 360.0f) * (3.14152f / 180.0f), 0, 0, 1); context.Clear(OpenGLColor(0, 0, 0, 0)); context.SetWorldTransform(world); context.SetColor(OpenGLColor(0, 1, 0, 1)); context.MoveTo(0, bigradius); for( int i = 1; i <= segments; ++i ) { if( i % 2 == 1 ) { context.LineTo( sinf((m2pi / segments) * i) * smallradius, cosf((m2pi / segments) * i) * smallradius); } else { context.LineTo( sinf((m2pi / segments) * i) * bigradius, cosf((m2pi / segments) * i) * bigradius); } } } time += 0.5f; Sleep(500); // 34 } }
bool InitScene() { SetWindowText(hwnd, TITLE); Quadron::qGLExtensions::QueryFeatures(hdc); if( !Quadron::qGLExtensions::ARB_shader_storage_buffer_object ) return false; #ifdef _DEBUG if( Quadron::qGLExtensions::ARB_debug_output ) { glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0, GL_TRUE); glDebugMessageCallback(ReportGLError, 0); } #endif glClearColor(0.0f, 0.125f, 0.3f, 1.0f); //glClearColor(1, 1, 1, 1); glClearDepth(1.0); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glDepthFunc(GL_LEQUAL); glEnable(GL_DEPTH_TEST); screenquad = new OpenGLScreenQuad(); // load objects if( !GLCreateMeshFromQM("../media/meshes/cube.qm", &box) ) { MYERROR("Could not load box"); return false; } if( !GLCreateMeshFromQM("../media/meshes/dragon.qm", &dragon) ) { MYERROR("Could not load dragon"); return false; } if( !GLCreateMeshFromQM("../media/meshes/happy1.qm", &buddha) ) { MYERROR("Could not load buddha"); return false; } // create texture glGenTextures(1, &white); glBindTexture(GL_TEXTURE_2D, white); { unsigned int wondercolor = 0xffffffff; glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, &wondercolor); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } // create buffers size_t headsize = 16; // start, count, pad, pad size_t nodesize = 16; // color, depth, next, pad size_t numlists = screenwidth * screenheight; glGenBuffers(1, &headbuffer); glGenBuffers(1, &nodebuffer); glGenBuffers(1, &counterbuffer); glBindBuffer(GL_SHADER_STORAGE_BUFFER, headbuffer); glBufferData(GL_SHADER_STORAGE_BUFFER, numlists * headsize, 0, GL_STATIC_DRAW); glBindBuffer(GL_SHADER_STORAGE_BUFFER, nodebuffer); glBufferData(GL_SHADER_STORAGE_BUFFER, numlists * 4 * nodesize, 0, GL_STATIC_DRAW); // 120 MB @ 1080p glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, counterbuffer); glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), 0, GL_DYNAMIC_DRAW); glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0); // calculate scene bounding box OpenGLAABox tmpbox; float world[16]; float tmp[16]; 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); if( obj.type == 0 ) tmpbox = box->GetBoundingBox(); else if( obj.type == 1 ) tmpbox = dragon->GetBoundingBox(); else if( obj.type == 2 ) tmpbox = buddha->GetBoundingBox(); tmpbox.TransformAxisAligned(world); scenebox.Add(tmpbox.Min); scenebox.Add(tmpbox.Max); } // head pointer initializer if( !GLCreateEffectFromFile("../media/shadersGL/basic2D.vert", 0, "../media/shadersGL/initheadpointers.frag", &init) ) { MYERROR("Could not load initializer shader"); return false; } // renderer shader if( !GLCreateEffectFromFile("../media/shadersGL/basic2D.vert", 0, "../media/shadersGL/renderfragments.frag", &render) ) { MYERROR("Could not load rendering shader"); return false; } // fragment collector shader if( !GLCreateEffectFromFile("../media/shadersGL/collectfragments.vert", 0, "../media/shadersGL/collectfragments.frag", &collect) ) { MYERROR("Could not load collector shader"); return false; } float angles[2] = { 0.25f, -0.7f }; cameraangle = angles; return true; }
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; }
bool InitScene() { SetWindowText(hwnd, TITLE); Quadron::qGLExtensions::QueryFeatures(hdc); hascompute = (Quadron::qGLExtensions::ARB_compute_shader && Quadron::qGLExtensions::ARB_shader_storage_buffer_object); #ifdef _DEBUG if( Quadron::qGLExtensions::ARB_debug_output ) { glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0, GL_TRUE); glDebugMessageCallback(ReportGLError, 0); } #endif glClearColor(0.0f, 0.125f, 0.3f, 1.0f); glClearDepth(1.0); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glDepthFunc(GL_LEQUAL); glEnable(GL_DEPTH_TEST); // load objects if( !GLCreateMeshFromQM("../media/meshes/teapot.qm", &teapot) ) { MYERROR("Could not load teapot"); return false; } if( !GLCreateMeshFromQM("../media/meshes/cube.qm", &box) ) { MYERROR("Could not load box"); return false; } // calculate scene bounding box OpenGLAABox tmpbox; float world[16]; float tmp[16]; 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); if( obj.type == 0 ) tmpbox = box->GetBoundingBox(); else if( obj.type == 1 ) tmpbox = teapot->GetBoundingBox(); tmpbox.TransformAxisAligned(world); scenebox.Add(tmpbox.Min); scenebox.Add(tmpbox.Max); } // create render targets framebuffer = new OpenGLFramebuffer(screenwidth, screenheight); framebuffer->AttachTexture(GL_COLOR_ATTACHMENT0, GLFMT_A16B16G16R16F); framebuffer->AttachTexture(GL_DEPTH_ATTACHMENT, GLFMT_D32F); if( !framebuffer->Validate() ) return false; shadowmap = new OpenGLFramebuffer(SHADOWMAP_SIZE, SHADOWMAP_SIZE); shadowmap->AttachTexture(GL_COLOR_ATTACHMENT0, GLFMT_G32R32F, GL_LINEAR); shadowmap->AttachRenderbuffer(GL_DEPTH_ATTACHMENT, GLFMT_D24S8); if( !shadowmap->Validate() ) return false; blurredshadow = new OpenGLFramebuffer(SHADOWMAP_SIZE, SHADOWMAP_SIZE); blurredshadow->AttachTexture(GL_COLOR_ATTACHMENT0, GLFMT_G32R32F, GL_LINEAR); if( !blurredshadow->Validate() ) return false; screenquad = new OpenGLScreenQuad(); // textures if( !GLCreateTextureFromFile("../media/textures/wood2.jpg", true, &texture1) ) { MYERROR("Could not load texture"); return false; } if( !GLCreateTextureFromFile("../media/textures/marble2.png", true, &texture2) ) { MYERROR("Could not load texture"); return false; } if( !GLCreateTextureFromFile("../media/textures/static_sky.jpg", true, &texture3, GLTEX_FLIPX) ) { MYERROR("Could not load texture"); return false; } // create buffers workgroupsx = (screenwidth + (screenwidth % 16)) / 16; workgroupsy = (screenheight + (screenheight % 16)) / 16; size_t numtiles = workgroupsx * workgroupsy; size_t headsize = 16; // start, count, pad, pad size_t nodesize = 16; // light index, next, pad, pad if( hascompute ) { glGenBuffers(1, &headbuffer); glGenBuffers(1, &nodebuffer); glGenBuffers(1, &lightbuffer); glGenBuffers(1, &counterbuffer); glBindBuffer(GL_SHADER_STORAGE_BUFFER, headbuffer); glBufferData(GL_SHADER_STORAGE_BUFFER, numtiles * headsize, 0, GL_STATIC_DRAW); glBindBuffer(GL_SHADER_STORAGE_BUFFER, nodebuffer); glBufferData(GL_SHADER_STORAGE_BUFFER, numtiles * nodesize * 1024, 0, GL_STATIC_DRAW); // 4 MB glBindBuffer(GL_SHADER_STORAGE_BUFFER, lightbuffer); glBufferData(GL_SHADER_STORAGE_BUFFER, NUM_LIGHTS * sizeof(LightParticle), 0, GL_DYNAMIC_DRAW); UpdateParticles(0, true); glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, counterbuffer); glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), 0, GL_DYNAMIC_DRAW); glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0); } // load effects if( !GLCreateEffectFromFile("../media/shadersGL/basic2D.vert", 0, "../media/shadersGL/basic2D.frag", &basic2D) ) { MYERROR("Could not load basic 2D shader"); return false; } if( !GLCreateEffectFromFile("../media/shadersGL/basic2D.vert", 0, "../media/shadersGL/boxblur3x3.frag", &boxblur3x3) ) { MYERROR("Could not load blur shader"); return false; } if( !GLCreateEffectFromFile("../media/shadersGL/basic2D.vert", 0, "../media/shadersGL/gammacorrect.frag", &gammacorrect) ) { MYERROR("Could not load gamma correction shader"); return false; } if( !GLCreateEffectFromFile("../media/shadersGL/shadowmap_variance.vert", 0, "../media/shadersGL/shadowmap_variance.frag", &varianceshadow) ) { MYERROR("Could not load shadowmap shader"); return false; } if( !GLCreateEffectFromFile("../media/shadersGL/blinnphong_variance.vert", 0, "../media/shadersGL/blinnphong_variance.frag", &shadowedlight) ) { MYERROR("Could not load shadowed light shader"); return false; } if( !GLCreateEffectFromFile("../media/shadersGL/ambient.vert", 0, "../media/shadersGL/ambient.frag", &ambient) ) { MYERROR("Could not load ambient shader"); return false; } if( hascompute ) { // light accumulation shader if( !GLCreateEffectFromFile("../media/shadersGL/lightaccum.vert", 0, "../media/shadersGL/lightaccum.frag", &lightaccum) ) { MYERROR("Could not load light accumulation shader"); return false; } // light culling shader if( !GLCreateComputeProgramFromFile("../media/shadersGL/lightcull.comp", &lightcull) ) { MYERROR("Could not load light culling shader"); return false; } lightcull->SetInt("depthSampler", 0); lightcull->SetInt("numLights", NUM_LIGHTS); lightaccum->SetInt("sampler0", 0); } float white[] = { 1, 1, 1, 1 }; shadowedlight->SetVector("matSpecular", white); shadowedlight->SetInt("sampler0", 0); shadowedlight->SetInt("sampler1", 1); boxblur3x3->SetInt("sampler0", 0); basic2D->SetInt("sampler0", 0); gammacorrect->SetInt("sampler0", 0); float angles[2] = { 0.25f, -0.7f }; cameraangle = angles; return true; }