我正在尝试使用GtkGLArea
小部件。类似问题的答案似乎都与这种情况无关。
glClear()
可以很好地设置背景颜色,但实际绘制的三角形数组不是。
根据this教程,下面的代码应该有效。
编辑 2015年5月21日:添加着色器,仍然获得相同的结果。
下面的新代码这里是main.c
和SConstruct
所以你可以用scons构建:
已解决:标题 SOLUTION:main.c 下的工作代码可以使用相同的SConstruct文件构建示例
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <glib.h>
#include <gdk/gdkx.h>
#include <epoxy/glx.h>
#include <epoxy/gl.h>
#include <gtk/gtk.h>
#include <gtk/gtkglarea.h>
#define IGNORE_VAR(type, identifier) \
{ \
type IGNORED_VARIABLE_abcd = identifier; \
identifier = IGNORED_VARIABLE_abcd; \
}
const GLchar *vert_src ="\n" \
"#version 330 \n" \
" \n" \
"layout(location = 0) in vec2 in_position; \n" \
" \n" \
"void main() \n" \
"{ \n" \
" gl_Position = in_position; \n" \
"} \n";
const GLchar *frag_src ="\n" \
"void main (void) \n" \
"{ \n" \
" gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); \n" \
"} \n";
GLuint gl_buffer, gl_program;
static gboolean realise(GtkGLArea *area, GdkGLContext *context)
{
IGNORE_VAR(GdkGLContext*, context);
gtk_gl_area_make_current(GTK_GL_AREA(area));
if (gtk_gl_area_get_error (GTK_GL_AREA(area)) != NULL)
{
printf("Failed to initialiize buffers\n");
return FALSE;
}
GLfloat verts[] =
{
+0.0f, +1.0f,
-1.0f, -1.0f,
+1.0f, -1.0f,
};
GLuint frag_shader, vert_shader;
frag_shader = glCreateShader(GL_FRAGMENT_SHADER);
vert_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(frag_shader, 1, &frag_src, NULL);
glShaderSource(vert_shader, 1, &vert_src, NULL);
glCompileShader(frag_shader);
glCompileShader(vert_shader);
gl_program = glCreateProgram();
glAttachShader(gl_program, frag_shader);
glAttachShader(gl_program, vert_shader);
glLinkProgram(gl_program);
glGenBuffers(1, &gl_buffer);
glBindBuffer(GL_ARRAY_BUFFER, gl_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
return TRUE;
}
static gboolean render(GtkGLArea *area, GdkGLContext *context)
{
IGNORE_VAR(GdkGLContext*, context);
IGNORE_VAR(GtkGLArea*, area);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindBuffer(GL_ARRAY_BUFFER, gl_buffer);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
//glUseProgram(gl_program);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
return TRUE;
}
int main(int argc, char** argv)
{
gtk_init(&argc, &argv);
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL),
*gl_area = gtk_gl_area_new();
g_signal_connect(window, "delete-event", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(gl_area, "realize", G_CALLBACK(realise), NULL);
g_signal_connect(gl_area, "render", G_CALLBACK(render), NULL);
gtk_container_add(GTK_CONTAINER(window), gl_area);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
import os
env = Environment(CC='gcc', CCFLAGS='--std=c11', ENV={'PATH':os.environ['PATH']})
env.Append(LIBS = ['GL', 'epoxy'])
env.ParseConfig('pkg-config --cflags --libs gtk+-3.0')
#env.ParseConfig('pkg-config --cflags gdkglext-1.0')
env.Program(target='gl', source=['main.c'])
# vim: set filetype=python:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <glib.h>
#include <gdk/gdkx.h>
#include <epoxy/glx.h>
#include <epoxy/gl.h>
#include <gtk/gtk.h>
#define IGNORE_VAR(type, identifier) \
{ \
type IGNORED_VARIABLE_abcd = identifier; \
identifier = IGNORED_VARIABLE_abcd; \
}
const GLchar *vert_src ="\n" \
"#version 330 \n" \
"#extension GL_ARB_explicit_attrib_location: enable \n" \
" \n" \
"layout(location = 0) in vec2 in_position; \n" \
" \n" \
"void main() \n" \
"{ \n" \
" gl_Position = vec4(in_position, 0.0, 1.0); \n" \
"} \n";
const GLchar *frag_src ="\n" \
"void main (void) \n" \
"{ \n" \
" gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); \n" \
"} \n";
GLuint gl_vao, gl_buffer, gl_program;
static gboolean realise(GtkGLArea *area, GdkGLContext *context)
{
IGNORE_VAR(GdkGLContext*, context);
gtk_gl_area_make_current(GTK_GL_AREA(area));
if (gtk_gl_area_get_error (GTK_GL_AREA(area)) != NULL)
{
printf("Failed to initialiize buffers\n");
return FALSE;
}
GLfloat verts[] =
{
+0.0f, +1.0f,
-1.0f, -1.0f,
+1.0f, -1.0f,
};
GLuint frag_shader, vert_shader;
frag_shader = glCreateShader(GL_FRAGMENT_SHADER);
vert_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(frag_shader, 1, &frag_src, NULL);
glShaderSource(vert_shader, 1, &vert_src, NULL);
glCompileShader(frag_shader);
glCompileShader(vert_shader);
gl_program = glCreateProgram();
glAttachShader(gl_program, frag_shader);
glAttachShader(gl_program, vert_shader);
glLinkProgram(gl_program);
glGenVertexArrays(1, &gl_vao);
glBindVertexArray(gl_vao);
glGenBuffers(1, &gl_buffer);
glBindBuffer(GL_ARRAY_BUFFER, gl_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
glBindVertexArray(0);
glDeleteBuffers(1, &gl_buffer);
return TRUE;
}
static gboolean render(GtkGLArea *area, GdkGLContext *context)
{
IGNORE_VAR(GdkGLContext*, context);
IGNORE_VAR(GtkGLArea*, area);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.0, 0.0, 0.0, 1.0);
glUseProgram(gl_program);
glBindVertexArray(gl_vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray (0);
glUseProgram (0);
glFlush();
return TRUE;
}
int main(int argc, char** argv)
{
gtk_init(&argc, &argv);
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL),
*gl_area = gtk_gl_area_new();
g_signal_connect(window, "delete-event", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(gl_area, "realize", G_CALLBACK(realise), NULL);
g_signal_connect(gl_area, "render", G_CALLBACK(render), NULL);
gtk_container_add(GTK_CONTAINER(window), gl_area);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
答案 0 :(得分:2)
您似乎没有任何着色器。您需要fragment和vertex着色器。
以下是有关如何编写和使用它们的教程:https://www.opengl.org/sdk/docs/tutorials/ClockworkCoders/loading.php
答案 1 :(得分:0)
您正在使用通用顶点属性。因此你应该使用着色器。如果您在兼容性配置文件中,则使用顶点属性0可能会被解释为内置属性“顶点位置”,但这不是给定的。因此,如果您想“按书”操作,则必须提供着色器(或坚持使用已弃用的内置属性)。
旁注:不建议启用顶点属性数组并在初始化代码中设置指针。这两者之间的OpenGL上下文可能会发生任何事情,包括绑定其他顶点数组,禁用/启用(其他)顶点属性数组,设置不同的缓冲区指针等。
根据经验,任何与绘图状态直接相关的内容(即不构成一次数据初始化/加载)都属于绘图代码的相应位置。在你的情况下
static gboolean render(GtkGLArea *area, GdkGLContext *context)
{
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//glFrontFace(GL_CW);
/* added these ---> */
glBindBuffer(GL_ARRAY_BUFFER, gl_buffer);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
/* <--- */
glDrawArrays(GL_TRIANGLES, 0, 3);
//gtk_widget_get_realized(area);
return TRUE;
}
不这样做会导致将从长远来看混淆你。
答案 2 :(得分:0)
您错过了VAO的创建; GTK +将创建GL核心配置文件上下文,这意味着您需要自己创建和选择VAO,否则将不使用顶点缓冲区对象。
初始化GL状态时,请添加:
.list {
display: inline-block;
font-size: 0;
height: 100%;
min-width: 100%;
overflow: hidden;
position: relative;
right: 0;
white-space: nowrap;
}
在创建VBO之前。
您应该查看my blog post about using OpenGL with GTK+及其相关的example code。