我想开始使用现代 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/