将OpenGL SuperBible(6E)示例中的代码应用到GLFW窗口时出现问题



我目前正在尝试通过OpenGL SuperBible(6E)学习OpenGL。然而,我并没有使用作者编写的窗口类,而是尝试将这些示例应用到我自己的GLFW窗口环境中。

到目前为止,我已经能够自己重新创建许多例子,但我遇到了一个我无法工作的例子。

以下是问题SuperBible示例"movingtri"的.cpp文件:

#include <sb6.h>
#include <math.h>
class singlepoint_app : public sb6::application
{
void init()
{
static const char title[] = "OpenGL SuperBible - Single Point";
sb6::application::init();
memcpy(info.title, title, sizeof(title));
}
virtual void startup()
{
static const char * vs_source[] =
{
"#version 410 core                                                 n"
"                                                                  n"
"layout (location = 0) in vec4 offset;                             n"
"                                                                  n"
"void main(void)                                                   n"
"{                                                                 n"
"    const vec4 vertices[] = vec4[](vec4( 0.25, -0.25, 0.5, 1.0),  n"
"                                   vec4(-0.25, -0.25, 0.5, 1.0),  n"
"                                   vec4( 0.25,  0.25, 0.5, 1.0)); n"
"                                                                  n"
"    // Add 'offset' to our hard-coded vertex position             n"
"    gl_Position = vertices[gl_VertexID] + offset;                 n"
"}                                                                 n"
};
static const char * fs_source[] =
{
"#version 410 core                                                 n"
"                                                                  n"
"out vec4 color;                                                   n"
"                                                                  n"
"void main(void)                                                   n"
"{                                                                 n"
"    color = vec4(0.0, 0.8, 1.0, 1.0);                             n"
"}                                                                 n"
};
program = glCreateProgram();
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, 1, fs_source, NULL);
glCompileShader(fs);
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, 1, vs_source, NULL);
glCompileShader(vs);
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
}
virtual void render(double currentTime)
{
static const GLfloat green[] = { 0.0f, 0.25f, 0.0f, 1.0f };
glClearBufferfv(GL_COLOR, 0, green);
glUseProgram(program);
GLfloat attrib[] = { (float)sin(currentTime) * 0.5f,
(float)cos(currentTime) * 0.6f,
0.0f, 0.0f };
glVertexAttrib4fv(0, attrib);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
virtual void shutdown()
{
glDeleteVertexArrays(1, &vao);
glDeleteProgram(program);
}
private:
GLuint          program;
GLuint          vao;
};
DECLARE_MAIN(singlepoint_app)

现在,这是我自己(使用GLFW和GLEW)应用此代码的失败尝试:

#include "glew.h"
#include "glfw3.h"
#include "math.h"
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
int main(void)
{
GLFWwindow* window;
if (!glfwInit())
{
exit(EXIT_FAILURE);
}
window = glfwCreateWindow(800, 600, "OpenGL - movingtri", NULL, NULL);
if (!window)
{
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window);
glewInit();
//begin OpenGL code from example movingtri.cpp
GLuint          program;
GLuint          vao;
static const char * vs_source[] =
{
"#version 410 core                                                 n"
"                                                                  n"
"layout (location = 0) in vec4 offset;                             n"
"                                                                  n"
"void main(void)                                                   n"
"{                                                                 n"
"    const vec4 vertices[] = vec4[](vec4( 0.25, -0.25, 0.5, 1.0),  n"
"                                   vec4(-0.25, -0.25, 0.5, 1.0),  n"
"                                   vec4( 0.25,  0.25, 0.5, 1.0)); n"
"                                                                  n"
"    // Add 'offset' to our hard-coded vertex position             n"
"    gl_Position = vertices[gl_VertexID] + offset;                 n"
"}                                                                 n"
};
static const char * fs_source[] =
{
"#version 410 core                                                 n"
"                                                                  n"
"out vec4 color;                                                   n"
"                                                                  n"
"void main(void)                                                   n"
"{                                                                 n"
"    color = vec4(0.0, 0.8, 1.0, 1.0);                             n"
"}                                                                 n"
};
program = glCreateProgram();
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, 1, fs_source, NULL);
glCompileShader(fs);
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, 1, vs_source, NULL);
glCompileShader(vs);
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// end of movingtri initialization
while (!glfwWindowShouldClose(window))
{  
double currentTime = glfwGetTime();
int width, height;
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
// begin rendering code from movingtri
static const GLfloat green[] = { 0.0f, 0.25f, 0.0f, 1.0f };
glClearBufferfv(GL_COLOR, 0, green);
glUseProgram(program);
GLfloat attrib[] = { (float)sin(currentTime) * 0.5f,
(float)cos(currentTime) * 0.6f,
0.0f, 0.0f };
glVertexAttrib4fv(0, attrib);
glDrawArrays(GL_TRIANGLES, 0, 3);
//end rendering code

glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);
}

