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

带GLFW和GLEW的OpenGL不渲染立方体?C++,GLM

戴靖
2023-03-14

我对OpenGL、GLFW或GLEW没有太多的经验,所以我对这些库的故障排除能力微乎其微。我已经设法呈现了一个三角形([-1,-1,0],[1,-1,0],[0,1,0]),但是当使用顶点属性坐标和颜色属性作为立方体时,它似乎无法呈现。我的代码、着色器和矩阵运算可能有很多问题。我希望我对我所做的事情有更清楚的了解,这样我就可以对我的错误有更详细的描述。目前,上面的代码只呈现窗口。我最初遵循https://learnopengl.com/,并获得了第一个教程,下面的代码是我的“测试”文件,我试图在其中重新实现一些元素。有许多复制粘贴的部分,可以与该教程共享,如果它有帮助的话。

#include "global.hpp"

using namespace std;
using namespace glm;

static const GLfloat g_color_buffer_data[] = {
    0.583f,  0.771f,  0.014f,
    0.609f,  0.115f,  0.436f,
    0.327f,  0.483f,  0.844f,
    0.822f,  0.569f,  0.201f,
    0.435f,  0.602f,  0.223f,
    0.310f,  0.747f,  0.185f,
    0.597f,  0.770f,  0.761f,
    0.559f,  0.436f,  0.730f,
    0.359f,  0.583f,  0.152f,
    0.483f,  0.596f,  0.789f,
    0.559f,  0.861f,  0.639f,
    0.195f,  0.548f,  0.859f,
    0.014f,  0.184f,  0.576f,
    0.771f,  0.328f,  0.970f,
    0.406f,  0.615f,  0.116f,
    0.676f,  0.977f,  0.133f,
    0.971f,  0.572f,  0.833f,
    0.140f,  0.616f,  0.489f,
    0.997f,  0.513f,  0.064f,
    0.945f,  0.719f,  0.592f,
    0.543f,  0.021f,  0.978f,
    0.279f,  0.317f,  0.505f,
    0.167f,  0.620f,  0.077f,
    0.347f,  0.857f,  0.137f,
    0.055f,  0.953f,  0.042f,
    0.714f,  0.505f,  0.345f,
    0.783f,  0.290f,  0.734f,
    0.722f,  0.645f,  0.174f,
    0.302f,  0.455f,  0.848f,
    0.225f,  0.587f,  0.040f,
    0.517f,  0.713f,  0.338f,
    0.053f,  0.959f,  0.120f,
    0.393f,  0.621f,  0.362f,
    0.673f,  0.211f,  0.457f,
    0.820f,  0.883f,  0.371f,
    0.982f,  0.099f,  0.879f
};
static const GLfloat g_vertex_buffer_data[] = {
    -1.0f,-1.0f,-1.0f, // triangle 1 : begin
    -1.0f,-1.0f, 1.0f,
    -1.0f, 1.0f, 1.0f, // triangle 1 : end
    1.0f, 1.0f,-1.0f, // triangle 2 : begin
    -1.0f,-1.0f,-1.0f,
    -1.0f, 1.0f,-1.0f, // triangle 2 : end
    1.0f,-1.0f, 1.0f,
    -1.0f,-1.0f,-1.0f,
    1.0f,-1.0f,-1.0f,
    1.0f, 1.0f,-1.0f,
    1.0f,-1.0f,-1.0f,
    -1.0f,-1.0f,-1.0f,
    -1.0f,-1.0f,-1.0f,
    -1.0f, 1.0f, 1.0f,
    -1.0f, 1.0f,-1.0f,
    1.0f,-1.0f, 1.0f,
    -1.0f,-1.0f, 1.0f,
    -1.0f,-1.0f,-1.0f,
    -1.0f, 1.0f, 1.0f,
    -1.0f,-1.0f, 1.0f,
    1.0f,-1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f,-1.0f,-1.0f,
    1.0f, 1.0f,-1.0f,
    1.0f,-1.0f,-1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f,-1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f, 1.0f,-1.0f,
    -1.0f, 1.0f,-1.0f,
    1.0f, 1.0f, 1.0f,
    -1.0f, 1.0f,-1.0f,
    -1.0f, 1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    -1.0f, 1.0f, 1.0f,
    1.0f,-1.0f, 1.0f
};

