我将转储所有信息。我正在使用c ++。不管我尝试什么,glClear()
都有效,渲染网格无效。没有错误。
我已经从freeglut切换到glfw。我以前没问题。我有glfw3 dll和lib,也有问题。由于外部问题未解决,我也链接了OpenGL32 lib。
我正在使用Visual Studio 2017,并且库是最新的。
我从glfw主站点获得了glfw,并下载了64位二进制文件。我从http://glew.sourceforge.net/获得了32位和64位二进制文件。我编译为64位,并在Windows 10 64位上运行。
它当前可以编译并运行,没有代码错误。
编辑: 我接受了一些建议,但仍然看不到四边形。感谢您的输入。
新代码:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <stdlib.h>
#include <stdio.h>
#include <fstream>
#include <string>
#include <iostream>
#include <vector>
GLFWwindow * window;
int width;
int height;
unsigned int vertex_array_buffer;
unsigned int vertex_buffer;
unsigned int index_buffer;
float vertex_model[24] = {
-0.5f, -0.5f, 0.0f,
0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, 0.0f,
0.0f, 1.0f, 1.0f,
0.5f, 0.5f, 0.0f,
1.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.0f,
1.0f, 0.0f, 1.0f
};
unsigned int index_model[6] = {
0, 1, 2,
0, 2, 3
};
unsigned int program;
float ratio;
int main() {
if (!glfwInit()) {
exit(-1);
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
window = glfwCreateWindow(640, 480, "RenderEngine v0.0.0", NULL, NULL);
if (!window)
{
exit(-1);
}
glfwMakeContextCurrent(window);
if (glewInit()) {
exit(-1);
}
glfwSwapInterval(1);
unsigned int vert_shader;
unsigned int frag_shader;
const char * vert_shader_text;
const char * frag_shader_text;
std::ifstream file;
std::string buffer;
size_t f_size;
file.open("shader.vert", std::ifstream::in | std::ifstream::binary);
file.seekg(0, std::ios::end);
f_size = file.tellg();
buffer.resize(f_size);
file.seekg(0);
file.read(&buffer[0], f_size);
file.close();
vert_shader_text = buffer.c_str();
buffer.clear();
file.open("shader.frag", std::ifstream::in | std::ifstream::binary);
file.seekg(0, std::ios::end);
f_size = file.tellg();
buffer.resize(f_size);
file.seekg(0);
file.read(&buffer[0], f_size);
file.close();
frag_shader_text = buffer.c_str();
vert_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vert_shader, 1, &vert_shader_text, NULL);
glCompileShader(vert_shader);
int result = GL_FALSE;
int log_length;
glGetShaderiv(vert_shader, GL_COMPILE_STATUS, &result);
glGetShaderiv(vert_shader, GL_INFO_LOG_LENGTH, &log_length);
std::vector<char> vert_shader_error((log_length > 1) ? log_length : 1);
glGetShaderInfoLog(vert_shader, log_length, NULL, &vert_shader_error[0]);
std::cout << &vert_shader_error[0] << '\n';
result = GL_FALSE;
frag_shader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(frag_shader, 1, &frag_shader_text, NULL);
glCompileShader(frag_shader);
glGetShaderiv(frag_shader, GL_COMPILE_STATUS, &result);
glGetShaderiv(frag_shader, GL_INFO_LOG_LENGTH, &log_length);
std::vector<char> frag_shader_error((log_length > 1) ? log_length : 1);
glGetShaderInfoLog(frag_shader, log_length, NULL, &frag_shader_error[0]);
std::cout << &frag_shader_error[0] << '\n';
program = glCreateProgram();
glAttachShader(program, vert_shader);
glAttachShader(program, frag_shader);
glBindAttribLocation(program, 0, "pos");
glBindAttribLocation(program, 1, "color");
glLinkProgram(program);
glDeleteShader(vert_shader);
glDeleteShader(frag_shader);
glGetProgramiv(program, GL_LINK_STATUS, &result);
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_length);
std::vector<char> program_error((log_length > 1) ? log_length : 1);
glGetProgramInfoLog(program, log_length, NULL, &program_error[0]);
std::cout << &program_error[0] << '\n';
glUseProgram(program);
glGenVertexArrays(1, &vertex_array_buffer);
glBindVertexArray(vertex_array_buffer);
glGenBuffers(1, &vertex_buffer);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_model), vertex_model, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 6, (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 6, (void*)(sizeof(float) * 3));
glGenBuffers(1, &index_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(index_model), index_model, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
if (glGetError()) {
exit(-1);
}
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
while (!glfwWindowShouldClose(window))
{
glfwGetFramebufferSize(window, &width, &height);
ratio = width / (float)height;
glViewport(0, 0, width, height);
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(vertex_array_buffer);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
glBindVertexArray(0);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}
如果需要,还可以使用着色器文件。顶点着色器:
#version 330
in layout(location = 0) vec3 pos;
in layout(location = 1) vec3 color;
out vec3 out_color;
void main() {
gl_Position = vec4(pos, 1.0f);
out_color = color;
}
片段着色器:
#version 330
in vec3 out_color;
out vec4 final_color;
void main() {
final_color = vec4(out_color, 1.0f);
}
答案 0 :(得分:2)
一些问题:
如今,甚至 Intel 也支持OpenGL 3.3 Core上下文。请求一个:
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
验证您的着色器是否实际编译/链接。在我的系统上,顶点着色器失败,并显示以下信息:
Vertex shader failed to compile with the following errors:
ERROR: 0:3: error(#12) Unexpected qualifier
ERROR: 0:4: error(#12) Unexpected qualifier
ERROR: error(#273) 2 compilation errors. No code generated
layout()
应该放在in
之前:
layout(location = 0) in vec3 pos;
layout(location = 1) in vec3 color;
取消绑定VAO后,请取消绑定GL_ELEMENT_ARRAY_BUFFER
。
index_model
正在从vertex_model
的结尾开始索引。除非您喜欢在OpenGL驱动程序内部降低访问冲突,否则不要这样做:)
屏幕截图:
一起:
#include <GL/glew.h>
#include <glfw/glfw3.h>
#include <iostream>
#include <cstdarg>
struct Program
{
static GLuint Load( const char* shader, ... )
{
GLuint prog = glCreateProgram();
va_list args;
va_start( args, shader );
while( shader )
{
const GLenum type = va_arg( args, GLenum );
AttachShader( prog, type, shader );
shader = va_arg( args, const char* );
}
va_end( args );
glLinkProgram( prog );
CheckStatus( prog );
return prog;
}
private:
static 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;
GLchar 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;
std::exit( EXIT_FAILURE );
}
static 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 );
}
};
const char* vert = 1 + R"GLSL(
#version 330 core
layout(location = 0) in vec3 pos;
layout(location = 1) in vec3 color;
out vec3 out_color;
void main() {
gl_Position = vec4(pos, 1.0f);
out_color = color;
}
)GLSL";
const char* frag = 1 + R"GLSL(
#version 330 core
in vec3 out_color;
out vec4 final_color;
void main() {
final_color = vec4(out_color, 1.0f);
}
)GLSL";
GLFWwindow * window;
int width;
int height;
unsigned int vertex_array_buffer;
unsigned int vertex_buffer;
unsigned int index_buffer;
float vertex_model[] =
{
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f,
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f,
0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f,
};
unsigned int index_model[] =
{
0, 1, 2,
};
unsigned int program;
float ratio;
int main()
{
if( !glfwInit() )
{
exit( -1 );
}
glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 );
glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 3 );
glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
window = glfwCreateWindow( 640, 480, "RenderEngine v0.0.0", NULL, NULL );
if( !window )
{
exit( -1 );
}
glfwMakeContextCurrent( window );
if( glewInit() )
{
exit( -1 );
}
glfwSwapInterval( 1 );
GLuint program = Program::Load( vert, GL_VERTEX_SHADER, frag, GL_FRAGMENT_SHADER, NULL );
glUseProgram( program );
glGenVertexArrays( 1, &vertex_array_buffer );
glBindVertexArray( vertex_array_buffer );
glGenBuffers( 1, &vertex_buffer );
glBindBuffer( GL_ARRAY_BUFFER, vertex_buffer );
glBufferData( GL_ARRAY_BUFFER, sizeof( vertex_model ), vertex_model, GL_STATIC_DRAW );
glEnableVertexAttribArray( 0 );
glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, sizeof( float ) * 6, (void*)0 );
glEnableVertexAttribArray( 1 );
glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, sizeof( float ) * 6, (void*)( sizeof( float ) * 3 ) );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
glGenBuffers( 1, &index_buffer );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, index_buffer );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( index_model ), index_model, GL_STATIC_DRAW );
glBindVertexArray( 0 );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
while( !glfwWindowShouldClose( window ) )
{
glfwGetFramebufferSize( window, &width, &height );
ratio = width / (float)height;
glViewport( 0, 0, width, height );
glClear( GL_COLOR_BUFFER_BIT );
glBindVertexArray( vertex_array_buffer );
glDrawElements( GL_TRIANGLES, 3, GL_UNSIGNED_INT, nullptr );
glBindVertexArray( 0 );
glfwSwapBuffers( window );
glfwPollEvents();
}
glfwDestroyWindow( window );
glfwTerminate();
return 0;
}
答案 1 :(得分:1)
glVertexAttribPointer
接受传递的参数和当前绑定的VBO ,并将该信息保存在当前绑定的VAO状态内。
glEnableVertexAttribArray
也会在当前绑定的VAO中启用属性。您启用它们为时过早。
因此,正确的处理顺序是:
glVertexAttribPointer
和glEnableVertexAttribArray
索引缓冲区应放置在1-5之间的任何位置。请注意不要在VAO仍绑定的情况下意外地解除索引缓冲区的绑定。因为VAO只记住一个索引缓冲区。
除了那些早期的电话,我再也没有发现错误。
通过将glVertexAttribPointer
的功能分为glVertexArrayAttribBinding
,glVertexArrayAttribFormat
和glBindVertexBuffer
,在OpenGL 4.5中“揭示了”对VBO的这种“隐藏”捕获。
答案 2 :(得分:1)
命名的index buffer对象是vertex array object状态向量的状态。
如果执行glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)
,则在绑定顶点数组对象时,对元素缓冲区的引用将被破坏。
删除glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
,以解决此问题:
glGenVertexArrays(1, &vertex_array_buffer);
glBindVertexArray(vertex_array_buffer);
// [...]
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
// [...]
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // <---- skip this
glBindVertexArray(0);
在顶点数组中有4个坐标和颜色属性,因此索引必须在[0,3]范围内。坐标排列在一个四边形中,一个四边形可以由2个三角形绘制,如下所示:
1 2
+-------+
| / |
| / |
| / |
+-------+
0 3
unsigned int index_model[6] = {
0, 1, 2,
0, 2, 3
};