我在上面使用的复制粘贴技术也适用于《超级圣经》中许多其他更复杂的例子。

我已经对这个代码进行了数小时的测试和修补,但我只做了一个潜在的相关观察:

如果我删除此行的"+偏移":

"    gl_Position = vertices[gl_VertexID] + offset;                 n"

然后三角形出现了,但当然不会移动。

以下是movingtri.cpp示例的gif图:

https://i.stack.imgur.com/deF3B.gif

以下是我在实现movingtri.cpp时失败的尝试的图像:

https://i.stack.imgur.com/Q1kI7.png

您需要向GLFW请求核心上下文。检查着色器编译和链接状态/日志也是一个好主意。

试试这样的东西:

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <cmath>
#include <cstdlib>
using namespace std;
void CheckStatus( GLuint obj )
{
GLint status = GL_FALSE;
if( glIsShader(obj) )   glGetShaderiv( obj, GL_COMPILE_STATUS, &status );
if( glIsProgram(obj) )  glGetProgramiv( obj, GL_LINK_STATUS, &status );
if( status == GL_TRUE ) return;
char log[ 1 << 15 ] = { 0 };
if( glIsShader(obj) )   glGetShaderInfoLog( obj, sizeof(log), NULL, log );
if( glIsProgram(obj) )  glGetProgramInfoLog( obj, sizeof(log), NULL, log );
std::cerr << log << std::endl;
exit( -1 );
}
void AttachShader( GLuint program, GLenum type, const char* src )
{
GLuint shader = glCreateShader( type );
glShaderSource( shader, 1, &src, NULL );
glCompileShader( shader );
CheckStatus( shader );
glAttachShader( program, shader );
glDeleteShader( shader );
}
GLuint LoadProgram( const char* vert, const char* geom, const char* frag )
{
GLuint prog = glCreateProgram();
if( vert ) AttachShader( prog, GL_VERTEX_SHADER, vert );
if( geom ) AttachShader( prog, GL_GEOMETRY_SHADER, geom );
if( frag ) AttachShader( prog, GL_FRAGMENT_SHADER, frag );
glLinkProgram( prog );
CheckStatus( prog );
return prog;
}
#define GLSL(version, shader) "#version " #version "n" #shader

int main( int argc, char** argv )
{
if( !glfwInit() )
{
exit(EXIT_FAILURE);
}
glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 4 );
glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 1 );
glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL - movingtri", NULL, NULL);
if( !window )
{
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window);
GLenum err = glewInit();
if( GLEW_OK != err )
{
cerr << "glewInit() failed: " << glewGetErrorString(err) << endl;
glfwTerminate();
exit(EXIT_FAILURE);
}
const char* vert = GLSL
(
410 core,
layout (location = 0) in vec4 offset;
void main()
{
const vec4 vertices[] = vec4[]
(
vec4( 0.25, -0.25, 0.5, 1.0),
vec4(-0.25, -0.25, 0.5, 1.0),
vec4( 0.25,  0.25, 0.5, 1.0)
);
// Add 'offset' to our hard-coded vertex position
gl_Position = vertices[ gl_VertexID ] + offset;
}
);
const char* frag = GLSL
(
410 core,
out vec4 color;
void main()
{
color = vec4(0.0, 0.8, 1.0, 1.0);
}
);
GLuint program = LoadProgram( vert, NULL, frag );
GLuint vao = 0;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
while( !glfwWindowShouldClose(window) )
{
double currentTime = glfwGetTime();
int width, height;
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
// begin rendering code from movingtri
static const GLfloat green[] = { 0.0f, 0.25f, 0.0f, 1.0f };
glClearBufferfv(GL_COLOR, 0, green);
glUseProgram(program);
GLfloat attrib[] =
{
(float)sin(currentTime) * 0.5f,
(float)cos(currentTime) * 0.6f,
0.0f, 
0.0f
};
glVertexAttrib4fv(0, attrib);
glDrawArrays(GL_TRIANGLES, 0, 3);
//end rendering code
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);
}

这里也有同样的问题,但我解决了。

顶点着色器:

layout (location = 1) in vec4 offset;

程序:

glVertexAttrib4fv(1, attrib);

所以我所做的就是把位置从0改为1。其他大于0的数字也可以。我不知道为什么除了顶点位置之外,位置=0似乎被禁止用于任何数据。

有人知道吗?

最新更新