计算机图形学 —— OpenGL光照模型

Specular.vs

attribute vec3 pos;
attribute vec2 texcoord;
attribute vec3 normal;

uniform mat4 M;
uniform mat4 V;
uniform mat4 P;
uniform mat4 NM;

varying vec3 V_Normal;
varying vec4 V_WorldPos;
void main()
{
	V_Normal = mat3(NM) * normal;
	V_WorldPos = M*vec4(pos,1.0);
	gl_Position=P*V*M*vec4(pos,1.0);
}

Specular.fs

//uniform vec4 U_AmbientLightColor;
//uniform vec4 U_AmbientMaterial;
varying vec3 V_Normal;
varying vec4 V_WorldPos;

void main()
{
	vec3 lightPos = vec3(10.0,10.0,0.0);
	vec3 L = lightPos;
	L = normalize(L);
	vec3 n = normalize(V_Normal);
	//ambient
	vec4 AmbientLightColor = vec4(0.2,0.2,0.2,1.0);
	vec4 AmbientMaterial = vec4(0.2,0.2,0.2,1.0);
	vec4 ambientColor = AmbientLightColor * AmbientMaterial;

	//diffuse
	vec4 DiffuseLightColor = vec4(1.0,1.0,1.0,1.0);
	vec4 DiffuseMaterial = vec4(0.4,0.4,0.4,1.0);
	vec4 diffuseColor = DiffuseLightColor * DiffuseMaterial * max(0.0, dot(L,n));
	//specular
	vec3 reflectDir = normalize(reflect(-L,n));
	vec4 SpecularLightColor = vec4(1.0,1.0,1.0,1.0);
	vec4 SpecularMaterial = vec4(0.8,0.8,0.8,1.0);
	//inverse view direction
	vec3 viewDir = normalize(vec3(0.0) - V_WorldPos.xyz);
	vec4 specularColor = SpecularLightColor * SpecularMaterial * pow(max(0.0, dot(viewDir, reflectDir)), 18.0);

	gl_FragColor = ambientColor + diffuseColor + specularColor;
}

Main.cpp

#include <windows.h>
#include <stdio.h>
#include <GLEW/glew.h>
#include <glm/glm.hpp>
#include <glm/ext.hpp>
#include <glm/ext/matrix_transform.hpp>
#include "misc.h"
#include "model.h"

#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glew32.lib")
#pragma comment(lib, "winmm.lib")

LRESULT CALLBACK GLWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg)
	{
	case WM_LBUTTONDOWN:
		break;
	case WM_LBUTTONUP:
		break;
	case WM_MOUSEMOVE:
		break;
	case WM_RBUTTONDOWN:
		break;
	case WM_RBUTTONUP:
		break;
	case WM_KEYDOWN:
		break;
	case WM_KEYUP:
		break;
	case WM_CLOSE:
		PostQuitMessage(0);
		break;
	default:
		break;
	}
	return DefWindowProc(hwnd, msg, wParam, lParam);
}


