graphics

experiments with opengl3.2/ogles3.3 on linux and win7
git clone http://frotz.net/git/graphics.git
Log | Files | Refs

buffers.cc (5596B)


      1 /* Copyright 2013 Brian Swetland <swetland@frotz.net>
      2  *
      3  * Licensed under the Apache License, Version 2.0 (the "License");
      4  * you may not use this file except in compliance with the License.
      5  * You may obtain a copy of the License at
      6  *
      7  *     http://www.apache.org/licenses/LICENSE-2.0
      8  *
      9  * Unless required by applicable law or agreed to in writing, software
     10  * distributed under the License is distributed on an "AS IS" BASIS,
     11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12  * See the License for the specific language governing permissions and
     13  * limitations under the License.
     14  */
     15 
     16 #include <stdio.h>
     17 #include <stdlib.h>
     18 
     19 #include "app.h"
     20 #include "util.h"
     21 
     22 static unsigned vattr_type(unsigned type) {
     23 	switch (type) {
     24 	case SRC_INT8:   return GL_BYTE;
     25 	case SRC_UINT8:  return GL_UNSIGNED_BYTE;
     26 	case SRC_INT16:  return GL_SHORT;
     27 	case SRC_UINT16: return GL_UNSIGNED_SHORT;
     28 	case SRC_INT32:  return GL_INT;
     29 	case SRC_UINT32: return GL_UNSIGNED_INT;
     30 	case SRC_FLOAT:  return GL_FLOAT;
     31 	default:         return GL_FLOAT;
     32 	}
     33 }
     34 
     35 #define OFF2PTR(off)  (((char*) NULL) + off)
     36 
     37 void VertexAttributes::init(VertexAttrDesc *desc, VertexBuffer **data, unsigned count) {
     38 	unsigned id = 0, n;
     39 	glGenVertexArrays(1, &vao);
     40 	glBindVertexArray(vao);
     41 	for (n = 0; n < count; n++) {
     42 		if (data && (data[n]->id != id)) {
     43 			id = data[n]->id;
     44 			glBindBuffer(GL_ARRAY_BUFFER, id);
     45 		}
     46 		switch (desc->dst_type) {
     47 		case DST_FLOAT:
     48 			glVertexAttribPointer(desc->index, desc->count,
     49 				vattr_type(desc->src_type), GL_FALSE, desc->stride,
     50 				OFF2PTR(desc->offset));
     51 			break;
     52 		case DST_NORMALIZED:
     53 			glVertexAttribPointer(desc->index, desc->count,
     54 				vattr_type(desc->src_type), GL_TRUE, desc->stride,
     55 				OFF2PTR(desc->offset));
     56 			break;
     57 		case DST_INTEGER:
     58 			glVertexAttribIPointer(desc->index, desc->count,
     59 				vattr_type(desc->src_type), desc->stride,
     60 				OFF2PTR(desc->offset));
     61 			break;
     62 		}
     63 		glVertexAttribDivisor(desc->index, desc->divisor);
     64 		glEnableVertexAttribArray(desc->index);
     65 		desc++;
     66 	}
     67 }
     68 
     69 
     70 void VertexBuffer::load(void *data, unsigned size) {
     71 	if (id == 0)
     72 		glGenBuffers(1, &id);
     73 	glBindBuffer(GL_ARRAY_BUFFER, id);
     74 	glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
     75 	sz = size;
     76 }
     77 
     78 void IndexBuffer::load(void *data, unsigned size) {
     79 	if (id == 0)
     80 		glGenBuffers(1, &id);
     81 	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, id);
     82 	glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
     83 	sz = size;
     84 }
     85 
     86 void UniformBuffer::load(void *data, unsigned size) {
     87 	if (id == 0)
     88 		glGenBuffers(1, &id);
     89 	glBindBuffer(GL_UNIFORM_BUFFER, id);
     90 	glBufferData(GL_UNIFORM_BUFFER, size, data, GL_STATIC_DRAW);
     91 	sz = size;
     92 }
     93 
     94 int Texture2D::load(const char *fn, int options) {
     95 	void *data;
     96 	unsigned dw, dh;
     97 	int r;
     98 	if (!(data = load_png_rgba(fn, &dw, &dh, options)))
     99 		return error("cannot load '%s'", fn);
    100 	r = load(data, dw, dh, options);
    101 	free(data);
    102 	return r;
    103 }
    104 
    105 int Texture2D::load(void *data, unsigned w, unsigned h, int options) {
    106 	if (id == 0)
    107 		glGenTextures(1, &id);
    108 
    109 	/* GL 3.x guarantees at least 16 texture units.  We'll use */
    110 	/* unit 15 for load operations to avoid stepping on other  */
    111 	/* state that might be important. */
    112 	glActiveTexture(GL_TEXTURE0 + 15);
    113 
    114 	glBindTexture(GL_TEXTURE_2D, id);
    115 	if (!(options & OPT_TEX2D_GEN_MIPMAP)) {
    116 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
    117 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
    118 	}
    119 	if (options & OPT_TEX2D_GRAY) {
    120 		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0,
    121 			GL_RED, GL_UNSIGNED_BYTE, data);
    122 	} else {
    123 		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0,
    124 			GL_RGBA, GL_UNSIGNED_BYTE, data);
    125 	}
    126 	if (options & OPT_TEX2D_GEN_MIPMAP) {
    127 		glGenerateMipmap(GL_TEXTURE_2D);
    128 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    129 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    130 	} else {
    131 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    132 		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    133 	}
    134 	width = w;
    135 	height = h;
    136 	return 0;
    137 }
    138 
    139 int Texture2D::createRGBA(unsigned w, unsigned h) {
    140 	if (id)
    141 		glDeleteTextures(1, &id);
    142 	glGenTextures(1, &id);
    143 	glActiveTexture(GL_TEXTURE0 + 15);
    144 	glBindTexture(GL_TEXTURE_2D, id);
    145 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
    146 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
    147 	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    148 	width = w;
    149 	height = h;
    150 	return 0;
    151 }
    152 
    153 void FrameBuffer::init(unsigned w, unsigned h, unsigned _depth) {
    154 	glGenTextures(1, &txid);
    155 	glActiveTexture(GL_TEXTURE0 + 15);
    156 	glBindTexture(GL_TEXTURE_RECTANGLE, txid);
    157 	glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_BASE_LEVEL, 0);
    158 	glTexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAX_LEVEL, 0);
    159 	glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    160 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    161 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    162 
    163 	if (_depth) {
    164 		glGenRenderbuffers(1, &depth);
    165 		glBindRenderbuffer(GL_RENDERBUFFER, depth);
    166 		glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, w, h);
    167 		glBindRenderbuffer(GL_RENDERBUFFER, 0);
    168 	}
    169 
    170 	glGenFramebuffers(1, &id);
    171 	glBindFramebuffer(GL_FRAMEBUFFER, id);
    172 
    173 	/* color buffer */
    174 	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
    175 		GL_TEXTURE_RECTANGLE, txid, 0);
    176 
    177 	/* depth buffer */
    178 	if (_depth) {
    179 		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
    180 			GL_RENDERBUFFER, depth);
    181 	}
    182 
    183 	glBindFramebuffer(GL_FRAMEBUFFER, 0);
    184 
    185 	width = w;
    186 	height = h;
    187 }