OpenGL纹理无法正常工作-黑屏[关闭]
Posted
技术标签:
【中文标题】OpenGL纹理无法正常工作-黑屏[关闭]【英文标题】:OpenGL texture does not work with no errors - black screen [closed] 【发布时间】:2020-10-09 18:29:11 【问题描述】:我只是不明白为什么它不起作用 - 它只是显示一个白色屏幕......(或黑色屏幕,因为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();
【问题讨论】:
【参考方案1】:您错过了为纹理坐标指定顶点属性。比如
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。您必须使用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);
【讨论】:
@MegapolisPlayer 此外,texver
中有一个错误。最后一个顶点是两次。将-1.0f, -1.0f
更改为-1.0f, 1.0f
以上是关于OpenGL纹理无法正常工作-黑屏[关闭]的主要内容,如果未能解决你的问题,请参考以下文章
OpenGL代码适用于GLFW,但不适用于Qt OpenGL