FPSCamera::FPSCamera(CollisionWorld* world) { Aspect = 4.0f / 3.0f; Fov = GLDegreesToRadians(80); Near = 0.1f; Far = 50.0f; state = 0; body = 0; collworld = world; isonground = false; array_state_set(anglecurve, 0, 0, 0); GLVec3Set(position, 0, 1.8f, 0); GLVec3Set(targetangles, 0, 0, 0); GLVec3Set(smoothedangles, 0, 0, 0); GLMatrixIdentity(view); if( world ) { body = world->AddDynamicSphere(CAMERA_RADIUS, 80); body->SetPosition(0, 0.1f, 0); } }
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 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); }
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; }
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; }
void Render(float alpha, float elapsedtime) { float world[16]; float view[16]; float proj[16]; float eye[3]; basiccamera.Animate(alpha); basiccamera.GetViewMatrix(view); basiccamera.GetProjectionMatrix(proj); basiccamera.GetEyePosition(eye); GLVec4Set(uniformDTO.vsuniforms.lightPos, 6, 3, 10, 1); GLVec4Set(uniformDTO.vsuniforms.eyePos, eye[0], eye[1], eye[2], 1); GLMatrixMultiply(uniformDTO.vsuniforms.matViewProj, view, proj); GLMatrixScaling(uniformDTO.vsuniforms.matWorld, OBJECT_SCALE, OBJECT_SCALE, OBJECT_SCALE); switch( rendermethod ) { case 1: GLVec4Set(uniformDTO.fsuniforms.color, 1, 0, 0, 1); break; case 2: GLVec4Set(uniformDTO.fsuniforms.color, 1, 0.5f, 0, 1); break; case 3: GLVec4Set(uniformDTO.fsuniforms.color, 1, 1, 0, 1); break; case 4: GLVec4Set(uniformDTO.fsuniforms.color, 0, 0.75f, 0, 1); break; case 5: GLVec4Set(uniformDTO.fsuniforms.color, 0, 1, 0, 1); break; default: break; } // render pass OpenGLEffect* effect = ((rendermethod > 1) ? effect2 : effect1); GLsync sync = 0; if( rendermethod == 1 ) { effect1->SetMatrix("matViewProj", uniformDTO.vsuniforms.matViewProj); effect1->SetVector("lightPos", uniformDTO.vsuniforms.lightPos); effect1->SetVector("eyePos", uniformDTO.vsuniforms.eyePos); effect1->SetVector("color", uniformDTO.fsuniforms.color); } framebuffer->Set(); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); effect->Begin(); { for( int i = 0; i < GRID_SIZE; ++i ) { for( int j = 0; j < GRID_SIZE; ++j ) { for( int k = 0; k < GRID_SIZE; ++k ) { if( currentcopy >= UNIFORM_COPIES ) { if( rendermethod == 4 || rendermethod == 2 ) { sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); } else if( rendermethod == 5 ) { glBindBuffer(GL_UNIFORM_BUFFER, uniformbuffer3); glUnmapBuffer(GL_UNIFORM_BUFFER); persistentdata = (EffectUniformBlock*)glMapBufferRange(GL_UNIFORM_BUFFER, 0, UNIFORM_COPIES * sizeof(EffectUniformBlock), GL_MAP_WRITE_BIT|GL_MAP_INVALIDATE_BUFFER_BIT|GL_MAP_PERSISTENT_BIT|GL_MAP_COHERENT_BIT); assert(persistentdata != 0); glBindBuffer(GL_UNIFORM_BUFFER, 0); currentcopy = 0; } } uniformDTO.vsuniforms.matWorld[12] = GRID_SIZE * -0.5f + i; uniformDTO.vsuniforms.matWorld[13] = GRID_SIZE * -0.5f + j; uniformDTO.vsuniforms.matWorld[14] = GRID_SIZE * -0.5f + k; if( rendermethod == 1 ) { effect1->SetMatrix("matWorld", uniformDTO.vsuniforms.matWorld); effect1->CommitChanges(); } else { if( rendermethod == 2 ) { if( sync != 0 ) { glWaitSync(sync, 0, GL_TIMEOUT_IGNORED); glDeleteSync(sync); sync = 0; } glBindBuffer(GL_UNIFORM_BUFFER, uniformbuffer1); glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(EffectUniformBlock), &uniformDTO); glBindBufferRange(GL_UNIFORM_BUFFER, 0, uniformbuffer1, 0, sizeof(EffectUniformBlock::VertexUniformData)); glBindBufferRange(GL_UNIFORM_BUFFER, 1, uniformbuffer1, offsetof(EffectUniformBlock, fsuniforms), sizeof(EffectUniformBlock::FragmentUniformData)); } else if( rendermethod == 3 ) { glBindBuffer(GL_UNIFORM_BUFFER, uniformbuffer1); void* data = glMapBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(EffectUniformBlock), GL_MAP_WRITE_BIT|GL_MAP_INVALIDATE_RANGE_BIT); { memcpy(data, &uniformDTO, sizeof(EffectUniformBlock)); } glUnmapBuffer(GL_UNIFORM_BUFFER); glBindBufferRange(GL_UNIFORM_BUFFER, 0, uniformbuffer1, 0, sizeof(EffectUniformBlock::VertexUniformData)); glBindBufferRange(GL_UNIFORM_BUFFER, 1, uniformbuffer1, offsetof(EffectUniformBlock, fsuniforms), sizeof(EffectUniformBlock::FragmentUniformData)); } else if( rendermethod == 4 ) { GLintptr baseoffset = currentcopy * sizeof(EffectUniformBlock); GLbitfield flags = GL_MAP_WRITE_BIT|GL_MAP_INVALIDATE_RANGE_BIT|GL_MAP_UNSYNCHRONIZED_BIT; if( sync != 0 ) { GLenum result = 0; GLbitfield waitflags = GL_SYNC_FLUSH_COMMANDS_BIT; do { result = glClientWaitSync(sync, waitflags, 500000); waitflags = 0; if( result == GL_WAIT_FAILED ) { std::cout << "glClientWaitSync() failed!\n"; break; } } while( result == GL_TIMEOUT_EXPIRED ); glDeleteSync(sync); sync = 0; currentcopy = 0; baseoffset = 0; } glBindBuffer(GL_UNIFORM_BUFFER, uniformbuffer2); void* data = glMapBufferRange(GL_UNIFORM_BUFFER, baseoffset, sizeof(EffectUniformBlock), flags); assert(data != 0); { memcpy(data, &uniformDTO, sizeof(EffectUniformBlock)); } glUnmapBuffer(GL_UNIFORM_BUFFER); glBindBufferRange(GL_UNIFORM_BUFFER, 0, uniformbuffer2, baseoffset, sizeof(EffectUniformBlock::VertexUniformData)); glBindBufferRange(GL_UNIFORM_BUFFER, 1, uniformbuffer2, baseoffset + offsetof(EffectUniformBlock, fsuniforms), sizeof(EffectUniformBlock::FragmentUniformData)); ++currentcopy; } else if( rendermethod == 5 ) { GLintptr baseoffset = currentcopy * sizeof(EffectUniformBlock); memcpy(persistentdata + currentcopy, &uniformDTO, sizeof(EffectUniformBlock)); glBindBufferRange(GL_UNIFORM_BUFFER, 0, uniformbuffer3, baseoffset, sizeof(EffectUniformBlock::VertexUniformData)); glBindBufferRange(GL_UNIFORM_BUFFER, 1, uniformbuffer3, baseoffset + offsetof(EffectUniformBlock, fsuniforms), sizeof(EffectUniformBlock::FragmentUniformData)); ++currentcopy; } } mesh->DrawSubset(0); } } } } effect->End(); framebuffer->Unset(); // present GLMatrixIdentity(world); glDisable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); basic2D->SetMatrix("matTexture", world); basic2D->Begin(); { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, framebuffer->GetColorAttachment(0)); screenquad->Draw(); } basic2D->End(); // render text glViewport(5, screenheight - 517, 512, 512); 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->Begin(); { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, text1); screenquad->Draw(); } basic2D->End(); glEnable(GL_DEPTH_TEST); glDisable(GL_BLEND); glViewport(0, 0, screenwidth, screenheight); // check errors GLenum err = glGetError(); if( err != GL_NO_ERROR ) std::cout << "Error\n"; SwapBuffers(hdc); }
bool InitScene() { SetWindowText(hwnd, TITLE); Quadron::qGLExtensions::QueryFeatures(); //CalculateSphereTetrahedron(4, 0.5f); // setup opengl glClearColor(0, 0, 0, 1); glClearDepth(1.0); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glDepthFunc(GL_LEQUAL); glEnable(GL_DEPTH_TEST); // create render targets for reference rendertargets[0] = new OpenGLFramebuffer(screenwidth, screenheight); rendertargets[1] = new OpenGLFramebuffer(screenwidth, screenheight); rendertargets[0]->AttachTexture(GL_COLOR_ATTACHMENT0, GLFMT_A32B32G32R32F, GL_NEAREST); rendertargets[1]->AttachTexture(GL_COLOR_ATTACHMENT0, GLFMT_A32B32G32R32F, GL_NEAREST); GL_ASSERT(rendertargets[0]->Validate()); GL_ASSERT(rendertargets[1]->Validate()); GLint value = 0; float white[] = { 1, 1, 1, 1 }; gbuffer = new OpenGLFramebuffer(screenwidth, screenheight); gbuffer->AttachTexture(GL_COLOR_ATTACHMENT0, GLFMT_A8B8G8R8_sRGB, GL_NEAREST); // color gbuffer->AttachTexture(GL_COLOR_ATTACHMENT1, GLFMT_A16B16G16R16F, GL_NEAREST); // normals gbuffer->AttachTexture(GL_COLOR_ATTACHMENT2, GLFMT_R32F, GL_NEAREST); // depth gbuffer->AttachTexture(GL_COLOR_ATTACHMENT3, GLFMT_G16R16F, GL_NEAREST); // velocity glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, white); gbuffer->AttachRenderbuffer(GL_DEPTH_STENCIL_ATTACHMENT, GLFMT_D24S8); GL_ASSERT(gbuffer->Validate()); glBindFramebuffer(GL_FRAMEBUFFER, gbuffer->GetFramebuffer()); { glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, &value); GL_ASSERT(value == GL_SRGB); glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, &value); GL_ASSERT(value == GL_LINEAR); glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, &value); GL_ASSERT(value == GL_LINEAR); } glBindFramebuffer(GL_FRAMEBUFFER, 0); // load shaders if( !GLCreateEffectFromFile("../media/shadersGL/AOpathtracer.vert", 0, "../media/shadersGL/AOpathtracer.frag", &pathtracer) ) { MYERROR("Could not load 'path tracer' shader"); return false; } if( !GLCreateEffectFromFile("../media/shadersGL/AOpathtracer.vert", 0, "../media/shadersGL/AOpathtracer.frag", &refgbuffereffect, "#define RENDER_GBUFFER\n") ) { MYERROR("Could not load 'gbuffer' shader"); return false; } if( !GLCreateEffectFromFile("../media/shadersGL/basic2D.vert", 0, "../media/shadersGL/gtao.frag", &refgtaoeffect, "#define NUM_DIRECTIONS 32\n#define NUM_STEPS 16\n") ) { MYERROR("Could not load 'GTAO' shader"); return false; } if( !GLCreateEffectFromFile("../media/shadersGL/basic2D.vert", 0, "../media/shadersGL/gtaocombine.frag", &combineeffect) ) { MYERROR("Could not load 'combine' shader"); return false; } if( !GLCreateEffectFromFile("../media/shadersGL/basic2D.vert", 0, "../media/shadersGL/basic2D.frag", &presenteffect) ) { MYERROR("Could not load 'basic2D' shader"); return false; } float id[16]; GLMatrixIdentity(id); presenteffect->SetMatrix("matTexture", id); refgtaoeffect->SetMatrix("matTexture", id); combineeffect->SetInt("sampler0", 0); combineeffect->SetInt("sampler1", 1); refgtaoeffect->SetInt("gbufferDepth", 0); refgtaoeffect->SetInt("gbufferNormals", 1); refgtaoeffect->SetInt("noise", 2); screenquad = new OpenGLScreenQuad(); // render text GLCreateTexture(512, 512, 1, GLFMT_A8B8G8R8, &text1); GLRenderText( "Use the mouse to rotate camera\n\nP - Toggle path tracer\nH - Toggle help text", text1, 512, 512); // setup camera orbitcamera.SetAspect((float)screenwidth / (float)screenheight); orbitcamera.SetFov(GL_PI / 4.0f); orbitcamera.SetPosition(0, 1.633f, 0); orbitcamera.SetOrientation(GLDegreesToRadians(135), GLDegreesToRadians(30), 0); orbitcamera.SetDistance(6); orbitcamera.SetClipPlanes(0.1f, 20); return true; }
void Render(float alpha, float elapsedtime) { static float time = 0; float world[16]; float view[16]; float proj[16]; float viewproj[16]; float viewinv[16]; float viewprojinv[16]; float eye[3]; float clip[4] = { 0, 0, 0, 0 }; orbitcamera.Animate(alpha); orbitcamera.GetViewMatrix(view); orbitcamera.GetProjectionMatrix(proj); orbitcamera.GetEyePosition(eye); clip[0] = orbitcamera.GetNearPlane(); clip[1] = orbitcamera.GetFarPlane(); GLMatrixInverse(viewinv, view); GLMatrixMultiply(viewproj, view, proj); GLMatrixInverse(viewprojinv, viewproj); glViewport(0, 0, screenwidth, screenheight); if( userefgtao ) { // using the reference spheres with GTAO refgbuffereffect->SetMatrix("matView", view); refgbuffereffect->SetMatrix("matViewInv", viewinv); refgbuffereffect->SetMatrix("matViewProjInv", viewprojinv); refgbuffereffect->SetVector("eyePos", eye); refgbuffereffect->SetVector("clipPlanes", clip); RenderReferenceWithGTAO(proj, clip, eye); } else { // using the reference spheres with path tracing RenderReferenceWithPathTracing(viewprojinv, eye, time); } if( drawtext ) { // render text glViewport(5, screenheight - 517, 512, 512); 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); presenteffect->SetMatrix("matTexture", world); presenteffect->Begin(); { glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, text1); screenquad->Draw(); } presenteffect->End(); glEnable(GL_DEPTH_TEST); glDisable(GL_BLEND); GLMatrixIdentity(world); presenteffect->SetMatrix("matTexture", world); } time += elapsedtime; #ifdef _DEBUG GLenum err = glGetError(); if( err != GL_NO_ERROR ) std::cout << "Error\n"; #endif SwapBuffers(hdc); }
//************************************************************************************************************* 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; }