带有着色器程序且没有错误的现代 OpenGL 黑屏
Posted
技术标签:
【中文标题】带有着色器程序且没有错误的现代 OpenGL 黑屏【英文标题】:Modern OpenGL Black Screen with shader program and no errors 【发布时间】:2020-07-03 01:14:17 【问题描述】:我没有错误,但是当我运行程序时,我只有一个黑屏,我应该有两个三角形:
#include <iostream> //includes C++ i/o stream
#include <GL/glew.h> //includes glew header
#include <GL/freeglut.h> //includes freeglut header
using namespace std; //Uses the standard namespace
#define WINDOW_TITLE "3-1 Assignment" //Macro for window title
//Vertex and Fragment shader source macro
#ifndef GLSL
#define GLSL(Version, Source) "#version " #Version "\n" #Source
#endif
//Windows Variables for height and width
int WindowWidth=800, WindowHeight=600;
/*User-defined function prototypes to: initialize the program, set the window size, redraw graphics on the window when resized and render graphics on the screen*/
void UInitalize(int, char*[]);
void UInitWindow(int, char*[]);
void UResizeWindow(int, int);
void URenderGraphics(void);
void UCreateShaders(void);
void UCreateVBO();
//Vertex and Shader program source code
const GLchar * VertexShader = GLSL(440,
//Receive Vertex coordinates from attribute
in layout(location=0) vec4 vertex_Position;
//for attribute 1 expect vec(4) floats passed into the vertex shader
in layout(location=1) vec4 colorFromVBO;
//Declare a vec4 variable that will reference the vertex colors passed into the vertex shader from the buffer
out vec4 colorFromVShader;
void main()
//Sends vertex positions
gl_Position= vertex_Position;
//References vertex colors sent from the buffer
colorFromVShader= colorFromVBO;
);
const GLchar * FragmentShader = GLSL(440,
//vertex colors from the shader
in vec4 colorFromVShader;
//vec 4 variable that will reference vertex colors passed into the fragment shader from the vertex shader
out vec4 vertex_color;
void main()
//gl_FragCOlor= vec4(0.0, 1.0, 0.0, 1.0);
vertex_Color= colorFromVShader;
);
//Main Function
int main(int argc, char* argv[])
UInitalize(argc, argv); //Initialize openGL program
glutMainLoop(); //Starts openGL loop in background
exit(EXIT_SUCCESS); //Ends the program
//Implements createVBO function
void UCreateVBO(void)
// Specifies Coordinates
GLfloat verts[]=
/*index 0*/
-1.0f, 1.0f, // top-center of the screen
1.0f, 0.0f, 0.0f, 1.0f, // Red vertex
/*index 1*/
-1.0f, 0.0f, // bottom-left of the screen
0.0f, 0.0f, 1.0f, 1.0f, // Blue vertex
/*index 2*/
-0.5f, 0.0f, // bottom-right of the screen
0.0f, 1.0f, 0.0f, 1.0f, // Green vertex
/*index 3*/
0.0f, 0.0f, // bottom-left of the screen
1.0f, 0.0f, 0.0f, 1.0f, // Red vertex
/*index 4*/
0.0f, -1.0f, // bottom-right of the screen
0.0f, 1.0f, 0.0f, 1.0f, // Green vertex
;
//Stores the size of the verts array
float numVertices= sizeof(verts);
//Variable for the vertex buffer object id
GLuint myBufferID;
//creates 1 buffer
glGenBuffers(1, &myBufferID);
//Activates the buffer
glBindBuffer(GL_ARRAY_BUFFER, myBufferID);
//Sends vertex data to the GPU
glBufferData(GL_ARRAY_BUFFER, numVertices, verts, GL_STATIC_DRAW);
//Creates vertex attribute pointer
//Number of coordinates per vertex
GLuint floatsPerVertex= 2;
//Specifies the initial position of the coordinates in the buffer
glEnableVertexAttribArray(0);
//Strides between vertex coordinates is 6 (x, y ,r, g, b, a)
//the number of floats before each vertex position
GLint vertexStride= sizeof(float)*6;
//Instructs GPU on how to handle the vertex buffer object
//parameters: atrribPointerPosition | coordinates per vertex|data type| deactivate normalizations | 0 strides | 0 offset
glVertexAttribPointer(0, floatsPerVertex, GL_FLOAT, GL_FALSE, vertexStride, 0);
//Sets an attribute pointer for the vertex colors
glEnableVertexAttribArray(1);
GLint colorStride= sizeof(float)*6;
//Parameters: attribPointerPosition 1 | floats per color is 4 | data type | deactivate normalization | 6 strides until the next color | 2 floats until the beginning of each color
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, colorStride, (char*)(sizeof(float)*2));
//Creates a buffer object for the indexes
GLushort indicies[]= 0,1,2,2,3,4;
float numIndicies= sizeof(indicies);
GLuint indexBufferID;
glGenBuffers(1, &indexBufferID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndicies, indicies, GL_STATIC_DRAW);
//Implements UInitalize function
void UInitalize(int argc, char* argv[])
//glew status variable
GLenum GlewInitResult;
UInitWindow(argc, argv);
//Check glew status
GlewInitResult= glewInit();
if (GLEW_OK != GlewInitResult)
fprintf(stderr,"ERROR: %s\n", glewGetErrorString(GlewInitResult));
exit(EXIT_FAILURE);
//Display GPU OpenGl version
fprintf(stdout, "INFO: OpenGL Version: %s\n", glGetString(GL_VERSION));
//Makes the screen black
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
//Implements the UInitWindow function
void UInitWindow(int argc, char* argv[])
//Initialize freeglut
glutInit(&argc, argv);
//Set window size
glutInitWindowSize(WindowWidth, WindowHeight);
//Memory buffer setup for display
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
//Creates a window with the macro placeholder title
glutCreateWindow(WINDOW_TITLE);
//Called when window is resized
glutReshapeFunc(UResizeWindow);
//Renders graphics on the screen
glutDisplayFunc(URenderGraphics);
//Implements the UResizeWindow function
void UResizeWindow(int Width, int Height)
glViewport(0, 0, Width, Height);
//Implements the URenderGraphics
void URenderGraphics(void)
//Clear the screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//Create the triangle
//Specifies the number of vertexes
GLuint totalVertices = 6;
//Draw the triangles
//glDrawArrays(GL_TRIANGLES, 0, totalVertices);
glDrawElements(GL_TRIANGLES, totalVertices, GL_UNSIGNED_SHORT, NULL);
//Flips the back buffer with the front buffer every frame, akin to GL Flush
glutSwapBuffers();
//Initialize the UCreateShaders function
void UCreateShaders(void)
//Create a shader program object
GLuint ProgramId = glCreateProgram();
//Create the vertex shader
GLuint vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
//Create the fragment shader
GLuint fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
//Get the source for the vertex shader
glShaderSource(vertexShaderId, 1, &VertexShader, NULL);
//Get the source for the fragment shader
glShaderSource(fragmentShaderId, 1, &FragmentShader, NULL);
//Complies the vertex shader
glCompileShader(vertexShaderId);
//Compiles the fragment shader
glCompileShader(fragmentShaderId);
//Attach shaders
glAttachShader(ProgramId, vertexShaderId);
glAttachShader(ProgramId, fragmentShaderId);
//Link the shader program
glLinkProgram(ProgramId);
//Utilizes the shader program
glUseProgram(ProgramId);
【问题讨论】:
【参考方案1】:几个问题:
UCreateShaders()
和 UCreateVBO()
永远不会被调用。
没有着色器或几何体绑定 glDrawElements()
无法做任何有用的事情。
片段着色器大小写不匹配导致链接失败:vertex_color
!= vertex_Color
:
0:6(2): error: `vertex_Color' undeclared
0:6(2): error: value of type vec4 cannot be assigned to variable of type error
确保在加载着色器时检查 GL_COMPILE_STATUS
和 GL_LINK_STATUS
并获取相应的信息日志 (glGetShaderInfoLog()
/glGetProgramInfoLog()
),以帮助在未来发现此类问题。
大家一起:
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <cstdio>
#include <cstdlib>
#include <iostream>
void CheckStatus( GLuint obj, bool isShader )
GLint status = GL_FALSE, log[ 1 << 11 ] = 0 ;
( isShader ? glGetShaderiv : glGetProgramiv )( obj, isShader ? GL_COMPILE_STATUS : GL_LINK_STATUS, &status );
if( status == GL_TRUE ) return;
( isShader ? glGetShaderInfoLog : glGetProgramInfoLog )( obj, sizeof( log ), NULL, (GLchar*)log );
std::cerr << (GLchar*)log << "\n";
std::exit( EXIT_FAILURE );
void AttachShader( GLuint program, GLenum type, const char* src )
GLuint shader = glCreateShader( type );
glShaderSource( shader, 1, &src, NULL );
glCompileShader( shader );
CheckStatus( shader, true );
glAttachShader( program, shader );
glDeleteShader( shader );
const char* const vert = R"GLSL(
#version 440
in layout(location=0) vec4 vertex_Position;
in layout(location=1) vec4 colorFromVBO;
out vec4 colorFromVShader;
void main()
gl_Position = vertex_Position;
colorFromVShader = colorFromVBO;
)GLSL";
const char* const frag = R"GLSL(
#version 440
in vec4 colorFromVShader;
out vec4 vertex_color;
void main()
vertex_color = colorFromVShader;
)GLSL";
void UCreateShaders()
GLuint prog = glCreateProgram();
AttachShader( prog, GL_VERTEX_SHADER, vert );
AttachShader( prog, GL_FRAGMENT_SHADER, frag );
glLinkProgram( prog );
CheckStatus( prog, false );
glUseProgram( prog );
void UCreateVBO()
// Specifies Coordinates
GLfloat verts[]=
/*index 0*/
-1.0f, 1.0f, // top-center of the screen
1.0f, 0.0f, 0.0f, 1.0f, // Red vertex
/*index 1*/
-1.0f, 0.0f, // bottom-left of the screen
0.0f, 0.0f, 1.0f, 1.0f, // Blue vertex
/*index 2*/
-0.5f, 0.0f, // bottom-right of the screen
0.0f, 1.0f, 0.0f, 1.0f, // Green vertex
/*index 3*/
0.0f, 0.0f, // bottom-left of the screen
1.0f, 0.0f, 0.0f, 1.0f, // Red vertex
/*index 4*/
0.0f, -1.0f, // bottom-right of the screen
0.0f, 1.0f, 0.0f, 1.0f, // Green vertex
;
//Variable for the vertex buffer object id
GLuint myBufferID;
glGenBuffers(1, &myBufferID);
glBindBuffer(GL_ARRAY_BUFFER, myBufferID);
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float)*6, 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(float)*6, (char*)(sizeof(float)*2));
glEnableVertexAttribArray(1);
//Creates a buffer object for the indexes
GLushort indicies[]= 0,1,2,2,3,4;
GLuint indexBufferID;
glGenBuffers(1, &indexBufferID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indicies), indicies, GL_STATIC_DRAW);
void URenderGraphics(void)
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLuint totalVertices = 6;
glDrawElements(GL_TRIANGLES, totalVertices, GL_UNSIGNED_SHORT, NULL);
glutSwapBuffers();
int main(int argc, char* argv[])
glutInit(&argc, argv);
glutInitWindowSize(640, 480);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutCreateWindow("GLUT");
glutDisplayFunc(URenderGraphics);
GLenum GlewInitResult = glewInit();
if (GLEW_OK != GlewInitResult)
fprintf(stderr,"ERROR: %s\n", glewGetErrorString(GlewInitResult));
exit(EXIT_FAILURE);
fprintf(stdout, "INFO: OpenGL Version: %s\n", glGetString(GL_VERSION));
UCreateVBO();
UCreateShaders();
glutMainLoop();
return 0;
【讨论】:
以上是关于带有着色器程序且没有错误的现代 OpenGL 黑屏的主要内容,如果未能解决你的问题,请参考以下文章