Browse Source

实现贴图和光照

master
blobt 4 years ago
parent
commit
613658e950
  1. BIN
      .vs/shader2/v14/.suo
  2. 1153
      FreeImage.h
  3. 27
      main.cpp
  4. 87
      misc.cpp
  5. 2
      misc.h
  6. BIN
      res/image/stone.jpg
  7. 17
      res/shader/test.fs
  8. 5
      res/shader/test.vs
  9. BIN
      shader2.VC.db

BIN
.vs/shader2/v14/.suo

1153
FreeImage.h
File diff suppressed because it is too large
View File

27
main.cpp

@ -90,7 +90,7 @@ INT WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
/*创建program*/
GLuint program = CreateGPUProgram("res/shader/test.vs", "res/shader/test.fs");
GLuint posLocation, texcoordLocation, normalLocation, MLocation, VLocation, PLocation, NMLocation;
GLuint posLocation, texcoordLocation, normalLocation, MLocation, VLocation, PLocation, NMLocation, textureLocation;
posLocation = glGetAttribLocation(program, "pos");
texcoordLocation = glGetAttribLocation(program, "texcoord");
normalLocation = glGetAttribLocation(program, "normal");
@ -98,6 +98,8 @@ INT WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
VLocation = glGetUniformLocation(program, "V");
PLocation = glGetUniformLocation(program, "P");
NMLocation = glGetUniformLocation(program, "NM");
textureLocation = glGetUniformLocation(program, "U_MainTexture");
/*load model*/
unsigned int *indexes = nullptr;
@ -114,8 +116,11 @@ INT WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
/*创建IBO*/
GLuint ibo = CreateBufferObject(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * indexCount, GL_STATIC_DRAW, indexes);
/*创建纹理*/
GLuint mainTexture = CreateTextureFromFile("res/image/stone.jpg");
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
//glEnable(GL_DEPTH_TEST);
glEnable(GL_DEPTH_TEST);
//创建一个单位矩阵和一个投影矩阵,后面用来传递到shader
float identify[] = {
@ -124,7 +129,7 @@ INT WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
0,0,1,0,
0,0,0,1
};
glm::mat4 model = glm::translate(0.0f, 0.0f, -3.0f);
glm::mat4 model = glm::translate(0.0f, 0.0f, -4.0f);
glm::mat4 projection = glm::perspective(45.0f, 800.0f/600.0f, 0.1f, 1000.0f);
glm::mat4 normalMatrix = glm::inverseTranspose(model);
@ -134,6 +139,8 @@ INT WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
/*监听并处理用户请求*/
MSG msg;
float angle = 0.0;
while (true) {
if (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE)) {
if (msg.message == WM_QUIT) {
@ -143,7 +150,16 @@ INT WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
DispatchMessage(&msg);
}
glClear(GL_COLOR_BUFFER_BIT);
if (angle > 360) {
angle = 0;
}
else {
angle += 0.01f;
}
model = glm::translate(0.0f, 0.0f, -4.0f) * glm::rotate(angle, 0.0f, 1.0f, 0.0f);
glm::mat4 normalMatrix = glm::inverseTranspose(model);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(program);
glUniformMatrix4fv(MLocation, 1, GL_FALSE, glm::value_ptr(model));
@ -151,6 +167,9 @@ INT WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
glUniformMatrix4fv(PLocation, 1, GL_FALSE, glm::value_ptr(projection));
glUniformMatrix4fv(NMLocation, 1, GL_FALSE, glm::value_ptr(normalMatrix));
glBindTexture(GL_TEXTURE_2D, mainTexture);
glUniform1i(textureLocation, 0);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glEnableVertexAttribArray(posLocation);
glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (void*)0);

87
misc.cpp

