版权声明:转载请注明出处 https://blog.csdn.net/qq_35294564/article/details/86534344
首先报的是这个错误:Fragment shader contains a user varying, but is linked without a vertex shader.Out of resource error.
已解决,附下
在没有添加纹理之前一切正常。下面是注释掉TextureCood的所有代码:
shader.vs
#version 330 core
layout (location = 0) in vec3 aPos;
//layout (location = 1) in vec2 TexCoods;
//out vec2 TexCoods;
void main(){
gl_Position = vec4(aPos, 1.0f);
//TexCoods = TexCoods;
};
shader.frag
#version 330 core
in vec3 ourColor;
//in vec2 TexCoods;
uniform sampler2D ourTexture;
uniform int flag;
out vec4 FragColor;
void main()
{
//FragColor = texture(ourTexture, TexCoods);
if(flag == 1){
FragColor = vec4(1.0f,0.0f,0.0f,1.0f);
}else{
FragColor = vec4(1.0f,1.0f,0.0f,1.0f);
}
}
main.cpp
#include <iostream>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
#include "Shader.h"//要用引号
#pragma comment(lib,"glfw3.lib")
using namespace std;
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);
int main() {
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, "LearnOpenGL", NULL, NULL);
if (window == NULL) {
cout << "Failed to create GLFW window" << endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){
cout << "Failed to initialize GLAD" << endl;
return -1;
}
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
//创建顶点缓存对象用来管理分配到的顶点缓存空间
//创建一个着色器对象
Shader ShaderColor("shader.vs","shader.frag");
GLfloat vertices[] = {
// 第一个三角形 texture
0.5f, 0.5f, 0.0f, 1.0f, 1.0f, // 右上角
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // 右下角
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f, // 左上角
// 第二个三角形
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // 右下角
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, // 左下角
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f // 左上角
};
GLuint VAO, VBO;
glGenVertexArrays(1, &VAO);//创建顶点数组对象
glGenBuffers(1, &VBO);//创建顶点缓冲对象
glBindBuffer(GL_ARRAY_BUFFER, VBO);//将顶点缓冲绑定到顶点缓冲对象
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);//缓冲区三角形顶点数据
glBindVertexArray(VAO);//将顶点数组绑定到顶点数组对象
//设置顶点属性指针
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
//纹理
GLuint texture;
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);
//加载并生成纹理
int width, height, nrChannels;
unsigned char *image = stbi_load("box2.png", &width, &height, &nrChannels, 0);
glBindTexture(GL_TEXTURE_2D, texture);
if (image) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
}
else {
std::cout << "Failed to load texture" << std::endl;
}
stbi_image_free(image);
glBindTexture(GL_TEXTURE_2D, 0);
//int flagLoc = glGetUniformLocation(ShaderColor.ID, "flag");//此处不再需要获取地址了
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
while (!glfwWindowShouldClose(window)) {
processInput(window);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
ShaderColor.use();
glBindTexture(GL_TEXTURE_2D, texture);
ShaderColor.setInt("flag", 1);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
ShaderColor.setInt("flag", 2);
glDrawArrays(GL_TRIANGLES, 3, 3);
//glBindTexture(GL_TEXTURE_2D, 0);
glBindVertexArray(0);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteBuffers(1, &VBO);
glDeleteVertexArrays(1, &VAO);
glfwTerminate();
return 0;
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
glViewport(0, 0, width, height);
}
void processInput(GLFWwindow* window) {
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
glfwSetWindowShouldClose(window, true);
}
}
Shader.h
#pragma once
#include <glad/glad.h>
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
class Shader {
public:
GLuint ID;//程序ID
//构造器读取并构建着色器
Shader(const GLchar* vertexPath, const GLchar* fragmentPath);
//使用、激活程序
void use();
//uniform工具函数
void setBool(const std::string &name, bool value) const;
void setInt(const std::string &name, int value) const;
void setFloat(const std::string &name, float value) const;
};
Shader::Shader(const GLchar* vertexPath, const GLchar* fragmentPath) {
//从文件路径中获取顶点、片段着色器
std::string vertexCode;//用来存储顶点着色器的字符串形式
std::string fragmentCode;//用来存储片段着色器的字符串形式
std::ifstream vShaderFile;//以输入方式打开
std::ifstream fShaderFile;//以输入方式打开
//保证ifstream对象可以抛出异常
vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try {
//打开文件
vShaderFile.open(vertexPath);//以输入方式打开
fShaderFile.open(fragmentPath);
std::stringstream vShaderStream, fShaderStream;
//读取文件的缓冲内容到数据流中
vShaderStream << vShaderFile.rdbuf();
fShaderStream << fShaderFile.rdbuf();
//关闭文件处理器
vShaderFile.close();
fShaderFile.close();
//转换数据流到string
vertexCode = vShaderStream.str();//字符串流转换成字符串
fragmentCode = fShaderStream.str();
}
catch (std::ifstream::failure e) {
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
}
const GLchar* vShaderCode = vertexCode.c_str();
const GLchar* fShaderCode = fragmentCode.c_str();
//编译着色器
GLuint vertex, fragment;
GLint success;
GLchar infoLog[512];
//VertexShader
vertex = glCreateShader(GL_VERTEX_ARRAY);
glShaderSource(vertex, 1, &vShaderCode, NULL);
glCompileShader(vertex);
glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(vertex, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
//fragmentShader
fragment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment, 1, &fShaderCode, NULL);
glCompileShader(fragment);
glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fragment, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
}
//ShaderProgram
this->ID = glCreateProgram();//产生着色器程序ID
glAttachShader(this->ID, vertex);
glAttachShader(this->ID, fragment);
glLinkProgram(this->ID);
glGetProgramiv(this->ID, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(this->ID, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED...\n" << infoLog << std::endl;
}
glDeleteShader(vertex);
glDeleteShader(fragment);
}
void Shader::use() {
glUseProgram(this->ID);
}
void Shader::setBool(const std::string &name, bool value) const
{
glUniform1i(glGetUniformLocation(this->ID, name.c_str()), (int)value);
}
void Shader::setInt(const std::string &name, int value) const
{
glUniform1i(glGetUniformLocation(this->ID, name.c_str()), value);
}
void Shader::setFloat(const std::string &name, float value) const
{
glUniform1f(glGetUniformLocation(this->ID, name.c_str()), value);
}
结果正常:
加上纹理之后:
shader.vs
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 TexCoods;
out vec2 TexCoods;
void main(){
gl_Position = vec4(aPos, 1.0f);
TexCoods = TexCoods;
};
shader.frag
#version 330 core
in vec2 TexCoods;
uniform sampler2D ourTexture;
uniform int flag;
out vec4 FragColor;
void main()
{
if(flag == 1){
FragColor = vec4(1.0f,0.0f,0.0f,1.0f);
}else{
FragColor = vec4(texture(ourTexture, TexCoods));
}
}
main.cpp
#include <iostream>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
#include "Shader.h"//要用引号
#pragma comment(lib,"glfw3.lib")
using namespace std;
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);
int main() {
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, "LearnOpenGL", NULL, NULL);
if (window == NULL) {
cout << "Failed to create GLFW window" << endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){
cout << "Failed to initialize GLAD" << endl;
return -1;
}
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
//创建顶点缓存对象用来管理分配到的顶点缓存空间
//创建一个着色器对象
Shader ShaderColor("shader.vs","shader.frag");
GLfloat vertices[] = {
// 第一个三角形 texture
0.5f, 0.5f, 0.0f, 1.0f, 1.0f, // 右上角
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // 右下角
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f, // 左上角
// 第二个三角形
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // 右下角
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, // 左下角
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f // 左上角
};
GLuint VAO, VBO;
glGenVertexArrays(1, &VAO);//创建顶点数组对象
glGenBuffers(1, &VBO);//创建顶点缓冲对象
glBindBuffer(GL_ARRAY_BUFFER, VBO);//将顶点缓冲绑定到顶点缓冲对象
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);//缓冲区三角形顶点数据
glBindVertexArray(VAO);//将顶点数组绑定到顶点数组对象
//设置顶点属性指针
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
//纹理
GLuint texture;
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);
//加载并生成纹理
int width, height, nrChannels;
unsigned char *image = stbi_load("box2.png", &width, &height, &nrChannels, 0);
glBindTexture(GL_TEXTURE_2D, texture);
if (image) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
}
else {
std::cout << "Failed to load texture" << std::endl;
}
stbi_image_free(image);
glBindTexture(GL_TEXTURE_2D, 0);
//int flagLoc = glGetUniformLocation(ShaderColor.ID, "flag");//此处不再需要获取地址了
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
while (!glfwWindowShouldClose(window)) {
processInput(window);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
ShaderColor.use();
glBindTexture(GL_TEXTURE_2D, texture);
ShaderColor.setInt("flag", 1);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
ShaderColor.setInt("flag", 2);
glDrawArrays(GL_TRIANGLES, 3, 3);
//glBindTexture(GL_TEXTURE_2D, 0);
glBindVertexArray(0);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteBuffers(1, &VBO);
glDeleteVertexArrays(1, &VAO);
glfwTerminate();
return 0;
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
glViewport(0, 0, width, height);
}
void processInput(GLFWwindow* window) {
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
glfwSetWindowShouldClose(window, true);
}
}
结果:
这是什么情况,求大神指点
问题更新:
有个大神帮忙指出了一处错误和一个问题:
一处错误:
一处问题:
png图片的话一般 是有透明通道的,所以如果是RGBA格式的,