当前位置: 首页 > 知识库问答 >
问题:

OpenGL着色器问题(不显示任何内容)

蒋嘉颖
2023-03-14
    null
    null
void myDisplay(void)
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDisable(GL_DEPTH_TEST);


glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glEnable(GL_TEXTURE_2D);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); 
glTranslatef(0, 0, -10);

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

glUseProgram(ourShader);
glBindVertexArray(VAO); 
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

glutSwapBuffers();
}
int main(){
//glut initialization stuff...left this out



float vertices[] = {
        // positions          // colors           // texture coords
         0.5f,  0.5f, 0.0f,   1.0f, 0.0f, 0.0f,   1.0f, 1.0f,   // top right
         0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,   1.0f, 0.0f,   // bottom right
        -0.5f, -0.5f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f,   // bottom left
        -0.5f,  0.5f, 0.0f,   1.0f, 1.0f, 0.0f,   0.0f, 1.0f    // top left 
    };
    float texCoords[] = {
    0.0f, 0.0f,  // lower-left corner  
    1.0f, 0.0f,  // lower-right corner
    0.5f, 1.0f   // top-center corner
    };

    unsigned int indices[] = {
       0, 1, 3, // first triangle
       1, 2, 3  // second triangle
    };

    //frameBuffer
    glGenBuffers(1, &FBO);
    glBindFramebuffer(GL_FRAMEBUFFER, FBO);

    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
        std::cout << "ERROR: Framebuffer not bound" << std::endl;

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    //glDeleteFramebuffers(1, &fbo);


    //VAO
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &EBO);

    glBindVertexArray(VAO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    // Vertex Attributes 
    glEnableVertexAttribArray(0); //pozicija
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(0));
    glEnableVertexAttribArray(1); //boja
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat)));
    glEnableVertexAttribArray(2); //boja
    glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(6 * sizeof(GLfloat)));

    glEnable(GL_TEXTURE_2D);
    glGenTextures(1, &texture);
    glActiveTexture(GL_TEXTURE0); 
    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);

    std::string path = "C:\\Projects\\Myproj\\container.jpg";
    bool success = loadTexture(path,texture_data,&tex_width, &tex_height, &nchannels);
    if (success) 
    {
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex_width, tex_height, 0, GL_RGB, GL_UNSIGNED_BYTE, texture_data);
        glGenerateMipmap(GL_TEXTURE_2D);
    }
    else 
    {
        std::cout << "ERROR::STBI::FAILED TO LOAD TEXTURE" << std::endl;
    }

    stbi_image_free(texture_data);

    int success_f;
    char infoLog[512];

    vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader);
    getShaderStatus(vertexShader, &success_f, infoLog);

    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);
    getShaderStatus(fragmentShader, &success_f, infoLog);


    ourShader = glCreateProgram();
    glAttachShader(ourShader, vertexShader);
    glAttachShader(ourShader, fragmentShader);
    glLinkProgram(ourShader);
    getShaderStatus(ourShader, &success_f, infoLog);

    glUseProgram(ourShader);
    glUniform1i(glGetUniformLocation(ourShader, "ourTexture"), 0);

    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);


    glutMainLoop();
}
const char* vertexShaderSource =
"#version 330 core\n"
"layout(location = 0) in vec3 aPos;\n"
"layout(location = 1) in vec3 aColor;\n"
"layout(location = 2) in vec2 aTexCoord;\n"
"out vec3 ourColor;\n"
"out vec2 TexCoord;\n"
"void main()\n"
"{\n"
"gl_Position = vec4(aPos, 1.0);\n"
"ourColor = aColor;\n"
"TexCoord = aTexCoord;\n"
"}\n";
const char* fragmentShaderSource =
"#version 330 core\n"
"out vec4 FragColor;\n"
"in vec3 ourColor;\n"
"in vec2 TexCoord;\n"
"uniform sampler2D ourTexture;\n"
"void main()\n"
"{\n"
"FragColor = texture(ourTexture, TexCoord);\n"
"}\n";

共有1个答案

胥博文
2023-03-14

glenable(GL_TEXTURE_2D)在使用着色器时是不必要的,因为是否使用纹理在(片段)着色器中实现。
着色器代码定义是否应用纹理。glenable(GL_TEXTURE_2D)用于不推荐使用的固定函数管道,仅不使用着色器。

同样,使用固定函数矩阵堆栈(GlMatrixModeGlloadidEntityGluPerspective、...)也是无用的。必须使用统一变量(mat4)。这些函数改变固定函数矩阵堆栈上的矩阵。这些矩阵应用于由glvertexglvertexpointer设置的固定函数顶点坐标,但只有在没有着色器代码的情况下才可以。
如果有着色器,您必须自己进行矩阵转换。
在GLSL中存在诸如gl_modelviewmatrixgl_projectionmatrixgl_modelviewprojectionmatrix之类的内置制服,它们允许您访问固定函数矩阵堆栈上的矩阵。但是这种制服也是不推荐的,在GLSL#Version330 Core中也没有更多的可访问性。