@ -1,6 +1,9 @@
#include "misc.h"
#include "FreeImage.h"
#include <stdio.h>
#pragma comment(lib,"FreeImage.lib")
GLuint CreateBufferObject(GLenum bufferType, GLsizeiptr size, GLenum usage, void * data)
{
GLuint object;
@ -109,3 +112,87 @@ GLuint CreateGPUProgram(const char* vsShaderPath, const char* fsShaderPath) {
return program;
}
GLuint CreateTextureFromBMP(const char * imagePath)
{
unsigned char* imgData = (unsigned char*)LoadFileContent(imagePath);
if (*((unsigned short*)imgData) != 0x4D42) {
printf("cannot decode %s\n", imagePath);
return 0;
}
//decode bmp
int pixelDataOffset = *((int*)(imgData + 10));
int width = *((int*)(imgData + 18));
int height = *((int*)(imgData + 22));
unsigned char* pixelData = imgData + pixelDataOffset;
//bgr 转 rgb
for (int i = 0; i < width * height * 3; i+=3) {
unsigned char tmp = pixelData[i + 2];
pixelData[i + 2] = pixelData[i + 0];
pixelData[i + 0] = tmp;
}
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
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_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, pixelData);
glBindTexture(GL_TEXTURE_2D, 0);
delete imgData;
return texture;
}
GLuint CreateTexture(int w, int h, const void* data, GLenum type)
{
GLuint texId;
glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_2D, texId);
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, type, w, h, 0, type, GL_UNSIGNED_BYTE, data);
return texId;
}
GLuint CreateTextureFromFile(const char * imagePath)
{
//1 获取图片格式
FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(imagePath, 0);
if (fifmt == FIF_UNKNOWN)
{
printf("File %s not found! ", imagePath);
return 0;
}
//2 加载图片
FIBITMAP *dib = FreeImage_Load(fifmt, imagePath, 0);
FREE_IMAGE_COLOR_TYPE type = FreeImage_GetColorType(dib);
//! 获取数据指针
FIBITMAP* temp = dib;
dib = FreeImage_ConvertTo32Bits(dib);
FreeImage_Unload(temp);
BYTE* pixels = (BYTE*)FreeImage_GetBits(dib);
int width = FreeImage_GetWidth(dib);
int height = FreeImage_GetHeight(dib);
for (int i = 0; i < width * height * 4; i += 4)
{
BYTE temp = pixels[i];
pixels[i] = pixels[i + 2];
pixels[i + 2] = temp;
}
GLuint res = CreateTexture(width, height, pixels, GL_RGBA);
FreeImage_Unload(dib);
return res;
}

2
misc.h

@ -5,3 +5,5 @@ GLuint CreateBufferObject(GLenum bufferType, GLsizeiptr size, GLenum usage, void
char* LoadFileContent(const char *path);
GLuint CompileShader(GLenum shaderType, const char* shaderPath);
GLuint CreateGPUProgram(const char* vsShaderPath, const char* fsShaderPath);
GLuint CreateTextureFromBMP(const char* imagePath);
GLuint CreateTextureFromFile(const char* imagePath);

BIN
res/image/stone.jpg

After

Width: 1024  |  Height: 1024  |  Size: 512 KiB

17
res/shader/test.fs

@ -1,8 +1,11 @@
uniform sampler2D U_MainTexture;
varying vec3 V_Normal;
varying vec4 V_WorldPos;//
varying vec2 V_Texcoord;
void main() {
vec3 lightPos = vec3(0.0, 10.0, 0.0);
vec3 lightPos = vec3(10.0, 10.0, 0.0);
vec3 L=lightPos;
L = normalize(L);
vec3 n = normalize(V_Normal);
@ -15,9 +18,17 @@ void main() {
//diffuse
vec4 DiffuseLightColor = vec4(1.0,1.0,1.0,1.0);
vec4 DiffuseMaterial = vec4(0.2, 0.2, 0.2, 1.0);
vec4 DiffuseMaterial = vec4(0.8, 0.8, 0.8, 1.0);
vec4 diffuseColor = DiffuseLightColor*DiffuseMaterial*max(0.0, dot(L,n));
//specular
vec4 SpecularLightColor = vec4(1.0,1.0,1.0,1.0);
vec4 SpecularMaterial = vec4(0.9,0.9,0.9,1.0);
vec3 reflectDir = normalize(reflect(-L,n));//-L线线
vec3 viewDir = normalize(vec3(0.0) - V_WorldPos.xyz);//vec3(0.0)线
vec4 specularColor = SpecularLightColor*SpecularMaterial*pow(max(0.0,dot(viewDir,reflectDir)),28.0);
gl_FragColor = AmbientColor + diffuseColor;
//gl_FragColor = texture2D(U_MainTexture, V_Texcoord) * (AmbientColor + diffuseColor + specularColor);
gl_FragColor = AmbientColor + texture2D(U_MainTexture, V_Texcoord) * diffuseColor + specularColor;
}

5
res/shader/test.vs

@ -8,7 +8,12 @@ uniform mat4 P;
uniform mat4 NM;
varying vec3 V_Normal;
varying vec4 V_WorldPos;//当前的位置
varying vec2 V_Texcoord;
void main() {
V_Normal = mat3(NM)*normal;
V_WorldPos = M * vec4(pos, 1.0);
V_Texcoord = texcoord;
gl_Position = P*V*M*vec4(pos,1.0);
}

BIN
shader2.VC.db

Loading…
Cancel
Save