tBane Temat założony przez niniejszego użytkownika |
C++ SDL opengles2 GLSL - blending czyli mieszanie tekstur » 2023-02-08 13:42:46
Blending Tekstur
C++ SDL opengles2 GLSL
Witam! Oto moj program, ktory pobiera dwie tekstury i rysuje albo jedna z nich, albo dwie zblendowane. Wyglada to calkiem niezle moim zdaniem, kod jest czytelny. Nie chcialbym tego zepsuc wiec .. jak zrobic rysowanie tekstur tak azeby z jednej gladko przeszlo w druga? Myslalem o czyms takim jak stworzenie maski - gradientu z czerni w biel. Ale jak zrobic taki gradient pod dowolnym katem? Wejscie:Rezultat programu:Kod programu:#include <SDL2/SDL.h> #include <SDL2/SDL_image.h> #include <SDL2/SDL_opengles2.h> #include<iostream> using namespace std;
#include "math.cpp"
SDL_Window * window;
GLuint vTextureShader; GLuint fTextureShader; GLuint vDoubleTextureShader; GLuint fDoubleTextureShader;
GLuint textureProgram; GLuint doubleTextureProgram;
GLuint textures[ 2 ]; static GLfloat vertexes[ 6 ];
const char * vTextureSource = "attribute vec4 position;\n" "attribute vec2 texcoord;\n" "varying vec2 Texcoord;\n" "void main()\n" "{\n" "gl_Position = position;\n" "Texcoord = texcoord;\n" "}\n";
const char * fTextureSource = "precision mediump float;\n" "uniform sampler2D texture;\n" "varying vec2 Texcoord;\n" "void main()\n" "{\n" "gl_FragColor = texture2D(texture, Texcoord);\n" "}\n";
const char * fDoubleTextureSource = "precision mediump float;\n" "uniform sampler2D texture1;\n" "uniform sampler2D texture2;\n" "varying vec2 Texcoord;\n" "void main()\n" "{\n" "vec4 color1 = texture2D(texture1, Texcoord);\n" "vec4 color2 = texture2D(texture2, Texcoord);\n" "gl_FragColor = color1*0.5 + color2*0.5;\n" "}\n";
void initSDL() { SDL_Init( SDL_INIT_EVERYTHING ); SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 2 ); SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 0 ); 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_DEPTH_SIZE, 8 ); SDL_DisplayMode DM; SDL_GetCurrentDisplayMode( 0, & DM ); window = SDL_CreateWindow( "Load PNG x2 and draw textures", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, int( DM.w ), int( DM.h ), SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN ); cout << "created window size is a [" << DM.w << "x" << DM.h << "]\n"; SDL_GL_CreateContext( window ); }
void initShaders() { vTextureShader = glCreateShader( GL_VERTEX_SHADER ); fTextureShader = glCreateShader( GL_FRAGMENT_SHADER ); vDoubleTextureShader = glCreateShader( GL_VERTEX_SHADER ); fDoubleTextureShader = glCreateShader( GL_FRAGMENT_SHADER ); glShaderSource( vTextureShader, 1, & vTextureSource, NULL ); glShaderSource( fTextureShader, 1, & fTextureSource, NULL ); glShaderSource( vDoubleTextureShader, 1, & vTextureSource, NULL ); glShaderSource( fDoubleTextureShader, 1, & fDoubleTextureSource, NULL ); glCompileShader( vTextureShader ); glCompileShader( fTextureShader ); glCompileShader( vDoubleTextureShader ); glCompileShader( fDoubleTextureShader ); textureProgram = glCreateProgram(); glAttachShader( textureProgram, vTextureShader ); glAttachShader( textureProgram, fTextureShader ); doubleTextureProgram = glCreateProgram(); glAttachShader( doubleTextureProgram, vDoubleTextureShader ); glAttachShader( doubleTextureProgram, fDoubleTextureShader ); glLinkProgram( textureProgram ); glLinkProgram( doubleTextureProgram ); }
void setVertexes( vec2f screenSize, vec2f v1, vec2f v2, vec2f v3 ) { vertexes[ 0 ] = v1.x /( screenSize.x / 2.f ); vertexes[ 1 ] = v1.y /( screenSize.y / 2.f ); vertexes[ 2 ] = v2.x /( screenSize.x / 2.f ); vertexes[ 3 ] = v2.y /( screenSize.y / 2.f ); vertexes[ 4 ] = v3.x /( screenSize.x / 2.f ); vertexes[ 5 ] = v3.y /( screenSize.y / 2.f ); }
void drawTriangle( vec2f screenSize, vec2f v1, vec2f v2, vec2f v3, GLuint texture ) { glUseProgram( textureProgram ); setVertexes( screenSize, v1, v2, v3 ); GLint position = glGetAttribLocation( textureProgram, "position" ); glEnableVertexAttribArray( position ); glVertexAttribPointer( position, 2, GL_FLOAT, GL_FALSE, 0, vertexes ); GLint texcoord = glGetAttribLocation( textureProgram, "texcoord" ); glEnableVertexAttribArray( texcoord ); glVertexAttribPointer( texcoord, 2, GL_FLOAT, GL_FALSE, 0, vertexes ); glActiveTexture( GL_TEXTURE0 ); glBindTexture( GL_TEXTURE_2D, texture ); GLint textureUniform = glGetUniformLocation( textureProgram, "texture" ); glUniform1i( textureUniform, 0 ); glDrawArrays( GL_TRIANGLES, 0, 4 ); }
void drawTriangle( vec2f screenSize, vec2f v1, vec2f v2, vec2f v3, GLuint tex1, GLuint tex2 ) { glUseProgram( doubleTextureProgram ); setVertexes( screenSize, v1, v2, v3 ); GLint position = glGetAttribLocation( doubleTextureProgram, "position" ); glEnableVertexAttribArray( position ); glVertexAttribPointer( position, 2, GL_FLOAT, GL_FALSE, 0, vertexes ); GLint texcoord = glGetAttribLocation( doubleTextureProgram, "texcoord" ); glEnableVertexAttribArray( texcoord ); glVertexAttribPointer( texcoord, 2, GL_FLOAT, GL_FALSE, 0, vertexes ); glActiveTexture( GL_TEXTURE0 ); glBindTexture( GL_TEXTURE_2D, tex1 ); GLint textureUniform1 = glGetUniformLocation( doubleTextureProgram, "texture1" ); glUniform1i( textureUniform1, 0 ); glActiveTexture( GL_TEXTURE1 ); glBindTexture( GL_TEXTURE_2D, tex2 ); GLint textureUniform2 = glGetUniformLocation( doubleTextureProgram, "texture2" ); glUniform1i( textureUniform2, 1 ); glDrawArrays( GL_TRIANGLES, 0, 4 ); }
void loadTexture( GLuint & texture, const char * path ) { SDL_Surface * img = IMG_Load( path ); if( img == NULL ) { cout << "error load texture: " << path << "\n"; return; } glGenTextures( 1, & texture ); glBindTexture( GL_TEXTURE_2D, texture ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, img->w, img->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, img->pixels ); cout << "load texture: " << path << "\n"; }
void loadTextures() { loadTexture( textures[ 0 ], "obraz1.png" ); loadTexture( textures[ 1 ], "obraz2.png" ); }
int main() { initSDL(); initShaders(); loadTextures(); vec2f screen, v1, v2, v3, v4; float side = 1024; screen = vec2f( 2640, 1200 ); v1 = vec2f( - side / 2, side / 2 ); v2 = vec2f( side / 2, side / 2 ); v3 = vec2f( side / 2, - side / 2 ); v4 = vec2f( - side / 2, - side / 2 ); while( true ) { glClearColor( 0.125f, 0.125f, 0.125f, 1.0f ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); drawTriangle( screen, v1, v2, v3, textures[ 0 ] ); drawTriangle( screen, v1, v3, v4, textures[ 0 ], textures[ 1 ] ); SDL_GL_SwapWindow( window ); } return 0; }
Maska przykladowa: |