我的 opengl 代码应该显示多个立方体,但只显示一个正方形
Posted
技术标签:
【中文标题】我的 opengl 代码应该显示多个立方体,但只显示一个正方形【英文标题】:My opengl code should display multiple cubes but only displays a single square 【发布时间】:2019-01-07 22:36:47 【问题描述】:我正在尝试运行一些代码,该代码应该使用矩阵变换来渲染多个立方体,以将一个立方体坐标转换到其他位置。但是我很确定矩阵不起作用,因为所有渲染的是原始立方体而没有被转换。
我在网上查看了问题可能是什么,发现我应该将我的矩阵初始化为我已经完成的身份矩阵,但我仍然看不到任何影响。这是我的代码:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "GLCALL.h"
#include <stb_image.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <shader.h>
#include <iostream>
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow *window);
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
int main()
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "CurrentProject1", NULL, NULL);
if (window == NULL)
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
if (glewInit() != GLEW_OK)
std::cout << "error not goeerrd\n";
GLCall(glEnable(GL_DEPTH_TEST));
float vertices[] = -0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f ;
glm::vec3 cubePositions[] = glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3(2.0f, 5.0f, -15.0f),
glm::vec3(-1.5f, -2.2f, -2.5f),
glm::vec3(-3.8f, -2.0f, -12.3f),
glm::vec3(2.4f, -0.4f, -3.5f),
glm::vec3(-1.7f, 3.0f, -7.5f),
glm::vec3(1.3f, -2.0f, -2.5f),
glm::vec3(1.5f, 2.0f, -2.5f),
glm::vec3(1.5f, 0.2f, -1.5f),
glm::vec3(-1.3f, 1.0f, -1.5f) ;
unsigned int VBO, VAO;
GLCall(glGenVertexArrays(1, &VAO));
GLCall(glGenBuffers(1, &VBO));
GLCall(glBindVertexArray(VAO));
GLCall(glBindBuffer(GL_ARRAY_BUFFER, VBO));
GLCall(glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW));
GLCall(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0));
GLCall(glEnableVertexAttribArray(0));
GLCall(glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))));
GLCall(glEnableVertexAttribArray(1));
GLCall(unsigned int s_ID = glCreateProgram());
GLCall(unsigned int vs_ID = glCreateShader(GL_VERTEX_SHADER));
GLCall(unsigned int fs_ID = glCreateShader(GL_FRAGMENT_SHADER));
const std::string vs_string = "#version 330 core\n"
"layout (location = 0) in vec3 position;\n"
"uniform mat4 model;\n"
"uniform mat4 view;\n"
"uniform mat4 projection;\n"
"\n"
"void main()\n"
"\n"
"gl_Position = projection * view * model * vec4(position, 1.0f);\n"
"\n";
const std::string fs_string = "#version 330 core\n"
"out vec4 color;\n"
"void main()\n"
"\n"
"color = vec4(1.0f, 0.5f, 0.2f, 1.0f)\n;"
"\n";
const char* vs_char = vs_string.c_str();
const char* fs_char = fs_string.c_str();
std::cout << *vs_char;
GLCall(glShaderSource(vs_ID, 1, &vs_char, NULL));
GLCall(glShaderSource(fs_ID, 1, &fs_char, NULL));
GLCall(glCompileShader(vs_ID));
int result;
GLCall(glGetShaderiv(vs_ID, GL_COMPILE_STATUS, &result));
if (result == GL_FALSE)
int length;
GLCall(glGetShaderiv(vs_ID, GL_INFO_LOG_LENGTH, &length));
char * message = (char*)alloca(length * sizeof(char));
GLCall(glGetShaderInfoLog(vs_ID, length, &length, message));
std::cout << "failed to compile vertexing shader" << std::endl;
std::cout << message << std::endl;
GLCall(glDeleteShader(vs_ID));
GLCall(glCompileShader(fs_ID));
int result1;
GLCall(glGetShaderiv(fs_ID, GL_COMPILE_STATUS, &result1));
if (result1 == GL_FALSE)
int length1;
GLCall(glGetShaderiv(fs_ID, GL_INFO_LOG_LENGTH, &length1));
char * message = (char*)alloca(length1 * sizeof(char));
GLCall(glGetShaderInfoLog(fs_ID, length1, &length1, message));
std::cout << "failed to compile fragmenting shader" << std::endl;
std::cout << message << std::endl;
GLCall(glDeleteShader(fs_ID));
GLCall((s_ID, vs_ID));
GLCall(glAttachShader(s_ID, fs_ID));
GLCall(glLinkProgram(s_ID));
GLCall(glDeleteShader(vs_ID));
GLCall(glDeleteShader(fs_ID));
GLCall(glUseProgram(s_ID));
while (!glfwWindowShouldClose(window))
processInput(window);
GLCall(glClearColor(0.2f, 0.3f, 0.3f, 1.0f));
GLCall(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
glm::mat4 view = glm::mat4(1.0f);
glm::mat4 projection = glm::mat4(1.0f);
projection = glm::perspective(glm::radians(45.0f), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
const std::string temp1 = "projection";
const std::string temp2 = "view";
const std::string temp3 = "model";
GLCall(glUniformMatrix4fv(glGetUniformLocation(s_ID, temp1.c_str()), 1, GL_FALSE, &projection[0][0]));
GLCall(glUniformMatrix4fv(glGetUniformLocation(s_ID, temp2.c_str()), 1, GL_FALSE, &view[0][0]));
GLCall(glPolygonMode(GL_FRONT_AND_BACK, GL_LINE));
GLCall(glBindVertexArray(VAO));
for (unsigned int i = 0; i < 10; i++)
glm::mat4 model = glm::mat4(1.0f);
model = glm::translate(model, cubePositions[i]);
float angle = 20.0f * i;
model = glm::rotate(model, glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f));
GLCall(glUniformMatrix4fv(glGetUniformLocation(s_ID, temp3.c_str()), 1, GL_FALSE, &model[0][0]));
GLCall(glDrawArrays(GL_TRIANGLES, 0, 36));
glfwSwapBuffers(window);
glfwPollEvents();
GLCall(glDeleteVertexArrays(1, &VAO));
GLCall(glDeleteBuffers(1, &VBO));
glfwTerminate();
return 0;
void processInput(GLFWwindow *window)
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
GLCall(glViewport(0, 0, width, height));
我希望多个立方体在透视投影中呈现在不同的位置,但是我看到如果根本不包含矩阵会看到什么,只是一个带有原始立方体坐标的立方体。是什么阻止了矩阵的工作?
【问题讨论】:
【参考方案1】:有点奇怪,你只有一个 glAttachShader()
电话。
我可以看到多个带有 GLM 0.9.9.2 和已知良好着色器加载器的立方体:
代码:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#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 position;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
gl_Position = projection * view * model * vec4(position, 1.0f);
;
)GLSL";
const char* frag = 1 + R"GLSL(
#version 330 core
out vec4 color;
void main()
color = vec4(1.0f, 0.5f, 0.2f, 1.0f);
;
)GLSL";
void framebuffer_size_callback( GLFWwindow* window, int width, int height );
void processInput( GLFWwindow *window );
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
int main()
glfwInit();
glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 );
glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 3 );
glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
GLFWwindow* window = glfwCreateWindow( SCR_WIDTH, SCR_HEIGHT, "CurrentProject1", NULL, NULL );
if( window == NULL )
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
glfwMakeContextCurrent( window );
glfwSetFramebufferSizeCallback( window, framebuffer_size_callback );
if( glewInit() != GLEW_OK )
std::cout << "error not goeerrd\n";
glEnable( GL_DEPTH_TEST );
float vertices[] =
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
;
glm::vec3 cubePositions[] =
glm::vec3( 0.0f, 0.0f, 0.0f ),
glm::vec3( 2.0f, 5.0f, -15.0f ),
glm::vec3( -1.5f, -2.2f, -2.5f ),
glm::vec3( -3.8f, -2.0f, -12.3f ),
glm::vec3( 2.4f, -0.4f, -3.5f ),
glm::vec3( -1.7f, 3.0f, -7.5f ),
glm::vec3( 1.3f, -2.0f, -2.5f ),
glm::vec3( 1.5f, 2.0f, -2.5f ),
glm::vec3( 1.5f, 0.2f, -1.5f ),
glm::vec3( -1.3f, 1.0f, -1.5f ),
;
unsigned int VBO, VAO;
glGenVertexArrays( 1, &VAO );
glGenBuffers( 1, &VBO );
glBindVertexArray( VAO );
glBindBuffer( GL_ARRAY_BUFFER, VBO );
glBufferData( GL_ARRAY_BUFFER, sizeof( vertices ), vertices, GL_STATIC_DRAW );
glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof( float ), (void*)0 );
glEnableVertexAttribArray( 0 );
glVertexAttribPointer( 1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof( float ), (void*)( 3 * sizeof( float ) ) );
glEnableVertexAttribArray( 1 );
GLuint s_ID = Program::Load( vert, GL_VERTEX_SHADER, frag, GL_FRAGMENT_SHADER, NULL );
glUseProgram( s_ID );
while( !glfwWindowShouldClose( window ) )
processInput( window );
glClearColor( 0.2f, 0.3f, 0.3f, 1.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glm::mat4 view = glm::mat4( 1.0f );
glm::mat4 projection = glm::mat4( 1.0f );
projection = glm::perspective( glm::radians( 45.0f ), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f );
view = glm::translate( view, glm::vec3( 0.0f, 0.0f, -3.0f ) );
const std::string temp1 = "projection";
const std::string temp2 = "view";
const std::string temp3 = "model";
glUniformMatrix4fv( glGetUniformLocation( s_ID, temp1.c_str() ), 1, GL_FALSE, &projection[ 0 ][ 0 ] );
glUniformMatrix4fv( glGetUniformLocation( s_ID, temp2.c_str() ), 1, GL_FALSE, &view[ 0 ][ 0 ] );
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
glBindVertexArray( VAO );
for( unsigned int i = 0; i < 10; i++ )
glm::mat4 model = glm::mat4( 1.0f );
model = glm::translate( model, cubePositions[ i ] );
float angle = 20.0f * i;
model = glm::rotate( model, glm::radians( angle ), glm::vec3( 1.0f, 0.3f, 0.5f ) );
glUniformMatrix4fv( glGetUniformLocation( s_ID, temp3.c_str() ), 1, GL_FALSE, &model[ 0 ][ 0 ] );
glDrawArrays( GL_TRIANGLES, 0, 36 );
glfwSwapBuffers( window );
glfwPollEvents();
glDeleteVertexArrays( 1, &VAO );
glDeleteBuffers( 1, &VBO );
glfwTerminate();
return 0;
void processInput( GLFWwindow *window )
if( glfwGetKey( window, GLFW_KEY_ESCAPE ) == GLFW_PRESS )
glfwSetWindowShouldClose( window, true );
void framebuffer_size_callback( GLFWwindow* window, int width, int height )
glViewport( 0, 0, width, height );
【讨论】:
以上是关于我的 opengl 代码应该显示多个立方体,但只显示一个正方形的主要内容,如果未能解决你的问题,请参考以下文章