用两个制服mat4 u_projmat4 u_view编写着色器。通过着色器代码转换顶点坐标。

#version 330 core

layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 aColor;
layout(location = 2) in vec2 aTexCoord;

out vec3 ourColor;
out vec2 TexCoord;

uniform mat4 u_proj;
uniform mat4 u_view;

void main()
{
    gl_Position = u_proj * u_view * vec4(aPos, 1.0);
    ourColor = aColor;
    TexCoord = aTexCoord;
}
GLint proj_loc = glGetUniformLocation(ourShader, "u_proj");
GLint view_loc = glGetUniformLocation(ourShader, "u_view");
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
glm::mat4 proj = glm::perspective(glm::radians(fov_degrees)), aspect, near, far);
glm::mat4 view = glm::lookAt(eye, target, up);
glUniformMatrix4fv(proj_loc, 1, GL_FALSE, glm::value_ptr(proj));
glUniformMatrix4fv(view_loc, 1, GL_FALSE, glm::value_ptr(view));
glGetShaderiv(shader_ID, GL_COMPILE_STATUS, &status);
glGetProgramiv(program_ID, GL_LINK_STATUS, success_f);
glVertexAttribPointer(2,
    2,                 // <---- 2 instead of 3 
    GL_FLOAT,
    GL_FALSE,
    8 * sizeof(GLfloat),
    (void*)(6 * sizeof(GLfloat))
); 
glDrawArrays(GL_TRIANGLES, 0, 6); // <---- 6 instead of 2
bool loadTexture(
   const std::string &filename,
   unsigned char*& buff,           // < ---- unsigned char*&
   int* w, int* h, int* nc);
void myDisplay(void) 
{

    // ....

    glBindVertexArray(VAO);

    // unecessary:
    //glEnableVertexAttribArray(0);
    //glEnableVertexAttribArray(1); 
    //glEnableVertexAttribArray(2); 
 类似资料:
  • OpenGL的渲染管线分为几个步骤。一个简单的OpenGL渲染管线将包含一个顶点着色器和一个片段着色器。 顶点着色器接收顶点数据,并且在程序最后赋值给gl_Position。然后,顶点将会被裁剪,转换和栅格化后作为像素输出。 片段(像素)进入片段着色器,进一步对片段操作并将结果的颜色赋值给gl_FragColor。顶点着色器调用多边形每个角的点(顶点=3D中的点),负责这些点的3D处理。片段(片度

  • 总之,我的全屏着色器没有输出任何东西, 在环境传递中的每个片段输出相同的颜色,以确保它是输出的。(作品) 在定向光路中的每个片段输出相同的颜色。(仍然一无所获) 将屏幕分辨率用于XY顶点坐标,而不是归一化坐标; 这适用于环境传递,因为我可以看到结果如预期的那样变化。 方向光通过时没有变化,我得到的输出也是一样的。 这是申请代码; 请原谅,如果我的数学是错误的,我一直在乱搞着色器,试图得到任何类型的

  • 我似乎无法理解从顶点到像素的OpenGL管道过程。 有人能告诉我顶点法线在这两种着色技术中有多重要吗?据我所知,在gouraud中,在每个顶点计算照明,然后在顶点之间的多边形上插值结果颜色(在光栅化之前,这是在片段操作中完成的吗?),phong着色包括首先插值顶点法线,然后计算每个法线上的照明。 另一件事是,当凹凸贴图应用于一个平面(2个三角形)和一个砖纹理作为漫反射时,使用其相应的凹凸贴图,所有

  • 我是OpenGL的新手,在整理如何将纹理和着色器绑定到VBOs时遇到了困难。 我正在使用Cinder的纹理和着色器类。以下是我绘制方法的一部分: 在上面的代码中,如果我注释掉对mShader的调用。bind(),我的球体VBO将显示纹理(myImage)。我的着色器适用于普通(无纹理)形状,但当我在绘制任何带有包裹纹理的形状之前绑定着色器时,它会阻止纹理显示。 这是我使用的着色器的问题,还是我不理

  • 应该是这样的: 而不是这个: 我的屏幕宽度是1000,高度是600。 我正在使用OpenGL(lwjgl)在java中制作2d游戏。我可以画一个三角形,但使用我的着色器时它不起作用。着色器编译没有错误,但屏幕变黑了。 我完全不知道该怎么做,我必须启用什么吗? 这是我在GLSL中的vertexShader代码 这是片段着色器: 我最近发现,如果我只运行它有效的片段着色器,我就会得到指定的颜色。但是如

  • 我对OpenGL有点生疏,我已经实现了一个场景的照明,场景中有小行星围绕行星旋转的实例。出于某种原因,我得到的唯一输出似乎是场景的环境照明。我无法使漫反射或镜面反射工作。 这是现场的一张照片(很难看到…)仅限环境 片段着色器代码如下所示。FragPos、Normal和TexCoords都是你所期待的。纹理_diffuse1是行星/小行星纹理,具体取决于使用的着色器。LightPos可以移动,它由图