Browse Source

finished

master
blobt 5 years ago
parent
commit
5f164cb2f9
  1. BIN
      .vs/shader/v14/.suo
  2. BIN
      Res/back.bmp
  3. BIN
      Res/bottom.bmp
  4. BIN
      Res/earth.bmp
  5. BIN
      Res/front.bmp
  6. 26
      Res/ground.fs
  7. 4
      Res/ground.vs
  8. BIN
      Res/left.bmp
  9. 41
      Res/model.fs
  10. 4
      Res/model.vs
  11. BIN
      Res/niutou.bmp
  12. 12
      Res/particle.fs
  13. 14
      Res/particle.vs
  14. BIN
      Res/right.bmp
  15. 9
      Res/skybox.fs
  16. 11
      Res/skybox.vs
  17. 9
      Res/texture.fs
  18. 11
      Res/texture.vs
  19. BIN
      Res/top.bmp
  20. 72
      framebufferobject.cpp
  21. 17
      framebufferobject.h
  22. 7
      ground.cpp
  23. 4
      main.cpp
  24. 34
      model.cpp
  25. 7
      model.h
  26. 44
      particleSystem.cpp
  27. 12
      particleSystem.h
  28. 69
      scene.cpp
  29. BIN
      shader.VC.db
  30. 16
      shader.cpp
  31. 5
      shader.h
  32. 12
      shader.vcxproj
  33. 56
      shader.vcxproj.filters
  34. 124
      skybox.cpp
  35. 17
      skybox.h
  36. 32
      utils.cpp
  37. 1
      utils.h

BIN
.vs/shader/v14/.suo

BIN
Res/back.bmp

BIN
Res/bottom.bmp

BIN
Res/earth.bmp

BIN
Res/front.bmp

26
Res/ground.fs

@ -1,8 +1,32 @@
#ifdef GL_ES #ifdef GL_ES
precision mediump float; precision mediump float;
#endif #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 vec4 V_Color;
varying vec3 V_Normal;
varying vec3 V_WorldPos;
void main() 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;
} }

4
Res/ground.vs

@ -5,8 +5,12 @@ uniform mat4 ModelMatrix;
uniform mat4 ViewMatrix; uniform mat4 ViewMatrix;
uniform mat4 ProjectionMatrix; uniform mat4 ProjectionMatrix;
varying vec4 V_Color; varying vec4 V_Color;
varying vec3 V_Normal;
varying vec3 V_WorldPos;
void main() void main()
{ {
V_Color=color; V_Color=color;
V_Normal=normal.xyz;
V_WorldPos=(ModelMatrix*position).xyz;
gl_Position=ProjectionMatrix*ViewMatrix*ModelMatrix*position; gl_Position=ProjectionMatrix*ViewMatrix*ModelMatrix*position;
} }

BIN
Res/left.bmp

41
Res/model.fs

@ -1,13 +1,36 @@
#ifdef GL_ES #ifdef GL_ES
precision mediump float; precision mediump float;
#endif #endif
uniform sampler2D U_Texture;
uniform vec4 U_LightPos; uniform vec4 U_LightPos;
uniform vec4 U_LightAmbient; uniform vec4 U_LightAmbient;
uniform vec4 U_LightDiffuse; uniform vec4 U_LightDiffuse;
uniform vec4 U_LightSpecular;
uniform vec4 U_AmbientMaterial; uniform vec4 U_AmbientMaterial;
uniform vec4 U_DiffuseMaterial; uniform vec4 U_DiffuseMaterial;
uniform vec4 U_SpecularMaterial;
uniform vec4 U_CameraPos;
uniform vec4 U_LightOpt;
varying vec4 V_Color; varying vec4 V_Color;
varying vec4 V_Normal; 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() void main()
{ {
vec4 color=vec4(0.0,0.0,0.0,0.0); vec4 color=vec4(0.0,0.0,0.0,0.0);
@ -18,6 +41,20 @@ void main()
vec3 n=normalize(V_Normal.xyz); vec3 n=normalize(V_Normal.xyz);
float diffuseIntensity=max(0.0,dot(L,n)); float diffuseIntensity=max(0.0,dot(L,n));
vec4 diffuseColor=U_LightDiffuse*U_DiffuseMaterial*diffuseIntensity; 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;
} }

4
Res/model.vs

@ -8,9 +8,13 @@ uniform mat4 ProjectionMatrix;
uniform mat4 IT_ModelMatrix; uniform mat4 IT_ModelMatrix;
varying vec4 V_Color; varying vec4 V_Color;
varying vec4 V_Normal; varying vec4 V_Normal;
varying vec4 V_WorldPos;
varying vec4 V_Texcoord;
void main() void main()
{ {
V_Color=color; V_Color=color;
V_Normal=IT_ModelMatrix*normal; V_Normal=IT_ModelMatrix*normal;
V_WorldPos=ModelMatrix*position;
V_Texcoord=texcoord;
gl_Position=ProjectionMatrix*ViewMatrix*ModelMatrix*position; gl_Position=ProjectionMatrix*ViewMatrix*ModelMatrix*position;
} }

BIN
Res/niutou.bmp

12
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;
}

14
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;
}

BIN
Res/right.bmp

9
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);
}

11
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;
}

9
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);
}

11
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;
}

BIN
Res/top.bmp

72
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<std::string, GLuint>(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<std::string, GLuint>(bufferName, depthMap));
}
void FrameBufferObject::Finish() {
int nCount = (int)mDrawBuffers.size();
if (nCount > 0) {
GLenum *buffers = new GLenum[nCount];
int i = 0;
while (i<nCount) {
buffers[i] = mDrawBuffers[i];
i++;
}
glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferObject);
glDrawBuffers(nCount, buffers);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
}
void FrameBufferObject::Bind() {
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &mPrevFrameBuffer);//绑定前记录一下buffer,为解绑返回这个buffer做准备
glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferObject);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
void FrameBufferObject::Unbind() {
glBindFramebuffer(GL_FRAMEBUFFER, mPrevFrameBuffer);
}
GLuint FrameBufferObject::GetBuffer(const char*bufferName) {
auto iter = mBuffers.find(bufferName);
if (iter != mBuffers.end()) {
return iter->second;
}
return 0;
}

17
framebufferobject.h

@ -0,0 +1,17 @@
#pragma once
#include "ggl.h"
class FrameBufferObject {
public:
GLuint mFrameBufferObject;
GLint mPrevFrameBuffer;
std::map<std::string, GLuint> mBuffers;
std::vector<GLenum> 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);
};

7
ground.cpp

@ -33,6 +33,13 @@ void Ground::Init() {
/*±àÒëºÍÁ´½Óshader*/ /*±àÒëºÍÁ´½Óshader*/
mShader = new Shader; mShader = new Shader;
mShader->Init("Res/ground.vs", "Res/ground.fs"); 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) { void Ground::Draw(glm::mat4 & viewMatrix, glm::mat4 & projectionMatrix) {

4
main.cpp

@ -62,9 +62,9 @@ INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
RECT rect; RECT rect;
rect.left = 0; rect.left = 0;
rect.right = 800;
rect.right = 1280;
rect.top = 0; rect.top = 0;
rect.bottom = 600;
rect.bottom = 720;
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, NULL); AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, NULL);
int windowWidth = rect.right - rect.left; int windowWidth = rect.right - rect.left;
int windowHeight = rect.bottom - rect.top; int windowHeight = rect.bottom - rect.top;

34
model.cpp

@ -102,14 +102,23 @@ void Model::Init(const char*modelPath) {
mShader = new Shader; mShader = new Shader;
mShader->Init("Res/model.vs", "Res/model.fs"); 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_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_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); glEnable(GL_DEPTH_TEST);
mVertexBuffer->Bind(); mVertexBuffer->Bind();
glm::mat4 it = glm::inverseTranspose(mModelMatrix); glm::mat4 it = glm::inverseTranspose(mModelMatrix);
@ -121,3 +130,20 @@ void Model::Draw(glm::mat4 & viewMatrix, glm::mat4 projectionMatrix) {
void Model::SetPosition(float x, float y, float z) { void Model::SetPosition(float x, float y, float z) {
mModelMatrix = glm::translate(x, y, z); mModelMatrix = glm::translate(x, y, z);
} }
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);
}

7
model.h

@ -9,6 +9,11 @@ public:
glm::mat4 mModelMatrix; glm::mat4 mModelMatrix;
Model(); Model();
void Init(const char*modelPath); 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 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);
}; };

44
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;
}
}
}

12
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);
};

69
scene.cpp

