我试图在带有SDL的OpenGL中显示简单的白色立方体。我已经这样设置了VBO和IBO:
GLfloat vertexData[] =
{
-0.5f, -0.5f, -0.5f, // bot, left, back
-0.5f, 0.5f, -0.5f, // top, left, back
-0.5f, -0.5f, 0.5f, // bot, left, front
-0.5f, 0.5f, 0.5f, // top, left, front
0.5f, -0.5f, -0.5f, // bot, right, back
0.5f, -0.5f, 0.5f, // bot, right, front
0.5f, 0.5f, -0.5f, // top, right, back
0.5f, 0.5f, 0.5f // top, right, front
};
GLint indexData[] =
{
//back
0, 1, 6,
0, 5, 6,
//left
0, 2, 3,
0, 1, 3,
//right
4, 5, 7,
4, 6, 7,
//bot
0, 4, 5,
0, 2, 5,
//top
1, 3, 7,
1, 6, 7,
//front
2, 3, 7,
2, 5, 7
};
但是,它看起来像这样:
我究竟做错了什么?
编辑:
我的初始化功能
bool App::OpenGLInit()
{
programID = glCreateProgram();
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
std::string vertexString = getShaderFromFile("src/shader.vert");
const GLchar * vertexShaderSource = vertexString.c_str();
glShaderSource(vertexShader, 1, (const GLchar **)&vertexShaderSource, NULL);
glCompileShader(vertexShader);
glAttachShader(programID, vertexShader);
GLuint fragmentShader = glCreateShader( GL_FRAGMENT_SHADER );
//Get fragment source
std::string fragmentString = getShaderFromFile("src/shader.frag");
const GLchar* fragmentShaderSource = fragmentString.c_str();
//Set fragment source
glShaderSource( fragmentShader, 1, (const GLchar **)&fragmentShaderSource, NULL );
//Compile fragment source
glCompileShader( fragmentShader );
glAttachShader(programID, fragmentShader );
glLinkProgram(programID);
return true;
}
bool App::OnInit()
{
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 2 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE );
if(SDL_Init(SDL_INIT_EVERYTHING) < 0) {
return false;
}
if((screen = SDL_CreateWindow("Color Wars", 100, 100, 1024, 600, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN)) == NULL) {
return false;
}
if ((gl_context = SDL_GL_CreateContext(screen)) == NULL)
{
return false;
}
if((renderer = SDL_CreateRenderer(screen, -1, 0)) == NULL)
{
return false;
}
if (SDL_GL_SetSwapInterval(1) < 0)
return false;
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK)
{
return false;
}
if (!OpenGLInit())
return false;
game_screen = new GameScreen();
game_screen->Init(programID);
return true;
}
我的渲染功能:
void App::OnRender()
{
glClear( GL_COLOR_BUFFER_BIT );
glUseProgram( programID );
game_screen->Render(renderer);
glUseProgram( NULL );
SDL_GL_SwapWindow(screen);
}
void GameScreen::Render(SDL_Renderer *renderer)
{
//Enable vertex position
glEnableVertexAttribArray(vertex2DPosition);
//Set vertex data
glBindBuffer( GL_ARRAY_BUFFER, VBO );
glVertexAttribPointer(vertex2DPosition, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), NULL );
//Set index data and render
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, IBO );
glDrawElements(GL_TRIANGLE_FAN, 12, GL_UNSIGNED_INT, NULL );
//Disable vertex position
glDisableVertexAttribArray( vertex2DPosition );
}
虚拟文字:asdasdasdasdasdasd
最佳答案
在此示例中,有三件事对您不利:
您正在标准化设备坐标中绘制一个多维数据集,其范围为XYZ:[-1,1]。
您正在绘制到一个非正方形的窗口中,所以立方体的面会被拉伸,因为坐标空间与窗口的大小无关。
它似乎是一个矩形,因为您尚未定义任何观看变换,并且正对着它而没有透视图。
如果在调整窗口大小时执行以下所有操作,则可以更正所有这些:
GLfloat aspect = (GLfloat)width / (GLfloat)height;
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glOrtho ((-1.0f * aspect), (1.0f * aspect), -1.0f, 1.0f, -1.0f, 1.0f);
glViewport (0, 0, width, height);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
glRotatef (45.0f, 0.25f, 0.5f, 0.75f); // Let's rotate this sucker!
其中width和height分别是SDL窗口的宽度和高度。
更新:
瞧,现在很清楚为什么这没有用。您从未在问题中提到使用着色器。感谢您发布更新的代码。为了使此功能与着色器一起使用,您需要传递投影和Modelview矩阵。您可以使用与我使用旧的OpenGL矩阵操作函数所描述的相同的设置来构建矩阵,而
glm
可能最简单。关于c - 带有SDL的OpenGL,我在做什么错?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18879124/