c - OpenGL4 gl_texture_2d_array不会显示

标签 c opengl texture2d

我想开始使用现代 OpenGL,同时阅读这本精彩的书,通过使用大小为 1280x1280x2 的二维数组纹理编码元胞自动机,并计算计算着色器中另一层的下一个状态。这个想法是从 glumpy examples 偷来的。 .

然而,虽然心中有这样的雄心,但我什至在尝试显示它时都感到困惑,甚至没有将采样器传递到着色器中。

下面我包括了运行正常的生成器和确实存在问题的代码段。

生成

#!/usr/bin/env perl

use strict;
use warnings;


sub get_arg {
    return (scalar @ARGV == 0) ? shift : shift @ARGV;
}

my $size = get_arg 1280;
my $rate = get_arg ($size >> 1);

my $symbol = (sub { ((shift) < $rate) ? '*' : '_' } );

print "$size\n";
for (0..$size) {
    print $symbol->(int(rand() * $size)) for (0..$size);
    print "\n";
}

代码

#include <stdio.h>
#include <stdbool.h>
#include <assert.h>


// including opengl libraries on linux/osx

//include glew
#include <GL/glew.h>

//include opengl
#if defined (__APPLE_CC__)
    #include <OpenGL/gl3.h>
#else
    #include <GL/gl3.h>       /* assert OpenGL 3.2 core profile available. */
#endif

//include glfw3
#define GLFW_INCLUDE_GL3  /* don't drag in legacy GL headers. */
#define GLFW_NO_GLU       /* don't drag in the old GLU lib - unless you must. */
#include <GLFW/glfw3.h>

// ----------- the program itself

GLFWwindow *g_window;

#define SIZE 1280
#define WIDTH SIZE
#define HEIGHT SIZE
#define DEPTH 2


init_glfw(const char *name) {
    // start GL context and O/S window using the GLFW helper library
    assert(glfwInit());

#if defined(__APPLE_CC__)
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#endif
    g_window = glfwCreateWindow(WIDTH, HEIGHT, name, NULL, NULL);
    assert(g_window != NULL);
    glfwMakeContextCurrent(g_window);

    // start GLEW extension handler
    glewExperimental = GL_TRUE;
    glewInit();

    // tell GL to only draw onto a pixel if the shape is closer to the viewer
    glEnable(GL_DEPTH_TEST); // enable depth-testing
    glDepthFunc(GL_LESS); // depth-testing interprets a smaller value as "closer"
    glEnable(GL_DEBUG_OUTPUT);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}


typedef enum { FILLED = '*', EMPTY = '_' } SYMBOL;
load_array(GLubyte array[SIZE * SIZE * DEPTH], FILE *stream) {
    static char c;
    for(int i = 0; i < SIZE; ++i) {
        for(int j = 0; j < SIZE; ++j) {
            bool approved = false;
            GLubyte *it = &array[SIZE * i + j];
            while(!approved) {
                approved = true;
                c = getc(stream);
                assert(c != EOF);
                switch(c) {
                    case FILLED:
                        *it = 0x00;
                    break;
                    case EMPTY:
                        *it = 0xff;
                    break;
                    default:
                        approved = false;
                    break;
                }
            }
            assert(*it == 0x00 || *it == 0xff);
            it[SIZE * SIZE] = it[0];
        }
    }
}


GLuint create_2d_texture() {
    static GLuint texture = 0;
    assert(texture == 0);

    static GLubyte field[SIZE * SIZE << 1];
    load_array(field, stdin);

    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D_ARRAY, texture);
    glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_ALPHA8, SIZE, SIZE, DEPTH);
    glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, SIZE, SIZE, DEPTH, GL_ALPHA, GL_UNSIGNED_BYTE, field);

    glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);

    return texture;
}


display() {
    GLuint texture = create_2d_texture();
    assert(texture != 0);
    glEnable(GL_CULL_FACE);
    glCullFace(GL_FRONT_AND_BACK);

    while(!glfwWindowShouldClose(g_window)) {
        glClearColor(1.0, 1.0, 1.0, 1.0);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glLoadIdentity();
        glMatrixMode(GL_PROJECTION);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D_ARRAY, texture);
        glPushMatrix();
        glEnable(GL_TEXTURE_2D_ARRAY);
        glBegin(GL_QUADS);
            glTexCoord3s(0, SIZE, 0);    glVertex3f( 0.0f, 0.0f, 0.0 );
            glTexCoord3s(SIZE, SIZE, 0); glVertex3f( SIZE, 0.0f, 0.0 );
            glTexCoord3s(0, SIZE, 0);    glVertex3f( SIZE, SIZE, 0.0 );
            glTexCoord3s(0, 0, 0);       glVertex3f( 0.0f, SIZE, 0.0 );
        glEnd();
        glPopMatrix();

        glfwSwapBuffers(g_window);
        glfwPollEvents();
        if(glfwGetKey(g_window, GLFW_KEY_ESCAPE)) {
            glfwSetWindowShouldClose(g_window, 1);
        }
    }
}


main() {
    init_glfw("I want to display a texture");
    display();
    glfwDestroyWindow(g_window);
    glfwTerminate();
}

您能帮我分析一下在屏幕上显示二维数组的问题吗?我想要实现的目标是使整个窗口随机变成黑白,但到目前为止,我最终完全困惑,只是从谷歌解决方案和手册页中添加更多层。

我并不是要求一个工作代码,只是一个可以帮助我解决这个问题的易于理解的解释。

最佳答案

glEnable(GL_TEXTURE_2D_ARRAY);

这给了你一个 OpenGL 错误。即使在兼容性配置文件中,您也无法启用任何类型的数组纹理。为什么?

因为你不能使用 array textures 的固定功能处理根本。您不能使用glTexEnv从数组纹理中获取。它们是完全基于着色器的构造。

因此,如果您想使用数组纹理,则必须使用着色器。

关于c - OpenGL4 gl_texture_2d_array不会显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38934054/

相关文章:

c - C语言中如何使用scanf和printf处理字符串

c - printf 由 Apple 实现

c - c winsock编程中服务器收不到客户端消息

c++ - 如何正确旋转 vector 以匹配另一个 vector ? (打开)

java - 在 Java 进度条中实现平滑过渡

c - 如何调用函数 glMultiDrawElements::GLenum -> GHC.Ptr.Ptr GLsizei -> GLenum -> GHC.Ptr.Ptr (GHC.Ptr.Ptr a) -> GLsizei -> IO ()

c# - Unity c#,截屏并保存为jpg文件

c - 一种方法会引发段错误,而另一种则不会。有什么不同?

c# - 使用 DirectX Texture2D 显示相机预览会导致 Windows Phone 8 上出现振荡

c# - 如何在运行时使用 .bmp 文件并在 Unity 中创建纹理?