请原谅长度(以及宽度;这是为了清晰度在IDE上)但我想要显示代码的全长,因为它的目的是在现代VBO和GLSL中使用简单的Hello World。
最初基于http://people.freedesktop.org/~idr/OpenGL_tutorials/02-GLSL-hello-world.pdf
重点是没有打印单个错误消息或警告 - 您可以看到printfs很多(实际上,几乎所有代码都会被捕获以查找错误)。
编译在-std = c99 -pedantic -O0 -g -Wall上完成(没有警告),因此编译错误也没有多少空间。
我把针引到了我的注意力
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
和
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
(后者是我还不完全理解的代码中唯一的部分;最不起眼的功能'永远')
信息日志不会打印任何内容,如果特意使着色器无效,它会正常打印健康文本。因此它既不是着色器字符串赋值,也不是它们的编译。
你能看到一些可以打印成黑屏的东西吗?
如果glDrawArrays与GL_POINTS一起使用,它会在中间打印一个点,如果glClear前面有一个合适的glClearColor,它会改变颜色。
#include "SDL.h" // Window and program management
#include "Glee.h" // OpenGL management; Notice SDL's OpenGL header is not included
#include <stdbool.h> // C99 bool
void initGL(void);
void drawGL(void);
int main (int argc, char **argv) {
// Load the SDL library; Initialize the Video Subsystem
if (SDL_Init(SDL_INIT_VIDEO) < 0 ) printf("SDL_Init fail: %s\n", SDL_GetError());
/* Video Subsystem: set up width, height, bits per pixel (0 = current display's);
Create an OpenGL rendering context */
if (SDL_SetVideoMode(800, 600, 0, SDL_OPENGL) == NULL) printf("SDL_SetVideoMode fail: %s\n", SDL_GetError());
// Title and icon text of window
SDL_WM_SetCaption("gl", NULL);
// Initialize OpenGL ..
initGL();
bool done = false;
// Loop indefinitely unless user quits
while (!done) {
// Draw OpenGL ..
drawGL();
// Deal with SDL events
SDL_Event sdl_event;
do {
if ( sdl_event.type == SDL_QUIT || (sdl_event.type == SDL_KEYDOWN && sdl_event.key.keysym.sym == SDLK_ESCAPE)) {
done = true;
break;
}
} while (SDL_PollEvent(&sdl_event));
}
// Clean SDL initialized systems, unload library and return.
SDL_Quit();
return 0;
}
GLuint program;
GLuint buffer;
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
void initGL(void) {
// Generate 1 buffer object; point its name (in uint form) to *buffer.
glGenBuffers(1, &buffer); if(glGetError()) printf("glGenBuffers error\n");
/* bind the named (by a uint (via the previous call)) buffer object to target GL_ARRAY_BUFFER (target for vertices)
apparently, one object is bound to a target at a time. */
glBindBuffer(GL_ARRAY_BUFFER, buffer); if(glGetError()) printf("glBindBuffer error\n");
/* Create a data store for the current object bound to GL_ARRAY_BUFFER (from above), of a size 8*size of GLfloat,
with no initial data in it (NULL) and a hint to the GrLib that data is going to be modified once and used a
lot (STATIC), and it's going to be modified by the app and used by the GL for drawing or image specification (DRAW)
Store is not mapped yet. */
glBufferData( GL_ARRAY_BUFFER, 4 * 2 * sizeof(GLfloat), NULL, GL_STATIC_DRAW); if(glGetError()) printf("glBufferData error\n");
/* Actually map to the GL client's address space the data store currently bound to GL_ARRAY_BUFFER (from above).
Write only. */
GLfloat *data = (GLfloat *) glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); if (!*data) printf("glMapBuffer error1\n"); if(glGetError()) printf("glMapBuffer error2\n");
// Apparently, write some data on the object.
data[0] = -0.75f; data[1] = -0.75f; data[2] = -0.75f; data[3] = 0.75f;
data[4] = 0.75f; data[5] = 0.75f; data[6] = 0.75f; data[7] = -0.75f;
// Unmap the data store. Required *before* the object is used.
if(!glUnmapBuffer(GL_ARRAY_BUFFER)) printf("glUnmapBuffer error\n");
// Specify the location and data format of an array of generic vertex attributes ..
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
// the shaders source
GLchar *vertex_shader_code[] = { "void main(void) { gl_Position = gl_Vertex; }"};
GLchar *fragment_shader_code[] = { "void main(void) { gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); }"};
/* Create an empty shader object; used to maintain the source string; intended to run
on the programmable vertex processor; GL_SHADER_TYPE is set to GL_VERTEX_SHADER
(e.g. for use on glGetShaderiv)*/
GLuint vs = glCreateShader(GL_VERTEX_SHADER); if (!vs) printf("glCreateShader fail\n");
/* Set the source code in vs; 1 string; GLchar **vertex_shader_code array of pointers to strings,
length is NULL, i.e. strings assumed null terminated */
glShaderSource(vs, 1, (const GLchar **) &vertex_shader_code, NULL); if(glGetError()) printf("glShaderSource error\n");
// Actually compile the shader
glCompileShader(vs); GLint compile_status; glGetShaderiv(vs, GL_COMPILE_STATUS, &compile_status); if (compile_status == GL_FALSE) printf("vertex_shader_code compilation fail\n"); if(glGetError()) printf("glGetShaderiv fail\n");
// same
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); if (!fs) printf("glCreateShader fail\n");
// same
glShaderSource(fs, 1, (const GLchar **) &fragment_shader_code, NULL); if(glGetError()) printf("glShaderSource error\n");
// same
glCompileShader(fs); glGetShaderiv(fs, GL_COMPILE_STATUS, &compile_status); if (compile_status == GL_FALSE) printf("fragment_shader_code compilation fail\n"); if(glGetError()) printf("glGetShaderiv fail\n");
/* Empty program for later attachment of shaders; it provides management mechanism for them.
Shaders can be compiled before or after their attachment. */
program = glCreateProgram(); if(!program) printf("glCreateProgram fail1\n"); if(glGetError()) printf("glCreateProgram fail2\n");
/* Attach shaders to program; this could be done before their compilation or their association with code
Destined to be linked together and form an executable. */
glAttachShader(program, vs); if(glGetError()) printf("glAttachShader fail1\n");
glAttachShader(program, fs); if(glGetError()) printf("glAttachShader fail2\n");
// Link the program; vertex shader objects create an executable for the vertex processor and similarly for fragment shaders.
glLinkProgram(program); GLint link_status; glGetProgramiv(program, GL_LINK_STATUS, &link_status); if (!link_status) printf("linking fail\n"); if(glGetError()) printf("glLinkProgram fail\n");
/* Get info log, if any (supported by the standard to be empty).
It does give nice output if compilation or linking fails. */
GLchar infolog[2048];
glGetProgramInfoLog(program, 2048, NULL, infolog); printf("%s", infolog); if (glGetError()) printf("glGetProgramInfoLog fail\n");
/* Install program to rendering state; one or more executables contained via compiled shaders inclusion.
Certain fixed functionalities are disabled for fragment and vertex processors when such executables
are installed, and executables may reimplement them. See glUseProgram manual page about it. */
glUseProgram(program); if(glGetError()) printf("glUseProgram fail\n");
}
void drawGL(void) {
// Clear color buffer to default value
glClear(GL_COLOR_BUFFER_BIT); if(glGetError()) printf("glClear error\n");
// Render the a primitive triangle
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); if(glGetError()) printf("glDrawArrays error\n");
SDL_GL_SwapBuffers();
}
答案 0 :(得分:3)
扩展Calvin1602的回答:
ftransform假设您不使用的矩阵。 gl_Vertex在这里应该没问题,考虑到最终结果应该是[-1:1] ^ 3立方体,并且他的数据在那个区间内。 现在,如果你真的想要全部使用GL3.1,那么应该是gl_VertexAttrib [0],而是gl_Vertex和gl_VertexAttrib [0]别名(见下文)。
至于启用。你使用vertex attrib 0,所以你需要:
glEnableVertexAttribArray(0)
关于解决一般事物的建议:不清楚黑色,它会让生活更难以弄清楚是否绘制了黑色或者是否绘制了任何东西(使用glClearColor来改变它)。
在迂腐的一面,当你投掷指针时,你的glShaderSource调用看起来很可疑。我用
清理它glShaderSource(fs, 1, fragment_shader_code, NULL);
目前使用&amp; fragment_shader_code的原因是interesting,但在这里,我不明白为什么你不简化。
==编辑添加==
Gah,不确定我在想gl_VertexAttrib。已经有一段时间我没有看到这个,我只是制作了自己的特色......
在GL4.1之前,提供非内置属性的标准方法实际上并不重要。
// glsl
attribute vec4 myinput;
gl_Position = myinput;
// C-code, rely on linker for location
glLinkProgram(prog);
GLint location = glGetAttribLocation(prog, "myinput");
glEnableVertexAttribArray(location, ...)
// alternative C-code, specify location
glBindAttribLocation(prog, 0, "myinput");
glLinkProgram(prog);
glEnableVertexAttribArray(0, ...)
GL4.1最终支持直接在着色器中指定位置。
// glsl 4.10
layout (location=0) in vec4 myinput;
答案 1 :(得分:2)
......我没有看到任何其他内容