diff --git a/.vs/shader/v14/.suo b/.vs/shader/v14/.suo index ec6cbff..2950203 100644 Binary files a/.vs/shader/v14/.suo and b/.vs/shader/v14/.suo differ 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/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 index 2f90d25..6f0feb6 100644 --- a/Res/ground.fs +++ b/Res/ground.fs @@ -1,8 +1,32 @@ #ifdef GL_ES precision mediump float; #endif +uniform vec4 U_LightPos; +uniform vec4 U_LightAmbient; +uniform vec4 U_LightDiffuse; +uniform vec4 U_AmbientMaterial; +uniform vec4 U_DiffuseMaterial; varying vec4 V_Color; +varying vec3 V_Normal; +varying vec3 V_WorldPos; void main() { - gl_FragColor=V_Color; + vec4 color=vec4(0.0,0.0,0.0,0.0); + vec4 ambientColor=U_LightAmbient*U_AmbientMaterial; + + float distance=0.0; + float constantFactor=1.0; + float linearFactor=0.0; + float quadricFactor=0.0; + vec3 L=U_LightPos.xyz-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=U_LightDiffuse*U_DiffuseMaterial*diffuseIntensity*attenuation*4.0; + + color=ambientColor+diffuseColor; + gl_FragData[0]=color*V_Color; + gl_FragData[1]=color*V_Color; } \ No newline at end of file diff --git a/Res/ground.vs b/Res/ground.vs index e001604..00b88d9 100644 --- a/Res/ground.vs +++ b/Res/ground.vs @@ -5,8 +5,12 @@ 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/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 index ff9f42b..a2e9cc2 100644 --- a/Res/model.fs +++ b/Res/model.fs @@ -1,13 +1,36 @@ #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_Color; varying vec4 V_Normal; +varying vec4 V_WorldPos; +varying vec4 V_Texcoord; +vec4 GetPointLight(){ + float distance=0.0; + float constantFactor=1.0; + float linearFactor=0.0; + float quadricFactor=0.0; + vec4 ambientColor=U_LightAmbient*U_AmbientMaterial; + 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*2.0; + return ambientColor+diffuseColor; +} void main() { vec4 color=vec4(0.0,0.0,0.0,0.0); @@ -18,6 +41,20 @@ void main() vec3 n=normalize(V_Normal.xyz); float diffuseIntensity=max(0.0,dot(L,n)); vec4 diffuseColor=U_LightDiffuse*U_DiffuseMaterial*diffuseIntensity; - color=ambientColor+diffuseColor; - gl_FragColor=color; + + 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.w==1.0){ + color=ambientColor+diffuseColor*texture2D(U_Texture,V_Texcoord.xy)+specularColor; + }else{ + color=ambientColor+diffuseColor+GetPointLight(); + color=color*texture2D(U_Texture,V_Texcoord.xy); + } + gl_FragData[0]=color; + gl_FragData[1]=color; } \ No newline at end of file diff --git a/Res/model.vs b/Res/model.vs index e0c9c76..3f99cf5 100644 --- a/Res/model.vs +++ b/Res/model.vs @@ -8,9 +8,13 @@ uniform mat4 ProjectionMatrix; uniform mat4 IT_ModelMatrix; varying vec4 V_Color; varying vec4 V_Normal; +varying vec4 V_WorldPos; +varying vec4 V_Texcoord; void main() { V_Color=color; V_Normal=IT_ModelMatrix*normal; + V_WorldPos=ModelMatrix*position; + V_Texcoord=texcoord; gl_Position=ProjectionMatrix*ViewMatrix*ModelMatrix*position; } \ 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..97fc965 --- /dev/null +++ b/Res/particle.fs @@ -0,0 +1,12 @@ +#version 120 +#ifdef GL_ES +precision mediump float; +#endif +uniform sampler2D U_Texture; +varying vec4 V_Color; +void main() +{ + vec4 color=texture2D(U_Texture,gl_PointCoord.xy)*V_Color; + gl_FragData[0]=color; + gl_FragData[1]=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/texture.fs b/Res/texture.fs new file mode 100644 index 0000000..92021ea --- /dev/null +++ b/Res/texture.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/texture.vs b/Res/texture.vs new file mode 100644 index 0000000..b38398f --- /dev/null +++ b/Res/texture.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/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/framebufferobject.cpp b/framebufferobject.cpp new file mode 100644 index 0000000..3033788 --- /dev/null +++ b/framebufferobject.cpp @@ -0,0 +1,72 @@ +#include "framebufferobject.h" + +FrameBufferObject::FrameBufferObject() +{ + glGenFramebuffers(1, &mFrameBufferObject); +} +void FrameBufferObject::AttachColorBuffer(const char*bufferName, GLenum attachment, int width, int height) { + + //在显存中申请一块空间,并置空 + GLuint colorBuffer; + glGenTextures(1, &colorBuffer); + glBindTexture(GL_TEXTURE_2D, colorBuffer); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, 0); + + //把上面申请的空间和frame buffer 绑定 + glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferObject); + glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, colorBuffer, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + mDrawBuffers.push_back(attachment); + mBuffers.insert(std::pair(bufferName, colorBuffer)); +} +void FrameBufferObject::AttachDepthBuffer(const char*bufferName, int width, int height) { + GLuint depthMap; + glGenTextures(1, &depthMap); + glBindTexture(GL_TEXTURE_2D, depthMap); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); + glBindTexture(GL_TEXTURE_2D, 0); + + glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferObject); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthMap, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + mBuffers.insert(std::pair(bufferName, depthMap)); +} +void FrameBufferObject::Finish() { + int nCount = (int)mDrawBuffers.size(); + if (nCount > 0) { + GLenum *buffers = new GLenum[nCount]; + int i = 0; + while (isecond; + } + return 0; +} \ No newline at end of file diff --git a/framebufferobject.h b/framebufferobject.h new file mode 100644 index 0000000..e3fb35c --- /dev/null +++ b/framebufferobject.h @@ -0,0 +1,17 @@ +#pragma once +#include "ggl.h" +class FrameBufferObject { +public: + GLuint mFrameBufferObject; + GLint mPrevFrameBuffer; + std::map mBuffers; + std::vector mDrawBuffers; +public: + FrameBufferObject(); + void AttachColorBuffer(const char*bufferName, GLenum attachment, int width, int height); + void AttachDepthBuffer(const char*bufferName, int width, int height); + void Finish(); + void Bind(); + void Unbind(); + GLuint GetBuffer(const char*bufferName); +}; \ No newline at end of file diff --git a/ground.cpp b/ground.cpp index cd4ee3a..f1d2f7f 100644 --- a/ground.cpp +++ b/ground.cpp @@ -33,6 +33,13 @@ void Ground::Init() { /*编译和链接shader*/ mShader = new Shader; mShader->Init("Res/ground.vs", "Res/ground.fs"); + + mShader->SetVec4("U_LightPos", 0.0f, 0.0f, 1.0f, 0.0f); + mShader->SetVec4("U_LightAmbient", 1.0f, 1.0f, 1.0f, 1.0f); + mShader->SetVec4("U_LightDiffuse", 1.0f, 1.0f, 1.0f, 1.0f); + mShader->SetVec4("U_LightOpt", 32.0f, 0.0f, 0.0f, 1.0f); + mShader->SetVec4("U_AmbientMaterial", 0.1f, 0.1f, 0.1f, 1.0f); + mShader->SetVec4("U_DiffuseMaterial", 0.1f, 0.4f, 0.6f, 1.0f); } void Ground::Draw(glm::mat4 & viewMatrix, glm::mat4 & projectionMatrix) { diff --git a/main.cpp b/main.cpp index 182377f..39804e5 100644 --- a/main.cpp +++ b/main.cpp @@ -62,9 +62,9 @@ INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine RECT rect; rect.left = 0; - rect.right = 800; + rect.right = 1280; rect.top = 0; - rect.bottom = 600; + rect.bottom = 720; AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, NULL); int windowWidth = rect.right - rect.left; int windowHeight = rect.bottom - rect.top; diff --git a/model.cpp b/model.cpp index f7060f5..4abd4b2 100644 --- a/model.cpp +++ b/model.cpp @@ -102,14 +102,23 @@ void Model::Init(const char*modelPath) { mShader = new Shader; mShader->Init("Res/model.vs", "Res/model.fs"); - mShader->SetVec4("U_LightPos", 0.0f, 1.0f, 1.0f, 0.0f);//设置光源位置 + mShader->SetVec4("U_LightAmbient", 1.0f, 1.0f, 1.0f, 1.0f);//设置环境光分量 + + mShader->SetVec4("U_LightPos", 0.0f, 1.0f, 2.0f, 0.0f);//设置光源位置 mShader->SetVec4("U_LightDiffuse", 1.0f, 1.0f, 1.0f, 1.0f);//设置慢反射光分量 - mShader->SetVec4("U_AmbientMaterial", 0.1f, 0.1f, 0.1f, 1.0f);//设置环境光材质分量 - mShader->SetVec4("U_DiffuseMaterial", 0.6f, 0.6f, 0.6f, 1.0f);//设置漫反射材质分量 + + mShader->SetVec4("U_LightSpecular", 1.0f, 1.0f, 1.0f, 1.0f);//设置镜面反射光分量 + mShader->SetVec4("U_CameraPos", 0.0f, 0.0f, 0.0f, 1.0f);//设置相机位置 + mShader->SetVec4("U_LightOpt", 32.0f, 0.0f, 0.0f, 1.0f);//TODO没有明白,只知道用着幂计算 + + SetAmbientMaterial(0.1f, 0.1f, 0.1f, 1.0f);//设置环境光材质反射系数 + SetDiffuseMaterial(0.6f, 0.6f, 0.6f, 1.0f);//设置漫反射材质反射系数 + SetSpecularMaterial(1.0f, 1.0f, 1.0f, 1.0f);//设置镜面反射材质反射系数 } -void Model::Draw(glm::mat4 & viewMatrix, glm::mat4 projectionMatrix) { +void Model::Draw(glm::mat4 & viewMatrix, glm::mat4 projectionMatrix, float x, float y, float z) { + mShader->SetVec4("U_CameraPos", x, y, z, 1.0); glEnable(GL_DEPTH_TEST); mVertexBuffer->Bind(); glm::mat4 it = glm::inverseTranspose(mModelMatrix); @@ -120,4 +129,21 @@ void Model::Draw(glm::mat4 & viewMatrix, glm::mat4 projectionMatrix) { } void Model::SetPosition(float x, float y, float z) { mModelMatrix = glm::translate(x, y, z); -} \ No newline at end of file +} +void Model::SetAmbientMaterial(float r, float g, float b, float a) { + mShader->SetVec4("U_AmbientMaterial", r, g, b, a); +} +void Model::SetDiffuseMaterial(float r, float g, float b, float a) { + mShader->SetVec4("U_DiffuseMaterial", r, g, b, a); +} +void Model::SetSpecularMaterial(float r, float g, float b, float a) { + mShader->SetVec4("U_SpecularMaterial", r, g, b, a); +} +void Model::SetTexture(const char* imagePath) { + mShader->SetTexture("U_Texture", imagePath); +} + +void Model::SetTexture(GLuint texture) +{ + mShader->SetTexture("U_Texture", texture); +} diff --git a/model.h b/model.h index 3ffcf27..a488607 100644 --- a/model.h +++ b/model.h @@ -9,6 +9,11 @@ public: glm::mat4 mModelMatrix; Model(); void Init(const char*modelPath); - void Draw(glm::mat4 & viewMatrix, glm::mat4 projectionMatrix); + void Draw(glm::mat4 & viewMatrix, glm::mat4 projectionMatrix, float x, float y, float z); void SetPosition(float x, float y, float z); + 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); + void SetTexture(const char*imagePath); + void SetTexture(GLuint texture); }; \ No newline at end of file diff --git a/particleSystem.cpp b/particleSystem.cpp new file mode 100644 index 0000000..8d847e8 --- /dev/null +++ b/particleSystem.cpp @@ -0,0 +1,44 @@ +#include "particleSystem.h" +#include "utils.h" + +void ParticleSystem::Init(float x, float y, float z) +{ + mModelMatrix = glm::translate(x, y, z); + mVertexBuffer = new VertexBuffer; + int particleCount = 180; + mVertexBuffer->SetSize(particleCount); + for (int i = 0; i < particleCount; ++i) { + mVertexBuffer->SetPosition(i, 2.0f*cosf(float(i) * 8.0f*3.14f / 180.0f), 0.0f, 2.0f*sinf(float(i) * 8.0f*3.14f / 180.0f)); + mVertexBuffer->SetColor(i, 0.1f, 0.4f, 0.6f); + } + + mShader = new Shader; + mShader->Init("Res/particle.vs", "Res/particle.fs"); + mShader->SetTexture("U_Texture", CreateProcedureTexture(128)); +} +void ParticleSystem::Draw(glm::mat4 & viewMatrix, glm::mat4 & projectionMatrix) { + glEnable(GL_POINT_SPRITE); + glEnable(GL_PROGRAM_POINT_SIZE); + glDisable(GL_DEPTH_TEST); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + mVertexBuffer->Bind(); + mShader->Bind(glm::value_ptr(mModelMatrix), glm::value_ptr(viewMatrix), glm::value_ptr(projectionMatrix)); + glDrawArrays(GL_POINTS, 0, mVertexBuffer->mVertexCount); + mVertexBuffer->Unbind(); + glDisable(GL_BLEND); + glDisable(GL_POINT_SPRITE); + glDisable(GL_PROGRAM_POINT_SIZE); +} +void ParticleSystem::Update(float deltaTime) { + static float angle = 0.0f; + angle += deltaTime*10.0f; + mModelMatrix = glm::rotate(angle, 0.0f, 1.0f, 0.0f); + for (int i = 0; i < mVertexBuffer->mVertexCount; ++i) { + Vertex &vertex = mVertexBuffer->Get(i); + vertex.Normal[1] = 0.1f*i; + if (i > 90) { + break; + } + } +} \ No newline at end of file diff --git a/particleSystem.h b/particleSystem.h new file mode 100644 index 0000000..3539d52 --- /dev/null +++ b/particleSystem.h @@ -0,0 +1,12 @@ +#pragma once +#include "vertexbuffer.h" +#include "shader.h" +class ParticleSystem { + VertexBuffer *mVertexBuffer; + glm::mat4 mModelMatrix; + Shader *mShader; +public: + void Init(float x, float y, float z); + void Draw(glm::mat4 & viewMatrix, glm::mat4 & projectionMatrix); + void Update(float deltaTime); +}; \ No newline at end of file diff --git a/scene.cpp b/scene.cpp index 5c2085e..167d830 100644 --- a/scene.cpp +++ b/scene.cpp @@ -2,26 +2,89 @@ #include "ggl.h" #include "utils.h" #include "ground.h" +#include "shader.h" #include "model.h" +#include "skybox.h" +#include "particleSystem.h" +#include "framebufferobject.h" glm::mat4 modelMatrix, viewMatrix, projectionMatrix; +glm::vec3 cameraPos(10.0f, 10.0f, 10.0f); Ground ground; -Model model; +Model model, niutou, sphere; +SkyBox skybox; +ParticleSystem ps; +FrameBufferObject *fbo; +VertexBuffer *fsqVertex; +Shader *fsqShader; +glm::mat4 fsqViewMatrix; void Init() { + viewMatrix = glm::lookAt(cameraPos, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f,1.0f,0.0f)); + ground.Init(); model.Init("Res/Sphere.obj"); - model.SetPosition(0.0f, 0.0f, -5.0f); + model.SetTexture("Res/earth.bmp"); + model.SetPosition(0.0f, 0.0f, 0.0f); + skybox.Init("Res/"); + niutou.Init("Res/niutou.obj"); + niutou.SetTexture("Res/niutou.bmp"); + niutou.mModelMatrix = glm::translate(-5.0f, 0.0f, 4.0f)*glm::scale(0.05f, 0.05f, 0.05f); + ps.Init(0.0f, 0.0f, 0.0f); } void SetViewPortSize(float width, float height) { projectionMatrix = glm::perspective(60.0f, width / height, 0.1f, 1000.0f); + + fbo = new FrameBufferObject; + fbo->AttachColorBuffer("color", GL_COLOR_ATTACHMENT0, (int)width, (int)height); + fbo->AttachColorBuffer("color1", GL_COLOR_ATTACHMENT1, (int)width, (int)height); + fbo->AttachDepthBuffer("depth", (int)width, (int)height); + fbo->Finish(); + + sphere.Init("Res/Sphere.obj"); + sphere.SetTexture(fbo->GetBuffer("color")); + sphere.mModelMatrix = glm::scale(4.0f, 4.0f, 4.0f)*glm::rotate(150.0f, 0.0f, 1.0f, 0.0f); + + float aspect = width / height; + float halfFOV = 60.0f / 2.0f; + float randianHalfFOV = 3.14f*halfFOV / 180.0f; + float tanHalfFOV = sinf(randianHalfFOV) / cosf(randianHalfFOV); + float y = tanHalfFOV*0.2f; + float x = y*aspect; + fsqVertex = new VertexBuffer; + fsqVertex->SetSize(4); + fsqVertex->SetPosition(0, -x, -y, -0.2f); + fsqVertex->SetTexcoord(0, 0.0f, 0.0f); + fsqVertex->SetPosition(1, x, -y, -0.2f); + fsqVertex->SetTexcoord(1, 1.0f, 0.0f); + fsqVertex->SetPosition(2, -x, y, -0.2f); + fsqVertex->SetTexcoord(2, 0.0f, 1.0f); + fsqVertex->SetPosition(3, x, y, -0.2f); + fsqVertex->SetTexcoord(3, 1.0f, 1.0f); + + fsqShader = new Shader; + fsqShader->Init("Res/texture.vs", "Res/texture.fs"); + fsqShader->SetTexture("U_Texture", fbo->GetBuffer("color")); } void Draw() { float frameTime = GetFrameTime(); glClearColor(0.1f, 0.4f, 0.6f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + fbo->Bind(); + skybox.Draw(viewMatrix, projectionMatrix, cameraPos.x, cameraPos.y, cameraPos.z); ground.Draw(viewMatrix, projectionMatrix); - model.Draw(viewMatrix, projectionMatrix); + model.Draw(viewMatrix, projectionMatrix, cameraPos.x, cameraPos.y, cameraPos.z); + niutou.Draw(viewMatrix, projectionMatrix, cameraPos.x, cameraPos.y, cameraPos.z); + ps.Update(frameTime); + ps.Draw(viewMatrix, projectionMatrix); + fbo->Unbind(); + + //sphere.Draw(viewMatrix, projectionMatrix, cameraPos.x, cameraPos.y, cameraPos.z); + + fsqVertex->Bind(); + fsqShader->Bind(glm::value_ptr(modelMatrix), glm::value_ptr(fsqViewMatrix), glm::value_ptr(projectionMatrix)); + glDrawArrays(GL_TRIANGLE_STRIP, 0, fsqVertex->mVertexCount); + fsqVertex->Unbind(); } \ No newline at end of file diff --git a/shader.VC.db b/shader.VC.db index 78937d8..f695140 100644 Binary files a/shader.VC.db and b/shader.VC.db differ diff --git a/shader.cpp b/shader.cpp index 73238ce..3c362c7 100644 --- a/shader.cpp +++ b/shader.cpp @@ -93,4 +93,20 @@ void Shader::SetVec4(const char * name, float x, float y, float z, float w) { iter->second->v[2] = z; iter->second->v[3] = w; } +} +void Shader::SetTexture(const char * name, GLuint texture) { + auto iter = mUniformTextures.find(name); + if (iter == mUniformTextures.end()) { + GLint location = glGetUniformLocation(mProgram, name); + if (location != -1) { + UniformTexture*t = new UniformTexture; + t->mLocation = location; + t->mTexture = texture; + mUniformTextures.insert(std::pair(name, t)); + } + } + else { + glDeleteTextures(1, &iter->second->mTexture); + iter->second->mTexture = texture; + } } \ No newline at end of file diff --git a/shader.h b/shader.h index 8358e5d..5610102 100644 --- a/shader.h +++ b/shader.h @@ -19,6 +19,10 @@ struct UniformVector4f { class Shader { public: GLuint mProgram; + GLuint mPosition; + GLuint mColor; + GLuint mTexcoord; + GLuint mNormal; std::map mUniformTextures; std::map mUniformVec4s; GLint mModelMatrixLocation, mViewMatrixLocation, mProjectionMatrixLocation; @@ -26,5 +30,6 @@ public: void Init(const char*vs, const char*fs); void Bind(float *M, float *V, float*P); void SetTexture(const char * name, const char*imagePath); + void SetTexture(const char * name, GLuint texture); void SetVec4(const char * name, float x, float y, float z, float w); }; \ No newline at end of file diff --git a/shader.vcxproj b/shader.vcxproj index edf2ade..da1e17e 100644 --- a/shader.vcxproj +++ b/shader.vcxproj @@ -143,20 +143,26 @@ + + + + + + @@ -165,8 +171,14 @@ + + + + + + diff --git a/shader.vcxproj.filters b/shader.vcxproj.filters index f8a7d60..0aa6658 100644 --- a/shader.vcxproj.filters +++ b/shader.vcxproj.filters @@ -36,28 +36,46 @@ 婧愭枃浠 + + 婧愭枃浠 + + + 婧愭枃浠 + + + 婧愭枃浠 + - 婧愭枃浠 + 澶存枃浠 + + + 澶存枃浠 + + + 澶存枃浠 - 婧愭枃浠 + 澶存枃浠 + + + 澶存枃浠 - 婧愭枃浠 + 澶存枃浠 - 婧愭枃浠 + 澶存枃浠 - - 婧愭枃浠 + + 澶存枃浠 - - 婧愭枃浠 + + 澶存枃浠 - - 婧愭枃浠 + + 澶存枃浠 @@ -79,5 +97,23 @@ 璧勬簮鏂囦欢 + + 璧勬簮鏂囦欢 + + + 璧勬簮鏂囦欢 + + + 璧勬簮鏂囦欢 + + + 璧勬簮鏂囦欢 + + + 璧勬簮鏂囦欢 + + + 璧勬簮鏂囦欢 + \ No newline at end of file diff --git a/skybox.cpp b/skybox.cpp new file mode 100644 index 0000000..65d3b20 --- /dev/null +++ b/skybox.cpp @@ -0,0 +1,124 @@ +#include "skybox.h" +#include "utils.h" +void SkyBox::Init(const char *imageDir) { + mShader = new Shader[6]; + mVertexBuffer = new VertexBuffer[6]; + InitFront(imageDir); + InitBack(imageDir); + InitLeft(imageDir); + InitRight(imageDir); + InitTop(imageDir); + InitBottom(imageDir); +} +void SkyBox::InitFront(const char *imageDir) { + mShader[0].Init("Res/skybox.vs", "Res/skybox.fs"); + char temp[256]; + memset(temp, 0, 256); + strcpy(temp, imageDir); + strcat(temp, "front.bmp"); + mShader[0].SetTexture("U_Texture", temp); + mVertexBuffer[0].SetSize(4); + mVertexBuffer[0].SetPosition(0, -0.5f, -0.5f, -0.5f); + mVertexBuffer[0].SetTexcoord(0, 0.0f, 0.0f); + mVertexBuffer[0].SetPosition(1, 0.5f, -0.5f, -0.5f); + mVertexBuffer[0].SetTexcoord(1, 1.0f, 0.0f); + mVertexBuffer[0].SetPosition(2, -0.5f, 0.5f, -0.5f); + mVertexBuffer[0].SetTexcoord(2, 0.0f, 1.0f); + mVertexBuffer[0].SetPosition(3, 0.5f, 0.5f, -0.5f); + mVertexBuffer[0].SetTexcoord(3, 1.0f, 1.0f); +} +void SkyBox::InitBack(const char *imageDir) { + mShader[1].Init("Res/skybox.vs", "Res/skybox.fs"); + char temp[256]; + memset(temp, 0, 256); + strcpy(temp, imageDir); + strcat(temp, "back.bmp"); + mShader[1].SetTexture("U_Texture", temp); + mVertexBuffer[1].SetSize(4); + mVertexBuffer[1].SetPosition(0, 0.5f, -0.5f, 0.5f); + mVertexBuffer[1].SetTexcoord(0, 0.0f, 0.0f); + mVertexBuffer[1].SetPosition(1, -0.5f, -0.5f, 0.5f); + mVertexBuffer[1].SetTexcoord(1, 1.0f, 0.0f); + mVertexBuffer[1].SetPosition(2, 0.5f, 0.5f, 0.5f); + mVertexBuffer[1].SetTexcoord(2, 0.0f, 1.0f); + mVertexBuffer[1].SetPosition(3, -0.5f, 0.5f, 0.5f); + mVertexBuffer[1].SetTexcoord(3, 1.0f, 1.0f); +} +void SkyBox::InitLeft(const char *imageDir) { + mShader[2].Init("Res/skybox.vs", "Res/skybox.fs"); + char temp[256]; + memset(temp, 0, 256); + strcpy(temp, imageDir); + strcat(temp, "left.bmp"); + mShader[2].SetTexture("U_Texture", temp); + mVertexBuffer[2].SetSize(4); + mVertexBuffer[2].SetPosition(0, -0.5f, -0.5f, 0.5f); + mVertexBuffer[2].SetTexcoord(0, 0.0f, 0.0f); + mVertexBuffer[2].SetPosition(1, -0.5f, -0.5f, -0.5f); + mVertexBuffer[2].SetTexcoord(1, 1.0f, 0.0f); + mVertexBuffer[2].SetPosition(2, -0.5f, 0.5f, 0.5f); + mVertexBuffer[2].SetTexcoord(2, 0.0f, 1.0f); + mVertexBuffer[2].SetPosition(3, -0.5f, 0.5f, -0.5f); + mVertexBuffer[2].SetTexcoord(3, 1.0f, 1.0f); +} +void SkyBox::InitRight(const char *imageDir) { + mShader[3].Init("Res/skybox.vs", "Res/skybox.fs"); + char temp[256]; + memset(temp, 0, 256); + strcpy(temp, imageDir); + strcat(temp, "right.bmp"); + mShader[3].SetTexture("U_Texture", temp); + mVertexBuffer[3].SetSize(4); + mVertexBuffer[3].SetPosition(0, 0.5f, -0.5f, -0.5f); + mVertexBuffer[3].SetTexcoord(0, 0.0f, 0.0f); + mVertexBuffer[3].SetPosition(1, 0.5f, -0.5f, 0.5f); + mVertexBuffer[3].SetTexcoord(1, 1.0f, 0.0f); + mVertexBuffer[3].SetPosition(2, 0.5f, 0.5f, -0.5f); + mVertexBuffer[3].SetTexcoord(2, 0.0f, 1.0f); + mVertexBuffer[3].SetPosition(3, 0.5f, 0.5f, 0.5f); + mVertexBuffer[3].SetTexcoord(3, 1.0f, 1.0f); +} +void SkyBox::InitTop(const char *imageDir) { + mShader[4].Init("Res/skybox.vs", "Res/skybox.fs"); + char temp[256]; + memset(temp, 0, 256); + strcpy(temp, imageDir); + strcat(temp, "top.bmp"); + mShader[4].SetTexture("U_Texture", temp); + mVertexBuffer[4].SetSize(4); + mVertexBuffer[4].SetPosition(0, -0.5f, 0.5f, -0.5f); + mVertexBuffer[4].SetTexcoord(0, 0.0f, 0.0f); + mVertexBuffer[4].SetPosition(1, 0.5f, 0.5f, -0.5f); + mVertexBuffer[4].SetTexcoord(1, 1.0f, 0.0f); + mVertexBuffer[4].SetPosition(2, -0.5f, 0.5f, 0.5f); + mVertexBuffer[4].SetTexcoord(2, 0.0f, 1.0f); + mVertexBuffer[4].SetPosition(3, 0.5f, 0.5f, 0.5f); + mVertexBuffer[4].SetTexcoord(3, 1.0f, 1.0f); +} +void SkyBox::InitBottom(const char *imageDir) { + mShader[5].Init("Res/skybox.vs", "Res/skybox.fs"); + char temp[256]; + memset(temp, 0, 256); + strcpy(temp, imageDir); + strcat(temp, "bottom.bmp"); + mShader[5].SetTexture("U_Texture", temp); + mVertexBuffer[5].SetSize(4); + mVertexBuffer[5].SetPosition(0, -0.5f, -0.5f, 0.5f); + mVertexBuffer[5].SetTexcoord(0, 0.0f, 0.0f); + mVertexBuffer[5].SetPosition(1, 0.5f, -0.5f, 0.5f); + mVertexBuffer[5].SetTexcoord(1, 1.0f, 0.0f); + mVertexBuffer[5].SetPosition(2, -0.5f, -0.5f, -0.5f); + mVertexBuffer[5].SetTexcoord(2, 0.0f, 1.0f); + mVertexBuffer[5].SetPosition(3, 0.5f, -0.5f, -0.5f); + mVertexBuffer[5].SetTexcoord(3, 1.0f, 1.0f); +} +void SkyBox::Draw(glm::mat4 &V, glm::mat4&P, float x, float y, float z) { + glDisable(GL_DEPTH_TEST); + mModelMatrix = glm::translate(x, y, z); + for (int i = 0; i < 6; ++i) { + mVertexBuffer[i].Bind(); + mShader[i].Bind(glm::value_ptr(mModelMatrix), glm::value_ptr(V), glm::value_ptr(P)); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + mVertexBuffer[i].Unbind(); + } +} \ No newline at end of file diff --git a/skybox.h b/skybox.h new file mode 100644 index 0000000..053b547 --- /dev/null +++ b/skybox.h @@ -0,0 +1,17 @@ +#pragma once +#include "shader.h" +#include "vertexbuffer.h" +class SkyBox { + Shader *mShader; + VertexBuffer *mVertexBuffer; + glm::mat4 mModelMatrix; +public: + void Init(const char *imageDir); + void InitFront(const char *imageDir); + void InitBack(const char *imageDir); + void InitLeft(const char *imageDir); + void InitRight(const char *imageDir); + void InitTop(const char *imageDir); + void InitBottom(const char *imageDir); + void Draw(glm::mat4 &V, glm::mat4&P, float x, float y, float z); +}; \ No newline at end of file diff --git a/utils.cpp b/utils.cpp index 2b29842..f81d69e 100644 --- a/utils.cpp +++ b/utils.cpp @@ -31,9 +31,9 @@ GLuint CreateProgram(GLuint vsShader, GLuint fsShader) glAttachShader(program, vsShader);//绑定编译好的shader glAttachShader(program, fsShader); glLinkProgram(program);//链接成一个程序 - - //判断链接是否成功 - GLint nResult = GL_TRUE; + glDetachShader(program, vsShader); + glDetachShader(program, fsShader); + GLint nResult; glGetProgramiv(program, GL_LINK_STATUS, &nResult); if (nResult == GL_FALSE) { char log[1024] = { 0 }; @@ -95,4 +95,30 @@ GLuint CreateBufferObject(GLenum bufferType, GLsizeiptr size, GLenum usage, void glBufferData(bufferType, size, data, usage); glBindBuffer(bufferType, 0); return object; -} \ No newline at end of file +} + +GLuint CreateProcedureTexture(int size) +{ + unsigned char *imageData = new unsigned char[size*size * 4]; + float halfSize = (float)size / 2.0f; + float maxDistance = sqrtf(halfSize*halfSize + halfSize*halfSize); + float centerX = halfSize; + float centerY = halfSize; + for (int y = 0; y < size; ++y) { + for (int x = 0; x < size; ++x) { + int currentPixelOffset = (x + y*size) * 4; + imageData[currentPixelOffset] = 255; + imageData[currentPixelOffset + 1] = 255; + imageData[currentPixelOffset + 2] = 255; + float deltaX = (float)x - centerX; + float deltaY = (float)y - centerY; + float distance = sqrtf(deltaX*deltaX + deltaY*deltaY); + float alpha = powf(1.0f - (distance / maxDistance), 8.0f); + alpha = alpha > 1.0f ? 1.0f : alpha; + imageData[currentPixelOffset + 3] = (unsigned char)(alpha*255.0f); + } + } + GLuint texture = CreateTexture2D(imageData, size, size, GL_RGBA); + delete imageData; + return texture; +} diff --git a/utils.h b/utils.h index 3b752c5..5b6cd65 100644 --- a/utils.h +++ b/utils.h @@ -7,4 +7,5 @@ float GetFrameTime(); 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 CreateBufferObject(GLenum bufferType, GLsizeiptr size, GLenum usage, void*data = nullptr); \ No newline at end of file +GLuint CreateBufferObject(GLenum bufferType, GLsizeiptr size, GLenum usage, void*data = nullptr); +GLuint CreateProcedureTexture(int size); \ No newline at end of file