C OpenGL glfw3 三角形不显示
C OpenGL glfw3 triangle not displaying
我有一个简单的 OpenGL C 应用程序,它试图在屏幕上绘制一个三角形。我已经成功地用 C++ 编写了类似的代码,没有任何问题。当我 运行 C 程序时,它创建了 window,但没有显示任何内容。我的代码的主要部分如下。
void init()
{
GLfloat vertices[] = {
// Positions
0.0f, 0.5f, 0.0f, 0.0f, // Top
0.5f, -0.5f, 0.0f, 0.0f, // Bottom Right
-0.5f, -0.5f, 0.0f, 0.0f // Bottom Left
};
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//glBindBuffer(GL_ARRAY_BUFFER, 0);
GLuint program = loadShader("/shader1.vert",
"/shader1.frag");
glUseProgram(program);
GLuint vPosition = glGetAttribLocation(program, "VPosition");
glEnableVertexAttribArray(vPosition);
glVertexAttribPointer(vPosition, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glBindVertexArray (vao);
}
int main()
{
glfwInit();
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
int w = 800;
int h = 600;
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
//glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "glfw3", NULL, NULL);
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, key_callback);
glViewport(0, 0, WIDTH, HEIGHT);
init();
while(!glfwWindowShouldClose(window))
{
glfwPollEvents();
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays( GL_TRIANGLES, 0, 3 );
glfwSwapBuffers(window);
}
glfwTerminate();
return 0;
}
使用顶点着色器
attribute vec4 vPosition;
void main()
{
gl_Position = vPosition;
}
和片段着色器
void main()
{
gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );
}
并加载着色器
char *readShader(char *filename)
{
FILE *fp;
char *content = NULL;
int count = 0;
if(filename != NULL)
{
fp = fopen(filename, "rt");
if(fp != NULL){
fseek(fp, 0, SEEK_END);
count = ftell(fp);
rewind(fp);
if (count > 0) {
content = (char *)malloc(sizeof(char) * (count+1));
count = fread(content,sizeof(char),count,fp);
content[count] = '[=13=]';
}
}
fclose(fp);
}
return content;
}
GLuint loadShader(char *vertex_path, char *fragement_path)
{
GLuint vertShader = glCreateShader(GL_VERTEX_SHADER);
GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER);
char *vertShaderStr = readShader(vertex_path);
char *fragShaderStr = readShader(fragement_path);
printf("Compiling vertex shader\n");
GLint vertLength = strlen(vertShaderStr);
glShaderSource(vertShader, 1, (const char **)&vertShaderStr, &vertLength);
glCompileShader(vertShader);
//Check vertex shader
GLint vertSuccess;
glGetShaderiv(vertShader, GL_COMPILE_STATUS, &vertSuccess);
if(vertSuccess == GL_FALSE) {
char log[1024];
glGetShaderInfoLog(vertShader, sizeof(log), 0, log);
printf("Vertex shader compile info: \n %s \n", log);
glDeleteShader(vertShader);
return 1;
}
printf("Compiling fragment shader\n");
GLint fragLength = strlen(fragShaderStr);
glShaderSource(fragShader, 1, (const char **)&fragShaderStr, &fragLength);
glCompileShader(fragShader);
//Check fragment shader
GLint fragSuccess;
glGetShaderiv(fragShader, GL_COMPILE_STATUS, &fragSuccess);
if(vertSuccess == GL_FALSE) {
char log[1024];
glGetShaderInfoLog(vertShader, sizeof(log), 0, log);
printf("Fragment shader compile info: \n %s \n", log);
glDeleteShader(fragShader);
return 1;
}
printf("Linking program\n");
GLuint program = glCreateProgram();
glAttachShader(program, vertShader);
glAttachShader(program, fragShader);
glLinkProgram(program);
GLint programSuccess;
glGetProgramiv(program, GL_LINK_STATUS, &programSuccess);
if(programSuccess == GL_FALSE) {
char log[1024];
glGetProgramInfoLog(program, sizeof(log), 0, log);
printf("shader link info: \n %s \n", log);
glDeleteProgram(program);
return 1;
}
//printf("%s", vertShaderStr);
//printf("%s", fragShaderStr);
return program;
}
这里:
GLfloat 顶点[] = {
// 位置
0.0f, 0.5f, 0.0f, 0.0f, // 顶部
0.5f, -0.5f, 0.0f, 0.0f, // 右下角
-0.5f, -0.5f, 0.0f, 0.0f // 左下角
}
您指定 0 作为所有顶点的 w 坐标。你真的要在这里放1,否则你的顶点无限远。
请注意,通常所有顶点的输入 w`坐标始终为 1,将其显式存储在数组中会浪费内存和带宽。如果未指定,GL 会自动将向量的第四个分量扩展为 1,因此您可以简单地使用
GLfloat vertices[] = {
// Positions
0.0f, 0.5f, 0.0f, // Top
0.5f, -0.5f, 0.0f, // Bottom Right
-0.5f, -0.5f, 0.0f, // Bottom Left
};
// ...
glVertexAttribPointer(vPosition, 3 GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
无需 完全改变着色器中的 attribute vec4
。
我还觉得可疑的是您从不加载 GL 函数指针。我没有粘贴你包含的内容 headers,但绝对不能在所有平台上运行。
我有一个简单的 OpenGL C 应用程序,它试图在屏幕上绘制一个三角形。我已经成功地用 C++ 编写了类似的代码,没有任何问题。当我 运行 C 程序时,它创建了 window,但没有显示任何内容。我的代码的主要部分如下。
void init()
{
GLfloat vertices[] = {
// Positions
0.0f, 0.5f, 0.0f, 0.0f, // Top
0.5f, -0.5f, 0.0f, 0.0f, // Bottom Right
-0.5f, -0.5f, 0.0f, 0.0f // Bottom Left
};
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//glBindBuffer(GL_ARRAY_BUFFER, 0);
GLuint program = loadShader("/shader1.vert",
"/shader1.frag");
glUseProgram(program);
GLuint vPosition = glGetAttribLocation(program, "VPosition");
glEnableVertexAttribArray(vPosition);
glVertexAttribPointer(vPosition, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glBindVertexArray (vao);
}
int main()
{
glfwInit();
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
int w = 800;
int h = 600;
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
//glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "glfw3", NULL, NULL);
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, key_callback);
glViewport(0, 0, WIDTH, HEIGHT);
init();
while(!glfwWindowShouldClose(window))
{
glfwPollEvents();
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays( GL_TRIANGLES, 0, 3 );
glfwSwapBuffers(window);
}
glfwTerminate();
return 0;
}
使用顶点着色器
attribute vec4 vPosition;
void main()
{
gl_Position = vPosition;
}
和片段着色器
void main()
{
gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );
}
并加载着色器
char *readShader(char *filename)
{
FILE *fp;
char *content = NULL;
int count = 0;
if(filename != NULL)
{
fp = fopen(filename, "rt");
if(fp != NULL){
fseek(fp, 0, SEEK_END);
count = ftell(fp);
rewind(fp);
if (count > 0) {
content = (char *)malloc(sizeof(char) * (count+1));
count = fread(content,sizeof(char),count,fp);
content[count] = '[=13=]';
}
}
fclose(fp);
}
return content;
}
GLuint loadShader(char *vertex_path, char *fragement_path)
{
GLuint vertShader = glCreateShader(GL_VERTEX_SHADER);
GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER);
char *vertShaderStr = readShader(vertex_path);
char *fragShaderStr = readShader(fragement_path);
printf("Compiling vertex shader\n");
GLint vertLength = strlen(vertShaderStr);
glShaderSource(vertShader, 1, (const char **)&vertShaderStr, &vertLength);
glCompileShader(vertShader);
//Check vertex shader
GLint vertSuccess;
glGetShaderiv(vertShader, GL_COMPILE_STATUS, &vertSuccess);
if(vertSuccess == GL_FALSE) {
char log[1024];
glGetShaderInfoLog(vertShader, sizeof(log), 0, log);
printf("Vertex shader compile info: \n %s \n", log);
glDeleteShader(vertShader);
return 1;
}
printf("Compiling fragment shader\n");
GLint fragLength = strlen(fragShaderStr);
glShaderSource(fragShader, 1, (const char **)&fragShaderStr, &fragLength);
glCompileShader(fragShader);
//Check fragment shader
GLint fragSuccess;
glGetShaderiv(fragShader, GL_COMPILE_STATUS, &fragSuccess);
if(vertSuccess == GL_FALSE) {
char log[1024];
glGetShaderInfoLog(vertShader, sizeof(log), 0, log);
printf("Fragment shader compile info: \n %s \n", log);
glDeleteShader(fragShader);
return 1;
}
printf("Linking program\n");
GLuint program = glCreateProgram();
glAttachShader(program, vertShader);
glAttachShader(program, fragShader);
glLinkProgram(program);
GLint programSuccess;
glGetProgramiv(program, GL_LINK_STATUS, &programSuccess);
if(programSuccess == GL_FALSE) {
char log[1024];
glGetProgramInfoLog(program, sizeof(log), 0, log);
printf("shader link info: \n %s \n", log);
glDeleteProgram(program);
return 1;
}
//printf("%s", vertShaderStr);
//printf("%s", fragShaderStr);
return program;
}
这里:
GLfloat 顶点[] = {
// 位置
0.0f, 0.5f, 0.0f, 0.0f, // 顶部
0.5f, -0.5f, 0.0f, 0.0f, // 右下角
-0.5f, -0.5f, 0.0f, 0.0f // 左下角
}
您指定 0 作为所有顶点的 w 坐标。你真的要在这里放1,否则你的顶点无限远。
请注意,通常所有顶点的输入 w`坐标始终为 1,将其显式存储在数组中会浪费内存和带宽。如果未指定,GL 会自动将向量的第四个分量扩展为 1,因此您可以简单地使用
GLfloat vertices[] = {
// Positions
0.0f, 0.5f, 0.0f, // Top
0.5f, -0.5f, 0.0f, // Bottom Right
-0.5f, -0.5f, 0.0f, // Bottom Left
};
// ...
glVertexAttribPointer(vPosition, 3 GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
无需 完全改变着色器中的 attribute vec4
。
我还觉得可疑的是您从不加载 GL 函数指针。我没有粘贴你包含的内容 headers,但绝对不能在所有平台上运行。