我擁有紋理,可以在OpenGL中通過常規方式渲染任何問題。但是現在我想在GLSL中渲染紋理,這是我目前遇到的問題。我沒有問題呈現一個常量矢量顏色,但它不檢測我發送給GLSL的紋理。無法通過GLSL呈現SDL紋理
下面是代碼:
GLunit wipeoutTexID;
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);
}
}
// Update objects
update();
// Render quad
render();
// Update screen
SDL_GL_SwapWindow(gWindow);
}
// Disable text input
SDL_StopTextInput();
}
// Free resources and close SDL
close();
return 0;
}
bool init() {
....
// Initialization flag
bool success = true;
....
if(!initGL()) {
success = false;
} else
{
....
wipeoutTexID = glLoadTexture(resPath + "wipeout.bmp");
if(wipeoutTexID == NULL)
{
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 vec3 aPos; void main() { vec4(aPos.x, aPos.y, aPos.z, 1.0); gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; gl_TexCoord[0] = gl_MultiTexCoord0; }"
};
// 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\nuniform sampler2D tex; uniform vec4 ourColor; void main() { vec4 color = texture2D(tex, gl_TexCoord[0].xy); gl_FragColor = mix(ourColor, color, 0.5); }"
};
// 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, "aPos");
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.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 1.0f
};
// 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)*/ sizeof(vertexData), vertexData, GL_STATIC_DRAW);
// Create IBO
glGenBuffers(1, &gIBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gIBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, /*4 * sizeof(GLuint)*/ sizeof(indexData), indexData, GL_STATIC_DRAW);
}
}
}
}
return success;
}
GLuint glLoadTexture(const std::string &file) {
GLuint tex;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
float color[] = {1.0f, 0.0f, 0.0f, 1.0f};
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glGenerateMipmap(GL_TEXTURE_2D);
gSurface = NULL;
gSurface = SDL_LoadBMP(file.c_str());
if (gSurface == NULL)
{
return NULL;
}
else
{
std::cout << "Image height: " << gSurface->h << std::endl;
std::cout << "Image width: " << gSurface->w << std::endl;
std::cout << "Images Pixels: " << gSurface->pixels << std::endl;
std::cout << "Images BitsPerPixel: " << gSurface->format->BitsPerPixel << std::endl;
std::cout << "Images Rmask: " << gSurface->format->Rmask << std::endl;
std::cout << "Images Surface: " << gSurface << std::endl;
int mode = GL_RGB;
if (gSurface->format->BitsPerPixel == 4)
{
mode = GL_RGBA;
}
GLenum data_fmt = mode;
Uint8 test = SDL_MapRGB(gSurface->format, 0xAA, 0xBB, 0xCC) & 0xFF;
if (test == 0xAA) data_fmt = GL_RGB;
else if (test == 0xCC) data_fmt = 0x80E0;//GL_BGR;
else {
printf("Error: \"Loaded surface was neither RGB or BGR!\"");
return NULL;
}
glTexImage2D(GL_TEXTURE_2D, 0, mode, gSurface->w, gSurface->h, 0, data_fmt, GL_UNSIGNED_BYTE, gSurface->pixels);
SDL_FreeSurface(gSurface);
return tex;
}
}
void render() {
// Clear color buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glActiveTexture(GL_TEXTURE0 + 0);
glBindTexture(GL_TEXTURE_2D, wipeoutTexID);
glUniform1i(glGetUniformLocation(gProgramID, "tex"), 0);
// Bind program
glUseProgram(gProgramID);
// Enable vertex position
glEnableVertexAttribArray(gVertexPos2DLocation);
// Set vertex data
glBindBuffer(GL_ARRAY_BUFFER, gVBO);
glVertexAttribPointer(gVertexPos2DLocation, 2, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), BUFFER_OFFSET(6 * sizeof(float)));
float timeValue = SDL_GetTicks();
float greenValue = 0.8f - 0.2f * abs(sin(0.001f*timeValue));
int vertexColorLocation = glGetUniformLocation(gProgramID, "ourColor");
glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f);
// 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);
glColor4f(1.f, 1.f, 1.f, 0.f);
}
你能看到我做錯了嗎?
頂點着色器:
#version 140
in vec3 aPos;
void main()
{
vec4(aPos.x, aPos.y, aPos.z, 1.0);
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_TexCoord[0] = gl_MultiTexCoord0;
}
片段着色器:
#version 140
uniform sampler2D tex;
uniform vec4 ourColor;
void main() {
vec4 color = texture2D(tex, gl_TexCoord[0].xy);
gl_FragColor = mix(ourColor, color, 0.5);
}
請張貼shader代碼更易讀的方式 – Jeka
嘗試做顯示紋理座標顏色,以檢查它是否正確。通常在片段着色器中使用每個頂點紋理座標的頂點着色器輸出。我看到你使用內置變量,但我不知道它們是如何工作的 – Jeka
好吧我已經使用這些着色器的結構化和可讀代碼更新了帖子。 – john13th