我已经遵循了几个教程,例子:
然而,我无法使用glClearColor
(在MacOS和Linux上尝试过它)来渲染纯色以外的东西。
这是我目前所拥有的一个简单的cmake,其中包含lazyfoo的修改示例以便编译它(只更改了标题的路径):
/*This source code copyrighted by Lazy Foo' Productions (2004-2015)
and may not be redistributed without written permission.*/
//Using SDL, SDL OpenGL, GLEW, standard IO, and strings
#include <SDL2/SDL.h>
#include <GL/glew.h>
#include <SDL2/SDL_opengl.h>
#include <stdio.h>
#include <string>
//Screen dimension constants
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
//Starts up SDL, creates window, and initializes OpenGL
bool init();
//Initializes rendering program and clear color
bool initGL();
//Input handler
void handleKeys( unsigned char key, int x, int y );
//Per frame update
void update();
//Renders quad to the screen
void render();
//Frees media and shuts down SDL
void close();
//Shader loading utility programs
void printProgramLog( GLuint program );
void printShaderLog( GLuint shader );
//The window we'll be rendering to
SDL_Window* gWindow = NULL;
//OpenGL context
SDL_GLContext gContext;
//Render flag
bool gRenderQuad = true;
//Graphics program
GLuint gProgramID = 0;
GLint gVertexPos2DLocation = -1;
GLuint gVBO = 0;
GLuint gIBO = 0;
bool init()
{
//Initialization flag
bool success = true;
//Initialize SDL
if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
{
printf( "SDL could not initialize! SDL Error: %s\n", SDL_GetError() );
success = false;
}
else
{
//Use OpenGL 3.1 core
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 1 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE );
//Create window
gWindow = SDL_CreateWindow( "SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN );
if( gWindow == NULL )
{
printf( "Window could not be created! SDL Error: %s\n", SDL_GetError() );
success = false;
}
else
{
//Create context
gContext = SDL_GL_CreateContext( gWindow );
if( gContext == NULL )
{
printf( "OpenGL context could not be created! SDL Error: %s\n", SDL_GetError() );
success = false;
}
else
{
//Initialize GLEW
glewExperimental = GL_TRUE;
GLenum glewError = glewInit();
if( glewError != GLEW_OK )
{
printf( "Error initializing GLEW! %s\n", glewGetErrorString( glewError ) );
}
//Use Vsync
if( SDL_GL_SetSwapInterval( 1 ) < 0 )
{
printf( "Warning: Unable to set VSync! SDL Error: %s\n", SDL_GetError() );
}
//Initialize OpenGL
if( !initGL() )
{
printf( "Unable to initialize OpenGL!\n" );
success = false;
}
}
}
}
return success;
}
bool initGL()
{
//Success flag
bool success = true;
//Generate program
gProgramID = glCreateProgram();
//Create vertex shader
GLuint vertexShader = glCreateShader( GL_VERTEX_SHADER );
//Get vertex source
const GLchar* vertexShaderSource[] =
{
"#version 140\nin vec2 LVertexPos2D; void main() { gl_Position = vec4( LVertexPos2D.x, LVertexPos2D.y, 0, 1 ); }"
};
//Set vertex source
glShaderSource( vertexShader, 1, vertexShaderSource, NULL );
//Compile vertex source
glCompileShader( vertexShader );
//Check vertex shader for errors
GLint vShaderCompiled = GL_FALSE;
glGetShaderiv( vertexShader, GL_COMPILE_STATUS, &vShaderCompiled );
if( vShaderCompiled != GL_TRUE )
{
printf( "Unable to compile vertex shader %d!\n", vertexShader );
printShaderLog( vertexShader );
success = false;
}
else
{
//Attach vertex shader to program
glAttachShader( gProgramID, vertexShader );
//Create fragment shader
GLuint fragmentShader = glCreateShader( GL_FRAGMENT_SHADER );
//Get fragment source
const GLchar* fragmentShaderSource[] =
{
"#version 140\nout vec4 LFragment; void main() { LFragment = vec4( 1.0, 1.0, 1.0, 1.0 ); }"
};
//Set fragment source
glShaderSource( fragmentShader, 1, fragmentShaderSource, NULL );
//Compile fragment source
glCompileShader( fragmentShader );
//Check fragment shader for errors
GLint fShaderCompiled = GL_FALSE;
glGetShaderiv( fragmentShader, GL_COMPILE_STATUS, &fShaderCompiled );
if( fShaderCompiled != GL_TRUE )
{
printf( "Unable to compile fragment shader %d!\n", fragmentShader );
printShaderLog( fragmentShader );
success = false;
}
else
{
//Attach fragment shader to program
glAttachShader( gProgramID, fragmentShader );
//Link program
glLinkProgram( gProgramID );
//Check for errors
GLint programSuccess = GL_TRUE;
glGetProgramiv( gProgramID, GL_LINK_STATUS, &programSuccess );
if( programSuccess != GL_TRUE )
{
printf( "Error linking program %d!\n", gProgramID );
printProgramLog( gProgramID );
success = false;
}
else
{
//Get vertex attribute location
gVertexPos2DLocation = glGetAttribLocation( gProgramID, "LVertexPos2D" );
if( gVertexPos2DLocation == -1 )
{
printf( "LVertexPos2D is not a valid glsl program variable!\n" );
success = false;
}
else
{
//Initialize clear color
glClearColor( 0.f, 0.f, 0.f, 1.f );
//VBO data
GLfloat vertexData[] =
{
-0.5f, -0.5f,
0.5f, -0.5f,
0.5f, 0.5f,
-0.5f, 0.5f
};
//IBO data
GLuint indexData[] = { 0, 1, 2, 3 };
//Create VBO
glGenBuffers( 1, &gVBO );
glBindBuffer( GL_ARRAY_BUFFER, gVBO );
glBufferData( GL_ARRAY_BUFFER, 2 * 4 * sizeof(GLfloat), vertexData, GL_STATIC_DRAW );
//Create IBO
glGenBuffers( 1, &gIBO );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, gIBO );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, 4 * sizeof(GLuint), indexData, GL_STATIC_DRAW );
}
}
}
}
return success;
}
void handleKeys( unsigned char key, int x, int y )
{
//Toggle quad
if( key == 'q' )
{
gRenderQuad = !gRenderQuad;
}
}
void update()
{
//No per frame update needed
}
void render()
{
//Clear color buffer
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
//Render quad
if( gRenderQuad )
{
//Bind program
glUseProgram( gProgramID );
//Enable vertex position
glEnableVertexAttribArray( gVertexPos2DLocation );
//Set vertex data
glBindBuffer( GL_ARRAY_BUFFER, gVBO );
glVertexAttribPointer( gVertexPos2DLocation, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), NULL );
//Set index data and render
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, gIBO );
glDrawElements( GL_TRIANGLE_FAN, 4, GL_UNSIGNED_INT, NULL );
//Disable vertex position
glDisableVertexAttribArray( gVertexPos2DLocation );
//Unbind program
glUseProgram( NULL );
}
}
void close()
{
//Deallocate program
glDeleteProgram( gProgramID );
//Destroy window
SDL_DestroyWindow( gWindow );
gWindow = NULL;
//Quit SDL subsystems
SDL_Quit();
}
void printProgramLog( GLuint program )
{
//Make sure name is shader
if( glIsProgram( program ) )
{
//Program log length
int infoLogLength = 0;
int maxLength = infoLogLength;
//Get info string length
glGetProgramiv( program, GL_INFO_LOG_LENGTH, &maxLength );
//Allocate string
char* infoLog = new char[ maxLength ];
//Get info log
glGetProgramInfoLog( program, maxLength, &infoLogLength, infoLog );
if( infoLogLength > 0 )
{
//Print Log
printf( "%s\n", infoLog );
}
//Deallocate string
delete[] infoLog;
}
else
{
printf( "Name %d is not a program\n", program );
}
}
void printShaderLog( GLuint shader )
{
//Make sure name is shader
if( glIsShader( shader ) )
{
//Shader log length
int infoLogLength = 0;
int maxLength = infoLogLength;
//Get info string length
glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &maxLength );
//Allocate string
char* infoLog = new char[ maxLength ];
//Get info log
glGetShaderInfoLog( shader, maxLength, &infoLogLength, infoLog );
if( infoLogLength > 0 )
{
//Print Log
printf( "%s\n", infoLog );
}
//Deallocate string
delete[] infoLog;
}
else
{
printf( "Name %d is not a shader\n", shader );
}
}
int main( int argc, char* args[] )
{
//Start up SDL and create window
if( !init() )
{
printf( "Failed to initialize!\n" );
}
else
{
//Main loop flag
bool quit = false;
//Event handler
SDL_Event e;
//Enable text input
SDL_StartTextInput();
//While application is running
while( !quit )
{
//Handle events on queue
while( SDL_PollEvent( &e ) != 0 )
{
//User requests quit
if( e.type == SDL_QUIT )
{
quit = true;
}
//Handle keypress with current mouse position
else if( e.type == SDL_TEXTINPUT )
{
int x = 0, y = 0;
SDL_GetMouseState( &x, &y );
handleKeys( e.text.text[ 0 ], x, y );
}
}
//Render quad
render();
//Update screen
SDL_GL_SwapWindow( gWindow );
}
//Disable text input
SDL_StopTextInput();
}
//Free resources and close SDL
close();
return 0;
}
的CMakeLists.txt:
cmake_minimum_required(VERSION 2.6)
project(wrench)
find_package(PkgConfig REQUIRED)
## PROJECT
set(PROJECT_NAME "wrench")
# for threading we need c11 std.
add_definitions("-std=c++11")
# source files go in src directory.
file(GLOB_RECURSE ${PROJECT_NAME}_SOURCES "${CMAKE_SOURCE_DIR}/src/*.cpp")
add_executable(${PROJECT_NAME} ${wrench_SOURCES})
# headers are placed along the source files and vendor directory can be used to
# have other libraries like LuaBridge.
include_directories(
"src"
"vendor"
)
## LIBRARIES
# Lua
find_package(Lua51 REQUIRED)
include_directories(${LUA_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} ${LUA_LIBRARIES})
# OpenGL
find_package(OpenGL REQUIRED)
include_directories(${OpenGL_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} ${OPENGL_LIBRARIES})
# GLEW
find_package(GLEW REQUIRED)
include_directories(${GLEW_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} ${GLEW_LIBRARIES})
# SDL2
find_package(SDL2 REQUIRED)
include_directories(${SDL2_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} ${SDL2_LIBRARIES})
pkg_search_module(SDL2_image REQUIRED SDL2_image)
target_link_libraries(${PROJECT_NAME} ${SDL2_image_LIBRARIES})
# BOOST
find_package(Boost 1.62.0 COMPONENTS filesystem system)
include_directories(${Boost_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES})
它应该渲染一个四边形,但我得到的只是一个黑屏:
有什么建议可以解决这个问题吗?