extern const char* VertexShader = R"(
#version 330 core

layout(location = 0) in vec3 vertexPosition_modelspace;

layout(location = 1) in vec3 vertexColor;

uniform mat4 MVP;
  
out vec3 fragmentColor;
 
//out vec2 UV;
  
void main(){
  gl_Position =  MVP * vec4(vertexPosition_modelspace,1);
  
  //UV = vertexUV;
  
  fragmentColor = vertexColor;
}
)";

extern const char* FragmentShader = R"(
#version 330 core
in vec3 fragmentColor;
out vec3 color;
void main(){
  //color = vec3(1,0,0);
  color = fragmentColor;
}
)";

static const float tri_vertex_array[] = {
    -.8, .8, 0,
    -.8, -.8, 0,
    .8, -.8, 0
};

int main()
{
    if (!glfwInitFull()) {
        printf("Unable To Init\n");
        return 1;
    }

    uint width = 1200, height = 720;
    GLFWwindow* window = glfwCreateWindow(width, height, "ME", 0, 0);

    if (!window)
        return -1;

    glfwMakeContextCurrent(window);
    if (glewInit() != GLEW_OK)
        return 0;

    //
    GLuint VertexArrayId;
    glGenVertexArrays(1, &VertexArrayId);
    glBindVertexArray(VertexArrayId);
    //

    GLuint vertexBuffer;
    glGenBuffers(1, &vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);

    //glBufferData(GL_ARRAY_BUFFER, sizeof(tri_vertex_array), tri_vertex_array, GL_STATIC_DRAW);
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);


    GLuint colorBuffer;
    glGenBuffers(1, &colorBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data), g_color_buffer_data, GL_STATIC_DRAW);


    GLuint vertexShaderId = compileShader(VertexShader, GL_VERTEX_SHADER);
    GLuint fragmentShaderId = compileShader(FragmentShader, GL_FRAGMENT_SHADER);

    GLuint programId = glCreateProgram();

    linkShader(programId, vertexShaderId);
    linkShader(programId, fragmentShaderId);

    // maybe nessacary?
    //glMatrixMode(GL_PROJECTION);

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LESS);
    glEnable(GL_CULL_FACE);
    glViewport(0, 0, width, height);

    //vec3 cameraPos = vec3(0.f, 0.f, 3.f);
    //vec3 cameraTarget = vec3(0.f, 0.f, 0.f);
    //vec3 cameraDirection = normalize(cameraPos - cameraTarget);
    //
    //vec3 up = vec3(0.f, 1.f, 0.f);
    //vec3 right = normalize(
    //    cross(
    //        up,
    //        cameraDirection
    //    )
    //);
    //
    //vec3 cameraUp = cross(cameraDirection, right);
    //
    //mat4 view = lookAt(
    //    vec3(4.f, 3.f, 3.f),
    //    vec3(0.f, 0.f, 0.f),
    //    vec3(0.f, 1.f, 0.f)
    //);

    mat4 projection = perspective(radians(45.f), width / (float)height, .1f, 100.f);
    mat4 view = lookAt(
        vec3(4, 3, -3),
        vec3(0, 0, 0),
        vec3(0, 1, 0)
    );

    mat4 model = mat4(1.0f); // identity
    mat4 mvp = projection * view * model;

    GLuint mvpId = glGetUniformLocation(programId, "MVP");

    do {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glClearColor(0.f, 0.f, .4f, 0.f);

        glUseProgram(programId);

        //gluLookAt(
        //    4, 3, 3,
        //    0, 0, 0,
        //    0, 1, 0
        //);

        glUniformMatrix4fv(mvpId, 1, 0, &mvp[0][0]);

        glEnableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
        glVertexAttribPointer(
            0,
            3,
            GL_FLOAT,
            GL_FALSE,
            0,
            NULL
        );

        glEnableVertexAttribArray(1);
        glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
        glVertexAttribPointer(
            1,          
            3,          
            GL_FLOAT,   
            GL_FALSE,   
            0,          
            (void*)0    
        );

        glDrawArrays(GL_TRIANGLES, 0, 3*12);

        glDisableVertexAttribArray(0);
        glDisableVertexAttribArray(1);

        glfwSwapBuffers(window);
        glfwPollEvents();
    } while (
        !glfwWindowShouldClose(window)
        &&
        !glfwGetKey(window, GLFW_KEY_ESCAPE)
    );

    glfwTerminate();
}

