渲染一张图片,但是貌似只能渲染出纯色
#pragma once
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <fstream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <gl/GL.h>
#include <glm/glm.hpp>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
//如果调整了窗口大小就调用该回调
void framebufffer_size_callback(GLFWwindow* window, int32_t width, int32_t height)
{
glViewport(0, 0, width, height);
}
//输入检测
void processInput(GLFWwindow* window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
{
glfwSetWindowShouldClose(window, true);
}
}
class Shader
{
public:
uint32_t id;
public:
//读取着色器代码
std::string ReadShaderCode(const char* path)
{
std::string ret;
std::ifstream fs;
std::stringstream buf;
fs.open(path);
if (fs.is_open()) {
buf << fs.rdbuf();
ret = buf.str();
}
else {
printf("Read shader source code erro");
}
fs.close();
return ret;
}
//检测着色器编译是否成功
GLuint ShaderIsCompile(GLint shader)
{
GLint success; //是否成功编译
GLchar infoLog[512]; //储存错误消息
glGetShaderiv(shader, GL_COMPILE_STATUS, &success); //检查是否编译成功
if (!success) {
glGetShaderInfoLog(shader, 512, NULL, infoLog);
std::cout << "Shader compile erro:" << infoLog << std::endl;
}
return success;
}
//检测着色器链接是否成功
GLuint ShaderIsLink(GLint shaderProgram)
{
GLint success; //是否成功编译
GLchar infoLog[512]; //储存错误消息
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); //检查是否编译成功
if (!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
std::cout << "Shader link erro:" << infoLog << std::endl;
}
return success;
}
Shader(const char* vertexSourceCodePath, const char* fragmentSourceCodePath)
{
//-----读取着色器-----
std::string vertexShaderSource = ReadShaderCode(vertexSourceCodePath);
std::string frgmentShaderSource = ReadShaderCode(fragmentSourceCodePath);
const char* vertexShaderCode = vertexShaderSource.c_str();
const char* frgmentShaderCode = frgmentShaderSource.c_str();
//-----编译着色器-----
GLint vertexShader = NULL, fagmentShader = NULL;
//创建着色器
fagmentShader = glCreateShader(GL_FRAGMENT_SHADER);
//附加源码到着色器
glShaderSource(vertexShader, 1, &vertexShaderCode, NULL);
glShaderSource(fagmentShader, 1, &frgmentShaderCode, NULL);
//编译着色器
glCompileShader(vertexShader);
glCompileShader(fagmentShader);
//检测着色器编译是否成功
ShaderIsCompile(vertexShader);
ShaderIsCompile(fagmentShader);
//-------着色器程序-------
//创建程序对象
this->id = glCreateProgram();
//将着色器附加到程序对象并链接
glAttachShader(this->id, vertexShader);
glAttachShader(this->id, fagmentShader);
glLinkProgram(this->id);
//检测着色器链接是否成功
ShaderIsLink(this->id);
//激活程序对象
glUseProgram(this->id);
//删除已经不需要的着色器对象
glDeleteShader(vertexShader);
glDeleteShader(fagmentShader);
}
//设置着色器Uniform值 Float vec4
void SetUniformValueInt(float x, float y, float z, float w, const char* name)
{
//查找uniform的位置
GLint up = glGetUniformLocation(this->id, name);
//设置值
glUniform4f(up, x, y, z, w);
}
//使用着色器
void Use()
{
glUseProgram(this->id);
}
//关闭着色器
void Close()
{
glDeleteProgram(id);
}
};
class NEO_Render
{
private:
GLFWwindow* window = nullptr;
unsigned int texture;
unsigned int VBO, VAO, EBO;
//初始化渲染器
void InitRender(int32_t width, int32_t height, const char* title)
{
/*-----------GLFW窗口创建-----------*/
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
window = glfwCreateWindow(width, height, title, nullptr, nullptr);
if (window == nullptr)
{
printf("创建窗口失败...\n");
glfwTerminate();
return;
}
glfwMakeContextCurrent(window);
//防止报错
glewExperimental = GL_TRUE;
glewInit();
}
//渲染主循环
void MainLoop()
{
Shader shaderObj = Shader("VertexShader.vert", "FragmentShader.frag");
SetRenderConfig(shaderObj);
while (glfwWindowShouldClose(window) == 0)
{
processInput(window);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
RenderModel(shaderObj);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glfwSwapBuffers(window);
glfwPollEvents();
}
}
public:
//设置渲染配置
void SetRenderConfig(Shader& shaderObj)
{
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[] = { // note that we start from 0!
0, 1, 3, // first Triangle
1, 2, 3 // second Triangle
};
glGenBuffers(1, &VBO); //生成VBO对象
glGenVertexArrays(1, &VAO); //生成VAO对象
glGenBuffers(1, &EBO); //生成EBO对象
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO); //绑定VBO到GL_ARRAY_BUFFER目标上
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW); //复制顶点数据到缓冲
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); //绑定EBO到GL_ELEMENT_ARRAY_BUFFER目标上
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_DYNAMIC_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); //启用顶点属性
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
//环绕方式
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);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
int32_t width, height, nrChannels;
unsigned char* data = stbi_load("awesomeface.png", &width, &height, &nrChannels, 0);
if (data)
{
//根据图片数据生成纹理
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D); //自动生成MIPMAP
}
else
{
printf("Load image erro!!!");
}
stbi_image_free(data); //释放图像内存
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
//绘制模型到窗口
void RenderModel(Shader& shaderObj)
{
shaderObj.Use();
}
//运行渲染器
void Run()
{
InitRender(1280, 720, "Hello");
MainLoop();
Close();
}
//关闭渲染器
void Close()
{
glfwTerminate();
return;
}
NEO_Render()
{
}
~NEO_Render()
{
}
};
顶点着色器
#version 430 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;
out vec3 ourColor;
out vec2 TexCoord;
void main()
{
gl_Position = vec4(aPos, 1.0);
ourColor = aColor;
TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}
片元着色器
#version 430 core
out vec4 FragColor;
in vec3 ourColor;
in vec2 TexCoord;
// texture sampler
uniform sampler2D texture1;
void main()
{
FragColor = texture(texture1, TexCoord);
}
修改贴图坐标无效,修改图片格式无效
我想要达到的结果类似