簡體   English   中英

Opengl 問題:很可能是簡單的紋理問題

[英]Opengl issue: Most likely simple texture issue

運行此代碼時,我得到一個黑色四邊形。 屏幕應該是全白的。 着色器本身工作得很好,我可以改變 out vec4 中的值並且它工作正常。 問題是將紋理加載到着色器或生成紋理。

GLFWwindow *window = nullptr;
GLuint shaderProgram = -1;
GLuint vbo = -1;
GLuint vao = -1;
GLuint tex0 = -1;
GLuint texture = -1;
unsigned char *pixels = nullptr;
int width = -1;
int height = -1;

pixels = new unsigned char[width * height * 3];

if (glfwInit() == GLFW_FALSE) {
    std::cout << "GLFW failed initialization!" << std::endl;
    return -1;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
window = glfwCreateWindow(width, height, "Engine From Scratch", NULL, NULL);

glfwMakeContextCurrent(window);

glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) {
    std::cout << "GLEW failed initialization!" << std::endl;
    return -1;
}

glViewport(0, 0, width, height);

if (window == nullptr) {
    std::cout << "Failed to create GLFW window" << std::endl;
    glfwTerminate();
    return -1;
}

// Shader generation
const char *vertexShaderSource = "#version 330 core\nlayout (location = 0) in vec3 aPos;\nout vec2 texCoords;\nvoid main()\n{\ngl_Position = vec4(aPos.x * 0.5, aPos.y * 0.5, aPos.z * 0.5, 1.0);\ntexCoords = aPos.xy;\n}\0";
const char *fragmentShaderSource = "#version 330 core\nout vec4 color;\nin vec2 texCoords;\nuniform sampler2D tex0;\nvoid main()\n{\ncolor = texture(tex0, texCoords);\n}\0";
unsigned int vertexShader, fragmentShader;

vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);

shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);

glUseProgram(shaderProgram);
tex0 = glGetUniformLocation(shaderProgram, "tex0");
glUniform1i(tex0, 0);

// Loading Data =
float points[] = { -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, -1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 0.0f, -1.0f, -1.0f, 0.0f };

glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, 18 * sizeof(float), points, GL_STATIC_DRAW);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);

glBindVertexArray(vao);

for(int i = 0; i < width * height * 3; i ++) {
    pixels[i] = 0xFF;
}

// generating texture
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &texture);

glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, &pixels[0]);

glClear(GL_COLOR_BUFFER_BIT);
glClearColor(1.0, 1.0, 1.0, 1.0);

glActiveTexture(GL_TEXTURE0);
glDrawArrays(GL_TRIANGLES, 0, 6);
glfwPollEvents();
glfwSwapBuffers(window);

我認為有問題的地區:

    glUseProgram(shaderProgram);
    tex0 = glGetUniformLocation(shaderProgram, "tex0");
    glUniform1i(tex0, 0);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glGenTextures(1, &texture);

    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, &pixels[0]);

您必須通過glTexParameter設置紋理縮小 function ( GL_TEXTURE_MIN_FILTER )(這可以在glTexImage2D之前完成):

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

如果您不生成glGenerateMipmap ,那么設置GL_TEXTURE_MIN_FILTER很重要。 由於默認過濾器是GL_NEAREST_MIPMAP_LINEAR紋理將是 mipmap 不完整的,如果您不將縮小 function 更改為GL_NEARESTGL_LINEAR

紋理單元必須在紋理綁定之前設置,分別創建。 無論如何,由於您使用紋理單元 0,這是不必要的,因為GL_TEXTURE0是默認值。 glActiveTexture

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, &pixels[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

此外,紋理坐標必須在 [0.0, 1.0] 范圍內。 由於您也使用頂點坐標(范圍 [-1.0, 1.0])作為紋理坐標,因此您必須轉換坐標:

texCoords = aPos.xy;

texCoords = aPos.xy + 0.5 * 0.5;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM