diff --git a/.gitignore b/.gitignore index e257658..8965e0f 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,9 @@ *.out *.app +#vs2015 +Debug +Release +x64 +.git +ipch diff --git a/Res/back.bmp b/Res/back.bmp new file mode 100644 index 0000000..2e719f9 Binary files /dev/null and b/Res/back.bmp differ diff --git a/Res/bottom.bmp b/Res/bottom.bmp new file mode 100644 index 0000000..1bb5dfb Binary files /dev/null and b/Res/bottom.bmp differ diff --git a/Res/chair.mtl b/Res/chair.mtl new file mode 100644 index 0000000..591e4de --- /dev/null +++ b/Res/chair.mtl @@ -0,0 +1,12 @@ +# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware +# 创建的文件:02.04.2020 16:02:29 + +newmtl wire_086086086 + Ns 32 + d 1 + Tr 0 + Tf 1 1 1 + illum 2 + Ka 0.0000 0.0000 0.0000 + Kd 0.3373 0.3373 0.3373 + Ks 0.3500 0.3500 0.3500 diff --git a/Res/earth.bmp b/Res/earth.bmp new file mode 100644 index 0000000..681bb7f Binary files /dev/null and b/Res/earth.bmp differ diff --git a/Res/front.bmp b/Res/front.bmp new file mode 100644 index 0000000..8f98874 Binary files /dev/null and b/Res/front.bmp differ diff --git a/Res/ground.fs b/Res/ground.fs new file mode 100644 index 0000000..736ede7 --- /dev/null +++ b/Res/ground.fs @@ -0,0 +1,26 @@ +#ifdef GL_ES +precision mediump float; +#endif +varying vec4 V_Color; +varying vec3 V_Normal; +varying vec3 V_WorldPos; +vec4 GetPointLight() +{ + float distance=0.0; + float constantFactor=1.0; + float linearFactor=0.0; + float quadricFactor=0.0; + vec4 ambientColor=vec4(1.0,1.0,1.0,1.0)*vec4(0.1,0.1,0.1,1.0); + vec3 L=vec3(0.0,1.0,0.0)-V_WorldPos; + distance=length(L); + float attenuation=1.0/(constantFactor+linearFactor*distance+quadricFactor*quadricFactor*distance); + L=normalize(L); + vec3 n=normalize(V_Normal); + float diffuseIntensity=max(0.0,dot(L,n)); + vec4 diffuseColor=vec4(1.0,1.0,1.0,1.0)*vec4(0.1,0.4,0.6,1.0)*diffuseIntensity*attenuation; + return ambientColor+diffuseColor; +} +void main() +{ + gl_FragColor=V_Color*GetPointLight(); +} \ No newline at end of file diff --git a/Res/ground.vs b/Res/ground.vs new file mode 100644 index 0000000..00b88d9 --- /dev/null +++ b/Res/ground.vs @@ -0,0 +1,16 @@ +attribute vec4 position; +attribute vec4 color; +attribute vec4 normal; +uniform mat4 ModelMatrix; +uniform mat4 ViewMatrix; +uniform mat4 ProjectionMatrix; +varying vec4 V_Color; +varying vec3 V_Normal; +varying vec3 V_WorldPos; +void main() +{ + V_Color=color; + V_Normal=normal.xyz; + V_WorldPos=(ModelMatrix*position).xyz; + gl_Position=ProjectionMatrix*ViewMatrix*ModelMatrix*position; +} \ No newline at end of file diff --git a/Res/head.png b/Res/head.png new file mode 100644 index 0000000..055c373 Binary files /dev/null and b/Res/head.png differ diff --git a/Res/left.bmp b/Res/left.bmp new file mode 100644 index 0000000..814b933 Binary files /dev/null and b/Res/left.bmp differ diff --git a/Res/model.fs b/Res/model.fs new file mode 100644 index 0000000..48e46b0 --- /dev/null +++ b/Res/model.fs @@ -0,0 +1,56 @@ +#ifdef GL_ES +precision mediump float; +#endif +uniform sampler2D U_Texture; +uniform vec4 U_LightPos; +uniform vec4 U_LightAmbient; +uniform vec4 U_LightDiffuse; +uniform vec4 U_LightSpecular; +uniform vec4 U_AmbientMaterial; +uniform vec4 U_DiffuseMaterial; +uniform vec4 U_SpecularMaterial; +uniform vec4 U_CameraPos; +uniform vec4 U_LightOpt; +varying vec4 V_Texcoord; +varying vec4 V_WorldPos; +varying vec4 V_Normal; + +vec4 GetPointLight() +{ + float distance=0.0; + float constantFactor=1.0; + float linearFactor=0.0; + float quadricFactor=0.0; + vec4 ambientColor=vec4(1.0,1.0,1.0,1.0)*vec4(0.1,0.1,0.1,1.0); + vec3 L=vec3(0.0,1.0,0.0)-V_WorldPos.xyz; + distance=length(L); + float attenuation=1.0/(constantFactor+linearFactor*distance+quadricFactor*quadricFactor*distance); + L=normalize(L); + vec3 n=normalize(V_Normal.xyz); + float diffuseIntensity=max(0.0,dot(L,n)); + vec4 diffuseColor=vec4(1.0,1.0,1.0,1.0)*vec4(0.1,0.4,0.6,1.0)*diffuseIntensity*attenuation; + return ambientColor+diffuseColor; +} +void main() +{ + vec4 ambientColor=U_LightAmbient*U_AmbientMaterial; + vec3 lightPos=U_LightPos.xyz; + vec3 L=lightPos; + L=normalize(L); + vec3 n=normalize(V_Normal.xyz); + float diffuseIntensity=max(0.0,dot(L,n)); + vec4 diffuseColor=U_LightDiffuse*U_DiffuseMaterial*diffuseIntensity; + vec4 specularColor=vec4(0.0,0.0,0.0,0.0); + if(diffuseIntensity!=0.0){ + vec3 reflectDir=normalize(reflect(-L,n)); + vec3 viewDir=normalize(U_CameraPos.xyz-V_WorldPos.xyz); + specularColor=U_LightSpecular*U_SpecularMaterial*pow(max(0.0,dot(viewDir,reflectDir)),U_LightOpt.x); + } + if(U_LightOpt.y==1.0){ + gl_FragColor=(ambientColor+diffuseColor)*texture2D(U_Texture,V_Texcoord.xy)+specularColor; + }else if(U_LightOpt.z==1.0){ + gl_FragColor=(ambientColor+diffuseColor+GetPointLight())*texture2D(U_Texture,V_Texcoord.xy); + }else if(U_LightOpt.w==1.0){ + gl_FragColor=ambientColor+diffuseColor+specularColor; + } +} \ No newline at end of file diff --git a/Res/model.vs b/Res/model.vs new file mode 100644 index 0000000..e3eb181 --- /dev/null +++ b/Res/model.vs @@ -0,0 +1,17 @@ +attribute vec4 position; +attribute vec4 texcoord; +attribute vec4 normal; +uniform mat4 ModelMatrix; +uniform mat4 IT_ModelMatrix; +uniform mat4 ViewMatrix; +uniform mat4 ProjectionMatrix; +varying vec4 V_Texcoord; +varying vec4 V_WorldPos; +varying vec4 V_Normal; +void main() +{ + V_Texcoord=texcoord; + V_Normal=IT_ModelMatrix*normal; + V_WorldPos=ModelMatrix*position; + gl_Position=ProjectionMatrix*ViewMatrix*V_WorldPos; +} \ No newline at end of file diff --git a/Res/niutou.bmp b/Res/niutou.bmp new file mode 100644 index 0000000..3ebf2b5 Binary files /dev/null and b/Res/niutou.bmp differ diff --git a/Res/particle.fs b/Res/particle.fs new file mode 100644 index 0000000..ee475ca --- /dev/null +++ b/Res/particle.fs @@ -0,0 +1,9 @@ +#ifdef GL_ES +precision mediump float; +#endif +uniform sampler2D U_Texture; +varying vec4 V_Color; +void main() +{ + gl_FragColor=texture2D(U_Texture,gl_PointCoord.xy)*V_Color; +} \ No newline at end of file diff --git a/Res/particle.vs b/Res/particle.vs new file mode 100644 index 0000000..213e629 --- /dev/null +++ b/Res/particle.vs @@ -0,0 +1,14 @@ +attribute vec4 position; +attribute vec4 color; +attribute vec4 normal; +uniform mat4 ModelMatrix; +uniform mat4 ViewMatrix; +uniform mat4 ProjectionMatrix; +varying vec4 V_Color; +void main() +{ + V_Color=color; + gl_PointSize=64.0; + vec4 pos=vec4(position.x+normal.x,position.y+normal.y,position.z+normal.z,1.0); + gl_Position=ProjectionMatrix*ViewMatrix*ModelMatrix*pos; +} \ No newline at end of file diff --git a/Res/right.bmp b/Res/right.bmp new file mode 100644 index 0000000..dbeeb24 Binary files /dev/null and b/Res/right.bmp differ diff --git a/Res/skybox.fs b/Res/skybox.fs new file mode 100644 index 0000000..92021ea --- /dev/null +++ b/Res/skybox.fs @@ -0,0 +1,9 @@ +#ifdef GL_ES +precision mediump float; +#endif +uniform sampler2D U_Texture; +varying vec4 V_Texcoord; +void main() +{ + gl_FragColor=texture2D(U_Texture,V_Texcoord.xy); +} \ No newline at end of file diff --git a/Res/skybox.vs b/Res/skybox.vs new file mode 100644 index 0000000..b38398f --- /dev/null +++ b/Res/skybox.vs @@ -0,0 +1,11 @@ +attribute vec4 position; +attribute vec4 texcoord; +uniform mat4 ModelMatrix; +uniform mat4 ViewMatrix; +uniform mat4 ProjectionMatrix; +varying vec4 V_Texcoord; +void main() +{ + V_Texcoord=texcoord; + gl_Position=ProjectionMatrix*ViewMatrix*ModelMatrix*position; +} \ No newline at end of file diff --git a/Res/test.bmp b/Res/test.bmp new file mode 100644 index 0000000..7448ec5 Binary files /dev/null and b/Res/test.bmp differ diff --git a/Res/texture.fs b/Res/texture.fs new file mode 100644 index 0000000..f91b87d --- /dev/null +++ b/Res/texture.fs @@ -0,0 +1,7 @@ +#ifdef GL_ES +precision mediump float; +#endif +void main() +{ + gl_FragColor=vec4(1.0,1.0,1.0,1.0); +} \ No newline at end of file diff --git a/Res/texture.vs b/Res/texture.vs new file mode 100644 index 0000000..deb535f --- /dev/null +++ b/Res/texture.vs @@ -0,0 +1,9 @@ +attribute vec4 position; +uniform mat4 ModelMatrix; +uniform mat4 ViewMatrix; +uniform mat4 ProjectionMatrix; + +void main() +{ + gl_Position=ProjectionMatrix*ViewMatrix*ModelMatrix*position; +} \ No newline at end of file diff --git a/Res/top.bmp b/Res/top.bmp new file mode 100644 index 0000000..b8edbe5 Binary files /dev/null and b/Res/top.bmp differ diff --git a/camera.cpp b/camera.cpp new file mode 100644 index 0000000..3b4c3a6 --- /dev/null +++ b/camera.cpp @@ -0,0 +1,106 @@ +#include "camera.h" + +Camera::Camera() : mPos(0.0f,0.0f,0.0f),mViewCenter(0.0f,0.0f,-1.0f),mUp(0.0f,1.0f,0.0f) +{ + mbMoveLeft = false; + mbMoveRight = false; + mbMoveForward = false; + mbMoveBack = false; +} + +void Camera::Update(float deltaTime) +{ + float moveSpeed = 10.0f; + + //前方的向量 + Vector3f forwardDirection = mViewCenter - mPos; + forwardDirection.Normalize(); + + //右方的向量 + Vector3f rightDirection = Cross(forwardDirection, mUp); + rightDirection.Normalize(); + + if (mbMoveLeft) { + Vector3f delta = rightDirection * deltaTime * moveSpeed; + mPos = mPos - delta; + mViewCenter = mViewCenter - delta; + } + + if (mbMoveRight) { + Vector3f delta = rightDirection * deltaTime * moveSpeed; + mPos = mPos + delta; + mViewCenter = mViewCenter + delta; + } + + if (mbMoveForward) { + Vector3f delta = forwardDirection * deltaTime * moveSpeed; + mPos = mPos + delta; + mViewCenter = mViewCenter + delta; + } + + if (mbMoveBack) { + Vector3f delta = forwardDirection * deltaTime * moveSpeed; + mPos = mPos - delta; + mViewCenter = mViewCenter - delta; + } + + glLoadIdentity(); + gluLookAt( + mPos.x, mPos.y, mPos.z, + mViewCenter.x, mViewCenter.y, mViewCenter.z, + mUp.x, mUp.y, mUp.z + ); + +} + +void Camera::Picth(float angle) +{ + Vector3f viewDirection = mViewCenter - mPos; + viewDirection.Normalize(); + Vector3f rightDirection = Cross(viewDirection, mUp); + rightDirection.Normalize(); + RotateView(angle, rightDirection.x, rightDirection.y, rightDirection.z); +} + +void Camera::Yaw(float angle) +{ + RotateView(angle, mUp.x, mUp.y, mUp.z); +} + +void Camera::RotateView(float angle, float x, float y, float z) +{ + Vector3f viewDirection = mViewCenter - mPos; + Vector3f newDirection(0.0f, 0.0f, 0.0f); + + float C = cosf(angle); + float S = sinf(angle); + + Vector3f tempX(C + x*x*(1-C), x*y*(1-C)-z*S,x*z*(1-C)+y*S); + newDirection.x = tempX*viewDirection; + + Vector3f tempY(x*y*(1-C)+z*S, C+y*y*(1-C),y*z*(1-C)-x*S); + newDirection.y = tempY * viewDirection; + + Vector3f tempZ(x*z*(1-C)-y*S, y*z*(1-C)+x*S, C+z*z*(1-C)); + newDirection.z = tempZ* viewDirection; + + mViewCenter = mPos + newDirection; +} + +void Camera::SwitchTo3D() +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(50.0f, (float)mViewportWidth / (float)mViewportHeight, 0.1f, 1000.0f); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +void Camera::SwitchTo2D() +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(-mViewportWidth / 2, mViewportWidth / 2, -mViewportHeight / 2, mViewportHeight / 2); + glMatrixMode(); + glLoadIdentity(); +} diff --git a/camera.h b/camera.h new file mode 100644 index 0000000..4f9d025 --- /dev/null +++ b/camera.h @@ -0,0 +1,16 @@ +#pragma once +#include "vector3.h" + +class Camera { +public: + Camera(); + Vector3f mPos, mViewCenter, mUp; + bool mbMoveLeft, mbMoveRight, mbMoveForward, mbMoveBack; + int mViewportWidth, mViewportHeight; + void Update(float deltaTime); + void Picth(float angle); + void Yaw(float angle); + void RotateView(float angle, float x, float y, float z); + void SwitchTo3D(); + void SwitchTo2D(); +}; \ No newline at end of file diff --git a/ggl.h b/ggl.h new file mode 100644 index 0000000..1a08d92 --- /dev/null +++ b/ggl.h @@ -0,0 +1,13 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include \ No newline at end of file diff --git a/ground.cpp b/ground.cpp new file mode 100644 index 0000000..d9e78e8 --- /dev/null +++ b/ground.cpp @@ -0,0 +1,58 @@ +#include "ground.h" + +void Ground::Draw() +{ + glEnable(GL_LIGHTING); + glMaterialfv(GL_FRONT, GL_AMBIENT, mAmbientMaterial); + glMaterialfv(GL_FRONT, GL_DIFFUSE, mDiffuseMaterial); + glMaterialfv(GL_FRONT, GL_SPECULAR, mSpecularMaterial); + + //由于地面没有贴图,所以这里要开启颜色追踪 + glEnable(GL_COLOR_MATERIAL); + + glEnable(GL_DEPTH_TEST); + glDisable(GL_TEXTURE_2D); + glBegin(GL_QUADS); + glNormal3f(0.0f, 1.0f, 0.0f); + + for (int z = 0; z < 20; z++) { + float zStart = 100.0f - z * 10.0f; + for (int x = 0; x < 20; x++) { + float xStart = x * 10.0f - 100.0f; + if ((z % 2) ^ (x % 2)) { + glColor4ub(41, 41, 41, 255); + } + else { + glColor4ub(200, 200, 200, 255); + } + + glVertex3f(xStart, -1.0f, zStart); + glVertex3f(xStart + 10.0f, -1.0f, zStart); + glVertex3f(xStart + 10.0f, -1.0f, zStart - 10.0f); + glVertex3f(xStart , -1.0f, zStart - 10.0f); + } + } + + glEnd(); +} + +void Ground::SetAmbientMaterial(float r, float g, float b, float a) { + mAmbientMaterial[0] = r; + mAmbientMaterial[1] = g; + mAmbientMaterial[2] = b; + mAmbientMaterial[3] = a; +} + +void Ground::SetDiffuseMaterial(float r, float g, float b, float a) { + mDiffuseMaterial[0] = r; + mDiffuseMaterial[1] = g; + mDiffuseMaterial[2] = b; + mDiffuseMaterial[3] = a; +} + +void Ground::SetSpecularMaterial(float r, float g, float b, float a) { + mSpecularMaterial[0] = r; + mSpecularMaterial[1] = g; + mSpecularMaterial[2] = b; + mSpecularMaterial[3] = a; +} \ No newline at end of file diff --git a/ground.h b/ground.h new file mode 100644 index 0000000..8c5f576 --- /dev/null +++ b/ground.h @@ -0,0 +1,13 @@ +#pragma once +#include "ggl.h" + +class Ground { +public: + float mAmbientMaterial[4], mDiffuseMaterial[4], mSpecularMaterial[4]; + void Draw(); + + //设置材质 + void SetAmbientMaterial(float r, float g, float b, float a); + void SetDiffuseMaterial(float r, float g, float b, float a); + void SetSpecularMaterial(float r, float g, float b, float a); +}; \ No newline at end of file diff --git a/light.cpp b/light.cpp new file mode 100644 index 0000000..de18cee --- /dev/null +++ b/light.cpp @@ -0,0 +1,96 @@ +#include "light.h" + +Light::Light() +{ +} + +void Light::SetAmbientColor(float r, float g, float b, float a) +{ + float ambientColor[] = { r,g,b,a }; + glLightfv(mLightIdentifier, GL_AMBIENT, ambientColor); +} + +void Light::SetDiffuseColor(float r, float g, float b, float a) +{ + float diffuseColor[] = { r,g,b,a }; + glLightfv(mLightIdentifier, GL_DIFFUSE, diffuseColor); +} + +void Light::SetSpecularColor(float r, float g, float b, float a) +{ + float specularColor[] = { r,g,b,a }; + glLightfv(mLightIdentifier, GL_SPECULAR, specularColor); +} + +void Light::Enable() +{ + glEnable(GL_LIGHTING); + glEnable(mLightIdentifier); +} + +DirectionLight::DirectionLight(GLenum light) +{ + mLightIdentifier = light; +} + +void DirectionLight::SetPosition(float x, float y, float z) +{ + float pos[] = { x,y,z, 0.0f }; //这里齐次坐标写了0.0f代表这个光在最远处 + glLightfv(mLightIdentifier, GL_POSITION, pos); +} + +PointLight::PointLight(GLenum light) +{ + mLightIdentifier = light; + memset(mPosition, 0, sizeof(mPosition)); +} + +void PointLight::SetPosition(float x, float y, float z) +{ + //float pos[] = {x,y,z, 1.0f};//这里的齐次坐标为1.0代表在近处 + //glLightfv(mLightIdentifier, GL_POSITION, pos); + mPosition[0] = x; + mPosition[1] = y; + mPosition[2] = z; +} + +void PointLight::SetConstAttenuation(float v) +{ + glLightf(mLightIdentifier, GL_CONSTANT_ATTENUATION, v); +} + +void PointLight::SetLinearAttenuation(float v) +{ + glLightf(mLightIdentifier, GL_LINEAR_ATTENUATION, v); +} + +void PointLight::SetQuadricAttenuation(float v) +{ + glLightf(mLightIdentifier, GL_QUADRATIC_ATTENUATION, v); +} + +void PointLight::Update(float x, float y, float z) +{ + float pos[] = {mPosition[0] - x, mPosition[1] - y, mPosition[2] - z, 1.0f}; + glLightfv(mLightIdentifier, GL_POSITION, pos); +} + +SpotLight::SpotLight(GLenum light):PointLight(light) +{ +} + +void SpotLight::SetDirection(float x, float y, float z) +{ + float dir[] = { x,y,z }; + glLightfv(mLightIdentifier, GL_SPOT_DIRECTION, dir);//设置聚光灯的朝向 +} + +void SpotLight::SetExpone(float v) +{ + glLightf(mLightIdentifier, GL_SPOT_EXPONENT, v);//设置聚光度,其实这里是一个角度,在这个角度内光是不衰减的 +} + +void SpotLight::SetCutoff(float v) +{ + glLightf(mLightIdentifier, GL_SPOT_CUTOFF, v);//设置聚光范围 +} diff --git a/light.h b/light.h new file mode 100644 index 0000000..e74275b --- /dev/null +++ b/light.h @@ -0,0 +1,38 @@ +#pragma once +#include "ggl.h" + +class Light { +protected: + GLenum mLightIdentifier; + Light(); +public: + void SetAmbientColor(float r, float g, float b, float a); + void SetDiffuseColor(float r, float g, float b, float a); + void SetSpecularColor(float r, float g, float b, float a); + void Enable(); +}; + +class DirectionLight : public Light { +public: + DirectionLight(GLenum light); + void SetPosition(float x, float y, float z); +}; + +class PointLight : public Light { + float mPosition[3]; +public: + PointLight(GLenum light); + void SetPosition(float x, float y, float z); + void SetConstAttenuation(float v); + void SetLinearAttenuation(float v); + void SetQuadricAttenuation(float v); + void Update(float x, float y, float z); +}; + +class SpotLight : public PointLight { +public: + SpotLight(GLenum light); + void SetDirection(float x, float y, float z); + void SetExpone(float v); + void SetCutoff(float v); +}; \ No newline at end of file diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..33dd5b2 --- /dev/null +++ b/main.cpp @@ -0,0 +1,167 @@ +#include "ggl.h" +#include "scene.h" +#include "utils.h" +#pragma comment(lib, "opengl32.lib") +#pragma comment(lib, "glu32.lib") +#pragma comment(lib, "winmm.lib") + +POINT originalPos;//鼠标右键被按下时的位置 +bool rotateView = false; + + +unsigned char* LoadFileContent(const char* path, int &filesize) { + unsigned char* fileContent = nullptr; + filesize = 0; + + FILE *pFile = fopen(path, "rb"); + + if (pFile) { + fseek(pFile, 0, SEEK_END);//把文件指针移动至文件末尾 + int nLen = ftell(pFile);//文件位置指针当前位置相对于文件首的偏移字节数,这里其实就是得到了文件的字节长度 + if (nLen > 0) { + rewind(pFile);//把文件指针移到头部 + fileContent = new unsigned char[nLen + 1]; + fread(fileContent, sizeof(unsigned char), nLen, pFile); + fileContent[nLen] = '\0'; + filesize = nLen; + } + fclose(pFile); + } + return fileContent; +} + +/** +* 获取每帧的消耗时间 +*/ +float GetFrameTime() { + static unsigned long lastTime = 0, timeSinceComputerStart = 0; + timeSinceComputerStart = timeGetTime(); + unsigned long frameTime = lastTime == 0 ? 0 : timeSinceComputerStart - lastTime; + lastTime = timeSinceComputerStart; + return float(frameTime) / 1000.0f; +} + +/** +* @hwnd 发起消息的窗口 +* @msg 消息类型 +*/ +LRESULT CALLBACK GLWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { + switch (msg) { + case WM_RBUTTONDOWN: + GetCursorPos(&originalPos);//获取坐标位置 + ShowCursor(false);//隐藏鼠标 + rotateView = true; + return 0; + case WM_RBUTTONUP: + SetCursorPos(originalPos.x, originalPos.y); + ShowCursor(true); + rotateView = false; + return 0; + case WM_MOUSEMOVE: + if (rotateView) { + POINT currentPos; + GetCursorPos(¤tPos);//再一次获取鼠标当前位置 + int deltaX = currentPos.x - originalPos.x; + int deltaY = currentPos.y - originalPos.y; + OnMouseMove(deltaX, deltaY); + SetCursorPos(originalPos.x, originalPos.y); + } + return 0; + case WM_KEYDOWN: + OnKeyDown(wParam); + return 0; + case WM_KEYUP: + OnKeyUp(wParam); + return 0; + case WM_CLOSE: + PostQuitMessage(0); + return 0; + } + + return DefWindowProc(hwnd, msg, wParam, lParam);//其他消息调用window默认处理函数 +} + +/** +* @hinstance 本应用程序启动实例 +* @hPrevInstance 上一次应用程式的实例 +* @IpCmdLine 命令行的参数 +* @ShowCmd 怎么显示窗口 +*/ +INT WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance, LPSTR IpCmdLine, int ShowCmd) { + + /*注册窗口*/ + WNDCLASSEX wndclass; + wndclass.cbClsExtra = 0; //窗口类型的额外空间,这里不需要 + wndclass.cbSize = sizeof(WNDCLASSEX); //窗口实际占用的内存 + wndclass.cbWndExtra = 0; //窗口的额外空间,这里不需要 + wndclass.hbrBackground = NULL; //窗口背景 + wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); //定义鼠标类型 + wndclass.hIcon = NULL; //应用程序exe文件显示图标 + 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) { + MessageBox(NULL, L"Register failed", L"Error", MB_OK); + return 0; + } + + + /*创建窗口*/ + //调整窗口大小 + RECT rect; + rect.left = 0; + rect.right = 800; + rect.top = 0; + rect.bottom = 600; + AdjustWindowRect(&rect, WS_EX_OVERLAPPEDWINDOW, NULL); + int windowWidth = rect.right - rect.left; + int windowHeight = rect.bottom - rect.top; + + //窗口名称一定要和刚才注册窗口的保持一致 + HWND hwnd = CreateWindowEx(NULL, L"GLWindow", L"OpenGL Window", WS_OVERLAPPEDWINDOW, 100, 100, windowWidth, windowHeight, NULL, NULL, hinstance, NULL); + + //设置渲染环境 + HDC dc = GetDC(hwnd);//获取设备上下文 + PIXELFORMATDESCRIPTOR pfd; + memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); + pfd.nVersion = 1; + pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); + pfd.cColorBits = 32; //颜色缓冲区每个像素为32比特4通道RGBA + pfd.cDepthBits = 24; //深度缓冲区每个像素大小,24比特表示一个浮点数 + pfd.cStencilBits = 8; //蒙板缓冲区每像素为8比特 + pfd.iPixelType = PFD_TYPE_RGBA; //设置像素类型为RGBA + pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER ; //表示像素最后输出到窗口 + //设置像素格式 + int pixelFormat = ChoosePixelFormat(dc, &pfd); + SetPixelFormat(dc, pixelFormat, &pfd); + //创建OpenGL渲染环境 + HGLRC rc = wglCreateContext(dc); + wglMakeCurrent(dc, rc);//设置OpenGL渲染环境生效 + + Init(); + + /*显示窗口*/ + ShowWindow(hwnd, SW_SHOW); + UpdateWindow(hwnd); + + /*监听并处理用户请求*/ + MSG msg; + while (true) { + if (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE)) { + if (msg.message == WM_QUIT) { + break; + } + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + Draw(); + SwapBuffers(dc); + } + + return 0; +} \ No newline at end of file diff --git a/model.cpp b/model.cpp new file mode 100644 index 0000000..0e3e618 --- /dev/null +++ b/model.cpp @@ -0,0 +1,193 @@ +#include "model.h" +#include "utils.h" + +Model::Model() +{ + //初始化材质 + memset(mAmbientMaterial, 0, sizeof(mAmbientMaterial)); + memset(mDiffuseMaterial, 0, sizeof(mDiffuseMaterial)); + memset(mSpecularMaterial, 0, sizeof(mSpecularMaterial)); +} + +void Model::Init(const char * modelPath) +{ + struct FloatData { + float v[3]; + }; + + struct VertexDefine { + int posIndex; + int texcoordIndex; + int normalIndex; + }; + + int nFileSize = 0; + unsigned char* fileContent = LoadFileContent(modelPath, nFileSize); + + if (fileContent == nullptr) { + return; + } + + std::vector positions, texcoords, normals; + std::vector vertexes; + std::vector indexes; + std::string temp; + + //存储文件内容,内存块 + std::stringstream ssFileContent((char*)fileContent); + + //存储行数据 + char szOneLine[256]; + + //使用流来读取文件 + while (!ssFileContent.eof()) { + //读取一行 + memset(szOneLine, 0, 256); + ssFileContent.getline(szOneLine, 256); + //空行不处理 + if (strlen(szOneLine) > 0) { + if (szOneLine[0] == 'v') { + std::stringstream ssOneLine(szOneLine); + if (szOneLine[1] == 't') { + ssOneLine >> temp;//通过流输出vt到 temp + FloatData floatData; + ssOneLine >> floatData.v[0]; + ssOneLine >> floatData.v[1]; + texcoords.push_back(floatData); + printf("texcoord : %f,%f\n", floatData.v[0], floatData.v[1]); + } + else if (szOneLine[1] == 'n') { + ssOneLine >> temp; + FloatData floatData; + ssOneLine >> floatData.v[0]; + ssOneLine >> floatData.v[1]; + ssOneLine >> floatData.v[2]; + normals.push_back(floatData); + printf("normal : %f,%f,%f\n", floatData.v[0], floatData.v[1], floatData.v[2]); + } + else { + ssOneLine >> temp; + FloatData floatData; + ssOneLine >> floatData.v[0]; + ssOneLine >> floatData.v[1]; + ssOneLine >> floatData.v[2]; + positions.push_back(floatData); + printf("position : %f,%f,%f\n", floatData.v[0], floatData.v[1], floatData.v[2]); + } + } + else if (szOneLine[0] == 'f') { + std::stringstream ssOneLine(szOneLine); + ssOneLine >> temp; + std::string vertexStr; + + for (int i = 0; i < 3; i++) { + ssOneLine >> vertexStr; + + //获取position索引 + size_t pos = vertexStr.find_first_of('/'); + std::string posIndexStr = vertexStr.substr(0, pos); + + //获取texcoord索引 + size_t pos2 = vertexStr.find_first_of('/', pos + 1); + std::string texcoordIndexStr = vertexStr.substr(pos + 1, pos2 - 1 - pos); + + //获取normal索引 + std::string normalIndexStr = vertexStr.substr(pos2 + 1, vertexStr.length() - 1 - pos2); + + VertexDefine vd; + vd.posIndex = atoi(posIndexStr.c_str()); + vd.texcoordIndex = atoi(texcoordIndexStr.c_str()); + vd.normalIndex = atoi(normalIndexStr.c_str()); + + //去除重复 + int nCurrentVertexIndex = -1; + int nCurrentVertexCount = (int)vertexes.size(); + + for (int j = 0; j < nCurrentVertexCount; j++) { + if (vertexes[j].posIndex == vd.posIndex && vertexes[j].texcoordIndex == vd.texcoordIndex && vertexes[j].normalIndex == vd.normalIndex) { + nCurrentVertexIndex = j; + break; + } + } + + if (nCurrentVertexIndex == -1) { + nCurrentVertexIndex = (int)vertexes.size(); + vertexes.push_back(vd); + } + indexes.push_back(nCurrentVertexIndex); + } + + printf("draw command : %s\n", szOneLine); + } + } + } + + //TODO为啥要复制??? + mIndexCount = (int)indexes.size(); + mIndexes = new unsigned short[mIndexCount]; + for (int i = 0; i < mIndexCount; ++i) { + mIndexes[i] = indexes[i]; + } + + int vertexCount = (int)vertexes.size(); + mVertexes = new VertexData[vertexCount]; + for (int i = 0; i < vertexCount; i++) { + memcpy(mVertexes[i].position, positions[vertexes[i].posIndex - 1].v, sizeof(float) * 3); + memcpy(mVertexes[i].texcoord, texcoords[vertexes[i].texcoordIndex - 1].v, sizeof(float) * 2); + memcpy(mVertexes[i].normal, normals[vertexes[i].normalIndex - 1].v, sizeof(float) * 3); + } + + delete fileContent; +} + +void Model::Draw() +{ + //开启光照 + glEnable(GL_LIGHTING); + glMaterialfv(GL_FRONT, GL_AMBIENT, mAmbientMaterial); + glMaterialfv(GL_FRONT, GL_DIFFUSE, mDiffuseMaterial); + glMaterialfv(GL_FRONT, GL_SPECULAR, mSpecularMaterial); + + //开启纹理 + glEnable(GL_TEXTURE_2D); + //glMaterialf(GL_FRONT, GL_SHININESS, 64.0f); + //glDisable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, mTexture); + glEnable(GL_DEPTH_TEST); + + glPushMatrix(); + glTranslatef(0.0f, 0.0f, -5.0f); + static float t = 0.0; + glRotated(t, 1.0f, 1.0f, 1.0f); + t += 0.05; + glBegin(GL_TRIANGLES); + for (int i = 0; i < mIndexCount; i++) { + glTexCoord2fv(mVertexes[mIndexes[i]].texcoord); + glNormal3fv(mVertexes[mIndexes[i]].normal); + glVertex3fv(mVertexes[mIndexes[i]].position); + } + glEnd(); + glPopMatrix(); +} + + +void Model::SetAmbientMaterial(float r, float g, float b, float a) { + mAmbientMaterial[0] = r; + mAmbientMaterial[1] = g; + mAmbientMaterial[2] = b; + mAmbientMaterial[3] = a; +} + +void Model::SetDiffuseMaterial(float r, float g, float b, float a) { + mDiffuseMaterial[0] = r; + mDiffuseMaterial[1] = g; + mDiffuseMaterial[2] = b; + mDiffuseMaterial[3] = a; +} + +void Model::SetSpecularMaterial(float r, float g, float b, float a) { + mSpecularMaterial[0] = r; + mSpecularMaterial[1] = g; + mSpecularMaterial[2] = b; + mSpecularMaterial[3] = a; +} \ No newline at end of file diff --git a/model.h b/model.h new file mode 100644 index 0000000..1fc584b --- /dev/null +++ b/model.h @@ -0,0 +1,27 @@ +#pragma once +#include "ggl.h" + +struct VertexData { + float position[3]; + float normal[3]; + float texcoord[2]; +}; + +class Model { + +public: + VertexData* mVertexes; + unsigned short *mIndexes; + int mIndexCount; + GLuint mTexture; + float mAmbientMaterial[4], mDiffuseMaterial[4], mSpecularMaterial[4]; + + Model(); + void Init(const char* modelPatch); + void Draw(); + + //设置材质 + void SetAmbientMaterial(float r, float g, float b, float a); + void SetDiffuseMaterial(float r, float g, float b, float a); + void SetSpecularMaterial(float r, float g, float b, float a); +}; \ No newline at end of file diff --git a/opengl.VC.db b/opengl.VC.db new file mode 100644 index 0000000..a1d4865 Binary files /dev/null and b/opengl.VC.db differ diff --git a/opengl.aps b/opengl.aps new file mode 100644 index 0000000..56e338b Binary files /dev/null and b/opengl.aps differ diff --git a/opengl.rc b/opengl.rc new file mode 100644 index 0000000..1d2130d Binary files /dev/null and b/opengl.rc differ diff --git a/opengl.sln b/opengl.sln new file mode 100644 index 0000000..c509877 --- /dev/null +++ b/opengl.sln @@ -0,0 +1,28 @@ +锘 +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl", "opengl.vcxproj", "{43BEF74F-1C6B-4178-AC60-32864B889DE7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {43BEF74F-1C6B-4178-AC60-32864B889DE7}.Debug|x64.ActiveCfg = Debug|x64 + {43BEF74F-1C6B-4178-AC60-32864B889DE7}.Debug|x64.Build.0 = Debug|x64 + {43BEF74F-1C6B-4178-AC60-32864B889DE7}.Debug|x86.ActiveCfg = Debug|Win32 + {43BEF74F-1C6B-4178-AC60-32864B889DE7}.Debug|x86.Build.0 = Debug|Win32 + {43BEF74F-1C6B-4178-AC60-32864B889DE7}.Release|x64.ActiveCfg = Release|x64 + {43BEF74F-1C6B-4178-AC60-32864B889DE7}.Release|x64.Build.0 = Release|x64 + {43BEF74F-1C6B-4178-AC60-32864B889DE7}.Release|x86.ActiveCfg = Release|Win32 + {43BEF74F-1C6B-4178-AC60-32864B889DE7}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/opengl.vcxproj b/opengl.vcxproj new file mode 100644 index 0000000..371c2bb --- /dev/null +++ b/opengl.vcxproj @@ -0,0 +1,173 @@ +锘 + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {43BEF74F-1C6B-4178-AC60-32864B889DE7} + Win32Proj + opengl + 8.1 + + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + + + Windows + true + + + + + + + Level3 + Disabled + _DEBUG;_WINDOWS;%(PreprocessorDefinitions) + + + Windows + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + + + Windows + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + NDEBUG;_WINDOWS;%(PreprocessorDefinitions) + + + Windows + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/opengl.vcxproj.filters b/opengl.vcxproj.filters new file mode 100644 index 0000000..2ca09a4 --- /dev/null +++ b/opengl.vcxproj.filters @@ -0,0 +1,83 @@ +锘 + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 澶存枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + + + + + 璧勬簮鏂囦欢 + + + \ No newline at end of file diff --git a/opengl.vcxproj.user b/opengl.vcxproj.user new file mode 100644 index 0000000..12a5054 --- /dev/null +++ b/opengl.vcxproj.user @@ -0,0 +1,6 @@ +锘 + + + false + + \ No newline at end of file diff --git a/resource.h b/resource.h new file mode 100644 index 0000000..8186be6 --- /dev/null +++ b/resource.h @@ -0,0 +1,14 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by opengl.rc + +// 新对象的下一组默认值 +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/scene.cpp b/scene.cpp new file mode 100644 index 0000000..ecb1f1e --- /dev/null +++ b/scene.cpp @@ -0,0 +1,506 @@ +#include "scene.h" +#include "utils.h" +#include "skybox.h" +#include "model.h" +#include "ground.h" +#include "light.h" +#include "camera.h" + +GLuint texture; +SkyBox skybox; +Model model; +Ground ground; +DirectionLight light(GL_LIGHT0); +PointLight light1(GL_LIGHT1); +PointLight light2(GL_LIGHT2); +SpotLight light3(GL_LIGHT3); +Camera camera; + +void Init() { + glMatrixMode(GL_PROJECTION); + gluPerspective(50.0f, 800.0f / 600.0f, 0.1f, 1000.0f); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + texture = CreateTexture2DFromBMP("Res/earth.bmp"); + + skybox.Init("Res/"); + model.Init("Res/Sphere.obj"); + model.mTexture = CreateTexture2DFromBMP("Res/earth.bmp"); + + light.SetAmbientColor(0.1f, 0.1f, 0.1f, 1.0f); + light.SetDiffuseColor(0.8f, 0.8f, 0.8f, 1.0f); + light.SetSpecularColor(1.0f, 1.0f, 1.0f, 1.0f); + light.SetPosition(0.0f, 1.0f, 0.0f); + + light1.SetAmbientColor(0.1f,0.1f,0.1f,1.0f); + light1.SetDiffuseColor(0.8f,0.8f,0.8f,1.0f); + light1.SetSpecularColor(1.0f,1.0f,1.0f,1.0f); + light1.SetPosition(0.0f,0.0f,0.0f);//把点光源放到摄像机位置 + light1.SetConstAttenuation(1.0f); + light1.SetLinearAttenuation(0.2f); + + light2.SetAmbientColor(0.1f, 0.1f, 0.1f, 1.0f); + light2.SetDiffuseColor(0.1f, 0.4f, 0.6f, 1.0f); + light2.SetSpecularColor(1.0f, 1.0f, 1.0f, 1.0f); + light2.SetPosition(0.0f, 0.0f, -30.0f);//把点光源放到摄像机位置 + light2.SetConstAttenuation(1.0f); + light2.SetLinearAttenuation(0.2f); + + light3.SetAmbientColor(0.1f, 0.1f, 0.1f, 1.0f); + light3.SetDiffuseColor(0.0f, 0.8f, 0.0f, 1.0f); + light3.SetSpecularColor(1.0f,0.0f,0.0f,1.0f); + light3.SetPosition(10.0f,50.0f,-30.0f); + light3.SetDirection(0.0,-1.0f,0.0f);//设置朝向 + light3.SetExpone(5.0f);//设置聚光度 5度 + light3.SetCutoff(10.0f);//设置照射范围 10度 + + + model.SetAmbientMaterial(0.1f, 0.1f, 0.1f, 1.0f); + model.SetDiffuseMaterial(0.4f, 0.4f, 0.4f, 1.0f); + model.SetSpecularMaterial(1.0f, 1.0f, 1.0f, 1.0f); + + ground.SetAmbientMaterial(0.1f, 0.1f, 0.1f, 1.0f); + ground.SetDiffuseMaterial(0.4f, 0.4f, 0.4f, 1.0f); + ground.SetSpecularMaterial(0.0f, 0.0f, 0.0f, 1.0f); + + camera.mViewportWidth = 800.0f; + camera.mViewportHeight = 600.0f; +} + +void DrawMutipl() { + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + glLoadIdentity(); + + glPushMatrix(); + glTranslatef(0.0f, 0.0f, -5.0f); + + static float r = 0; + glPushMatrix(); + glRotatef(r, 0.0f, 1.0f, 0.0f); + + r += 0.1f; + + glBegin(GL_TRIANGLES); + glColor4ub(255, 0, 0, 255); glVertex3f(-0.5f, -0.25f, -2.5f); + glColor4ub(0, 0, 255, 255); glVertex3f(0.5f, -0.25f, -2.5f); + glColor4ub(0, 255, 0, 255); glVertex3f(0.0f, 0.25f, -2.5f); + glEnd(); + + glPopMatrix(); + glPopMatrix(); + +} + +void DrawPushMatrix() { + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + glLoadIdentity();//重置模型视口矩阵为单位矩阵 + + glPushMatrix(); + glTranslatef(-1.0f, 0.0f, 0.0f); + glBegin(GL_TRIANGLES); + glColor4ub(255, 0, 0, 255); glVertex3f(-0.5f, -0.25f, -2.5f); + glColor4ub(0, 0, 255, 255); glVertex3f(0.5f, -0.25f, -2.5f); + glColor4ub(0, 255, 0, 255); glVertex3f(0.0f, 0.25f, -2.5f); + glEnd(); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(1.0f, 0.0f, 0.0f); + glBegin(GL_TRIANGLES); + glColor4ub(255, 0, 0, 255); glVertex3f(-0.5f, -0.25f, -2.5f); + glColor4ub(0, 0, 255, 255); glVertex3f(0.5f, -0.25f, -2.5f); + glColor4ub(0, 255, 0, 255); glVertex3f(0.0f, 0.25f, -2.5f); + glEnd(); + glPopMatrix(); + +} + +void DrawRoated() { + glClearColor(30.0f / 255.0f, 30.0f / 255.0f, 30.0f / 255.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + + static float r = 0.0f; + + glLoadIdentity(); + glRotated(r, 0, 0, 1);// (角度,x,y,z) + + r += 0.1f; + + glBegin(GL_TRIANGLES); + glColor4ub(255, 0, 0, 255); glVertex3f(-0.5f, -0.25f, -2.5f); + glColor4ub(0, 0, 255, 255); glVertex3f(0.5f, -0.25f, -2.5f); + glColor4ub(0, 255, 0, 255); glVertex3f(0.0f, 0.25f, -2.5f); + glEnd(); +} + +void DrawTranslate() { + glClearColor(30.0f / 255.0f, 30.0f / 255.0f, 30.0f / 255.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + glLoadIdentity(); + glTranslatef(0, 0, -2.5f); + + glBegin(GL_TRIANGLES); + glColor4ub(255, 0, 0, 255); glVertex3f(-0.5f, -0.25f, 0.0f); + glColor4ub(0, 0, 255, 255); glVertex3f(0.5f, -0.25f, 0.0f); + glColor4ub(0, 255, 0, 255); glVertex3f(0.0f, 0.25f, 0.0f); + glEnd(); +} + + +void DrawPolygon() { + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + + glBegin(GL_POLYGON); + + glColor4ub(255, 0, 0, 255); glVertex3f(-0.5f, -0.25f, -2.5f); + glColor4ub(0, 0, 255, 255); glVertex3f(0.5f, -0.25, -2.5f); + glColor4ub(0, 255, 0, 255); glVertex3f(1.0f, 0.25f, -2.5f); + glColor4ub(255, 0, 0, 255); glVertex3f(0.5f, 0.25f, -2.5f); + glColor4ub(0, 255, 0, 255); glVertex3f(-0.1f, 0.1f, -2.5f); + + glEnd(); + +} + + +void DrawQuadStrip() { + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + + glBegin(GL_QUAD_STRIP); + glColor4ub(255, 0, 0, 255); glVertex3f(-0.25f, -0.25f, -2.5f); + glColor4ub(0, 0, 255, 255); glVertex3f(0.25f, -0.25f, -2.5f); + glColor4ub(255, 0, 0, 255); glVertex3f(-0.25f, 0.25f, -2.5f); + glColor4ub(0, 255, 0, 255); glVertex3f(0.25, 0.25, -2.5f); + + glColor4ub(255, 0, 0, 255); glVertex3f(-0.25f, 0.5f, -2.5f); + glColor4ub(0, 255, 0, 255); glVertex3f(0.25, 0.5, -2.5f); + glEnd(); +} + +void DrawQuads() { + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + + glBegin(GL_QUADS); + + glColor4ub(255, 0, 0, 255); glVertex3f(-0.5f, -0.25f, -2.5f); + glColor4ub(0, 0, 255, 255); glVertex3f(0.5f, -0.25f, -2.5f); + glColor4ub(0, 255, 0, 255); glVertex3f(1.0f, 0.5f, -2.5f); + glColor4ub(255, 0, 0, 255); glVertex3f(0.5f, 0.5f, -2.5f); + + glEnd(); +} + +void DrawLineStrip() { + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + + glLineWidth(10.0f); + glBegin(GL_LINE_STRIP); + + glColor4ub(255, 0, 0, 255); glVertex3f(-0.5f, -0.25f, -2.5f); + glColor4ub(0, 0, 255, 255); glVertex3f(0.5f, -0.25f, -2.5f); + glColor4ub(0, 255, 0, 255); glVertex3f(0.5f, 0.25f, -2.5f); + + glEnd(); +} + +void DrawLineLoop() { + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + + glLineWidth(10.0f); + glBegin(GL_LINE_LOOP); + + glColor4ub(255, 0, 0, 255); glVertex3f(-0.5f, -0.25f, -2.5f); + glColor4ub(0, 0, 255, 255); glVertex3f(0.5f, -0.25f, -2.5f); + glColor4ub(0, 255, 0, 255); glVertex3f(0.5f, 0.25f, -2.5f); + + glEnd(); +} + +void DrawLines() { + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + + glLineWidth(10.0f); + glBegin(GL_LINES); + + glColor4ub(255, 0, 0, 255); glVertex3f(-0.5f, -0.25f, -2.5f); + glColor4ub(0, 0, 255, 255); glVertex3f(0.5f, -0.25f, -2.5f); + + glColor4ub(0, 0, 255, 255); glVertex3f(0.5f, -0.25f, -2.5f); + glColor4ub(0, 255, 0, 255); glVertex3f(0.5f, 0.25f, -2.5f); + + glEnd(); +} + +void DrawPoints() { + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + + glPointSize(10.0f); + glBegin(GL_POINTS); + glColor4ub(255, 0, 0, 255); glVertex3f(-0.5f, -0.25f, -2.5f); + glColor4ub(0, 255, 0, 255); glVertex3f(0.5f, -0.25f, -2.5f); + glEnd(); +} + +void DrawTriangleFan() { + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + + glBegin(GL_TRIANGLE_FAN); + glColor4ub(255, 0, 0, 255); glVertex3f(0.0f, -0.25f, -2.5f); + glColor4ub(0, 255, 0, 255); glVertex3f(0.5f, -0.25f, -2.5f); + glColor4ub(0, 0, 255, 255); glVertex3f(0.4f, 0.0f, -2.5f); + glColor4ub(0, 0, 255, 255); glVertex3f(0.2f, 0.15f, -2.5f); + glColor4ub(0, 0, 255, 255); glVertex3f(0.0f, 0.2f, -2.5f); + glEnd(); +} + +void DrawTriangleStrip() { + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + + glBegin(GL_TRIANGLE_STRIP); + + glColor4ub(255, 0, 0, 255); glVertex3f(-0.5f, -0.25f, -2.5f); + glColor4ub(0, 0, 255, 255); glVertex3f(0.5f, -0.25, -2.5f); + glColor4ub(0, 255, 0, 255); glVertex3f(-0.5f, 0.25f, -2.5f); + glColor4ub(0, 255, 0, 255); glVertex3f(0.5f, 0.25f, -2.5f); + + glEnd(); +} + +void DrawTriangles() { + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + + glBegin(GL_TRIANGLES); + + glColor4ub(255, 255, 255, 255); + glVertex3f(-0.2f, -0.2f, -1.5f); + + glColor4ub(255, 0, 0, 255); + glVertex3f(0.2f, -0.2f, -1.5f); + + glColor4ub(0, 255, 0, 255); + glVertex3f(0.0f, 0.2f, -1.5f); + + glEnd(); +} + +void DrawEnableLight() { + glClearColor(30.0f / 255.0f, 30.0f / 255.0f, 30.0f / 255.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + glEnable(GL_LIGHTING); + + glEnable(GL_LIGHT0); + glEnable(GL_CULL_FACE);//???? + float lightPos[] = { 0.0f,1.0f,0.0f,0.0f }; + glLightfv(GL_LIGHT0, GL_POSITION, lightPos);//设置方向光的2位置 + + float whiteColor[] = { 1.0f, 1.0f, 1.0f, 1.0f }; + glLightfv(GL_LIGHT0, GL_AMBIENT, whiteColor);//设置环境光 + + float ambientMat[] = { 0.07f,0.07f, 0.07f, 1.0f };//设置物体表面材质的反射系数 + glMaterialfv(GL_FRONT, GL_AMBIENT, ambientMat); + + float diffuseMat[] = { 0.4f,0.4f,0.4f,1.0f };//设置漫反射系数 + + glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuseMat); + + float specularMat[] = { 0.9f,0.9f,0.9f,1.0f };//设置镜面反射系数 + glMaterialfv(GL_FRONT, GL_SPECULAR, specularMat); + + glBegin(GL_QUADS); + glColor4ub(255, 255, 255, 255); + glVertex3f(-0.5f, -0.2f, -0.5f); + glVertex3f(0.5f, -0.2f, -0.5f); + glVertex3f(0.5f, -0.2f, -1.0f); + glVertex3f(-0.5f, -0.2f, -1.0f); + glEnd(); +} + +void DrawTexture() { + glClearColor(0.1f, 0.4f, 0.6f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + //开启纹理 + glEnable(GL_TEXTURE_2D); + //绑定纹理 + glBindTexture(GL_TEXTURE_2D, texture); + + glBegin(GL_QUADS); + glColor4ub(255, 255, 255, 255); + glTexCoord2f(0.0f, 0.0f); glVertex3f(-0.1f, -0.1f, -0.4f); + glTexCoord2f(1.0f, 0.0f); glVertex3f(0.1f, -0.1f, -0.4f); + glTexCoord2f(1.0f, 1.0f); glVertex3f(0.1f, 0.1f, -0.4f); + glTexCoord2f(0.0f, 1.0f); glVertex3f(-0.1f, 0.1f, -0.4f); + glEnd(); +} + +void DrawDepthBk() { + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清除深度缓冲区和颜色缓存区 + + glEnable(GL_DEPTH_TEST);//开启深度测试 + + glBegin(GL_QUADS); + glColor4ub(255, 0, 0, 0); + glVertex3f(-0.1f, -0.1f, -0.4f); + glVertex3f(0.1f, -0.1f, -0.4f); + glVertex3f(0.1f, 0.1f, -0.4f); + glVertex3f(-0.1f, 0.1f, -0.4f); + glEnd(); + + glBegin(GL_QUADS); + glColor4ub(0, 255, 0, 0); + glVertex3f(-0.1f, -0.1f, -0.6f); + glVertex3f(0.1f, -0.1f, -0.6f); + glVertex3f(0.1f, 0.1f, -0.6f); + glVertex3f(-0.1f, 0.1f, -0.6f); + glEnd(); +} + +void DrawDepth() { + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清除深度缓冲区和颜色缓存区 + + //glEnable(GL_DEPTH_TEST);//开启深度测试 + + GLuint texture2; + + texture2 = CreateTexture2DFromBMP("Res/test.bmp"); + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, texture2); + + glBegin(GL_QUADS); + + + glColor4ub(255, 255, 255, 255); + glTexCoord2d(0.0f, 0.0f); glVertex3f(-0.1f, -0.1f, -0.4f); + glTexCoord2d(1.0f, 0.0f); glVertex3f(0.1f, -0.1f, -0.4f); + glTexCoord2d(1.0f, 1.0f); glVertex3f(0.1f, 0.1f, -0.4f); + glTexCoord2d(0.0f, 1.0f); glVertex3f(-0.1f, 0.1f, -0.4f); + glEnd(); + + glBindTexture(GL_TEXTURE_2D, 0); + glBegin(GL_QUADS); + glColor4ub(0, 255, 0, 0); + glVertex3f(-0.1f, -0.1f, -0.6f); + glVertex3f(0.1f, -0.1f, -0.6f); + glVertex3f(0.1f, 0.1f, -0.6f); + glVertex3f(-0.1f, 0.1f, -0.6f); + glEnd(); +} + +void DrawSkyBox() { + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清除深度缓冲区和颜色缓存区 + skybox.Draw(); + + glEnable(GL_DEPTH_TEST);//开启深度测试 + glBindTexture(GL_TEXTURE_2D, 0); + glBegin(GL_QUADS); + glColor4ub(0, 255, 0, 0); + glVertex3f(-0.1f, -0.1f, -0.6f); + glVertex3f(0.1f, -0.1f, -0.6f); + glVertex3f(0.1f, 0.1f, -0.6f); + glVertex3f(-0.1f, 0.1f, -0.6f); + glEnd(); + +} + +void DrawModel() { + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清除深度缓冲区和颜色缓存区 + light.Enable(); + skybox.Draw(); + model.Draw(); + ground.Draw(); +} + +void DrawLight() { + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清除深度缓冲区和颜色缓存区 + light1.Enable(); + light2.Enable(); + light3.Enable(); + ground.Draw(); +} + +void DrawCamera() { + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清除深度缓冲区和颜色缓存区 + + float frameTime = GetFrameTime(); + camera.Update(frameTime); + + light1.Enable(); + light1.Update(camera.mPos.x, camera.mPos.y, camera.mPos.z); + light2.Enable(); + light2.Update(camera.mPos.x, camera.mPos.y, camera.mPos.z); + light3.Enable(); + light3.Update(camera.mPos.x, camera.mPos.y, camera.mPos.z); + ground.Draw(); +} + + +void Draw() { + DrawCamera(); +} + +void OnKeyDown(char code) +{ + switch (code) { + case 'A': + camera.mbMoveLeft = true; + break; + case 'D': + camera.mbMoveRight = true; + break; + case 'W': + camera.mbMoveForward = true; + break; + case 'S': + camera.mbMoveBack = true; + break; + } +} + +void OnKeyUp(char code) +{ + switch (code) { + case 'A': + camera.mbMoveLeft = false; + break; + case 'D': + camera.mbMoveRight = false; + break; + case 'W': + camera.mbMoveForward = false; + break; + case 'S': + camera.mbMoveBack = false; + break; + } +} + +void OnMouseMove(float deltaX, float deltaY) +{ + float angleRotateByUp = deltaX / 1000.0f; + float angleRotateByRight = deltaY / 1000.0f; + camera.Yaw(-angleRotateByUp); + camera.Picth(-angleRotateByRight); +} diff --git a/scene.h b/scene.h new file mode 100644 index 0000000..ef789f8 --- /dev/null +++ b/scene.h @@ -0,0 +1,8 @@ +#pragma once +#include "ggl.h" + +void Init(); +void Draw(); +void OnKeyDown(char code); +void OnKeyUp(char code); +void OnMouseMove(float deltaX, float deltaY); \ No newline at end of file diff --git a/skybox.cpp b/skybox.cpp new file mode 100644 index 0000000..5561448 --- /dev/null +++ b/skybox.cpp @@ -0,0 +1,100 @@ +#include "skybox.h" +#include "utils.h" + +void SkyBox::Init(const char * imageDir) +{ + char temp[256]; + + memset(temp, 0, 256); + strcpy(temp, imageDir); + strcat(temp, "front.bmp"); + mTextures[0] = CreateTexture2DFromBMP(temp); + + memset(temp, 0, 256); + strcpy(temp, imageDir); + strcat(temp, "back.bmp"); + mTextures[1] = CreateTexture2DFromBMP(temp); + + memset(temp, 0, 256); + strcpy(temp, imageDir); + strcat(temp, "left.bmp"); + mTextures[2] = CreateTexture2DFromBMP(temp); + + memset(temp, 0, 256); + strcpy(temp, imageDir); + strcat(temp, "right.bmp"); + mTextures[3] = CreateTexture2DFromBMP(temp); + + memset(temp, 0, 256); + strcpy(temp, imageDir); + strcat(temp, "top.bmp"); + mTextures[4] = CreateTexture2DFromBMP(temp); + + memset(temp, 0, 256); + strcpy(temp, imageDir); + strcat(temp, "bottom.bmp"); + mTextures[5] = CreateTexture2DFromBMP(temp); + + mFastDrawCall = CreateDisplayList([this]()->void {DrawCommand();}); +} + +void SkyBox::DrawCommand() +{ + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + glEnable(GL_TEXTURE_2D); + + glBindTexture(GL_TEXTURE_2D, mTextures[0]); + glBegin(GL_QUADS); + glColor4ub(255, 255, 255, 255); + glTexCoord2d(0.0f, 0.0f); glVertex3f(-0.5f,-0.5f,-0.5f); + glTexCoord2d(1.0f, 0.0f); glVertex3f(0.5f, -0.5f, -0.5f); + glTexCoord2d(1.0f, 1.0f); glVertex3f(0.5f, 0.5f, -0.5f); + glTexCoord2d(0.0f, 1.0f); glVertex3f(-0.5f, 0.5f, -0.5f); + glEnd(); + + glBindTexture(GL_TEXTURE_2D, mTextures[1]); + glBegin(GL_QUADS); + glTexCoord2d(0.0f, 0.0f); glVertex3f(-0.5f, -0.5f, 0.5f); + glTexCoord2d(1.0f, 0.0f); glVertex3f(0.5f, -0.5f, 0.5f); + glTexCoord2d(1.0f, 1.0f); glVertex3f(0.5f, 0.5f, 0.5f); + glTexCoord2d(0.0f, 1.0f); glVertex3f(-0.5f, 0.5f, 0.5f); + glEnd(); + + glBindTexture(GL_TEXTURE_2D, mTextures[2]); + glBegin(GL_QUADS); + glTexCoord2d(0.0f, 0.0f); glVertex3f(-0.5f, -0.5f, 0.5f); + glTexCoord2d(1.0f, 0.0f); glVertex3f(-0.5f, -0.5f, -0.5f); + glTexCoord2d(1.0f, 1.0f); glVertex3f(-0.5f, 0.5f, -0.5f); + glTexCoord2d(0.0f, 1.0f); glVertex3f(-0.5f, 0.5f, 0.5f); + glEnd(); + + glBindTexture(GL_TEXTURE_2D, mTextures[3]); + glBegin(GL_QUADS); + glTexCoord2d(0.0f, 0.0f); glVertex3f(0.5f, -0.5f, -0.5f); + glTexCoord2d(1.0f, 0.0f); glVertex3f(0.5f, -0.5f, 0.5f); + glTexCoord2d(1.0f, 1.0f); glVertex3f(0.5f, 0.5f, 0.5f); + glTexCoord2d(0.0f, 1.0f); glVertex3f(0.5f, 0.5f, -0.5f); + glEnd(); + + glBindTexture(GL_TEXTURE_2D, mTextures[4]); + glBegin(GL_QUADS); + glTexCoord2d(0.0f, 0.0f); glVertex3f(-0.5f, 0.5f, -0.5f); + glTexCoord2d(1.0f, 0.0f); glVertex3f(0.5f, 0.5f, -0.5f); + glTexCoord2d(1.0f, 1.0f); glVertex3f(0.5f, 0.5f, 0.5f); + glTexCoord2d(0.0f, 1.0f); glVertex3f(-0.5f, 0.5f, 0.5f); + glEnd(); + + glBindTexture(GL_TEXTURE_2D, mTextures[5]); + glBegin(GL_QUADS); + glTexCoord2d(0.0f, 0.0f); glVertex3f(-0.5f, -0.5f, 0.5f); + glTexCoord2d(1.0f, 0.0f); glVertex3f(0.5f, -0.5f, 0.5f); + glTexCoord2d(1.0f, 1.0f); glVertex3f(0.5f, -0.5f, -0.5f); + glTexCoord2d(0.0f, 1.0f); glVertex3f(-0.5f, -0.5f, -0.5f); + glEnd(); +} + +void SkyBox::Draw() +{ + glCallList(mFastDrawCall); +} diff --git a/skybox.h b/skybox.h new file mode 100644 index 0000000..e7af42c --- /dev/null +++ b/skybox.h @@ -0,0 +1,11 @@ +#pragma once +#include "ggl.h" + +class SkyBox { + GLuint mTextures[6]; + GLuint mFastDrawCall; +public: + void Init(const char* imageDir); + void DrawCommand(); + void Draw(); +}; \ No newline at end of file diff --git a/utils.cpp b/utils.cpp new file mode 100644 index 0000000..83f373c --- /dev/null +++ b/utils.cpp @@ -0,0 +1,79 @@ +#include "utils.h" + +unsigned char * DecodeBMP(unsigned char * bmpFileData, int & width, int & height) +{ + if (0x4D42 == *((unsigned short*)bmpFileData)) {//通过前两个字节去判断数据是否是BMP数据 + int pixelDataOffset = *((int*)(bmpFileData + 10));//取出位图像素数据的偏移地址、 + width = *((int*)(bmpFileData + 18));//获取图片宽度 + height = *((int*)(bmpFileData + 22));//获取图片宽度 + + /*读取图片内容*/ + unsigned char* pixelData = bmpFileData + pixelDataOffset; + for (int i = 0; i < width * height * 3; i += 3) { + unsigned char temp = pixelData[i]; + //BGR 转换成 RGB + pixelData[i] = pixelData[i + 2]; + pixelData[i + 2] = temp; + } + return pixelData; + } + return nullptr; +} + +GLuint CreateTexture2D(unsigned char * pixelData, int width, int height, GLenum type) +{ + GLuint texture; + glGenTextures(1, &texture); + + //绑定纹理 + glBindTexture(GL_TEXTURE_2D, texture); + + //设置纹理放大/缩小时候数据采集的算法 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);//使用线性过滤 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);//使用线性过滤 + + //设置当纹理坐标大于1.0时候的数据采集方式 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + + //数据上传到显卡 + glTexImage2D(GL_TEXTURE_2D, 0, type, width, height, 0, type, GL_UNSIGNED_BYTE, pixelData); + + //释放纹理 + glBindTexture(GL_TEXTURE_2D, 0); + return texture; +} + +GLuint CreateTexture2DFromBMP(const char * bmpPath) +{ + int nFileSize = 0; + unsigned char* bmpFileContent = LoadFileContent(bmpPath, nFileSize); + + if (bmpFileContent == nullptr) { + return 0; + } + + int bmpWidth = 0; + int bmpHeight = 0; + unsigned char* pixelData = DecodeBMP(bmpFileContent, bmpWidth, bmpHeight); + + if (bmpWidth == 0) { + delete bmpFileContent; + return 0; + } + + GLuint textrue = CreateTexture2D(pixelData, bmpWidth, bmpHeight, GL_RGB); + + return textrue; +} + +GLuint CreateDisplayList(std::function foo) +{ + GLuint displayList = glGenLists(1);//申请一个显示列表 + + glNewList(displayList, GL_COMPILE); + foo(); + glEndList(); + + return displayList; +} diff --git a/utils.h b/utils.h new file mode 100644 index 0000000..adb1cbd --- /dev/null +++ b/utils.h @@ -0,0 +1,9 @@ +#pragma once +#include "ggl.h" + +unsigned char* LoadFileContent(const char* path, int &filesize); +unsigned char* DecodeBMP(unsigned char* bmpFileData, int &width, int &height); +GLuint CreateTexture2D(unsigned char* pixelData, int width, int height, GLenum type); +GLuint CreateTexture2DFromBMP(const char* bmpPath); +GLuint CreateDisplayList(std::functionfoo); +float GetFrameTime(); \ No newline at end of file diff --git a/vector3.cpp b/vector3.cpp new file mode 100644 index 0000000..7e5858e --- /dev/null +++ b/vector3.cpp @@ -0,0 +1,53 @@ +#include "vector3.h" + +Vector3f::Vector3f(float x, float y, float z) +{ + this->x = x; + this->y = y; + this->z = z; +} + +Vector3f Vector3f::operator+(Vector3f & r) +{ + return Vector3f(x + r.x, y + r.y, z + r.z); +} + +Vector3f Vector3f::operator-(Vector3f & r) +{ + return Vector3f(x - r.x, y - r.y, z - r.z); +} + +Vector3f Vector3f::operator*(float scaler) +{ + return Vector3f(x*scaler, y*scaler, z*scaler); +} + +float Vector3f::operator*(Vector3f & r) +{ + return x *r.x + y * r.y + z*r.z; +} + +void Vector3f::operator=(Vector3f & r) +{ + x = r.x; + y = r.y; + z = r.z; +} + +void Vector3f::Normalize() +{ + float len = Magnitude(); + x /= len; + y /= len; + z /= len; +} + +float Vector3f::Magnitude() +{ + return sqrtf(x*x + y*y + z*z); +} + +Vector3f Cross(Vector3f v1, Vector3f v2) +{ + return Vector3f(v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x); +} diff --git a/vector3.h b/vector3.h new file mode 100644 index 0000000..cf758dc --- /dev/null +++ b/vector3.h @@ -0,0 +1,17 @@ +#pragma once +#include "ggl.h" + +class Vector3f { +public: + float x, y, z; + Vector3f(float x = 0.0f, float y = 0.0f, float z = 0.f); + Vector3f operator+(Vector3f &r); + Vector3f operator-(Vector3f &r); + Vector3f operator*(float scaler); + float operator*(Vector3f &r); + void operator=(Vector3f &r); + void Normalize(); + float Magnitude(); +}; + +Vector3f Cross(Vector3f v1, Vector3f v2);