#include<glad/glad.h>
#include<GLFW/glfw3.h>
#include<glm/glm.hpp>
#include<glm/gtc/type_ptr.hpp>
#include<glm/gtc/matrix_transform.hpp>
#include<iostream>
#define STB_IMAGE_IMPLEMENTATION
#include"stb/stb_image.h"
#define Wwidth 1080
#define Wheight 960
//顶点着色器源码
const char* vertexShaderSource = "#version 330 core \n"
"layout ( location = 0 ) in vec3 aPos; \n" //顶点位置
"layout ( location = 1 ) in vec3 aColor;\n" //顶点颜色
"layout ( location = 2 ) in vec2 aTex1; \n" //纹理1坐标
"layout ( location = 3 ) in vec2 aTex2; \n" //纹理2坐标
"out vec3 verColor; \n"
"out vec2 tex1Coord; \n"
"out vec2 tex2Coord; \n"
"uniform mat4 transform; \n"
"void main() \n"
"{ \n"
" gl_Position = transform "
" *vec4(aPos, 1.0f); \n"
" verColor = aColor; \n"
" tex1Coord = aTex1; \n"
" tex2Coord = aTex2; \n"
"} \n"
;
//片段着色器源码
const char* fragmentShaderSource = "#version 330 core \n"
"in vec3 verColor; \n"
"in vec2 tex1Coord; \n"
"in vec2 tex2Coord; \n"
"uniform sampler2D ourTexture1; \n"
"uniform sampler2D ourTexture2; \n"
"out vec4 fragColor; \n"
"void main() \n"
"{ \n"
" fragColor = mix( "
" texture(ourTexture1, tex1Coord), "
" texture(ourTexture2, tex2Coord), "
" 0.9 ) *vec4(verColor, 0.0f); \n"
"} \n"
;
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
int main()
{
//初始化并配置glfw
if(!glfwInit())
{
perror("failed to init glfw");
return -1;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//创建glfw上下文窗口
GLFWwindow* window = glfwCreateWindow(Wwidth, Wheight, "纹理", NULL, NULL);
if (!window)
{
printf("failed to create glfw window");
return -1;
}
//将当前glfw窗口上下文绑定到当前线程上下文
glfwMakeContextCurrent(window);
//设置帧缓冲回调函数
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
//启动glad
if(!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
printf("failed to load glad");
return -1;
}
//启动顶点着色器
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
int success;
char infoLog[512];
//获取编译状态
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if(!success)
{
//生成日志信息
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
printf("%s\n", infoLog);
return -1;
}
/***************************************************着色器****************************************************/
/*************************************************************************************************************/
//启动顶点着色器
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
//获取编译状态
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if(!success)
{
//生成日志信息
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
printf("%s\n", infoLog);
return -1;
}
//生成着色器项目
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
//获取链接状态
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if(!success)
{
//生成日志信息
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
printf("%s\n", infoLog);
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
/*************************************************************************************************************/
//顶点属性数组
float vertices[] = { //顶点坐标 //顶点颜色 //纹理1坐标 //纹理2坐标
-0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, -1.0f,
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 2.0f, 0.0f, 2.0f, -1.0f,
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 2.0f, 2.0f, 2.0f, 2.0f,
-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 2.0f, -1.0f, 2.0f
};
//索引数组
GLuint indices[] = {
0, 1, 2,
2, 3, 0
};
//创建 顶点数组对象, 顶点缓冲对象, 索引缓冲对象
GLuint VAO, VBO, EBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
//绑定顶点数组对象
glBindVertexArray(VAO);
//绑定顶点缓冲对象
glBindBuffer(GL_ARRAY_BUFFER, VBO);
//填充VBO数据
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//绑定索引缓冲对象,并填充数据
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
//设置顶点位置属性,并启用
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 10*sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
//设置顶点颜色属性,并启用
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 10*sizeof(float), (void*)(3*sizeof(float)));
glEnableVertexAttribArray(1);
//设置纹理1位置属性,并启用
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 10*sizeof(float), (void*)(6*sizeof(float)));
glEnableVertexAttribArray(2);
//设置纹理2位置属性,并启用
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 10*sizeof(float), (void*)(8*sizeof(float)));
glEnableVertexAttribArray(3);
/*************************************************************************************************************/
//创建纹理
GLuint texture1, texture2;
glGenTextures(1, &texture1);
glBindTexture(GL_TEXTURE_2D, texture1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
int width, height, nrchannels;
stbi_set_flip_vertically_on_load(true);
unsigned char* datas = stbi_load("C:\\Users\\fusheng\\Desktop\\opengl\\texture\\pear.png", &width, &height, &nrchannels, 0);
if(datas)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, datas);
glGenerateMipmap(GL_TEXTURE_2D);
printf("yes\n");
}
else
{
printf("failed to load png %s\n", stbi_failure_reason());
}
stbi_image_free(datas);
glGenTextures(1, &texture2);
glBindTexture(GL_TEXTURE_2D, texture2);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
const GLfloat borderColor[] = { 0.95f, 0.95f, 0.95f, 0.0f};
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
datas = stbi_load("C:\\Users\\fusheng\\Desktop\\opengl\\texture\\tt.png", &width, &height, &nrchannels, 0);
if(datas)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, datas);
glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
printf("failed to load jpg %s\n", stbi_failure_reason());
}
stbi_image_free(datas);
/*************************************************************************************************************/
glUseProgram(shaderProgram);
GLuint uniformLocation = glGetUniformLocation(shaderProgram, "ourTexture1");
glUniform1i(uniformLocation, 0);
uniformLocation = glGetUniformLocation(shaderProgram, "ourTexture2");
glUniform1i(uniformLocation, 1);
while(!glfwWindowShouldClose(window))
{
glClearColor(0.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture2);
glm::mat4 transform = glm::mat4(1.0f);
transform = glm::translate(transform, glm::vec3(0.5, -0.5, 0.0));
transform = glm::rotate(transform, (float)glfwGetTime(), glm::vec3(0.0, 0.0f, 1.0f));
glUseProgram(shaderProgram);
GLuint transformLocation = glGetUniformLocation(shaderProgram, "transform");
glUniformMatrix4fv(transformLocation, 1, GL_FALSE, glm::value_ptr(transform));
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);
glDeleteProgram(shaderProgram);
glfwTerminate();
return 0;
}
最新发布