//Render lighting on geometry in gbuffer
void DeferredLightingPass::render(glm::mat4 proj, glm::mat4 view, GBuffer* gBuffer, std::vector<std::shared_ptr<SceneNode>> nodes, std::vector<std::shared_ptr<Light>> lights) {
    
    glDepthMask(GL_FALSE);
    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE);
    
    resultBuffer->bind();
    glClear(GL_COLOR_BUFFER_BIT);
    
    
    gBuffer->bindAttachments();
    
    glm::mat4 mat1 = glm::mat4(1.0f);
    
    for(auto it = lights.begin(); it != lights.end(); it++) {
        std::shared_ptr<Light> light = (*it);
        
        shadowPass.render(proj, view, nodes, light);
        
        // Restore gl states after shadow pass
        glDepthMask(GL_FALSE);
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);
        resultBuffer->bind();
        
        shadowPass.bindBufferTextures();
        
        deferredPhong.use();
        deferredPhong.setLight(light->properties);
        deferredPhong.setUniforms(proj, view, mat1);
        
        glm::vec3 position = glm::vec3(light->properties.position);
        glm::vec3 lightDir = glm::vec3(light->properties.direction);
        
        // Takes [-1, 1] to [0, 1]
        glm::mat4 biasMatrix(
                             0.5, 0.0, 0.0, 0.0,
                             0.0, 0.5, 0.0, 0.0,
                             0.0, 0.0, 0.5, 0.0,
                             0.5, 0.5, 0.5, 1.0
                             );
        
        glm::mat4 depthProjectionMatrix = glm::perspective(light->properties.angle * 2, width/(float)height, 0.1f, 50.0f);
        glm::mat4 depthViewMatrix = glm::lookAt(position, position + lightDir, glm::vec3(0,1,0));
        deferredPhong.setLightMvp(biasMatrix * depthProjectionMatrix * depthViewMatrix);
        
        unitQuad.render();
        
        shadowPass.unbindBufferTextures();
        
    }
    
    
    gBuffer->unbindAttachments();
    
    glDepthMask(GL_TRUE);
    glDisable(GL_BLEND);
    resultBuffer->unbind();
    
}
void ShadowMapShaderModule::Use(Mesh* mesh, mat4 toWorldTransform, Camera* camera)
{
	DirectionLight* dirLight = Director::GetInstance()->GetCurrentTree()->_directionLight;
	if (!dirLight || !dirLight->IsOpenShadow())
	{
		glUniform1i(_openShadowLocation, 0);
	}
	else
	{
		mat4 dirLightViewTransform = dirLight->GetViewTransform();
		mat4 dirLightProjTransform = dirLight->GetProjectTransform();

		bool isOpenShadow = dirLight->IsOpenShadow();
		glUniform1i(_openShadowLocation, 1);
		if (isOpenShadow)
		{
			glm::mat4 biasMatrix(
				0.5, 0.0, 0.0, 0.0,
				0.0, 0.5, 0.0, 0.0,
				0.0, 0.0, 0.5, 0.0,
				0.5, 0.5, 0.5, 1.0
				);
			mat4 vp = biasMatrix * dirLightProjTransform * dirLightViewTransform * toWorldTransform;
			glUniformMatrix4fv(_lightMVPLocation, 1, GL_FALSE, &vp[0][0]);

			glUniform1i(_shadowmapSamplerLocation, SHADOW_MAP_TEXTURE_DIRECTION_LIGHT_INDEX);
			dirLight->GetTexture()->Bind(SHADOW_MAP_TEXTURE_DIRECTION_LIGHT);
		}
	}
}
void ShadowMappingShader::SetParameters(va_list uniformList)
{
	Matrix44f biasMatrix(
		0.5, 0.0, 0.0, 0.0,
		0.0, 0.5, 0.0, 0.0,
		0.0, 0.0, 0.5, 0.0,
		0.5, 0.5, 0.5, 1.0);

	m_OpenGL->SetUniformMatrix4f(theProgram, "mMVP", va_arg(uniformList, Matrix44f).GetTranspose());
	m_OpenGL->SetUniformMatrix4f(theProgram, "mWorldMatrix", va_arg(uniformList, Matrix44f).GetTranspose());
	m_OpenGL->SetUniformMatrix4f(theProgram, "mDepthMatrix", biasMatrix.GetTranspose());
	m_OpenGL->SetUniformVector3f(theProgram, "vLight", va_arg(uniformList, Vector3f).GetValue());

	// Set active the texture in the fragment shader.
	m_OpenGL->BindActiveShadowTexture2D(va_arg(uniformList, GLuint));

	// Set the texture in the fragment shader.
	m_OpenGL->SetUniform1i(theProgram, "iTexture", 1);
}
Beispiel #4
0
// TODO implement proper light system
void MeshRenderer::Render(Camera& cam, GLuint shader) {
    // matrix to transform range [-1,1] to [0,1]
     glm::mat4 biasMatrix(
            0.5, 0.0, 0.0, 0.0,
            0.0, 0.5, 0.0, 0.0,
            0.0, 0.0, 0.5, 0.0,
            0.5, 0.5, 0.5, 1.0
            );

    current_tex = 0;

    glUseProgram(shader);

    for (entityx::Entity e : entities) {
        Transform* transform = e.component<Transform>().get();
        MeshComponent* mesh_component = e.component<MeshComponent>().get();
        Mesh* mesh = mesh_component->mesh;
        Texture* texture = mesh_component->texture;

        if (!mesh) continue;

        if (texture && current_tex != texture->texture_id) {
            glActiveTexture(GL_TEXTURE0);
            current_tex = texture->texture_id;
            glBindTexture(GL_TEXTURE_2D, current_tex);
        }

        glm::mat4 worldMat = transform->WorldSpace();
        glm::mat4 mvp = cam.combined * worldMat;

        glUniformMatrix4fv(glGetUniformLocation(shader, "MVP"), 1, GL_FALSE, glm::value_ptr(mvp));
        glUniformMatrix4fv(glGetUniformLocation(shader, "worldMat"), 1, GL_FALSE, glm::value_ptr(worldMat));
        glUniform2f(glGetUniformLocation(shader, "material"), mesh_component->material.roughness,
                                                                      mesh_component->material.metallic);

        glBindVertexArray(mesh->vertex_array_object);
        glDrawElements(GL_TRIANGLES, mesh->num_indices, GL_UNSIGNED_INT, 0);
    }
    glBindVertexArray(0);
}
Beispiel #5
0
void Mesh::Draw(Shader shader, bool drawFBO)
{
	// Bind appropriate textures
	GLuint diffuseNr = 1;
	GLuint specularNr = 1;
	GLuint reflectionNr = 1;

	//设备坐标系->纹理坐标系
	glm::mat4 biasMatrix(
		0.5, 0.0, 0.0, 0.0,
		0.0, 0.5, 0.0, 0.0,
		0.0, 0.0, 0.5, 0.0,
		0.5, 0.5, 0.5, 1.0
		);

	for (GLuint i = 0; i < this->textures.size(); i++)
	//int i = 1;
	{
		//float w = this->cam_pos[this->textures[i].id].at<float>(3, 0);
		glm::vec3 imageNorm(this->img_norm[this->textures[i].id].at<float>(0, 0), this->img_norm[this->textures[i].id].at<float>(1, 0), 
			this->img_norm[this->textures[i].id].at<float>(2, 0));
		glm::vec3 camPos(this->cam_pos[this->textures[i].id].at<float>(0, 0), this->cam_pos[this->textures[i].id].at<float>(1, 0), 
			this->cam_pos[this->textures[i].id].at<float>(2, 0));
		
		//cv::Mat VM = this->viewMatrices[i] * this->modelMatrix;// .inv() * this->modelMatrix.inv();
		cv::Mat VM = this->viewMatrices[i].inv() * this->modelMatrix.inv();

		cv::Mat vVM(VM, cv::Rect(3, 0, 1, 4));

		glm::vec3 cam(vVM.at<float>(0, 0), vVM.at<float>(1, 0), vVM.at<float>(2, 0));

		// Compute the MVP matrix from the light's point of view
		glm::mat4 depthProjectionMatrix = glm::perspective<float>(45.0f, 1.0f, near_plane, far_plane);

		glm::vec3 origin(0, 0, 0);
		glm::mat4 depthViewMatrix = glm::lookAt(camPos, origin, glm::vec3(0, 1, 0));//glm::lookAt(lightInvDir, glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
		
		glm::mat4 depthModelMatrix;
		
		depthModelMatrix = glm::scale(depthModelMatrix, glm::vec3(0.01f, 0.01f, 0.01f));	// It's a bit too big for our scene, so scale it down
		glm::mat4 depthMVP = depthProjectionMatrix * depthViewMatrix * depthModelMatrix;

		
		if (drawFBO == false)
		{
			
			glActiveTexture(GL_TEXTURE0 + i); // Active proper texture unit before binding
			// Retrieve texture number (the N in diffuse_textureN)
			stringstream ss;
			string number;
			string name = this->textures[i].type;
			if (name == "texture_diffuse")
				ss << diffuseNr++; // Transfer GLuint to stream
			
			number = ss.str();
			// Now set the sampler to the correct texture unit
			glUniform1i(glGetUniformLocation(shader.Program, ( name).c_str()), i);

			glUniform3fv(glGetUniformLocation(shader.Program, "imgNorm" ), 1, glm::value_ptr(imageNorm));

			glUniform3fv(glGetUniformLocation(shader.Program, "camPos"), 1, glm::value_ptr(camPos));

			// And finally bind the texture
			glBindTexture(GL_TEXTURE_2D, i+1);
			
			glm::mat4 depthBiasMVP = biasMatrix*depthMVP;
			glUniformMatrix4fv(glGetUniformLocation(shader.Program, "DepthBiasMVP"), 1, GL_FALSE, glm::value_ptr(depthBiasMVP));

			//zhongyao
			int d = this->textures.size() + i;
			glActiveTexture(GL_TEXTURE0 + d);
			glBindTexture(GL_TEXTURE_2D, in.depthTexture[i]);
			glUniform1i(glGetUniformLocation(shader.Program, "shadowMap"), d);

			glEnable(GL_CULL_FACE);
			glCullFace(GL_BACK); // Cull back-facing triangles -> draw only front-facing triangles
			glBindVertexArray(this->VAO[textures[i].id]);
			glDrawElements(GL_TRIANGLES, this->indices4draw[textures[i].id].size(), GL_UNSIGNED_INT, 0);
			glCullFace(GL_FRONT); // Cull back-facing triangles -> draw only front-facing triangles
			glBindVertexArray(0);
		}
		else
		{
			glBindFramebuffer(GL_DRAW_FRAMEBUFFER, in.depthMapFBO[i]);
			
			// Clear the screen
			glClear(GL_DEPTH_BUFFER_BIT);

			glm::mat4 shadowProj = glm::perspective(90.0f, 1.0f, 1.0f, 25.0f);

			glm::mat4 depthMVPD = shadowProj *
				glm::lookAt(camPos, camPos + glm::vec3(1.0, 0.0, 0.0), glm::vec3(0.0, -1.0, 0.0));
			glUniformMatrix4fv(glGetUniformLocation(shader.Program, "depthMVP"), 1, GL_FALSE, glm::value_ptr(depthMVPD));
			
			glEnable(GL_CULL_FACE);
			glCullFace(GL_BACK); // Cull back-facing triangles -> draw only front-facing triangles
			glBindVertexArray(this->VAO[textures[i].id]);
			glDrawElements(GL_TRIANGLES, this->indices4draw[textures[i].id].size(), GL_UNSIGNED_INT, 0);
			glCullFace(GL_FRONT);
			glBindVertexArray(0);
			
		}
		glActiveTexture(GL_TEXTURE0);	
	}
}
void DeferredContainer::draw() const {
    //"The Screen". It may not be actually the screen since a upper container might be postprocessing
    const RenderTargetBase* screen = RenderTargetBase::getCurrent();

    GL_ASSERT(glEnable(GL_DEPTH_TEST));
    GL_ASSERT(glDisable(GL_BLEND));

    //Deferred pass
    Debugger::pushMark("Deferred Pass", "Time spent rendering geometry to the g-buffer");
    drawMode = Deferred;
    RenderTargetBase::bind(gBuffer);
    GL_ASSERT(glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT));
    ContainerObject::draw();
    Debugger::popMark(); //deferred

    //Shadowmap pass
    Debugger::pushMark("Shadowmap Pass", "Time spent rendering geometry to the layered shadowmap");
    glEnable(GL_DEPTH_CLAMP);
    drawMode = ShadowMap;
    RenderTargetBase::bind(sunTarget);
    GL_ASSERT(glClear(GL_DEPTH_BUFFER_BIT));
    ContainerObject::draw();
    glDisable(GL_DEPTH_CLAMP);
    Debugger::popMark(); //shadow

    //Transparent shadowmap pass
    Debugger::pushMark("Transparent ShadowMap Pass", "Time spent rendering transparent geometry to the layered shadowmap");
    glEnable(GL_DEPTH_CLAMP);
    drawMode = TransShadowMap;
    RenderTargetBase::bind(sunTargetTrans);
    GL_ASSERT(glClear(GL_DEPTH_BUFFER_BIT));
    ContainerObject::draw();
    glDisable(GL_DEPTH_CLAMP);
    Debugger::popMark(); //transparent shadow

    Debugger::pushMark("Light Pass", "Time spent rendering deferred lights");
    //bind output texture (screen)
    RenderTargetBase::bind(screen);
    GL_ASSERT(glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT));

    //Light pass
    GL_ASSERT(glEnable(GL_BLEND));
    GL_ASSERT(glBlendFunc(GL_ONE, GL_ONE)); //additive
    GL_ASSERT(glDepthMask(GL_FALSE));
    GL_ASSERT(glDepthFunc(GL_ALWAYS));
    drawMode = Light;
    ContainerObject::draw();
    Debugger::popMark(); //lights

    //Ambient+Visibility pass
    Debugger::pushMark("Ambient+Visibility Pass", "Time spent rendering ambient light and sunlight contribution to the scene");
    GL_ASSERT(glDepthMask(GL_TRUE));
    const Camera* cam = (Camera*)getGame()->getObjectByName("playerCam");
    Sun* sun = (Sun*)getGame()->getObjectByName("sun");
    glm::mat4 biasMatrix( //gets coords from [-1..1] to [0..1]
                          0.5, 0.0, 0.0, 0.0,
                          0.0, 0.5, 0.0, 0.0,
                          0.0, 0.0, 0.5, 0.0,
                          0.5, 0.5, 0.5, 1.0
                          );
    //compute each of the cascaded cameras's matrices
    std::vector<mat4f> depthMVP(NUM_SUN_CASCADES);
    for(int i = 0; i < NUM_SUN_CASCADES; ++i)
        depthMVP[i] = biasMatrix*(sun->getVPMatrices()[i]*fullTransform);
    Programs.get("ambientPass").uniform("MVP")->set(mat4f(1.0f));
    Programs.get("ambientPass").uniform("camMV")->set(cam->getView()*fullTransform);
    Programs.get("ambientPass").uniform("color0")->set(getColor0());
    Programs.get("ambientPass").uniform("color1")->set(getColor1());
    Programs.get("ambientPass").uniform("invResolution")->set(vec2f(1.0f/screen->getSize().x, 1.0f/screen->getSize().y));
    Programs.get("ambientPass").uniform("invCamProj")->set(glm::inverse(cam->projection));
    Programs.get("ambientPass").uniform("invCamView")->set(glm::inverse(cam->getView()));
    Programs.get("ambientPass").uniform("lightDir")->set(sun->getCam(0)->getForward());
    Programs.get("ambientPass").uniform("worldsize")->set(WORLDSIZE);
    Programs.get("ambientPass").uniform("depthMVP")->set(depthMVP);
    Programs.get("ambientPass").uniform("depthPlanes")->set(sun->getDepthPlanes());
    Programs.get("ambientPass").uniform("depth")->set(gBuffer.getTexture(RenderTargetBase::DEPTH));
    Programs.get("ambientPass").uniform("sunDepth")->set(sunTarget.getTexture(RenderTargetBase::DEPTH));
    Programs.get("ambientPass").uniform("sunDepthTrans")->set(sunTargetTrans.getTexture(RenderTargetBase::DEPTH));
    quad->draw(Programs.get("ambientPass"));
    Debugger::popMark(); //ambient+shadowmap

    //Forward pass
    Debugger::pushMark("Forward Pass", "Time spent rendering forward-render stuff");
    GL_ASSERT(glDepthMask(GL_TRUE));
    GL_ASSERT(glDepthFunc(GL_LEQUAL));
    GL_ASSERT(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); //forward rendering blending
    drawMode = Forward;
    ContainerObject::draw();
    Debugger::popMark();
}
Beispiel #7
0
void SuzanneGL::RenderShadowMaps()
{
	GLuint FramebufferName = 0;
	glCreateFramebuffers(1, &FramebufferName);
	glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);

	glm::mat4 depthViewProjectionMatrices[NUMBER_OF_LIGHTS];
	for (int i = 0; i < NUMBER_OF_LIGHTS; ++i)
	{
		glCreateTextures(GL_TEXTURE_2D, 1, &shadowMaps[i]);
		glTextureImage2DEXT(shadowMaps[i], GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, SHADOW_RESOLUTION, SHADOW_RESOLUTION, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
		glTextureParameteri(shadowMaps[i], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTextureParameteri(shadowMaps[i], GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTextureParameteri(shadowMaps[i], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
		glTextureParameteri(shadowMaps[i], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
		glTextureParameteri(shadowMaps[i], GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
		glTextureParameteri(shadowMaps[i], GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);

		glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadowMaps[i], 0);

		glDrawBuffer(GL_NONE);

		if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
			return;

		glEnable(GL_DEPTH_TEST);
		glClear(GL_DEPTH_BUFFER_BIT);
		glViewport(0, 0, SHADOW_RESOLUTION, SHADOW_RESOLUTION);

		glm::vec3 lightDir = glm::normalize(glm::vec3(lighting.lights[i].position.x, lighting.lights[i].position.y, lighting.lights[i].position.z));
		glm::mat4 depthProjectionMatrix = glm::ortho<float>(-10, 10, -10, 10, -10, 20);
		glm::mat4 depthViewMatrix = glm::lookAt(lightDir, glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
		depthViewProjectionMatrices[i] = depthProjectionMatrix * depthViewMatrix;

		shadowModelMatrixIndex = glGetUniformLocation(shadowShaderProgram, "modelMatrix");
		shadowViewProjectionMatrixIndex = glGetUniformLocation(shadowShaderProgram, "viewProjectionMatrix");

		glProgramUniformMatrix4fv(shadowShaderProgram, shadowViewProjectionMatrixIndex, 1, GL_FALSE, glm::value_ptr(depthViewProjectionMatrices[i]));

		for (ModelGL model : models)
		{
			glProgramUniformMatrix4fv(shadowShaderProgram, shadowModelMatrixIndex, 1, GL_FALSE, glm::value_ptr(model.modelMatrix));
			glNamedBufferSubData(materialBuffer, 0, sizeof(Material), &model.material);
			glBindVertexArray(model.vertexArray);
			glUseProgram(shadowShaderProgram);
			glDrawArrays(GL_TRIANGLES, 0, model.vertexCount);
		}
	}

	glBindFramebuffer(GL_FRAMEBUFFER, 0);

	glm::mat4 biasMatrix(
		0.5, 0.0, 0.0, 0.0,
		0.0, 0.5, 0.0, 0.0,
		0.0, 0.0, 0.5, 0.0,
		0.5, 0.5, 0.5, 1.0
		);

	shadowViewProjectionMatrixIndex = glGetUniformLocation(shaderProgram, "shadowViewProjectionMatrix");
	shadowBiasMatrixIndex = glGetUniformLocation(shaderProgram, "shadowBiasMatrix");
	glProgramUniformMatrix4fv(shaderProgram, shadowViewProjectionMatrixIndex, 2, GL_FALSE, glm::value_ptr(depthViewProjectionMatrices[0]));
	glProgramUniformMatrix4fv(shaderProgram, shadowBiasMatrixIndex, 1, GL_FALSE, glm::value_ptr(biasMatrix));
}
Beispiel #8
0
void draw() {
#pragma region shadow
	glm::mat4 depthMVP = glm::mat4( 1.0 );
	glm::vec4 lightInvDir = mainLight->getPos();

	//Only render the shadow pass if we have shadows enabled
	if( Settings::getShadowQuality() > 0 ) {
		//We'll give the meshes and shaders and whatnot to the light so it can render them however
		//the light returns the depthMVP
		depthMVP = mainLight->renderShadow( mesh, 1, depth );
	}
#pragma endregion

#pragma region main_render
	// Render to the screen
	lastEightFrames[curFrame]->bind();
	curFrame++;
	if( curFrame > 7 ) {
		curFrame = 0;
	}
	glViewport( 0, 0, width, height );

	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
	mainCamera->update();
	glm::mat4 ProjectionMatrix = mainCamera->getProjMatrix();
	glm::mat4 ViewMatrix = mainCamera->getViewMatrix();
	glm::mat4 ModelMatrix = glm::mat4( 1.0 );	//change this per model
	glm::mat4 MVP = ProjectionMatrix * ViewMatrix * ModelMatrix;

	glm::mat4 biasMatrix(
		0.5, 0.0, 0.0, 0.0,
		0.0, 0.5, 0.0, 0.0,
		0.0, 0.0, 0.5, 0.0,
		0.5, 0.5, 0.5, 1.0
		);

	glm::mat4 depthBiasMVP = biasMatrix * depthMVP;

	// Use our shader
	diffuse->bind();

	// Send our transformation to the currently bound shader, 
	// in the "MVP" uniform
	diffuse->setUniformMat4x4( "MVP", &MVP[0][0] );
	diffuse->setUniformMat4x4( "M", &ModelMatrix[0][0] );
	diffuse->setUniformMat4x4( "V", &ViewMatrix[0][0] );
	diffuse->setUniformMat4x4( "DepthBiasMVP", &depthBiasMVP[0][0] );

	diffuse->setUniform4f( "lightPosition_worldspace",
		lightInvDir.x, lightInvDir.y, lightInvDir.z, lightInvDir.w );

	diffuse->setUniform4f( "lightColor", 
		mainLight->getColor().r, mainLight->getColor().g, 
		mainLight->getColor().b, mainLight->getColor().a );

	// Bind our texture in Texture Unit 0
	normalMap->bind( 0 );
	// Set our "myTextureSampler" sampler to user Texture Unit 0
	diffuse->setUniform1i( "diffuse", 0 );

	normalMap->bind( 1 );
	diffuse->setUniform1i( "normalMap", 1 );

	glActiveTexture( GL_TEXTURE2 );
	glBindTexture( GL_TEXTURE_2D, mainLight->getDepthTexture() );
	diffuse->setUniform1i( "shadowMap", 2 );

	diffuse->setUniform1i( "shadowLevel", Settings::getShadowQuality() );

	internalLighting->bind();
	internalLighting->setUniformMat4x4( "MVP", &MVP[0][0] );
	internalLighting->setUniformMat4x4( "M", &ModelMatrix[0][0] );
	internalLighting->setUniformMat4x4( "V", &ViewMatrix[0][0] );

	mesh->bind( internalLighting->getAttribute( "vertexPosition_worldspace" ),
		internalLighting->getAttribute( "vertexUV" ),
		internalLighting->getAttribute( "vertexNormal_modelspace" ),
		internalLighting->getAttribute( "vertexTangent_modelspace" ) );
	mesh->draw();
#pragma endregion

#pragma region debugRenders
#pragma endregion

	glfwSwapBuffers( window );
}
Beispiel #9
0
int main( void )
{
	//init bullet
	initBullet();
	// Initialise GLFW
	if( !glfwInit() )
	{
		fprintf( stderr, "Failed to initialize GLFW\n" );
		return -1;
	}
	glfwWindowHint(GLFW_SAMPLES, 4);
//	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
//	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
//	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

	//screen resolution GLFW
	const GLFWvidmode * mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
	int  w = mode->width;
	int  h = mode->height;

	if(MessageBox(NULL, L"Would you like to run in fullscreen?", L"Fullscreen", MB_ICONQUESTION | MB_YESNO) == IDYES) 
	{
		window = glfwCreateWindow( w, h, "Ray Tracing - Alfonso Oricchio", glfwGetPrimaryMonitor(), NULL);
		printf("fullscreen\n");
	}
	else
	{
		window = glfwCreateWindow( WINDOW_WIDTH, WINDOW_HEIGHT, "Ray Tracing - Alfonso Oricchio", NULL, NULL);
		printf("window\n");
	}
	// Open a window and create its OpenGL context
	
	if( window == NULL ){
		fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" );
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(window);

	// Initialize GLEW
	glewExperimental = true; // Needed for core profile
	if (glewInit() != GLEW_OK) {
		fprintf(stderr, "Failed to initialize GLEW\n");
		return -1;
	}

	// Ensure we can capture the escape key being pressed below
	glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
	glfwSetCursorPos(window, WINDOW_WIDTH/2, WINDOW_HEIGHT/2);

	// Dark blue background
	glClearColor(0.0f, 0.0f, 0.4f, 0.0f);

	// Enable depth test
	glEnable(GL_DEPTH_TEST);
	// Accept fragment if it closer to the camera than the former one
	glDepthFunc(GL_LESS); 
	// Cull triangles which normal is not towards the camera
	//glEnable(GL_CULL_FACE);

	GLuint VertexArrayID;
	glGenVertexArrays(1, &VertexArrayID);
	glBindVertexArray(VertexArrayID);
	
		// Create and compile our GLSL program from the shaders
	GLuint depthProgramID = LoadShaders( "DepthRTT.vertexshader", "DepthRTT.fragmentshader" );

	// Get a handle for our "MVP" uniform
	GLuint depthMatrixID = glGetUniformLocation(depthProgramID, "depthMVP");
	
	// The framebuffer, which regroups 0, 1, or more textures, and 0 or 1 depth buffer.
	GLuint FramebufferName = 0;
	glGenFramebuffers(1, &FramebufferName);
	glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);

	// Depth texture. Slower than a depth buffer, but you can sample it later in your shader
	GLuint depthTexture;
	glGenTextures(1, &depthTexture);
	glBindTexture(GL_TEXTURE_2D, depthTexture);
	glTexImage2D(GL_TEXTURE_2D, 0,GL_DEPTH_COMPONENT16, 1024, 1024, 0,GL_DEPTH_COMPONENT, GL_FLOAT, 0);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
		 
	glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexture, 0);

	// No color output in the bound framebuffer, only depth.
	glDrawBuffer(GL_NONE);

	// Always check that our framebuffer is ok
	if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
		return false;
	/***********************************************************/
		// The quad's FBO. Used only for visualizing the shadowmap.
	static const GLfloat g_quad_vertex_buffer_data[] = { 
		-1.0f, -1.0f, 0.0f,
		 1.0f, -1.0f, 0.0f,
		-1.0f,  1.0f, 0.0f,
		-1.0f,  1.0f, 0.0f,
		 1.0f, -1.0f, 0.0f,
		 1.0f,  1.0f, 0.0f,
	};

	GLuint quad_vertexbuffer;
	glGenBuffers(1, &quad_vertexbuffer);
	glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer);
	glBufferData(GL_ARRAY_BUFFER, sizeof(g_quad_vertex_buffer_data), g_quad_vertex_buffer_data, GL_STATIC_DRAW);

	// Create and compile our GLSL program from the shaders
	GLuint quad_programID = LoadShaders( "Passthrough.vertexshader", "SimpleTexture.fragmentshader" );
	GLuint texID = glGetUniformLocation(quad_programID, "texture");
	/**********************************************************/


		// Create and compile our GLSL program from the shaders
	GLuint programID = LoadShaders( "TransformVertexShader.vertexshader", "ColorFragmentShader.fragmentshader" );



	// Get a handle for our "MVP" uniform
	GLuint MatrixID = glGetUniformLocation(programID, "MVP");
	GLuint ViewMatrixID = glGetUniformLocation(programID, "V");
	GLuint ModelMatrixID = glGetUniformLocation(programID, "M");
	GLuint DepthBiasID = glGetUniformLocation(programID, "DepthBiasMVP");
	GLuint ShadowMapID = glGetUniformLocation(programID, "shadowMap");
	
	// Get a handle for our "LightPosition" uniform
	GLuint lightInvDirID = glGetUniformLocation(programID, "LightInvDirection_worldspace");

	//CUBO1
	addBox(2,2,2,0,0,0,1.0);

	//CUBO2
	addBox2(2,2,2,0,6,0,1.0);
	//FLOOR
	initFloor();

	//WALL
	initWall();
	//BALL
	addScene();

	do{
		world->stepSimulation(1/60.f);
		if (glfwGetKey( window, GLFW_KEY_SPACE ) == GLFW_PRESS){
			btRigidBody* ball = addBall(1.0,CamGetPosition().x,CamGetPosition().y,CamGetPosition().z,2.0);
			ball->setLinearVelocity(btVector3((CamGetDirection().x*50),(CamGetDirection().y*50),(CamGetDirection().z*50)));	
		}
		// Render to our framebuffer
		glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
		glViewport(0,0,1024,1024); // Render on the whole framebuffer, complete from the lower left corner to the upper right

		// Clear the screen
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		//////////////////////////////
		// Use our shader
		//SHADOW RENDER
		glUseProgram(depthProgramID);

		glm::vec3 lightInvDir = glm::vec3(0.5f,2,2);

		// Compute the MVP matrix from the light's point of view
		glm::mat4 depthProjectionMatrix = glm::ortho<float>(-10,10,-10,10,-10,20);
		glm::mat4 depthViewMatrix = glm::lookAt(lightInvDir, glm::vec3(0,0,0), glm::vec3(0,1,0));
		// or, for spot light :
		//glm::vec3 lightPos(5, 20, 20);
		//glm::mat4 depthProjectionMatrix = glm::perspective<float>(45.0f, 1.0f, 2.0f, 50.0f);
		//glm::mat4 depthViewMatrix = glm::lookAt(lightPos, lightPos-lightInvDir, glm::vec3(0,1,0));

		glm::mat4 depthModelMatrix = glm::mat4(1.0);
		glm::mat4 depthMVP = depthProjectionMatrix * depthViewMatrix * depthModelMatrix;

		// Send our transformation to the currently bound shader, 
		// in the "MVP" uniform
		glUniformMatrix4fv(depthMatrixID, 1, GL_FALSE, &depthMVP[0][0]);

		// CUBE1 -------------------------------------------------------------------------
		renderBox(bodies[0],true); //just a cube not really needed
		//CUBE2 --------------------------------------------------------------------------
		renderBox2(bodies[1],true); //just a cube not really needed
		//FLOOR --------------------------------------------------------------------------
		renderPlane(bodies[2],true); //floor 
		//WALL ---------------------------------------------------------------------------
		renderWall(bodies[3],true); //back wall
		//CASTLE -------------------------------------------------------------------------
		renderScene(true); //castle, main scene
		//BALL ---------------------------------------------------------------------------
		int iv;
		for(iv = 4; iv < bodies.size();iv++)
			{
				renderBall(bodies[iv],(iv - 4),true); //"cannon balls" shooted from the camera 
			}
		
		

		
		//////////////////////////////
		//STANDARD RENDER
		// Compute the MVP matrix from keyboard and mouse input
		// Clear the screen
		// Render to the screen
		glBindFramebuffer(GL_FRAMEBUFFER, 0);
		glViewport(0,0,1024,768); // Render on the whole framebuffer, complete from the lower left corner to the upper right

		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		
		// Use our shader
		glUseProgram(programID);

		computeMatricesFromInputs();
		glm::mat4 ProjectionMatrix = getProjectionMatrix();
		glm::mat4 ViewMatrix = getViewMatrix();
		glm::mat4 ModelMatrix = glm::mat4(1.0);
		glm::mat4 MVP = ProjectionMatrix * ViewMatrix * ModelMatrix;		
		
				
		glm::mat4 biasMatrix(
			0.5, 0.0, 0.0, 0.0, 
			0.0, 0.5, 0.0, 0.0,
			0.0, 0.0, 0.5, 0.0,
			0.5, 0.5, 0.5, 1.0
		);

		glm::mat4 depthBiasMVP = biasMatrix*depthMVP;

// Send our transformation to the currently bound shader, 
		// in the "MVP" uniform
		glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
		glUniformMatrix4fv(ModelMatrixID, 1, GL_FALSE, &ModelMatrix[0][0]);
		glUniformMatrix4fv(ViewMatrixID, 1, GL_FALSE, &ViewMatrix[0][0]);
		glUniformMatrix4fv(DepthBiasID, 1, GL_FALSE, &depthBiasMVP[0][0]);

		glUniform3f(lightInvDirID, lightInvDir.x, lightInvDir.y, lightInvDir.z);

		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, depthTexture);
		glUniform1i(ShadowMapID, 0);

		// CUBE1 -------------------------------------------------------------------------
		renderBox(bodies[0],false); //just a cube not really needed
		//CUBE2 --------------------------------------------------------------------------
		renderBox2(bodies[1],false); //just a cube not really needed
		//FLOOR --------------------------------------------------------------------------
		renderPlane(bodies[2],false); //floor 
		//WALL ---------------------------------------------------------------------------
		renderWall(bodies[3],false); //back wall
		//CASTLE -------------------------------------------------------------------------
		renderScene(false); //castle, main scene
		//BALL ---------------------------------------------------------------------------
	//	int iv;
		for(iv = 4; iv < bodies.size();iv++)
			{ 
				renderBall(bodies[iv],(iv - 4),false); //"cannon balls" shooted from the camera 
			}
		
	/*--------------------------------------------------*/
	// Optionally render the shadowmap (for debug only)

		// Render only on a corner of the window (or we we won't see the real rendering...)
		glViewport(0,0,512,512);

		// Use our shader
		glUseProgram(quad_programID);

		// Bind our texture in Texture Unit 0
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, depthTexture);
		// Set our "renderedTexture" sampler to user Texture Unit 0
		glUniform1i(texID, 0);

		// 1rst attribute buffer : vertices
		glEnableVertexAttribArray(0);
		glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer);
		glVertexAttribPointer(
			0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
			3,                  // size
			GL_FLOAT,           // type
			GL_FALSE,           // normalized?
			0,                  // stride
			(void*)0            // array buffer offset
		);

		// Draw the triangle !
		// You have to disable GL_COMPARE_R_TO_TEXTURE above in order to see anything !
		//glDrawArrays(GL_TRIANGLES, 0, 6); // 2*3 indices starting at 0 -> 2 triangles
		glDisableVertexAttribArray(0);

	/*--------------------------------------------------*/
		// Swap buffers
		glfwSwapBuffers(window);
		glfwPollEvents();

	} // Check if the ESC key was pressed or the window was closed
	while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
		   glfwWindowShouldClose(window) == 0 );



	deleteALL();
	glDeleteProgram(programID);
	glDeleteVertexArrays(1, &VertexArrayID);
	// Close OpenGL window and terminate GLFW
	glfwTerminate();

	return 0;
}
Beispiel #10
0
int main( void )
{

	crap::audiodevice audio_device;
	
	/*
	openalcode



	*/

	//setup window
	crap::window_setup win_setup;
	win_setup.title = "Funny Window";
	win_setup.width = 1024;
	win_setup.height = 768;
	win_setup.multisampling_count = 8;
	win_setup.opengl_version = 3.3f;
    win_setup.opengl_profile = crap::compat;

	//create window
	crap::window window( win_setup );
	window.open();

	//get keyboard and mouse
	crap::keyboard keyboard;
	crap::mouse mouse;

	// temporary
	crap::opengl::enable(crap::opengl::depth_test);
	crap::opengl::setDepthComparison(crap::opengl::less);
	crap::opengl::enable(crap::opengl::cull_face);

	//camera setup
	camera cam;
	cam.setPosition( glm::vec3( 0.0f, 0.0f, 5.0f ) );
	mouse_pos = mouse.position();

	//create contentmanager
	content_manager cm;
	cm.init( "spg.ini" );

	//create vertex array
	crap::vertex_array vert_array;
	vert_array.bind();

	//test: load vbo onto GPU
	vbo cube_vbo( "cube", &cm, vbo::static_draw );
	vbo ape_vbo("ape", &cm, vbo::static_draw );
	vbo cube_big_vbo( "cube", &cm, vbo::static_draw );
	//vbo people_vbo("people", &cm, vbo::static_draw );

	//////////////////////////
	// Read our .obj file
	std::vector<glm::vec3> vertices;
	std::vector<glm::vec2> uvs;
	std::vector<glm::vec3> normals;
	bool res = loadOBJ("../../../data/geometry/dupercube.obj", vertices, uvs, normals);

	std::vector<glm::vec3> tangents;
	std::vector<glm::vec3> bitangents;
	computeTangentBasis(
		vertices, uvs, normals, // input
		tangents, bitangents    // output
	);

	std::vector<unsigned short> indices;
	std::vector<glm::vec3> indexed_vertices;
	std::vector<glm::vec2> indexed_uvs;
	std::vector<glm::vec3> indexed_normals;
	std::vector<glm::vec3> indexed_tangents;
	std::vector<glm::vec3> indexed_bitangents;
	indexVBO_TBN(
		vertices, uvs, normals, tangents, bitangents, 
		indices, indexed_vertices, indexed_uvs, indexed_normals, indexed_tangents, indexed_bitangents
	);

	GLuint vertexbuffer;
	glGenBuffers(1, &vertexbuffer);
	glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
	glBufferData(GL_ARRAY_BUFFER, indexed_vertices.size() * sizeof(glm::vec3), &indexed_vertices[0], GL_STATIC_DRAW);

	GLuint uvbuffer;
	glGenBuffers(1, &uvbuffer);
	glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
	glBufferData(GL_ARRAY_BUFFER, indexed_uvs.size() * sizeof(glm::vec2), &indexed_uvs[0], GL_STATIC_DRAW);

	GLuint normalbuffer;
	glGenBuffers(1, &normalbuffer);
	glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
	glBufferData(GL_ARRAY_BUFFER, indexed_normals.size() * sizeof(glm::vec3), &indexed_normals[0], GL_STATIC_DRAW);

	GLuint tangentbuffer;
	glGenBuffers(1, &tangentbuffer);
	glBindBuffer(GL_ARRAY_BUFFER, tangentbuffer);
	glBufferData(GL_ARRAY_BUFFER, indexed_tangents.size() * sizeof(glm::vec3), &indexed_tangents[0], GL_STATIC_DRAW);

	GLuint bitangentbuffer;
	glGenBuffers(1, &bitangentbuffer);
	glBindBuffer(GL_ARRAY_BUFFER, bitangentbuffer);
	glBufferData(GL_ARRAY_BUFFER, indexed_bitangents.size() * sizeof(glm::vec3), &indexed_bitangents[0], GL_STATIC_DRAW);

	// Generate a buffer for the indices as well
	GLuint elementbuffer;
	glGenBuffers(1, &elementbuffer);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned short), &indices[0], GL_STATIC_DRAW);
	/////////////////////////

	geometry_content ig;
	cm.create_content( "cube" , &ig, type_name::geometry );

	//test: load texture onto GPU
	tbo diffuse_tbo( "stone_diff", &cm, tbo::tga );
	tbo normal_tbo( "stone_norm", &cm, tbo::tga );
	tbo height_tbo( "stone_height", &cm, tbo::tga );

	//shadow stuff
	crap::frame_buffer frame_buffer;
	frame_buffer.bind();
	tbo depthmap( "", &cm, tbo::depth );
	frame_buffer.unbind();

	//shadow stuff
	crap::quad_buffer quad_buffer;

	//test: load linked shader progam onto GPU
	shader_manager sm(&cm);
	sm.add("epr_vert", "epr_frag");
	sm.add("shadow_vert", "shadow_frag");
	
	//get stuff from shader program
	//shadow shader
	sm.set_current("shadow_vert", "shadow_frag");
	crap::uniform DepthBiasMVPID = sm.current()->uniform_location("depthMVP");

	//vertex shader
	sm.set_current("epr_vert", "epr_frag");
	crap::uniform WorldMatrixID = sm.current()->uniform_location("world_matrix4x4");
	crap::uniform ViewMatrixID = sm.current()->uniform_location("view_matrix4x4");
	crap::uniform ModelMatrixID = sm.current()->uniform_location("model_matrix4x4");
	crap::uniform ModelView3x3MatrixID = sm.current()->uniform_location("model_view_matrix3x3");

	//fragment shader
	crap::uniform DiffuseTextureID  = sm.current()->uniform_location("diffuse_texture");
	crap::uniform NormalTextureID  = sm.current()->uniform_location("normal_texture");
	crap::uniform HeightTextureID = sm.current()->uniform_location("height_texture");

	crap::uniform LightAmbientPowerID = sm.current()->uniform_location("ambient_power");

	crap::uniform LightPowerArrayID = sm.current()->uniform_location("light_power");
	crap::uniform LightSpecularTypeArrayID = sm.current()->uniform_location("light_specular_type");
	crap::uniform LightSpecularLobeArrayID = sm.current()->uniform_location("light_specular_lobe");
	crap::uniform LightColorArrayID = sm.current()->uniform_location("light_color");
	crap::uniform LightSelfShadowingOnID = sm.current()->uniform_location("selfshadowing_on");

	crap::uniform DisplacementOnID = sm.current()->uniform_location("displacement_on");
	crap::uniform DisplacementStepsID = sm.current()->uniform_location("displacement_steps");
	crap::uniform DisplacementRefinementStepsID = sm.current()->uniform_location("displacement_refinement_steps");
	crap::uniform DisplacementUVFactorID = sm.current()->uniform_location("displacement_uv_factor");

	//both shaders
	crap::uniform LightPositionArrayID = sm.current()->uniform_location("light_position");
	crap::uniform LightDirectionArrayID = sm.current()->uniform_location("light_direction");
	crap::uniform LightTypeArrayID = sm.current()->uniform_location("light_type");
	crap::uniform LightStateArrayID = sm.current()->uniform_location("light_state");

	crap::uniform LightNormalMappingOnID = sm.current()->uniform_location("normal_mapping_on");

	//shadow stuff
	crap::uniform ShadowMapID = sm.current()->uniform_location("shadow_map");
	crap::uniform ShadowMappingOnID = sm.current()->uniform_location("shadow_mapping_on");
	crap::uniform ShadowDepthBiasMVPID = sm.current()->uniform_location("depth_bias_mvp");

	//SHADER DATA
	// Projection matrix : 60° Field of View, 4:3 ratio, display range : 0.1 unit <-> 100 units
	float display_field_of_view = 60.f; //60°
	float display_ratio_horizontal = 4.f;
	float display_ratio_vertical = 3.f;
	float display_range_near = 0.1f;
	float display_range_far = 100.f;

	glm::mat4 projection_matrix = glm::perspective(
		display_field_of_view, 
		display_ratio_horizontal / display_ratio_vertical, 
		display_range_near, 
		display_range_far);

	glm::mat4 model_matrix(1.0f);
	glm::mat4 model_view_matrix(1.0f);
	glm::mat4 view_matrix = cam.view();
	glm::mat4 world_matrix(1.0f);
	glm::mat3 model_view_matrix3x3(1.0f);

	//light stuff
	float light_ambient_power = 0.5f;
	float light_power_array[MAX_LIGHTS] = { 1.f, 1.f, 1.f };
	int light_specular_type_array[MAX_LIGHTS] = { 1, 1, 1 };
	float light_specular_lobe_array[MAX_LIGHTS] = { 100.f, 100.f, 100.f };
	glm::vec3 light_color_array[MAX_LIGHTS] = { glm::vec3(1.f), glm::vec3(1.f), glm::vec3(1.f) };
	int light_self_shadowing_on = 1;
	glm::vec3 light_position_array[MAX_LIGHTS] = { glm::vec3(4,0,0), glm::vec3(0,0,-4), glm::vec3(4,4,4) };
	glm::vec3 light_direction_array[MAX_LIGHTS] = { glm::vec3(-4,0,0), glm::vec3(0,0,4), glm::vec3(-4,-4,-4) };
	int light_type_array[MAX_LIGHTS] = { 0, 0, 0 };
	int light_state_array[MAX_LIGHTS] = { 1, 0, 0 };
	int light_normal_mapping_on = 1;

	//shadowstuff
	int shadow_mapping_on = 1;

	//displacement stuff
	int displacement_on = 1;
	float displacement_steps = 20;
	float displacement_refinement_steps = 20;
	float displacmenet_uv_factor = 20;

	//GUI
	TwInit(TW_OPENGL, NULL);
	TwWindowSize(1024, 768);

	TwBar * GeneralGUI = TwNewBar("General settings");
	TwBar * LightGUI = TwNewBar("Light Settings");
	TwBar * DisplacementGUI = TwNewBar("Displacement Settings");

	TwSetParam(GeneralGUI, NULL, "refresh", TW_PARAM_CSTRING, 1, "0.1");
	TwSetParam(LightGUI, NULL, "refresh", TW_PARAM_CSTRING, 1, "0.1");
	TwSetParam(DisplacementGUI, NULL, "refresh", TW_PARAM_CSTRING, 1, "0.1");

	//general gui
	TwAddSeparator(GeneralGUI, "Funny seperator", NULL);
	TwAddVarRW(GeneralGUI, "Field of View", TW_TYPE_FLOAT , &display_field_of_view, "help='Field of View value'");
	TwAddVarRW(GeneralGUI, "Ratio Horizontal", TW_TYPE_FLOAT , &display_ratio_horizontal, "help='Ratio Horizontal'");
	TwAddVarRW(GeneralGUI, "Ratio Vertical", TW_TYPE_FLOAT , &display_ratio_vertical, "help='Ratio Vertical'");
	TwAddVarRW(GeneralGUI, "Range Near", TW_TYPE_FLOAT , &display_range_near, "help='Range near'");
	TwAddVarRW(GeneralGUI, "Range far", TW_TYPE_FLOAT , &display_range_far, "help='Range far'");

	//light gui
	TwAddVarRW(LightGUI, "Ambient light", TW_TYPE_FLOAT , &light_ambient_power, "help='Ambient power'");
	TwAddVarRW(LightGUI, "Self Shadowing", TW_TYPE_BOOL32, &light_self_shadowing_on, NULL);
	TwAddVarRW(LightGUI, "Normal Mapping", TW_TYPE_BOOL32, &light_normal_mapping_on, NULL);
	TwType gui_light_type = TwDefineEnumFromString("LightType", "Directionallight,Pointlight");
	TwType gui_light_specular_type = TwDefineEnumFromString("LightSpecularType", "Blinn,Phong");
	//shadow
	TwAddVarRW(LightGUI, "Cast Shadows", TW_TYPE_BOOL32, &shadow_mapping_on, NULL);
	//light1
	TwAddVarRW(LightGUI, "Light 1", TW_TYPE_BOOL32, light_state_array, NULL);
	TwAddVarRW(LightGUI, "Light Type 1", gui_light_type, light_type_array, NULL);
	TwAddVarRW(LightGUI, "Light Specular Type 1", gui_light_specular_type, light_specular_type_array, NULL);
	TwAddVarRW(LightGUI, "Light Power 1", TW_TYPE_FLOAT , light_power_array, NULL);
	TwAddVarRW(LightGUI, "Light Specular Lobe 1", TW_TYPE_FLOAT , light_specular_lobe_array, NULL);
	TwAddVarRW(LightGUI, "Light Color 1", TW_TYPE_COLOR3F , light_color_array, NULL);
	TwAddVarRW(LightGUI, "Light Position 1", TW_TYPE_DIR3F , light_position_array, NULL);
	TwAddVarRW(LightGUI, "Light Direction 1", TW_TYPE_DIR3F , light_direction_array, NULL);
	//light2
	TwAddVarRW(LightGUI, "Light 2", TW_TYPE_BOOL32, light_state_array+1, NULL);
	TwAddVarRW(LightGUI, "Light Type 2", gui_light_type, light_type_array+1, NULL);
	TwAddVarRW(LightGUI, "Light Specular Type 2", gui_light_specular_type, light_specular_type_array+1, NULL);
	TwAddVarRW(LightGUI, "Light Power 2", TW_TYPE_FLOAT , light_power_array+1, NULL);
	TwAddVarRW(LightGUI, "Light Specular Lobe 2", TW_TYPE_FLOAT , light_specular_lobe_array+1, NULL);
	TwAddVarRW(LightGUI, "Light Color 2", TW_TYPE_COLOR3F , light_color_array+1, NULL);
	TwAddVarRW(LightGUI, "Light Position 2", TW_TYPE_DIR3F , light_position_array+1, NULL);
	TwAddVarRW(LightGUI, "Light Direction 2", TW_TYPE_DIR3F , light_direction_array+1, NULL);
	//light3
	TwAddVarRW(LightGUI, "Light 3", TW_TYPE_BOOL32, light_state_array+2, NULL);
	TwAddVarRW(LightGUI, "Light Type 3", gui_light_type, light_type_array+2, NULL);
	TwAddVarRW(LightGUI, "Light Specular Type 3", gui_light_specular_type, light_specular_type_array+2, NULL);
	TwAddVarRW(LightGUI, "Light Power 3", TW_TYPE_FLOAT , light_power_array+2, NULL);
	TwAddVarRW(LightGUI, "Light Specular Lobe 3", TW_TYPE_FLOAT , light_specular_lobe_array+2, NULL);
	TwAddVarRW(LightGUI, "Light Color 3", TW_TYPE_COLOR3F , light_color_array+2, NULL);
	TwAddVarRW(LightGUI, "Light Position 3", TW_TYPE_DIR3F , light_position_array+2, NULL);
	TwAddVarRW(LightGUI, "Light Direction 3", TW_TYPE_DIR3F , light_direction_array+2, NULL);

	//displacement gui
	TwAddVarRW(DisplacementGUI, "Displacement ON/OFF", TW_TYPE_BOOL32, &displacement_on, NULL);
	TwAddVarRW(DisplacementGUI, "Displacment steps", TW_TYPE_FLOAT , &displacement_steps, NULL);
	TwAddVarRW(DisplacementGUI, "Displacement refinement", TW_TYPE_FLOAT , &displacement_refinement_steps, NULL);
	TwAddVarRW(DisplacementGUI, "Displacement UV factor", TW_TYPE_FLOAT , &displacmenet_uv_factor, NULL);

	//gui mouse setup
	mouse.set_on_pressed_function( (crap::mouse::user_button_callback_function)gui_mouse_down );
	mouse.set_on_release_function( (crap::mouse::user_button_callback_function)gui_mouse_up );
	mouse.set_on_move_function( (crap::mouse::user_move_callback_function)TwEventMousePosGLFW );
	mouse.set_on_wheel_function( (crap::mouse::user_wheel_callback_function)TwEventMouseWheelGLFW );
	keyboard.set_on_pressed_function( (crap::keyboard::user_callback_function)TwEventKeyGLFW );
	//todo set char input

	// temporary
	crap::opengl::clearColor(1.0f, 1.0f, 1.0f, 0.0f);

	while( !keyboard.is_pressed( crap::keyboard::key_escape ) && window.is_open() )
	{
		// update positions
		handleInput(keyboard, mouse, cam);

		crap::opengl::clear(crap::opengl::color_depth_buffer);

		frame_buffer.bind();
		glViewport(0,0,1024,1024); // Render on the whole framebuffer, complete from the lower left corner to the upper right
		sm.set_current("shadow_vert", "shadow_frag");
		sm.activate();

		glm::vec3 lightInvDir = light_direction_array[0]; //glm::vec3(0.5f,2,2);

		// Compute the MVP matrix from the light's point of view
		glm::mat4 depthProjectionMatrix = glm::ortho<float>(-10,10,-10,10,-10,20);
		glm::mat4 depthViewMatrix = glm::lookAt(lightInvDir, glm::vec3(0,0,0), glm::vec3(0,1,0));
		glm::mat4 depthModelMatrix = glm::mat4(1.0);
		glm::mat4 depthMVP = depthProjectionMatrix * depthViewMatrix * depthModelMatrix;

		sm.current()->uniform_matrix4f_value( DepthBiasMVPID, 1, &depthMVP[0][0]);

		sm.current()->vertex_attribute_array.enable(0);
		cube_vbo.bind_buffer( vbo::verticies );
		sm.current()->vertex_attribute_array.pointer( 0, 3, crap::gl_float, false, 0, (void*)0);

		cube_vbo.bind_buffer( vbo::indicies );
		crap::opengl::draw_elements(
			crap::opengl::triangles,		// mode
			cube_vbo.indicies_size,			// count
			crap::opengl::unsigned_short	// type
		);

		sm.current()->vertex_attribute_array.disable(0);

		frame_buffer.unbind();

		glViewport(0,0,1024,768); // Render on the whole framebuffer, complete from the lower left corner to the upper right

		crap::opengl::clear(crap::opengl::color_depth_buffer);

		sm.set_current("epr_vert", "epr_frag");
		sm.activate();

		///////////////////////////////////////
		//////////////////////////////////////

		projection_matrix = glm::perspective(
			display_field_of_view, 
			display_ratio_horizontal / display_ratio_vertical, 
			display_range_near, 
			display_range_far);

		view_matrix = cam.view();
		model_view_matrix = view_matrix * world_matrix;
		model_view_matrix3x3 = glm::mat3(model_view_matrix);
		world_matrix = projection_matrix * view_matrix * model_matrix;

		glm::mat4 biasMatrix(
			0.5, 0.0, 0.0, 0.0, 
			0.0, 0.5, 0.0, 0.0,
			0.0, 0.0, 0.5, 0.0,
			0.5, 0.5, 0.5, 1.0
		);

		glm::mat4 depthBiasMVP = biasMatrix*depthMVP;
		
		sm.current()->uniform_matrix4f_value( ShadowDepthBiasMVPID, 1, &depthBiasMVP[0][0]);
		sm.current()->uniform_1i(ShadowMappingOnID, shadow_mapping_on);

		//activate shader porgram and connect data
		//sm.activate();
		//default stuff
		sm.current()->uniform_matrix4f_value( WorldMatrixID, 1, &world_matrix[0][0]);
		sm.current()->uniform_matrix4f_value( ModelMatrixID, 1, &model_matrix[0][0]);
		sm.current()->uniform_matrix4f_value( ViewMatrixID, 1, &view_matrix[0][0]);
		sm.current()->uniform_matrix3f_value( ModelView3x3MatrixID, 1, &model_view_matrix3x3[0][0]);
		//light
		sm.activate();
		sm.current()->uniform_1f(LightAmbientPowerID, light_ambient_power);
		sm.current()->uniform_1i(LightSelfShadowingOnID, light_self_shadowing_on);
		sm.current()->uniform_1i(LightNormalMappingOnID, light_normal_mapping_on);
		sm.current()->uniform_1f_value( LightPowerArrayID, 3, light_power_array );
		sm.current()->uniform_1i_value( LightSpecularTypeArrayID, 3, light_specular_type_array );
		sm.current()->uniform_1f_value( LightSpecularLobeArrayID, 3, light_specular_lobe_array );
		sm.current()->uniform_3f_value( LightColorArrayID, 3, (f32*)light_color_array );
		sm.current()->uniform_3f_value( LightPositionArrayID, 3, (f32*)light_position_array );
		sm.current()->uniform_3f_value( LightDirectionArrayID, 3, (f32*)light_direction_array );
		sm.current()->uniform_1i_value( LightTypeArrayID, 3, light_type_array );
		sm.current()->uniform_1i_value( LightStateArrayID, 3, light_state_array );
		//displacement
		sm.current()->uniform_1i( DisplacementOnID, displacement_on );
		sm.current()->uniform_1f( DisplacementStepsID, displacement_steps);
		sm.current()->uniform_1f( DisplacementRefinementStepsID, displacement_refinement_steps);
		sm.current()->uniform_1f( DisplacementUVFactorID, displacmenet_uv_factor);

		//activate texture buffer and connect data
		diffuse_tbo.activate();
		diffuse_tbo.bind_buffer();
		sm.current()->uniform_1i( DiffuseTextureID, 0);

		normal_tbo.activate();
		normal_tbo.bind_buffer();
		sm.current()->uniform_1i( NormalTextureID, 1);

		height_tbo.activate();
		height_tbo.bind_buffer();
		sm.current()->uniform_1i( HeightTextureID, 2 );

		depthmap.activate();
		depthmap.bind_buffer();
		sm.current()->uniform_1i( ShadowMapID, 4);

		//define data of buffers
		sm.current()->vertex_attribute_array.enable(0);
		//cube_vbo.bind_buffer( vbo::verticies );
		glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
		sm.current()->vertex_attribute_array.pointer( 0, 3, crap::gl_float, false, 0, (void*)0);

		sm.current()->vertex_attribute_array.enable(1);
		glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
		//cube_vbo.bind_buffer( vbo::uvs );
		sm.current()->vertex_attribute_array.pointer( 1, 2, crap::gl_float, false, 0, (void*)0);

		sm.current()->vertex_attribute_array.enable(2);
		glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
		//cube_vbo.bind_buffer( vbo::normals );
		sm.current()->vertex_attribute_array.pointer( 2, 3, crap::gl_float, false, 0, (void*)0);

		sm.current()->vertex_attribute_array.enable(3);
		glBindBuffer(GL_ARRAY_BUFFER, tangentbuffer);
		//cube_vbo.bind_buffer( vbo::tangents );
		sm.current()->vertex_attribute_array.pointer( 3, 3, crap::gl_float, false, 0, (void*)0);

		sm.current()->vertex_attribute_array.enable(4);
		glBindBuffer(GL_ARRAY_BUFFER, bitangentbuffer);
		//cube_vbo.bind_buffer( vbo::binormals );
		sm.current()->vertex_attribute_array.pointer( 4, 3, crap::gl_float, false, 0, (void*)0);

		////draw the f**k
		cube_vbo.bind_buffer( vbo::indicies );
		crap::opengl::draw_elements(
			crap::opengl::triangles,		// mode
			cube_vbo.indicies_size,			// count
			crap::opengl::unsigned_short	// type
		);

		sm.current()->vertex_attribute_array.disable(0);
		sm.current()->vertex_attribute_array.disable(1);
		sm.current()->vertex_attribute_array.disable(2);
		sm.current()->vertex_attribute_array.disable(3);
		sm.current()->vertex_attribute_array.disable(4);

		//next object
		glm::mat4 model_matrix_2 = model_matrix * glm::translate(3.f,0.f,0.f);
		model_view_matrix = view_matrix * model_matrix_2;
		model_view_matrix3x3 = glm::mat3(model_view_matrix);
		world_matrix = projection_matrix * view_matrix * model_matrix_2;

		//activate shader porgram and connect data
		//sm.activate();
		sm.current()->uniform_matrix4f_value( WorldMatrixID, 1, &world_matrix[0][0]);
		sm.current()->uniform_matrix4f_value( ModelMatrixID, 1, &model_matrix_2[0][0]);
		sm.current()->uniform_matrix3f_value( ModelView3x3MatrixID, 1, &model_view_matrix3x3[0][0]);

		//attempt
		//define data of buffers
		sm.current()->vertex_attribute_array.enable(0);
		ape_vbo.bind_buffer( vbo::verticies );
		sm.current()->vertex_attribute_array.pointer( 0, 3, crap::gl_float, false, 0, (void*)0);

		sm.current()->vertex_attribute_array.enable(1);
		ape_vbo.bind_buffer( vbo::uvs );
		sm.current()->vertex_attribute_array.pointer( 1, 2, crap::gl_float, false, 0, (void*)0);

		sm.current()->vertex_attribute_array.enable(2);
		ape_vbo.bind_buffer( vbo::normals );
		sm.current()->vertex_attribute_array.pointer( 2, 3, crap::gl_float, false, 0, (void*)0);

		sm.current()->vertex_attribute_array.enable(3);
		ape_vbo.bind_buffer( vbo::tangents );
		sm.current()->vertex_attribute_array.pointer(3, 3, crap::gl_float, false, 0, (void*)0);

		sm.current()->vertex_attribute_array.enable(4);
		ape_vbo.bind_buffer( vbo::binormals );
		sm.current()->vertex_attribute_array.pointer( 4, 3, crap::gl_float, false, 0, (void*)0);


		//draw the f**k
		ape_vbo.bind_buffer( vbo::indicies );
		crap::opengl::draw_elements(
			crap::opengl::triangles,		// mode
			ape_vbo.indicies_size,			// count
			crap::opengl::unsigned_short	// type
		);

		//disable data define stuff
		sm.current()->vertex_attribute_array.disable(0);
		sm.current()->vertex_attribute_array.disable(1);
		sm.current()->vertex_attribute_array.disable(2);
		sm.current()->vertex_attribute_array.disable(3);
		sm.current()->vertex_attribute_array.disable(4);

		//next object
		glm::mat4 model_matrix_3 = model_matrix * glm::translate(0.f,-2.f,0.f);
		model_view_matrix = view_matrix * model_matrix_2;
		model_view_matrix3x3 = glm::mat3(model_view_matrix);
		world_matrix = projection_matrix * view_matrix * model_matrix_3;

		//activate shader porgram and connect data
		//sm.activate();
		sm.current()->uniform_matrix4f_value( WorldMatrixID, 1, &world_matrix[0][0]);
		sm.current()->uniform_matrix4f_value( ModelMatrixID, 1, &model_matrix_3[0][0]);
		sm.current()->uniform_matrix3f_value( ModelView3x3MatrixID, 1, &model_view_matrix3x3[0][0]);

		//attempt
		//define data of buffers
		sm.current()->vertex_attribute_array.enable(0);
		cube_big_vbo.bind_buffer( vbo::verticies );
		sm.current()->vertex_attribute_array.pointer( 0, 3, crap::gl_float, false, 0, (void*)0);

		sm.current()->vertex_attribute_array.enable(1);
		cube_big_vbo.bind_buffer( vbo::uvs );
		sm.current()->vertex_attribute_array.pointer( 1, 2, crap::gl_float, false, 0, (void*)0);

		sm.current()->vertex_attribute_array.enable(2);
		cube_big_vbo.bind_buffer( vbo::normals );
		sm.current()->vertex_attribute_array.pointer( 2, 3, crap::gl_float, false, 0, (void*)0);

		sm.current()->vertex_attribute_array.enable(3);
		cube_big_vbo.bind_buffer( vbo::tangents );
		sm.current()->vertex_attribute_array.pointer(3, 3, crap::gl_float, false, 0, (void*)0);

		sm.current()->vertex_attribute_array.enable(4);
		cube_big_vbo.bind_buffer( vbo::binormals );
		sm.current()->vertex_attribute_array.pointer( 4, 3, crap::gl_float, false, 0, (void*)0);


		//draw the f**k
		cube_big_vbo.bind_buffer( vbo::indicies );
		crap::opengl::draw_elements(
			crap::opengl::triangles,		// mode
			cube_big_vbo.indicies_size,			// count
			crap::opengl::unsigned_short	// type
		);

		//disable data define stuff
		sm.current()->vertex_attribute_array.disable(0);
		sm.current()->vertex_attribute_array.disable(1);
		sm.current()->vertex_attribute_array.disable(2);
		sm.current()->vertex_attribute_array.disable(3);
		sm.current()->vertex_attribute_array.disable(4);

		glMatrixMode(GL_PROJECTION);
		glLoadMatrixf((const GLfloat*)&projection_matrix[0]);
		glMatrixMode(GL_MODELVIEW);
		glm::mat4 MV = view_matrix * model_matrix;
		glLoadMatrixf((const GLfloat*)&MV[0]);

		sm.activate();

		// normals
		glColor3f(0,0,1);
		glBegin(GL_LINES);
		for (unsigned int i=0; i<ig.indices_size; i++){
			glm::vec3 p = glm::vec3(ig.positions[ig.indices[i]].x, ig.positions[ig.indices[i]].y, ig.positions[ig.indices[i]].z );
			glVertex3fv(&p.x);
			glm::vec3 o = glm::normalize( glm::vec3(ig.normals[ig.indices[i]].x, ig.normals[ig.indices[i]].y, ig.normals[ig.indices[i]].z)  );
			p+=o*0.1f;
			glVertex3fv(&p.x);
		}
		glEnd();
		// tangents
		glColor3f(1,0,0);
		glBegin(GL_LINES);
		for (unsigned int i=0; i<ig.indices_size; i++){
			glm::vec3 p = glm::vec3(ig.positions[ig.indices[i]].x, ig.positions[ig.indices[i]].y, ig.positions[ig.indices[i]].z );
			glVertex3fv(&p.x);
			glm::vec3 o = glm::normalize( glm::vec3(ig.tangents[ig.indices[i]].x, ig.tangents[ig.indices[i]].y, ig.tangents[ig.indices[i]].z)  );
			p+=o*0.1f;
			glVertex3fv(&p.x);
		}
		glEnd();

		// bitangents
		glColor3f(0,1,0);
		glBegin(GL_LINES);
		for (unsigned int i=0; i<ig.indices_size; i++){
			glm::vec3 p = glm::vec3(ig.positions[ig.indices[i]].x, ig.positions[ig.indices[i]].y, ig.positions[ig.indices[i]].z );
			glVertex3fv(&p.x);
			glm::vec3 o = glm::normalize( glm::vec3(ig.binormals[ig.indices[i]].x, ig.binormals[ig.indices[i]].y, ig.binormals[ig.indices[i]].z)  );
			p+=o*0.1f;
			glVertex3fv(&p.x);
		}
		glEnd();

		glm::vec3 debug_light;

		// light pos 1
		glColor3f(1,1,1);
		glBegin(GL_LINES);
			debug_light = light_position_array[0];
			glVertex3fv(&debug_light.x);
			debug_light+=glm::vec3(1,0,0)*0.1f;
			glVertex3fv(&debug_light.x);
			debug_light-=glm::vec3(1,0,0)*0.1f;
			glVertex3fv(&debug_light.x);
			debug_light+=glm::vec3(0,1,0)*0.1f;
			glVertex3fv(&debug_light.x);
		glEnd();


			// light pos 2
			glColor3f(1,1,1);
			glBegin(GL_LINES);
				debug_light = light_position_array[1];
				glVertex3fv(&debug_light.x);
				debug_light+=glm::vec3(1,0,0)*0.1f;
				glVertex3fv(&debug_light.x);
				debug_light-=glm::vec3(1,0,0)*0.1f;
				glVertex3fv(&debug_light.x);
				debug_light+=glm::vec3(0,1,0)*0.1f;
				glVertex3fv(&debug_light.x);
			glEnd();
	


			// light pos3
			glColor3f(1,1,1);
			glBegin(GL_LINES);
				debug_light = light_position_array[2];
				glVertex3fv(&debug_light.x);
				debug_light+=glm::vec3(1,0,0)*0.1f;
				glVertex3fv(&debug_light.x);
				debug_light-=glm::vec3(1,0,0)*0.1f;
				glVertex3fv(&debug_light.x);
				debug_light+=glm::vec3(0,1,0)*0.1f;
				glVertex3fv(&debug_light.x);
			glEnd();
		

		// Draw GUI
		TwDraw();

		//poll and swap
		window.swap();
		window.poll_events();

	}

	TwTerminate();

	//geometry_content ig;
	//cm.create_content( "ape" , &ig, type_name::geometry );

	//texture_content tc;
	//cm.create_content( "color", &tc, type_name::texture );

	//shader_content sc;
	//cm.create_content( "fragment_texture_only", &sc, type_name::shader );

	//cm.save_content( "fragment_texture_only", &sc, type_name::shader );
	return 0;
}