我正在尝试使用2个三角形绘制一个红色矩形。我可以清除屏幕,但我不能让我的三角形渲染。我做错了什么?
Solid.vert着色器:
#ifndef STRINGIFY
#define STRINGIFY(a) #a
#endif
char *vsSolid = STRINGIFY(
uniform mat4 Projection;
uniform mat4 ModelView;
attribute vec4 vPosition;
void main()
{
gl_Position = Projection * ModelView * vPosition;
}
);
Solid.frag着色器:
#ifndef STRINGIFY
#define STRINGIFY(a) #a
#endif
char *fsSolid = STRINGIFY(
precision mediump float;
void main()
{
gl_FragColor = vec4( 1.0, 0, 0, 1 );
}
);
程序:
#import <Foundation/Foundation.h>
#include "SDL.h"
#include <time.h>
#include "SDL_opengles.h"
#include "SDL_opengles2.h"
#define FALSE 0
#define TRUE 1
#ifndef BOOL
#define BOOL int
#endif
#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 480
#include "Solid.vert"
#include "Solid.frag"
GLuint g_SolidProgram = 0;
BOOL g_Running = TRUE;
SDL_Window *g_SDLWindow = NULL;
SDL_Surface *g_SDLSurface = NULL;
SDL_Renderer *g_SDLRenderer = NULL;
SDL_Texture *g_SDLTexture = NULL;
int g_ScreenHeight = SCREEN_HEIGHT;
int g_ScreenWidth = SCREEN_WIDTH;
//--------------------------------------------------------------------------------------------
// BuildShader()
//--------------------------------------------------------------------------------------------
GLuint BuildShader( char *pszSource, GLenum shaderType )
{
GLuint hShader = glCreateShader( shaderType );
glShaderSource(hShader, 1, &pszSource, 0 );
glCompileShader( hShader );
GLint compileSuccess;
if( compileSuccess == GL_FALSE )
{
GLchar message[ 256 ];
glGetShaderInfoLog( hShader, sizeof( message ), 0, &message[ 0 ] );
printf( "%s\n", message );
exit( 1 );
}
return hShader;
}
//--------------------------------------------------------------------------------------------
// BuildProgram()
//--------------------------------------------------------------------------------------------
GLuint BuildProgram( char *pszVertexShaderSource, char *pszFragmentShaderSource )
{
GLuint vShader = BuildShader( pszVertexShaderSource, GL_VERTEX_SHADER );
GLuint fShader = BuildShader( pszFragmentShaderSource, GL_FRAGMENT_SHADER );
GLuint hProgram = glCreateProgram();
glAttachShader( hProgram, vShader );
glAttachShader( hProgram, fShader );
glLinkProgram( hProgram );
GLint linkSuccess;
glGetProgramiv( hProgram, GL_LINK_STATUS, &linkSuccess );
if( linkSuccess == GL_FALSE )
{
GLchar message[ 256 ];
glGetProgramInfoLog( hProgram, sizeof( message ), 0, &message[ 0 ] );
printf( "%s\n", message );
exit( 1 );
}
return hProgram;
}
//--------------------------------------------------------------------------------------------
// ApplyOrtho()
//--------------------------------------------------------------------------------------------
void ApplyOrtho( float maxX, float maxY )
{
float a = 1.0f / maxX;
float b = 1.0f / maxY;
float ortho[ 16 ] =
{
a, 0, 0, 0,
0, b, 0, 0,
0, 0, -1, 0,
0, 0, 0, 1
};
GLint uProjection = glGetUniformLocation( g_SolidProgram, "Projection" );
glUniformMatrix4fv( uProjection, 1, 0, &ortho[ 0 ] );
}
//--------------------------------------------------------------------------------------------
// ApplyRotation()
//--------------------------------------------------------------------------------------------
void ApplyRotation( float degrees )
{
float radians = degrees * 3.14159f / 180.0f;
float s = sinf( radians );
float c = cosf( radians );
float zRotation[ 16 ] =
{
c, s, 0, 0,
-s, c, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
};
GLint uModelView = glGetUniformLocation( g_SolidProgram, "ModelView" );
glUniformMatrix4fv( uModelView, 1, 0, &zRotation[ 0 ] );
}
//--------------------------------------------------------------------------------------------
// InitSDL()
//--------------------------------------------------------------------------------------------
void InitSDL( void )
{
if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
exit( -1 );
atexit( SDL_Quit );
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // *new*
SDL_DisplayMode currentDisplay;
SDL_GetCurrentDisplayMode( 0, ¤tDisplay );
g_ScreenWidth = max( currentDisplay.w, currentDisplay.h );
g_ScreenHeight = min( currentDisplay.w, currentDisplay.h );
SDL_DisplayMode displayMode;
SDL_GetDesktopDisplayMode( 0, &displayMode );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 2 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 0 );
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 24 );
g_SDLWindow = SDL_CreateWindow( "Test",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
g_ScreenWidth,
g_ScreenHeight,
/* SDL_WINDOW_FULLSCFREEN | */ SDL_WINDOW_OPENGL );
if( g_SDLWindow == NULL )
exit( -1 );
SDL_GL_CreateContext( g_SDLWindow );
glViewport( 0, 0, g_ScreenWidth, g_ScreenHeight ); // Reset The Current Viewport
glClearColor( 0.9f, 0.9f, 0.9f, 1.0f );
g_SolidProgram = BuildProgram( vsSolid, fsSolid );
glUseProgram( g_SolidProgram );
ApplyOrtho( 2, 3 );
ApplyRotation( 0 );
}
// We have to create the vertices of our triangle.
float vertices[] =
{
10.0f, 200.0f, 0.0f,
10.0f, 100.0f, 0.0f,
100.0f, 100.0f, 0.0f,
100.0f, 200.0f, 0.0f,
};
short indices[] =
{
0, 1, 2,
0, 2, 3
}; // The order of vertex rendering.
//--------------------------------------------------------------------------------------------
// Draw()
//--------------------------------------------------------------------------------------------
void Draw( int x, int y )
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
GLuint hPosition = glGetAttribLocation( g_SolidProgram, "vPosition" );
glEnableVertexAttribArray( hPosition );
// Prepare the triangle coordinate data
glVertexAttribPointer( hPosition, 3, GL_FLOAT, FALSE, 0, vertices );
// Draw the triangle
glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices );
// Disable vertex array
glDisableVertexAttribArray( hPosition );
}
//--------------------------------------------------------------------------------------------
// main()
//--------------------------------------------------------------------------------------------
int main( int argc, char* argv[] )
{
InitSDL();
SDL_Event event;
while( g_Running )
{
while( SDL_PollEvent( &event ) )
{
switch( event.type )
{
case SDL_QUIT:
g_Running = false;
break;
}
}
Draw( 100, 100 );
SDL_GL_SwapWindow( g_SDLWindow );
}
SDL_Quit();
return EXIT_SUCCESS;
}
答案 0 :(得分:0)
问题是顶点着色器中的Projection * ModelView乘数。删除它,它的工作原理..我显然不理解这是源于它的书籍内容。
更新:我使用的顶点很大。以下程序有效。我希望它可以帮助其他任何被困的人:
#import <Foundation/Foundation.h>
#include "SDL.h"
#include <time.h>
#include "SDL_opengles.h"
#include "SDL_opengles2.h"
#define FALSE 0
#define TRUE 1
#ifndef BOOL
#define BOOL int
#endif
#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 480
#include "Solid.vert"
#include "Solid.frag"
void Draw( int x, int y );
GLuint g_SolidProgram = 0;
BOOL g_Running = TRUE;
SDL_Window *g_SDLWindow = NULL;
SDL_Surface *g_SDLSurface = NULL;
SDL_Renderer *g_SDLRenderer = NULL;
SDL_Texture *g_SDLTexture = NULL;
int g_ScreenHeight = SCREEN_HEIGHT;
int g_ScreenWidth = SCREEN_WIDTH;
//--------------------------------------------------------------------------------------------
// BuildShader()
//--------------------------------------------------------------------------------------------
GLuint BuildShader( char *pszSource, GLenum shaderType )
{
GLuint hShader = glCreateShader( shaderType );
glShaderSource(hShader, 1, &pszSource, 0 );
glCompileShader( hShader );
GLint compileSuccess;
if( compileSuccess == GL_FALSE )
{
GLchar message[ 256 ];
glGetShaderInfoLog( hShader, sizeof( message ), 0, &message[ 0 ] );
printf( "%s\n", message );
exit( 1 );
}
return hShader;
}
//--------------------------------------------------------------------------------------------
// BuildProgram()
//--------------------------------------------------------------------------------------------
GLuint BuildProgram( char *pszVertexShaderSource, char *pszFragmentShaderSource )
{
GLuint vShader = BuildShader( pszVertexShaderSource, GL_VERTEX_SHADER );
GLuint fShader = BuildShader( pszFragmentShaderSource, GL_FRAGMENT_SHADER );
GLuint hProgram = glCreateProgram();
glAttachShader( hProgram, vShader );
glAttachShader( hProgram, fShader );
glLinkProgram( hProgram );
GLint linkSuccess;
glGetProgramiv( hProgram, GL_LINK_STATUS, &linkSuccess );
if( linkSuccess == GL_FALSE )
{
GLchar message[ 256 ];
glGetProgramInfoLog( hProgram, sizeof( message ), 0, &message[ 0 ] );
printf( "%s\n", message );
exit( 1 );
}
return hProgram;
}
//--------------------------------------------------------------------------------------------
// ApplyOrtho()
//--------------------------------------------------------------------------------------------
void ApplyOrtho( float maxX, float maxY )
{
float a = 1.0f / maxX;
float b = 1.0f / maxY;
float ortho[ 16 ] =
{
a, 0, 0, 0,
0, b, 0, 0,
0, 0, -1, 0,
0, 0, 0, 1
};
GLint uProjection = glGetUniformLocation( g_SolidProgram, "Projection" );
glUniformMatrix4fv( uProjection, 1, 0, &ortho[ 0 ] );
}
//--------------------------------------------------------------------------------------------
// ApplyRotation()
//--------------------------------------------------------------------------------------------
void ApplyRotation( float degrees )
{
float radians = degrees * 3.14159f / 180.0f;
float s = sinf( radians );
float c = cosf( radians );
float zRotation[ 16 ] =
{
c, s, 0, 0,
-s, c, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
};
GLint uModelView = glGetUniformLocation( g_SolidProgram, "ModelView" );
glUniformMatrix4fv( uModelView, 1, 0, &zRotation[ 0 ] );
}
//--------------------------------------------------------------------------------------------
// InitSDL()
//--------------------------------------------------------------------------------------------
void InitSDL( void )
{
if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
exit( -1 );
atexit( SDL_Quit );
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
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_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_DisplayMode currentDisplay;
SDL_GetCurrentDisplayMode( 0, ¤tDisplay );
g_ScreenWidth = max( currentDisplay.w, currentDisplay.h );
g_ScreenHeight = min( currentDisplay.w, currentDisplay.h );
SDL_DisplayMode displayMode;
SDL_GetDesktopDisplayMode( 0, &displayMode );
g_SDLWindow = SDL_CreateWindow( "Test",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
g_ScreenWidth,
g_ScreenHeight,
/* SDL_WINDOW_FULLSCFREEN | */ SDL_WINDOW_OPENGL );
if( g_SDLWindow == NULL )
exit( -1 );
SDL_GL_CreateContext( g_SDLWindow );
g_SolidProgram = BuildProgram( vsSolid, fsSolid );
glUseProgram( g_SolidProgram );
ApplyOrtho( 4, 3 );
ApplyRotation( 0 );
}
// We have to create the vertices of our triangle.
float vertices[] =
{
-0.25, -0.25, 0.0f,
-0.25, 0.25, 0,
0.25, 0.25, 0,
0.25, -0.25, 0,
};
short indices[] =
{
0, 1, 2,
0, 2, 3
}; // The order of vertex rendering.
//--------------------------------------------------------------------------------------------
// Draw()
//--------------------------------------------------------------------------------------------
void Draw( int x, int y )
{
glViewport( 0, 0, g_ScreenWidth, g_ScreenHeight ); // Reset The Current Viewport
glClearColor( 0.9f, 0.9f, 0.9f, 1.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
GLuint hPosition = glGetAttribLocation( g_SolidProgram, "vPosition" );
glEnableVertexAttribArray( hPosition );
// Prepare the triangle coordinate data
glVertexAttribPointer( hPosition, 3, GL_FLOAT, FALSE, 0, vertices );
// Draw the triangle
glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices );
// Disable vertex array
glDisableVertexAttribArray( hPosition );
}
//--------------------------------------------------------------------------------------------
// main()
//--------------------------------------------------------------------------------------------
int main( int argc, char* argv[] )
{
InitSDL();
SDL_Event event;
while( g_Running )
{
while( SDL_PollEvent( &event ) )
{
switch( event.type )
{
case SDL_QUIT:
g_Running = false;
break;
}
}
Draw( 100, 100 );
SDL_GL_SwapWindow( g_SDLWindow );
}
SDL_Quit();
return EXIT_SUCCESS;
}