c++ - 使用 SDL2 和 OpenGL 编译一个简单的三角形
问题描述
这个问题已经在整个互联网上提出,但我尝试的每个代码示例似乎都与我个人使用 OpenGL 和 SDL2 生成简单三角形的所有尝试具有相同的结果。在切换到不同的窗口 API 之前,我的好奇心不会让我让这个困境简单地存在。
至于我要解决的问题,我只是想弄清楚源是否是我的系统(考虑到我发现的所有代码示例看起来都相似并且似乎在两台不同的计算机上都知道)或者如果我只是自己做错了什么。
我的 PC 在 ubuntu 18.04 上运行 GTX 1050m 我的驱动程序是 ubuntu ppa 上的官方 nvidia 驱动程序,它能够支持 OpenGL 4.6
这是 display.h 我用于初始化 SDL2 和 Glew 的头文件
#ifndef DISPLAY_H
#define DISPLAY_H
#include<SDL2/SDL.h>
#include<string>
class Display
{
public:
//initializes SDL2 and Glew
Display( int width, int height, const std::string& title );
//Clears the screen and creates a triangle
void Clear();
//Calls SDL_GL_SwapWindow()
void Update();
//Determines whether or not SDL_QUIT Event is called
bool IsClosed();
//Destroys application
virtual ~Display();
protected:
private:
Display( const Display& other )
void operator=( const Display& other );
SDL_Window* m_window;
SDL_GLContext m_glContext;
bool m_isClosed;
};
#endif //DISPLAY_H
这是 display.cpp
//Constructor and Destructor container
#include"display.h"
//Glew container
#include<GL/glew.h>
//Standard I\0 lib
#include<cstdio>
//Constructor
Display::Display( int width, int height, const std::string& title )
{
//SDL2 initialization and error check
if( SDL_Init( SDL_INIT_VIDEO ) != 0 ){
printf( "Unable to initialize SDL: %s\n", SDL_GetError() );
SDL_ClearError();
}
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,
SDL_GL_CONTEXT_PROFILE_COMPATIBILITY );
//SDL Create window stored in variable m_window
m_window = SDL_CreateWindow( title.c_str(),
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
width,
height,
SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE );
// Error checking window
if( !m_window ) {
fprintf( stderr, "Could not create window: %s\n", SDL_GetError() );
return;
}
//Creates OpenGL context
m_glContext = SDL_GL_CreateContext( m_window );
if ( !m_glContext ){
fprintf( stderr, "Couldn't create context: %s\n", SDL_GetError() );
return;
}
//Makes the open window the current context
SDL_GL_MakeCurrent( m_window, m_glContext );
//Checks How OpenGL handled setting
int rs, gs,bs;
SDL_GL_GetAttribute( SDL_GL_RED_SIZE, &rs );
SDL_GL_GetAttribute( SDL_GL_GREEN_SIZE, &gs );
SDL_GL_GetAttribute( SDL_GL_BLUE_SIZE, &bs );
printf( "Red size: %d, Green size: %d, Blue size: %d\n", rs, gs, bs );
//To be implemented
//glewExperimental = GL_TRUE;
//initialization of glew
GLenum status = glewInit();
if(GLEW_OK != status ){
printf( "GLEW Error: ", glewGetErrorString( status ) );
}
printf( "Status: Using GLEW: %s\n", glewGetString( GLEW_VERSION ) );
}
//Destructer
Display::~Display()
{
//Deletes GL context
SDL_GL_DeleteContext( m_glContext );
//Close and destroy the window
SDL_DestroyWindow( m_window );
//Clean up
SDL_Quit();
}
void Display::Clear()
{
//Clears the screen
glClear( GL_COLOR_BUFFER_BIT );
//Creating a triangle
glBegin( GL_POLYGON );
glColor3f( 1, 0, 0 );
glVertex3f( -0.6, -0.75, 0.5 );
glColor3f( 0, 1, 0 );
glVertex3f( 0.6, -0.75, 0 );
glColor3f( 0, 0, 1 );
glVertex3f( -0, -0.75, 0 );
glEnd();
glFlush();
}
//Closes the window on SDL_QUIT event
bool Display::IsClosed()
{
return m_isClosed;
}
void Display::Update()
{
SDL_GL_SwapWindow( m_window );
SDL_Event e;
while( SDL_PollEvent( &e ) )
{
if( e.type == SDL_QUIT )
m_isClosed = true;
}
}
最后这是我的简单 main.cpp
#include<GL/glew.h>
#include<iostream>
#include"display.h"
int main( int argc, char* argv[] )
{
Display display( 640, 480, "flagShip" );
while( !display.IsClosed() )
{
display.Clear();
display.Update();
}
return 0;
}
方便的 Makefile
CC=g++
OBJS= main.cpp
LINKER_FLAGS= -lSDL2 -lGL -lGLEW
COMPILER_FLAGS= -w -pedantic
OBJ_NAME=flagShip
$(OBJ_NAME):main.o display.o
$(CC) $(COMPILER_FLAGS) -o $(OBJ_NAME) main.o display.o $(LINKER_FLAGS)
main.o:$(OBJS) display.h
$(CC) $(COMPILER_FLAGS) -c $(OBJS)
display.o: display.cpp display.h
$(CC) $(COMPILER_FLAGS) -c display.cpp
解决方案
您不使用任何视图矩阵或投影矩阵。这意味着您必须在剪辑空间中设置三角形的顶点坐标,分别在标准化设备空间中。
标准化设备空间是一个立方体,其中左下近坐标为 (-1, -1, -1),右上远坐标为 (1, 1, 1):
x 轴到视口的投影,从左到右,y 轴的投影从底部到顶部。
由于三角形的所有 y 坐标都相等,因此三角形垂直于视口:
glVertex3f( -0.6, -0.75, 0.5 );
...
glVertex3f( 0.6, -0.75, 0 );
...
glVertex3f( -0, -0.75, 0 );
交换三角形顶点坐标的 y 分量和 z 分量,以解决问题:
glVertex3f( -0.6, 0.5, -0.75 );
...
glVertex3f( 0.6, 0.0, -0.75 );
...
glVertex3f( -0.0, 0.0, -0.75 );
预习:
推荐阅读
- image - TclTk 图像宽度始终返回零
- javascript - 如何在新行而不是主行中呈现 CKEditor5 工具栏按钮?
- python - Flask 无法识别 heroku 上的 POST 方法
- python-3.x - KeyError: (nan, '发生在索引 95')
- c# - 如何从最小到最大的C#获取字符串的长度
- javascript - csv数据日志但json数据没有?
- javascript - 如何将 Shopify 订单数据获取到产品页面
- java - 不遵守 Tomcat 连接池超时
- php - 如何在 laravel 7 中编写自我加入作为我的 php sql 查询
- r - 观星者中具有交互作用的协变量