INT WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
	//注册窗口
	WNDCLASSEX wndclass;
	wndclass.cbClsExtra = 0;
	wndclass.cbSize = sizeof(WNDCLASSEX);
	wndclass.cbWndExtra = 0;
	wndclass.hbrBackground = NULL;
	wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
	wndclass.hIcon = NULL;
	wndclass.hIconSm = NULL;
	wndclass.hInstance = hInstance;
	wndclass.lpfnWndProc = GLWindowProc;
	wndclass.lpszClassName = L"GLWindow";
	wndclass.lpszMenuName = NULL;
	wndclass.style = CS_VREDRAW | CS_HREDRAW;
	ATOM atom = RegisterClassEx(&wndclass);
	if (!atom) {
		return -1;
	}
	RECT rect;
	rect.left = 0;
	rect.right = 1280;
	rect.top = 0;
	rect.bottom = 720;
	AdjustWindowRect(&rect, WS_EX_OVERLAPPEDWINDOW, NULL);

	//创建窗口
	HWND hwnd = CreateWindowEx(NULL, L"GLWindow", L"OpenGL Window", WS_OVERLAPPEDWINDOW,
		100, 100, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, hInstance, NULL);

	GetClientRect(hwnd, &rect);
	int viewportWidth = rect.right - rect.left;
	int viewportHeight = rect.bottom - rect.top;
	//创建OpenGL渲染窗口 
	//create opengl render context
	HDC dc = GetDC(hwnd);
	PIXELFORMATDESCRIPTOR pfd;
	memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
	pfd.nVersion = 1;
	pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
	pfd.cColorBits = 32;
	pfd.cDepthBits = 24;
	pfd.cStencilBits = 8;
	pfd.iPixelType = PFD_TYPE_RGBA;
	pfd.iLayerType = PFD_MAIN_PLANE;
	pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;

	int pixelFormat = ChoosePixelFormat(dc, &pfd);
	SetPixelFormat(dc, pixelFormat, &pfd);

	HGLRC rc = wglCreateContext(dc);
	wglMakeCurrent(dc, rc); // setup OpenGL context complete

	glewInit();
	GLuint program = CreateGPUProgram("res/shader/Specular.vs", "res/shader/Specular.fs");
	GLint posLocation, texcoordLocation, normalLocation, MLocation, VLocation, PLocation, NMLocation;
	posLocation = glGetAttribLocation(program, "pos");
	texcoordLocation = glGetAttribLocation(program, "texcoord");
	normalLocation = glGetAttribLocation(program, "normal");

	MLocation = glGetUniformLocation(program, "M");
	VLocation = glGetUniformLocation(program, "V");
	PLocation = glGetUniformLocation(program, "P");
	NMLocation = glGetUniformLocation(program, "NM");
	//load obj model: vertexes, vertex count, indexes, index count
	unsigned int *indexes = nullptr;
	int vertexCount = 0, indexCount = 0;
	VertexData*vertexes = LoadObjModel("res/model/Sphere.obj", &indexes, vertexCount, indexCount);
	if (vertexes == nullptr)
	{
		printf("load obj model fail");
	}

	//obj model -> vbo & ibo
	GLuint vbo = CreateBufferObject(GL_ARRAY_BUFFER, sizeof(VertexData) * vertexCount, GL_STATIC_DRAW, vertexes);
	GLuint ibo = CreateBufferObject(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * indexCount, GL_STATIC_DRAW, indexes);
	printf("vetex count %d index count %d", vertexCount, indexCount);

	glClearColor(0.f, 0.f, 0.f, 1.f);

	//显示窗口
	glViewport(0, 0, viewportWidth, viewportHeight);
	//glClearColor(41.f / 255.f, 71.f / 255.f, 121.f / 255.f, 1.0f); //set "clear color" for background
	glEnable(GL_DEPTH_TEST);
	ShowWindow(hwnd, SW_SHOW);
	UpdateWindow(hwnd);

	glm::mat4 identity = glm::mat4(1.0f);

	glm::mat4 model;
	model = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -4.0f)); //平移
	model = glm::rotate(model, glm::radians(-90.0f), glm::vec3(0.f, 1.f, 0.f)); //旋转
	//model = glm::scale(model, glm::vec3(0.01f, 0.01f, 0.01f)); //缩放
	glm::mat4 projection = glm::perspective(45.f, (float)viewportWidth / (float)viewportHeight, 0.1f, 1000.f);

	glm::mat4 normalMatrix = glm::inverseTranspose(model);

	static float sTimeSinceStartUp = timeGetTime() / 1000.0f;
	MSG msg;
	while (true)
	{
		if (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE)) {
			if (msg.message == WM_QUIT) {
				break;
			}
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		//draw scene

		//计算两帧之间的时间
		float currentTime = timeGetTime() / 1000.0f;
		float timeElapse = currentTime - sTimeSinceStartUp;
		sTimeSinceStartUp = currentTime;

		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		glUseProgram(program);
		glUniformMatrix4fv(MLocation, 1, GL_FALSE, glm::value_ptr(model));
		glUniformMatrix4fv(VLocation, 1, GL_FALSE, glm::value_ptr(identity));
		glUniformMatrix4fv(PLocation, 1, GL_FALSE, glm::value_ptr(projection));
		glUniformMatrix4fv(NMLocation, 1, GL_FALSE, glm::value_ptr(normalMatrix));

		glBindBuffer(GL_ARRAY_BUFFER, vbo);
		glEnableVertexAttribArray(posLocation);
		glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)0);
		glEnableVertexAttribArray(texcoordLocation);
		glVertexAttribPointer(texcoordLocation, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)(sizeof(float) * 3));
		glEnableVertexAttribArray(normalLocation);
		glVertexAttribPointer(normalLocation, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)(sizeof(float) * 5));

		glBindBuffer(GL_ARRAY_BUFFER, 0);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
		glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, 0);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
		glUseProgram(0);
		//printf("time elapse since last frame: %f\n", timeElapse);
		//present scene
		SwapBuffers(dc);
	}
	return 0;
}

其他模块代码见上一章
计算机图形学 —— OpenGL绘制模型

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值