global.hpp

#ifndef _glfw3_h_
// opengl extensions
#include <GL/glew.h>

// opengl utility / wrapper
#include <GLFW/glfw3.h>

// operations in space
#include <glm/glm.hpp>

#include <glm/gtc/matrix_transform.hpp>

#endif // !_glfw3_h_


#include <iostream>
#include <string>
#include <sstream>
#include <map>
#include <vector>
#include <fstream>

#include <random>
#include <ctime>
#include <cmath>

static void glfwErrorCb(int errorCode, const char* error) {
    printf("GLFW Error Thrown\n -> %d\n%s\n", errorCode, error);
}

static bool glfwInitFull() {
    srand(time(0));

    if (!glfwInit())
        return 0;

    glfwSetErrorCallback(glfwErrorCb);
    glewExperimental = true;

    glfwWindowHint(GLFW_SAMPLES, 4); // anti-aliasing
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // version
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // version
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // no-old-gl

    return 1;
}

static GLuint compileShader(const char* content, GLenum type) {
    GLuint shaderId = glCreateShader(type);
    GLint returnValBuf;

    glShaderSource(shaderId, 1, &content, NULL);
    glCompileShader(shaderId);

    glGetShaderiv(shaderId, GL_COMPILE_STATUS, &returnValBuf);

    if (returnValBuf == GL_FALSE) {
        printf("Unable To Compile Shader\n```\n%s\n```\n\nInfo Log:\n", content);
        
        GLint logLen;
        glGetShaderiv(shaderId, GL_INFO_LOG_LENGTH, &logLen);

        if (logLen <= 0)
            return 0;

        char* infoBuffer = new char[logLen + 1];
        infoBuffer[logLen] = '\0';
            
        glGetShaderInfoLog(shaderId, logLen, &returnValBuf, infoBuffer);
        printf("%s\n", infoBuffer);

        delete[] infoBuffer;
        return 0;
    }
    
    return shaderId;
}

static GLuint linkShader(GLuint programId, GLuint shaderId) {
    glAttachShader(programId, shaderId);
    glLinkProgram(programId);

    GLint returnValBuf;
    glGetProgramiv(programId, GL_LINK_STATUS, &returnValBuf);
    
    if (returnValBuf == GLFW_FALSE) {
        printf("Unable To Link Shader\nInfo Log:\n");

        GLint logLen;
        glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &logLen);

        if (logLen <= 0)
            return 0;

        char* infoBuffer = new char[logLen + 1];
        infoBuffer[logLen] = '\0';

        glGetProgramInfoLog(programId, logLen, &returnValBuf, infoBuffer);
        printf("%s\n", infoBuffer);

        delete[] infoBuffer;
    }

    glDetachShader(programId, shaderId);
    glDeleteShader(shaderId);

    return programId;
}

typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
typedef unsigned long long ullong;

#pragma once

共有1个答案

杨乐意
2023-03-14

