我在 OpenGL 中做一个标准图,不同颜色的片段交错在 vbo 中。这是相当常规的事情,一直都在做。但就我而言,结果似乎在得到我想要的东西和得到一个什么也没有的黑色空间之间随机交替。我在这里错过了什么?
我希望它能正常工作,并在 z=1 处显示一个黑白棋盘。该例程只是复制其他人为此所做的事情。但是结果似乎在我正在寻找的东西和一个简单的黑色区域之间随机交替,不知道为什么。
我一定在这里遗漏了一些微妙的点,但它是什么?
这里的代码是一个不起作用的例子,只是给了一个黑色区域。你可以编译它
```gcc -g -o test test.c
pkg-config --cflags --libs gtk+-3.0
-lepoxy
type here
type here
#include <epoxy/gl.h>
#include <gtk/gtk.h>
static void realize(GtkGLArea *gl_area);
static void render (GtkGLArea *gl_area);
static float *chessboard_vba(void);
static GLuint shader_load_program(const char *vertex, const char *fragment);
static GLuint shader_load_file(const char *filename, GLenum type);
static void print_shader_compilation_log(GLuint shader, const char *filename);
static void shader_print_log(GLuint object);
GLuint program;
GLuint vao, vbo;
int Npix=64;
GtkGLArea *gl_area;
/*------------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
GtkWidget *window;``
GtkWidget *gl_area;
gtk_init(&argc, &argv);
// Initialize Window
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(window), 640, 480);
gtk_window_set_type_hint(GTK_WINDOW(window), GDK_WINDOW_TYPE_HINT_UTILITY);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
// Initialize GTK GL Area
gl_area = gtk_gl_area_new();
gtk_widget_set_vexpand(gl_area, TRUE);
gtk_widget_set_hexpand(gl_area, TRUE);
g_signal_connect(gl_area, "realize", G_CALLBACK(realize), NULL);
g_signal_connect(gl_area, "render" , G_CALLBACK(render) , NULL);
gtk_container_add(GTK_CONTAINER(window), gl_area);
glClearColor(.5, .5, .5, 1);
gtk_widget_set_can_focus(GTK_WIDGET(gl_area), TRUE);
gtk_widget_grab_focus(GTK_WIDGET(gl_area));
// Show widgets
gtk_widget_show_all(window);
gtk_main();
return 0;
}
/*------------------------------------------------------------------------*/
//new 1/11/23
static void realize(GtkGLArea *gl_area)
{
GLfloat *vba;
gtk_gl_area_make_current(gl_area);
glClearColor(.5, .5, .5, 1);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
const char *vs = "shaders/vertex.glsl";
const char *fs = "shaders/fragment.glsl";
program = shader_load_program(vs, fs);
glUseProgram(program);
vba=chessboard_vba();//"vertex buffer array""
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, Npix*12*sizeof(GLfloat), vba, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glFlush();
free(vba);
}
/*------------------------------------------------------------------------*/
//new 12/10/22
static void render(GtkGLArea *gl_area)
{
int i, j, err;
int lseg=8, span=2*2*3;
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), 0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), (void *)(3*sizeof(GLfloat)));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
for (i=0; i<8; i++) {
glDrawArrays(GL_TRIANGLE_STRIP, 2*i*span, 2*(i+lseg)*span);
while ((err = glGetError()))
printf("%sWARNING:glError %i\n, err", err);
}
}
/*------------------------------------------------------------------------*/
static float *chessboard_vba()
{
int i, j, offset, ibw=1;
GLfloat *vba, size=5, rhi[3], rlo[3], z=1, bw[2][3]={{1,1,1},{0,0,0}};
vba=(float *)malloc(Npix*12*sizeof(GLfloat));
for (j=0; j<8; j++)
for (i=0; i<8; i++) {
rhi[0] = i*size; rhi[1] = (j )*size; rhi[2] = z;
rlo[0] = i*size; rhi[1] = (j+1)*size; rhi[2] = z;
offset=(8*j+i)*12;
ibw=!ibw;
memcpy(vba+offset , rhi , 3*sizeof(float));
memcpy(vba+offset+3, bw+ibw, 3*sizeof(float));
memcpy(vba+offset+6, rhi , 3*sizeof(float));
memcpy(vba+offset+9, bw+ibw, 3*sizeof(float));
}
return vba;
}
/*------------------------------------------------------------------------*/
/*---------------------------- From DashGL.c -----------------------------*/
/*------------------------------------------------------------------------*/
//from DashGL
static GLuint shader_load_program(const char *vertex, const char *fragment)
{
GLint link_ok;
GLuint program;
GLuint vs = shader_load_file(vertex, GL_VERTEX_SHADER);
GLuint fs = shader_load_file(fragment, GL_FRAGMENT_SHADER);
if(vs == 0 || fs == 0) {
return 0;
}
program = glCreateProgram();
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &link_ok);
if(!link_ok) {
fprintf(stderr, "Program Link Error: ");
shader_print_log(program);
return 0;
}
glDetachShader(program, vs);
glDetachShader(program, fs);
return program;
}
/*------------------------------------------------------------------------*/
//from DashGL
static GLuint shader_load_file(const char *filename, GLenum type)
{
FILE *fp;
unsigned int file_len;
char *source;
GLuint shader;
GLint compile_ok;
fp = fopen(filename, "r");
if(fp == NULL) {
fprintf(stderr, "Could not open %s for reading\n", filename);
return 0;
}
fseek(fp, 0, SEEK_END);
file_len = ftell(fp);
fseek(fp, 0, SEEK_SET);
source = malloc(file_len + 1);
fread(source, file_len, sizeof(char), fp);
fclose(fp);
source[file_len] = '\0';
const GLchar *sources[] = { source };
shader = glCreateShader(type);
glShaderSource(shader, 1, sources, NULL);
glCompileShader(shader);
free(source);
glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_ok);
if(compile_ok == GL_FALSE) {
fprintf(stderr, "Shader compile error: %s\n", filename);
shader_print_log(shader);
glDeleteShader(shader);
return 0;
}
print_shader_compilation_log(shader, filename);
return shader;
}
/*------------------------------------------------------------------------*/
//from DashGL
static void shader_print_log(GLuint object)
{
char *log;
GLint log_length;
if (glIsShader(object)) {
glGetShaderiv(object, GL_INFO_LOG_LENGTH, &log_length);
}
else if (glIsProgram(object)) {
glGetProgramiv(object, GL_INFO_LOG_LENGTH, &log_length);
}
else {
fprintf(stderr, "Not a shader or program\n");
return;
}
log = (char*)malloc(log_length);
if(glIsShader(object)) {
glGetShaderInfoLog(object, log_length, NULL, log);
}
else if(glIsProgram(object)) {
glGetProgramInfoLog(object, log_length, NULL, log);
}
fprintf(stderr, "%s\n", log);
free(log);
}
/*------------------------------------------------------------------------*/
static void print_shader_compilation_log(GLuint shader, const char *filename)
{
GLint logSize=0;
GLsizei length;
GLchar *infoLog;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logSize);
if (logSize<=0) {
printf("No error log for .glsl file %s\n", filename);
return;
}
infoLog = (GLchar *)malloc(logSize*sizeof(GLchar));
glGetShaderInfoLog(shader, logSize*sizeof(GLchar), &length, infoLog);
printf("Info Log from compilation:\n");
printf("%s\n", infoLog);
free(infoLog);
}