OpenGL 纹理无法正常工作 - 黑屏
OpenGL texture does not work with no errors - black screen
我只是不明白为什么它不起作用 - 它只是显示白屏...(或黑屏,因为 glClearColor
)
PS。 > 纹理也打破了其他一切......
我检查了着色器和代码:没有错误,没有响应,什么都没有。包括质地。
我认为着色器是正确的,但我不知道其他任何事情。我还有所有的库:GLEW、GLFW、OPENGL,从 stb_image...
复制的单个头文件
代码如下:
#include <iostream>
#include <fstream>
#include <string>
#include "GL/glew.h"
#include "GLFW/glfw3.h"
#define ASSERT(x) if(!(x)) __debugbreak();
#define CALL(x) OpenGlClError(); x; ASSERT(OpenGlError(#x, __LINE__, __FILE__));
#define STB_IMAGE_IMPLEMENTATION
#include "extern/stb_image/stb_image_vendor/stb_image.h"
void OpenGlClError() {
while (glGetError());
}
bool OpenGlError(const char* func, int line, const char* file) {
while (GLenum error = glGetError()) {
std::cout << "GLTest: OPENGL ERROR: " << error << " in function " << func << " at line " << line << ", FILE: " << file << "\n";
return false;
}
return true;
}
#define ASSERT(x) if(!(x)) __debugbreak();
#define CALL(x) OpenGlClError(); x; ASSERT(OpenGlError(#x, __LINE__, __FILE__));
class Texture {
private:
unsigned int TextID;
std::string FilePath;
unsigned char* LocalBuffer;
int Width, Height, BytesPixel;
public:
Texture(const std::string path)
: TextID(0), FilePath(path), LocalBuffer(nullptr), Width(0), Height(0), BytesPixel(0) {
CALL(glGenTextures(1, &TextID));
CALL(glBindTexture(GL_TEXTURE_2D, TextID));
stbi_set_flip_vertically_on_load(1);
LocalBuffer = stbi_load(path.c_str(), &Width, &Height, &BytesPixel, 4);
CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, LocalBuffer));
CALL(glBindTexture(GL_TEXTURE_2D, 0));
if (LocalBuffer) { //if localbuffer exists
stbi_image_free(LocalBuffer);
}
}
~Texture() {
glDeleteTextures(1, &TextID);
}
void Bind(unsigned int slot = 0){
CALL(glActiveTexture(GL_TEXTURE0 + slot));
CALL(glBindTexture(GL_TEXTURE_2D, TextID));
}
void Unbind() {
glBindTexture(GL_TEXTURE_2D, 0);
}
};
static std::string ReadShader(const std::string& filename) {
std::ifstream stream;
std::string line;
std::string str;
stream.open(filename);
while (getline(stream, line)) {
str.append(line).append("\n");
}
std::cout << str;
stream.close();
return str;
}
static unsigned int CompileShader(const std::string& source, unsigned int type) {
unsigned int shader = glCreateShader(type);
const char* src = source.c_str();
glShaderSource(shader, 1, &src, nullptr);
glCompileShader(shader);
int result;
glGetShaderiv(shader, GL_COMPILE_STATUS, &result);
// i - int
// v - vector
if (result == GL_FALSE) {
std::cout << "Shader cannot be compiled.\n" << (type == GL_VERTEX_SHADER ? "vertex s." : "fragments.") << "\n";
int length;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
char* message = (char*)_malloca(length * sizeof(char));
glGetShaderInfoLog(shader, length, &length, message);
std::cout << message << "\n";
glDeleteShader(shader);
}
return shader;
}
static int CreateShader(const std::string& vShader, const std::string& fShader) {
unsigned int program = glCreateProgram();
unsigned int vs = CompileShader(vShader, GL_VERTEX_SHADER);
unsigned int fs = CompileShader(fShader, GL_FRAGMENT_SHADER);
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
glValidateProgram(program);
glDeleteShader(vs);
glDeleteShader(fs);
return program;
}
int main() {
glfwInit();
//make window
GLFWwindow* window;
//std::cout << "GLTest:" << glGetString(GL_VERSION) << "\n";
window = glfwCreateWindow(800, 500, "Modern OpenGL Test", NULL, NULL);
glfwMakeContextCurrent(window);
glewInit();
float texver[16] = {
-1.0f, -1.0f , 0.0f, 0.0f,
1.0f, -1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, 0.0f, 1.0f
};
float texindex[6] = {
0, 1, 2,
2, 3, 0
};
float vertices[12] = {
1.0f, 1.0f,
0.0f, -1.0f,
1.0f, -1.0f,
-1.0f, 1.0f,
0.0f, 1.0f,
-1.0f, -1.0f
};
//unsigned int varray; //< dont actually need it...
//glGenVertexArrays(1, &varray);
//glBindVertexArray(varray);
//unsigned int vb;
//glGenBuffers(1, &vb);
//glBindBuffer(GL_ARRAY_BUFFER, vb);
//glBufferData(GL_ARRAY_BUFFER, 6 * 2 * sizeof(float), vertices, GL_STATIC_DRAW);
//
//glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0); //said hey we have this set up like that, links in vertex array
//glEnableVertexAttribArray(0); //yea remember it
unsigned int tb;
glGenBuffers(1, &tb);
glBindBuffer(GL_ARRAY_BUFFER, tb);
glBufferData(GL_ARRAY_BUFFER, 4 * 4 * sizeof(float), texver, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, 0); //said hey we have this set up like that, links in vertex array
glEnableVertexAttribArray(0); //yea remember it
unsigned int shaders = CreateShader(ReadShader("shaders/basic_texture_vertex.shader"), ReadShader("shaders/basic_texture_fragment.shader"));
glUseProgram(shaders);
Texture tt("../!Assets/editor/img/intro_logo.png");
tt.Bind();
CALL(int location = glGetUniformLocation(shaders, "u_Texture"));
CALL(glUniform1i(location, 0));
CALL(glBindBuffer(GL_ARRAY_BUFFER, 0));
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(1, 1, 1, 1);
//Drawing
glDrawArrays(GL_TRIANGLES, 0, 6 * 2);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteProgram(shaders);
glfwTerminate();
}
您错过了为纹理坐标指定顶点属性。例如
unsigned int tb;
glGenBuffers(1, &tb);
glBindBuffer(GL_ARRAY_BUFFER, tb);
glBufferData(GL_ARRAY_BUFFER, 4 * 4 * sizeof(float), texver, GL_STATIC_DRAW);
// vertex cooridnates
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, 0);
glEnableVertexAttribArray(0);
// texture coordinates
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float)*4, (void*)(sizeof(float)*2));
glEnableVertexAttribArray(1);
glDrawArrays
的最后一个参数是顶点数。由于您只有 4 个顶点,因此参数不能是 6*2
.
无论如何,由于您已经指定了一个数组索引,因此您似乎想要为索引渲染指定一个 Index buffer. You have to use glDrawElements
。
索引必须是整数数据类型:
int texindex[6] = {
0, 1, 2,
0, 2, 3
};
生成索引(GL_ELEMENT_ARRAY_BUFFER
)缓冲区:
unsigned int ibo;
glGenBuffers(1, &ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(int), texindex, GL_STATIC_DRAW);
画出发声:
glDrawArrays(GL_TRIANGLES, 0, 6 * 2);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
我只是不明白为什么它不起作用 - 它只是显示白屏...(或黑屏,因为 glClearColor
)
PS。 > 纹理也打破了其他一切......
我检查了着色器和代码:没有错误,没有响应,什么都没有。包括质地。
我认为着色器是正确的,但我不知道其他任何事情。我还有所有的库:GLEW、GLFW、OPENGL,从 stb_image...
代码如下:
#include <iostream>
#include <fstream>
#include <string>
#include "GL/glew.h"
#include "GLFW/glfw3.h"
#define ASSERT(x) if(!(x)) __debugbreak();
#define CALL(x) OpenGlClError(); x; ASSERT(OpenGlError(#x, __LINE__, __FILE__));
#define STB_IMAGE_IMPLEMENTATION
#include "extern/stb_image/stb_image_vendor/stb_image.h"
void OpenGlClError() {
while (glGetError());
}
bool OpenGlError(const char* func, int line, const char* file) {
while (GLenum error = glGetError()) {
std::cout << "GLTest: OPENGL ERROR: " << error << " in function " << func << " at line " << line << ", FILE: " << file << "\n";
return false;
}
return true;
}
#define ASSERT(x) if(!(x)) __debugbreak();
#define CALL(x) OpenGlClError(); x; ASSERT(OpenGlError(#x, __LINE__, __FILE__));
class Texture {
private:
unsigned int TextID;
std::string FilePath;
unsigned char* LocalBuffer;
int Width, Height, BytesPixel;
public:
Texture(const std::string path)
: TextID(0), FilePath(path), LocalBuffer(nullptr), Width(0), Height(0), BytesPixel(0) {
CALL(glGenTextures(1, &TextID));
CALL(glBindTexture(GL_TEXTURE_2D, TextID));
stbi_set_flip_vertically_on_load(1);
LocalBuffer = stbi_load(path.c_str(), &Width, &Height, &BytesPixel, 4);
CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, LocalBuffer));
CALL(glBindTexture(GL_TEXTURE_2D, 0));
if (LocalBuffer) { //if localbuffer exists
stbi_image_free(LocalBuffer);
}
}
~Texture() {
glDeleteTextures(1, &TextID);
}
void Bind(unsigned int slot = 0){
CALL(glActiveTexture(GL_TEXTURE0 + slot));
CALL(glBindTexture(GL_TEXTURE_2D, TextID));
}
void Unbind() {
glBindTexture(GL_TEXTURE_2D, 0);
}
};
static std::string ReadShader(const std::string& filename) {
std::ifstream stream;
std::string line;
std::string str;
stream.open(filename);
while (getline(stream, line)) {
str.append(line).append("\n");
}
std::cout << str;
stream.close();
return str;
}
static unsigned int CompileShader(const std::string& source, unsigned int type) {
unsigned int shader = glCreateShader(type);
const char* src = source.c_str();
glShaderSource(shader, 1, &src, nullptr);
glCompileShader(shader);
int result;
glGetShaderiv(shader, GL_COMPILE_STATUS, &result);
// i - int
// v - vector
if (result == GL_FALSE) {
std::cout << "Shader cannot be compiled.\n" << (type == GL_VERTEX_SHADER ? "vertex s." : "fragments.") << "\n";
int length;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
char* message = (char*)_malloca(length * sizeof(char));
glGetShaderInfoLog(shader, length, &length, message);
std::cout << message << "\n";
glDeleteShader(shader);
}
return shader;
}
static int CreateShader(const std::string& vShader, const std::string& fShader) {
unsigned int program = glCreateProgram();
unsigned int vs = CompileShader(vShader, GL_VERTEX_SHADER);
unsigned int fs = CompileShader(fShader, GL_FRAGMENT_SHADER);
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
glValidateProgram(program);
glDeleteShader(vs);
glDeleteShader(fs);
return program;
}
int main() {
glfwInit();
//make window
GLFWwindow* window;
//std::cout << "GLTest:" << glGetString(GL_VERSION) << "\n";
window = glfwCreateWindow(800, 500, "Modern OpenGL Test", NULL, NULL);
glfwMakeContextCurrent(window);
glewInit();
float texver[16] = {
-1.0f, -1.0f , 0.0f, 0.0f,
1.0f, -1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, 0.0f, 1.0f
};
float texindex[6] = {
0, 1, 2,
2, 3, 0
};
float vertices[12] = {
1.0f, 1.0f,
0.0f, -1.0f,
1.0f, -1.0f,
-1.0f, 1.0f,
0.0f, 1.0f,
-1.0f, -1.0f
};
//unsigned int varray; //< dont actually need it...
//glGenVertexArrays(1, &varray);
//glBindVertexArray(varray);
//unsigned int vb;
//glGenBuffers(1, &vb);
//glBindBuffer(GL_ARRAY_BUFFER, vb);
//glBufferData(GL_ARRAY_BUFFER, 6 * 2 * sizeof(float), vertices, GL_STATIC_DRAW);
//
//glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0); //said hey we have this set up like that, links in vertex array
//glEnableVertexAttribArray(0); //yea remember it
unsigned int tb;
glGenBuffers(1, &tb);
glBindBuffer(GL_ARRAY_BUFFER, tb);
glBufferData(GL_ARRAY_BUFFER, 4 * 4 * sizeof(float), texver, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, 0); //said hey we have this set up like that, links in vertex array
glEnableVertexAttribArray(0); //yea remember it
unsigned int shaders = CreateShader(ReadShader("shaders/basic_texture_vertex.shader"), ReadShader("shaders/basic_texture_fragment.shader"));
glUseProgram(shaders);
Texture tt("../!Assets/editor/img/intro_logo.png");
tt.Bind();
CALL(int location = glGetUniformLocation(shaders, "u_Texture"));
CALL(glUniform1i(location, 0));
CALL(glBindBuffer(GL_ARRAY_BUFFER, 0));
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT);
glClearColor(1, 1, 1, 1);
//Drawing
glDrawArrays(GL_TRIANGLES, 0, 6 * 2);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteProgram(shaders);
glfwTerminate();
}
您错过了为纹理坐标指定顶点属性。例如
unsigned int tb;
glGenBuffers(1, &tb);
glBindBuffer(GL_ARRAY_BUFFER, tb);
glBufferData(GL_ARRAY_BUFFER, 4 * 4 * sizeof(float), texver, GL_STATIC_DRAW);
// vertex cooridnates
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, 0);
glEnableVertexAttribArray(0);
// texture coordinates
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float)*4, (void*)(sizeof(float)*2));
glEnableVertexAttribArray(1);
glDrawArrays
的最后一个参数是顶点数。由于您只有 4 个顶点,因此参数不能是 6*2
.
无论如何,由于您已经指定了一个数组索引,因此您似乎想要为索引渲染指定一个 Index buffer. You have to use glDrawElements
。
索引必须是整数数据类型:
int texindex[6] = {
0, 1, 2,
0, 2, 3
};
生成索引(GL_ELEMENT_ARRAY_BUFFER
)缓冲区:
unsigned int ibo;
glGenBuffers(1, &ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(int), texindex, GL_STATIC_DRAW);
画出发声:
glDrawArrays(GL_TRIANGLES, 0, 6 * 2);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);