diff --git a/CMakeLists.txt b/CMakeLists.txt index 2846520..0be0a8a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,10 +26,19 @@ ELSE(WIN32) MESSAGE(STATUS "WIN32") set(CMAKE_PREFIX_PATH D:/document/lib/) set(THIRD_LIB_DIR D:/document/lib/) + #opencv + include_directories(${THIRD_LIB_DIR}/opencv/opencv/build/include) + link_directories(${THIRD_LIB_DIR}/opencv/opencv/build/x64/vc15/lib) + set(OpenCV_LIBS + opencv_world460d.lib + ) #glad include_directories(${THIRD_LIB_DIR}/glad/glad3.3/include) set(GLAD_SRCS ${THIRD_LIB_DIR}/glad/glad3.3/src/glad.c - src/practice_1.cpp) + src/triangle.cpp + src/shaderService.cpp + src/texture.cpp + src/stb_image.cpp) #glfw include_directories(${THIRD_LIB_DIR}/glfw/glfw-3.3.8.bin.WIN64/glfw-3.3.8.bin.WIN64/include) link_directories(${THIRD_LIB_DIR}/glfw/glfw-3.3.8.bin.WIN64/glfw-3.3.8.bin.WIN64/lib-vc2022) @@ -51,5 +60,6 @@ ELSE(WIN32) target_link_libraries(${PROJECT_N} ${Glfw_LIBS} ${Opengl_LIBS} + ${OpenCV_LIBS} ) endif () diff --git a/include/shaderService.h b/include/shaderService.h new file mode 100644 index 0000000..59429ff --- /dev/null +++ b/include/shaderService.h @@ -0,0 +1,38 @@ +// +// Created by jie on 2023/10/11. +// + +#ifndef LEARNOPENGL_SHADERHELPER_H +#define LEARNOPENGL_SHADERHELPER_H + +#include "glad/glad.h" +#include +#include + +class ShaderService { +private: + unsigned int programId; +public: + ShaderService(const std::filesystem::path &vertexShaderPath, const std::filesystem::path &fragShaderPath); + bool CheckShader(unsigned int shaderIndex, bool isProgram = false); + void Use(); + + template + requires std::is_same_v || std::is_same_v || std::is_same_v + void SetUniform(std::string_view name, T value); +}; + +template +requires std::is_same_v || std::is_same_v || std::is_same_v +void ShaderService::SetUniform(std::string_view name, T value) { + if constexpr (std::is_same_v) { + glUniform1i(glGetUniformLocation(programId, name.data()), (int) value); + } else if constexpr (std::is_same_v) { + glUniform1i(glGetUniformLocation(programId, name.data()), value); + } else if constexpr (std::is_same_v) { + glUniform1f(glGetUniformLocation(programId, name.data()), value); + } +} + + +#endif //LEARNOPENGL_SHADERHELPER_H diff --git a/include/texture.h b/include/texture.h new file mode 100644 index 0000000..01ea751 --- /dev/null +++ b/include/texture.h @@ -0,0 +1,23 @@ +// +// Created by jie on 2023/10/11. +// + +#ifndef LEARNOPENGL_TEXTURE_H +#define LEARNOPENGL_TEXTURE_H +#include "pch.h" +#include "shaderService.h" + +namespace TEXTURE { + int Texture(); + + void frameBufferSizeChange(GLFWwindow *window, int width, int height); + + void processInput(GLFWwindow *window); + + void CheckShader(unsigned int shaderIndex, bool isPorgram = false); +} + + + + +#endif //LEARNOPENGL_TEXTURE_H diff --git a/main.cpp b/main.cpp index 2c6a6ed..214b687 100644 --- a/main.cpp +++ b/main.cpp @@ -1,7 +1,9 @@ #include +#include "texture.h" #include "triangle.h" int main(int argc, char **const argv) { - PRACTICE::Practice1(); - return 0; +// TRIANGLE::Practice1(); + auto res = TEXTURE::Texture(); + return res ; } \ No newline at end of file diff --git a/shaders/texture.frag b/shaders/texture.frag new file mode 100644 index 0000000..265b961 --- /dev/null +++ b/shaders/texture.frag @@ -0,0 +1,13 @@ +#version 330 core +in vec2 ourTexCoord; +in vec3 ourColor; +out vec4 fragColor; + +uniform sampler2D ourTexture1; +uniform sampler2D ourTexture2; +uniform float mixCount; +void main() { +// fragColor = texture(ourTexture1, ourTexCoord); + fragColor = mix(texture(ourTexture1, ourTexCoord), texture(ourTexture2, vec2(-ourTexCoord.x, ourTexCoord.y)), mixCount); +//fragColor = mix(texture(ourTexture1, ourTexCoord), texture(ourTexture2, vec2(1.0 - ourTexCoord.x, ourTexCoord.y)), 0.2); +} \ No newline at end of file diff --git a/shaders/texture.vert b/shaders/texture.vert new file mode 100644 index 0000000..11abedd --- /dev/null +++ b/shaders/texture.vert @@ -0,0 +1,11 @@ +#version 330 core +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec3 aColor; +layout (location = 2) in vec2 aTexCoord; +out vec3 ourColor; +out vec2 ourTexCoord; +void main() { + gl_Position=vec4(aPos, 1.0f); + ourColor = aColor; + ourTexCoord = aTexCoord; +} \ No newline at end of file diff --git a/src/shaderService.cpp b/src/shaderService.cpp new file mode 100644 index 0000000..5b771d5 --- /dev/null +++ b/src/shaderService.cpp @@ -0,0 +1,72 @@ +// +// Created by jie on 2023/10/11. +// + +#include "shaderService.h" +#include +#include + +ShaderService::ShaderService(const std::filesystem::path &vertexShaderPath, + const std::filesystem::path &fragShaderPath) { + if(!(exists(vertexShaderPath) && exists(fragShaderPath))){ + return; + } + + std::stringstream ss, sss; + std::ifstream verIn{}; + std::ifstream fragIn{}; + verIn.open(vertexShaderPath); + fragIn.open(fragShaderPath); + ss << verIn.rdbuf(); + const auto vertexSource = ss.str(); + sss << fragIn.rdbuf(); + const auto fragmentSource = sss.str(); + verIn.close();fragIn.close(); + + const char* vSource = vertexSource.c_str(); + const char* fSource = fragmentSource.c_str(); + + unsigned int frag, vertex; + frag = glCreateShader(GL_FRAGMENT_SHADER); + vertex = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertex, 1, &vSource, nullptr); + glShaderSource(frag, 1, &fSource, nullptr); + glCompileShader(vertex); + glCompileShader(frag); + if(const auto res = (CheckShader(vertex) && CheckShader(frag));!res){ + return; + } + programId = glCreateProgram(); + glAttachShader(programId, vertex); + glAttachShader(programId, frag); + glLinkProgram(programId); + CheckShader(programId, true); + + glDeleteShader(vertex); + glDeleteShader(frag); +} + +void ShaderService::Use() { + glUseProgram(programId); +} + +bool ShaderService::CheckShader(const unsigned int shaderIndex, bool isProgram) { + int successful; + char logInfo[512]; + if (isProgram) { + glad_glGetProgramiv(shaderIndex, GL_LINK_STATUS, &successful); + } else { + glad_glGetShaderiv(shaderIndex, GL_COMPILE_STATUS, &successful); + } + if (!successful) { + if (isProgram) { + glad_glGetProgramInfoLog(shaderIndex, 512, nullptr, logInfo); + std::cout< 0) mixValue -= 0.01f; + } + } + + void CheckShader(unsigned int shaderIndex, bool isPorgram) { + int successful; + char logInfo[512]; + if (isPorgram) { + glad_glGetProgramiv(shaderIndex, GL_LINK_STATUS, &successful); + } else { + glad_glGetShaderiv(shaderIndex, GL_COMPILE_STATUS, &successful); + } + if (!successful) { + if (isPorgram) { + glad_glGetProgramInfoLog(shaderIndex, 512, nullptr, logInfo); + } else { + glad_glGetShaderInfoLog(shaderIndex, 512, nullptr, logInfo); + } + std::cout << logInfo << std::endl; + } + } + + int Texture() { + glfwInit(); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + + GLFWwindow *window = glfwCreateWindow(800, 600, "Windows", nullptr, nullptr); + if (window == nullptr) { + return -1; + } + glfwMakeContextCurrent(window); + glfwSetWindowSizeCallback(window, frameBufferSizeChange); + + if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)) { + auto error = glad_glGetError(); + return static_cast(error); + } + + float vertices[] = { + 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, + 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, + -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, + -0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, + }; + + unsigned int indices[] = { + 0, 1, 3, // first triangle + 1, 2, 3 // second triangle + }; + + unsigned int VAO, VBO, EBO; + glGenVertexArrays(1, &VAO); + glGenBuffers(1, &VBO); + glGenBuffers(1, &EBO); + + glBindVertexArray(VAO); + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); + + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *) 0); + glEnableVertexAttribArray(0); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *) (3 * sizeof(float))); + glEnableVertexAttribArray(1); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *) (6 * sizeof(float))); + glEnableVertexAttribArray(2); + glBindVertexArray(0); + auto wall = cv::imread("../../resources/container.jpg"); + auto awesomeFace = cv::imread("../../resources/awesomeface.png"); + cv::flip(awesomeFace, awesomeFace, 0); + unsigned int texture[2]; + glGenTextures(2, texture); + glBindTexture(GL_TEXTURE_2D, texture[0]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, wall.cols, wall.rows, 0, GL_BGR, GL_UNSIGNED_BYTE, wall.data); + glGenerateMipmap(GL_TEXTURE_2D); + + glBindTexture(GL_TEXTURE_2D, texture[1]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, awesomeFace.cols, awesomeFace.rows, 0, GL_BGR, GL_UNSIGNED_BYTE, + awesomeFace.data); + glGenerateMipmap(GL_TEXTURE_2D); + + auto shader = ShaderService("../../shaders/texture.vert", + "../../shaders/texture.frag"); + + shader.Use(); + shader.SetUniform("ourTexture1", 0); + shader.SetUniform("ourTexture2", 1); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + while (!glfwWindowShouldClose(window)) { + processInput(window); + + glClearColor(.2f, .3f, .3f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + shader.Use(); +// std::this_thread::sleep_for(5ms); + shader.SetUniform("mixCount", mixValue); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture[0]); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, texture[1]); + + glBindVertexArray(VAO); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); +// glUseProgram(shaderProgram[1]); +// glDrawArrays(GL_TRIANGLES, 0, 3); + glfwSwapBuffers(window); + glfwPollEvents(); + } + + glDeleteBuffers(1, &VBO); + glDeleteVertexArrays(1, &VAO); + glDeleteBuffers(1, &EBO); + + glfwTerminate(); + return 0; + } +} \ No newline at end of file