@ -2,26 +2,89 @@
#include "ggl.h" #include "ggl.h"
#include "utils.h" #include "utils.h"
#include "ground.h" #include "ground.h"
#include "shader.h"
#include "model.h" #include "model.h"
#include "skybox.h"
#include "particleSystem.h"
#include "framebufferobject.h"
glm::mat4 modelMatrix, viewMatrix, projectionMatrix; glm::mat4 modelMatrix, viewMatrix, projectionMatrix;
glm::vec3 cameraPos(10.0f, 10.0f, 10.0f);
Ground ground; Ground ground;
Model model;
Model model, niutou, sphere;
SkyBox skybox;
ParticleSystem ps;
FrameBufferObject *fbo;
VertexBuffer *fsqVertex;
Shader *fsqShader;
glm::mat4 fsqViewMatrix;
void Init() { void Init() {
viewMatrix = glm::lookAt(cameraPos, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f,1.0f,0.0f));
ground.Init(); ground.Init();
model.Init("Res/Sphere.obj"); 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) { void SetViewPortSize(float width, float height) {
projectionMatrix = glm::perspective(60.0f, width / height, 0.1f, 1000.0f); 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() { void Draw() {
float frameTime = GetFrameTime(); float frameTime = GetFrameTime();
glClearColor(0.1f, 0.4f, 0.6f, 1.0f); glClearColor(0.1f, 0.4f, 0.6f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 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); 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();
} }

BIN
shader.VC.db

16
shader.cpp

@ -94,3 +94,19 @@ void Shader::SetVec4(const char * name, float x, float y, float z, float w) {
iter->second->v[3] = w; 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<std::string, UniformTexture*>(name, t));
}
}
else {
glDeleteTextures(1, &iter->second->mTexture);
iter->second->mTexture = texture;
}
}

5
shader.h

@ -19,6 +19,10 @@ struct UniformVector4f {
class Shader { class Shader {
public: public:
GLuint mProgram; GLuint mProgram;
GLuint mPosition;
GLuint mColor;
GLuint mTexcoord;
GLuint mNormal;
std::map<std::string, UniformTexture*> mUniformTextures; std::map<std::string, UniformTexture*> mUniformTextures;
std::map<std::string, UniformVector4f*> mUniformVec4s; std::map<std::string, UniformVector4f*> mUniformVec4s;
GLint mModelMatrixLocation, mViewMatrixLocation, mProjectionMatrixLocation; GLint mModelMatrixLocation, mViewMatrixLocation, mProjectionMatrixLocation;
@ -26,5 +30,6 @@ public:
void Init(const char*vs, const char*fs); void Init(const char*vs, const char*fs);
void Bind(float *M, float *V, float*P); void Bind(float *M, float *V, float*P);
void SetTexture(const char * name, const char*imagePath); 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); void SetVec4(const char * name, float x, float y, float z, float w);
}; };

12
shader.vcxproj

@ -143,20 +143,26 @@
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="framebufferobject.cpp" />
<ClCompile Include="ground.cpp" /> <ClCompile Include="ground.cpp" />
<ClCompile Include="main.cpp" /> <ClCompile Include="main.cpp" />
<ClCompile Include="model.cpp" /> <ClCompile Include="model.cpp" />
<ClCompile Include="particleSystem.cpp" />
<ClCompile Include="scene.cpp" /> <ClCompile Include="scene.cpp" />
<ClCompile Include="shader.cpp" /> <ClCompile Include="shader.cpp" />
<ClCompile Include="skybox.cpp" />
<ClCompile Include="utils.cpp" /> <ClCompile Include="utils.cpp" />
<ClCompile Include="vertexbuffer.cpp" /> <ClCompile Include="vertexbuffer.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="framebufferobject.h" />
<ClInclude Include="ggl.h" /> <ClInclude Include="ggl.h" />
<ClInclude Include="ground.h" /> <ClInclude Include="ground.h" />
<ClInclude Include="model.h" /> <ClInclude Include="model.h" />
<ClInclude Include="particleSystem.h" />
<ClInclude Include="scene.h" /> <ClInclude Include="scene.h" />
<ClInclude Include="shader.h" /> <ClInclude Include="shader.h" />
<ClInclude Include="skybox.h" />
<ClInclude Include="utils.h" /> <ClInclude Include="utils.h" />
<ClInclude Include="vertexbuffer.h" /> <ClInclude Include="vertexbuffer.h" />
</ItemGroup> </ItemGroup>
@ -165,8 +171,14 @@
<None Include="Res\ground.vs" /> <None Include="Res\ground.vs" />
<None Include="Res\model.fs" /> <None Include="Res\model.fs" />
<None Include="Res\model.vs" /> <None Include="Res\model.vs" />
<None Include="Res\particle.fs" />
<None Include="Res\particle.vs" />
<None Include="Res\skybox.fs" />
<None Include="Res\skybox.vs" />
<None Include="Res\test.fs" /> <None Include="Res\test.fs" />
<None Include="Res\test.vs" /> <None Include="Res\test.vs" />
<None Include="Res\texture.fs" />
<None Include="Res\texture.vs" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">