问题是,您为每个着色器分别调用LinkShader。可以多次链接一个程序。但是,LinkShader函数将着色器附加到程序,链接程序并将着色器与程序分离。因此,顶点和碎片着色器永远不会同时附加。

附加顶点和片段着色器并调用LinkShader一次:

static GLuint linkShader(GLuint programId) {
    glLinkProgram(programId);

    GLint returnValBuf;
    glGetProgramiv(programId, GL_LINK_STATUS, &returnValBuf);

    if (returnValBuf == GLFW_FALSE) {
        printf("Unable To Link Shader\nInfo Log:\n");

        GLint logLen;
        glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &logLen);

        if (logLen <= 0)
            return 0;

        char* infoBuffer = new char[logLen + 1];
        infoBuffer[logLen] = '\0';

        glGetProgramInfoLog(programId, logLen, &returnValBuf, infoBuffer);
        printf("%s\n", infoBuffer);

        delete[] infoBuffer;
    }

    return programId;
}
int main()
{
    // [...]

    GLuint vertexShaderId = compileShader(VertexShader, GL_VERTEX_SHADER);
    GLuint fragmentShaderId = compileShader(FragmentShader, GL_FRAGMENT_SHADER);

    GLuint programId = glCreateProgram();
    glAttachShader(programId, vertexShaderId);
    glAttachShader(programId, fragmentShaderId);

    linkShader(programId);
    
    glDetachShader(programId, vertexShaderId);
    glDeleteShader(vertexShaderId);
    glDetachShader(programId, fragmentShaderId);
    glDeleteShader(fragmentShaderId);

    // [...]
}
 类似资料:
  • 所以,我试图在openGL和GLFW中绘制一个简单的立方体。

  • 我试图在屏幕上画一堆点。我使用CUDA生成数据(位置和颜色),并用OpenGL绘制它。我试图让CUDA更新一个VBO,然后用OpenGL来绘制它,但是我得到了一个空白的屏幕。我不确定CUDA是否无法更新缓冲区,或者缓冲区绘制不正确。我的GPU是GTX 1080,我正在尝试使用OpenGL 4.0。颜色也由CUDA指定。如果我的问题是我需要一个着色器,我如何添加它,但仍然通过CUDA指定颜色? 更新

  • 我试图使用opengl在lwjgl显示器上显示自定义字体的文本。目前,我正在使用自定义位图字体类从png文件加载字体,并以与tileset相同的方式显示它们。它工作正常,但当我将文本绘制到屏幕上时,字符之间的间距完全不同,因为字母M比字母i宽得多,并且所有字符的宽度都不同。有没有办法检测每个字符的宽度?或者是否有任何特定于lwjgl字体的库?有一种方法可以使用slick2d来实现,但加载整个库只是

  • 我试图通过本教程学习OpenGL,我试图在OS X Mavericks中进行编码,但结果只是一个黑窗口。我相信应该有一个白色的三角形,但不知道我错过了什么。 glut_utils.cpp TUT01.CPP

  • 本节课对WebGL光照的介绍主要目的是让你对WebGL光照,以及如何在代码层面实现WebGL光照算法有个大致的轮廓认知,计算机图形学中关于光照相关算法的介绍更为详细和系统,如果有兴趣可以阅读计算机图形学的书籍。 光线照在物体上,物体反射光线就会构成一个光场,眼睛看到生活中的物体有立体感就是因为有光的存在。因此在学习物理光学在WebGL编程中如何应用, 你就要先了解基本的光学知识。 生活中你看到一个

  • 我一直致力于渲染一个球体使用三角形条在OpenGL ES 2.0为Android。我有一个问题,当球体旋转时,它似乎自己重叠了。 我创建顶点列表的代码是 我的渲染代码将多个查看矩阵和透视矩阵相乘,然后执行以下操作: 显然,渲染过程中涉及到很多不同的部分。然而,我认为问题在于顶点生成。