Opengl 3.3 在我的程序中加载纹理的问题
Opengl 3.3 Issue with loading textures in my program
我目前在使用 OpenGL 3.3 Core 一次渲染多个纹理时遇到问题。我通过 SOIL(图像加载库)加载了 2 个单独的图像,但只有一个图像出现在最终程序中。这是我当前的代码:
#include <iostream>
#include <GL\glew.h>
#include <GL\GL.h>
#include <GLFW\glfw3.h>
#include <SOIL.h>
#include "Shader.h"
#include "texture2D.h"
using namespace std;
void processInput(GLFWwindow *window) {
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
glfwSetWindowShouldClose(window, true);
}
}
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, "OpenGL", NULL, NULL);
if (window == NULL) {
cout << "GLFW WINDOW CREATION FAILED! " << endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
cout << "Made By Rial Seebran " << endl;
cout << glfwGetVersionString() << endl;
glewInit();
if (glewInit() != GLEW_OK) {
cout << "GLEW INITIALIZATION FAILED! " << endl;
glfwTerminate();
return -1;
}
float positions[] = {
-0.5f, -0.5f, 0.0f, 0.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, 1.0f, 1.0f
};
unsigned int indices[] = {
0, 1, 2,
3, 2, 1
};
unsigned int VAO;
unsigned int VBO;
unsigned int EBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, ((GLvoid*)(0)));
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 5, ((GLvoid*)(sizeof(float) * 3)));
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
Shader shader("shader.vs", "shader.fs");
Texture2D texture1;
texture1.LoadTexture("container.jpg");
Texture2D texture2;
texture2.LoadTexture("awesomeface.png");
shader.Use();
while (!glfwWindowShouldClose(window)) {
glClearColor(0.1f, 0.15f, 0.2f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
texture1.BindTexture(0);
texture2.BindTexture(1);
shader.Uniform1I("myTexture1", 0);
shader.Uniform1I("myTexture2", 1);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
processInput(window);
glfwPollEvents();
glfwSwapBuffers(window);
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);
glfwTerminate();
return 0;
}
这是纹理 class(全部在 .h 文件中):
#ifndef TEXTURE2D
#define TEXTURE2D
#include <GL\glew.h>
#include <GL\GL.h>
#include <SOIL.h>
#include <iostream>
using namespace std;
class Texture2D {
public:
Texture2D();
~Texture2D();
void LoadTexture(const char* texPath);
void BindTexture(unsigned int texUnit);
unsigned int texture_M;
};
Texture2D::Texture2D() {
}
Texture2D::~Texture2D() {
glDeleteTextures(1, &texture_M);
}
void Texture2D::LoadTexture(const char* texPath) {
int width;
int height;
unsigned char *image = SOIL_load_image(texPath, &width, &height, 0, SOIL_LOAD_RGBA);
if (image == NULL) {
cout << "Failed to load Image! " << endl;
}
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_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, texture_M);
if (image != NULL) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
}
SOIL_free_image_data(image);
glBindTexture(GL_TEXTURE_2D, 0);
}
void Texture2D::BindTexture(unsigned int texUnit) {
glActiveTexture(GL_TEXTURE0 + texUnit);
glBindTexture(GL_TEXTURE_2D, texture_M);
}
#endif
在片段着色器中,我使用 mix()
函数对 2 个纹理进行线性插值,但 "awesomeface.png" 图像是最终程序中唯一出现的纹理。应该修复什么,程序才能显示两种纹理?
您必须在 Texture::LoadTexture()
的开头添加以下行以生成纹理 ID:
glGenTextures(1, &texture_M);
这将保留一个用于识别纹理对象的有效 ID(稍后必须通过调用 glBindTexture()
进行初始化)。它可用于在后续 OpenGL 调用中引用纹理(包括使用 glDeleteTextures()
删除纹理)。
我没有在texture2D中调用glGenTextures()
class。感谢 Whosebug 用户@Rabbid76 指出这一点
当一个未使用的名称通过glBindTexture
绑定到一个纹理目标时,就会生成一个纹理对象。
但是 glGenTextures
.
必须保留一个新的未使用的纹理名称
glTexParameteri
设置的纹理参数设置为绑定到指定目标的纹理对象。
保留未使用的纹理名称,然后创建纹理对象。之后你可以设置参数并指定two-dimensional纹理图像。
// 1. reserve texture name
glGenTextures(1, &texture_M);
// 2. generate texture object
glBindTexture(GL_TEXTURE_2D, texture_M);
// set parameters
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_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// generate texture image
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
我目前在使用 OpenGL 3.3 Core 一次渲染多个纹理时遇到问题。我通过 SOIL(图像加载库)加载了 2 个单独的图像,但只有一个图像出现在最终程序中。这是我当前的代码:
#include <iostream>
#include <GL\glew.h>
#include <GL\GL.h>
#include <GLFW\glfw3.h>
#include <SOIL.h>
#include "Shader.h"
#include "texture2D.h"
using namespace std;
void processInput(GLFWwindow *window) {
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
glfwSetWindowShouldClose(window, true);
}
}
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, "OpenGL", NULL, NULL);
if (window == NULL) {
cout << "GLFW WINDOW CREATION FAILED! " << endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
cout << "Made By Rial Seebran " << endl;
cout << glfwGetVersionString() << endl;
glewInit();
if (glewInit() != GLEW_OK) {
cout << "GLEW INITIALIZATION FAILED! " << endl;
glfwTerminate();
return -1;
}
float positions[] = {
-0.5f, -0.5f, 0.0f, 0.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, 1.0f, 1.0f
};
unsigned int indices[] = {
0, 1, 2,
3, 2, 1
};
unsigned int VAO;
unsigned int VBO;
unsigned int EBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, ((GLvoid*)(0)));
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 5, ((GLvoid*)(sizeof(float) * 3)));
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
Shader shader("shader.vs", "shader.fs");
Texture2D texture1;
texture1.LoadTexture("container.jpg");
Texture2D texture2;
texture2.LoadTexture("awesomeface.png");
shader.Use();
while (!glfwWindowShouldClose(window)) {
glClearColor(0.1f, 0.15f, 0.2f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
texture1.BindTexture(0);
texture2.BindTexture(1);
shader.Uniform1I("myTexture1", 0);
shader.Uniform1I("myTexture2", 1);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
processInput(window);
glfwPollEvents();
glfwSwapBuffers(window);
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);
glfwTerminate();
return 0;
}
这是纹理 class(全部在 .h 文件中):
#ifndef TEXTURE2D
#define TEXTURE2D
#include <GL\glew.h>
#include <GL\GL.h>
#include <SOIL.h>
#include <iostream>
using namespace std;
class Texture2D {
public:
Texture2D();
~Texture2D();
void LoadTexture(const char* texPath);
void BindTexture(unsigned int texUnit);
unsigned int texture_M;
};
Texture2D::Texture2D() {
}
Texture2D::~Texture2D() {
glDeleteTextures(1, &texture_M);
}
void Texture2D::LoadTexture(const char* texPath) {
int width;
int height;
unsigned char *image = SOIL_load_image(texPath, &width, &height, 0, SOIL_LOAD_RGBA);
if (image == NULL) {
cout << "Failed to load Image! " << endl;
}
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_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, texture_M);
if (image != NULL) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
}
SOIL_free_image_data(image);
glBindTexture(GL_TEXTURE_2D, 0);
}
void Texture2D::BindTexture(unsigned int texUnit) {
glActiveTexture(GL_TEXTURE0 + texUnit);
glBindTexture(GL_TEXTURE_2D, texture_M);
}
#endif
在片段着色器中,我使用 mix()
函数对 2 个纹理进行线性插值,但 "awesomeface.png" 图像是最终程序中唯一出现的纹理。应该修复什么,程序才能显示两种纹理?
您必须在 Texture::LoadTexture()
的开头添加以下行以生成纹理 ID:
glGenTextures(1, &texture_M);
这将保留一个用于识别纹理对象的有效 ID(稍后必须通过调用 glBindTexture()
进行初始化)。它可用于在后续 OpenGL 调用中引用纹理(包括使用 glDeleteTextures()
删除纹理)。
我没有在texture2D中调用glGenTextures()
class。感谢 Whosebug 用户@Rabbid76 指出这一点
当一个未使用的名称通过glBindTexture
绑定到一个纹理目标时,就会生成一个纹理对象。
但是 glGenTextures
.
glTexParameteri
设置的纹理参数设置为绑定到指定目标的纹理对象。
保留未使用的纹理名称,然后创建纹理对象。之后你可以设置参数并指定two-dimensional纹理图像。
// 1. reserve texture name
glGenTextures(1, &texture_M);
// 2. generate texture object
glBindTexture(GL_TEXTURE_2D, texture_M);
// set parameters
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_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// generate texture image
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);