56
shader.vcxproj.filters

@ -36,28 +36,46 @@
<ClCompile Include="model.cpp"> <ClCompile Include="model.cpp">
<Filter>源文件</Filter> <Filter>源文件</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="skybox.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="particleSystem.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="framebufferobject.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="ggl.h"> <ClInclude Include="ggl.h">
<Filter>源文件</Filter>
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="ground.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="model.h">
<Filter>头文件</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="scene.h"> <ClInclude Include="scene.h">
<Filter>源文件</Filter>
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="shader.h">
<Filter>头文件</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="utils.h"> <ClInclude Include="utils.h">
<Filter>源文件</Filter>
<Filter>文件</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="vertexbuffer.h"> <ClInclude Include="vertexbuffer.h">
<Filter>文件</Filter>
<Filter>文件</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="ground.h">
<Filter>文件</Filter>
<ClInclude Include="skybox.h">
<Filter>文件</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="shader.h">
<Filter>文件</Filter>
<ClInclude Include="particleSystem.h">
<Filter>文件</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="model.h">
<Filter>文件</Filter>
<ClInclude Include="framebufferobject.h">
<Filter>文件</Filter>
</ClInclude> </ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@ -79,5 +97,23 @@
<None Include="Res\model.vs"> <None Include="Res\model.vs">
<Filter>资源文件</Filter> <Filter>资源文件</Filter>
</None> </None>
<None Include="Res\skybox.fs">
<Filter>资源文件</Filter>
</None>
<None Include="Res\skybox.vs">
<Filter>资源文件</Filter>
</None>
<None Include="Res\particle.fs">
<Filter>资源文件</Filter>
</None>
<None Include="Res\particle.vs">
<Filter>资源文件</Filter>
</None>
<None Include="Res\texture.fs">
<Filter>资源文件</Filter>
</None>
<None Include="Res\texture.vs">
<Filter>资源文件</Filter>
</None>
</ItemGroup> </ItemGroup>
</Project> </Project>

124
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();
}
}

17
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);
};

32
utils.cpp

@ -31,9 +31,9 @@ GLuint CreateProgram(GLuint vsShader, GLuint fsShader)
glAttachShader(program, vsShader);//绑定编译好的shader glAttachShader(program, vsShader);//绑定编译好的shader
glAttachShader(program, fsShader); glAttachShader(program, fsShader);
glLinkProgram(program);//链接成一个程序 glLinkProgram(program);//链接成一个程序
//判断链接是否成功
GLint nResult = GL_TRUE;
glDetachShader(program, vsShader);
glDetachShader(program, fsShader);
GLint nResult;
glGetProgramiv(program, GL_LINK_STATUS, &nResult); glGetProgramiv(program, GL_LINK_STATUS, &nResult);
if (nResult == GL_FALSE) { if (nResult == GL_FALSE) {
char log[1024] = { 0 }; char log[1024] = { 0 };
@ -96,3 +96,29 @@ GLuint CreateBufferObject(GLenum bufferType, GLsizeiptr size, GLenum usage, void
glBindBuffer(bufferType, 0); glBindBuffer(bufferType, 0);
return object; return object;
} }
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;
}

1
utils.h

@ -8,3 +8,4 @@ unsigned char * DecodeBMP(unsigned char*bmpFileData, int&width, int&height);
GLuint CreateTexture2D(unsigned char*pixelData, int width, int height, GLenum type); GLuint CreateTexture2D(unsigned char*pixelData, int width, int height, GLenum type);
GLuint CreateTexture2DFromBMP(const char *bmpPath); GLuint CreateTexture2DFromBMP(const char *bmpPath);
GLuint CreateBufferObject(GLenum bufferType, GLsizeiptr size, GLenum usage, void*data = nullptr); GLuint CreateBufferObject(GLenum bufferType, GLsizeiptr size, GLenum usage, void*data = nullptr);
GLuint CreateProcedureTexture(int size);
Loading…
Cancel
Save